Test Metadata
【免费下载链接】agenticYour API ⇒ Paid MCP. Instantly.项目地址: https://gitcode.com/GitHub_Trending/ag/agentic
This is testingreadme rendering.
Misc
- Item 1
- Item 2
- Item 3
- italic
- bold
- link
code
Code
const a = 1 export function foo() { console.log('hello world') }Images
逐段对照,可以看到它刻意覆盖了以下渲染要点: | 文档段落 | 覆盖的 Markdown 特性 | | --- | --- | | `Misc` 小节 | 任务列表(`- [ ]` / `- [x]` 未勾选与已勾选两种状态)、水平分割线 `---`、斜体 `_italic_`、加粗 `**bold**`、超链接、行内代码 | | `Code` 小节 | 带语言标注(`ts`)的围栏代码块,可检验代码高亮与转义 | | `Images` 小节 | 外链图片语法,可检验远程图片加载 | 需要注意:这些内容在解析阶段只是“被整段读入文件”,并不会被真正渲染;渲染发生在 Agentic 对外展示项目详情的环节。解析层要保证的只是“字节级完整读取 + 正确的 MIME 判定”,这一点由下一节的源码来印证。 ## agentic.config.ts:readme 与 icon 如何挂到项目配置上 夹具的完整配置如下([agentic.config.ts](https://link.gitcode.com/i/37974a4369416a50f50765ad474bb9a6),全文): ```ts import { defineConfig } from '@agentic/platform' export default defineConfig({ name: 'Test Metadata 0', origin: { type: 'raw', url: 'https://httpbin.org' }, icon: './agentic-dev-icon-circle-dark.svg', readme: './readme.md' }) ``` 要点说明: - `name` 为 `Test Metadata 0`,配置中没有手写 `slug`,由平台从 name 自动派生 kebab-case slug(快照结果为 `test-metadata-0`,见后文)。slug 的规则可从负向夹具的错误信息确认:“Must be ascii-only, lower-case, and kebab-case with no spaces between 1 and 256 characters”(快照 [load-agentic-config.test.ts.snap](https://link.gitcode.com/i/89dbea9bdbece01c46535d4329c1b36e) 中 `invalid-slug-3` 用例)。 - `origin` 使用 `raw` 类型并指向 `https://httpbin.org`,与元数据本身无关,只是为了满足配置必填项。 - `icon` 与 `readme` 都使用以 `./` 开头的**本地相对路径**——这正是 metadata-0 区别于其他夹具的核心特征:它验证“本地文件”这一取值分支。 ## 元数据的两阶段处理:URL 直通 vs 本地文件 Base64 内联 ### 校验阶段:validateMetadataFile `loadAgenticConfig`([load-agentic-config.ts](https://link.gitcode.com/i/c2f31d73ed6456b7503a5528e72ebac7))先用 unconfig 按 `agentic.config` + 扩展名 `['ts', 'mts', 'cts', 'js', 'mjs', 'cjs', 'json']` 加载配置文件,再交给 `validateAgenticProjectConfig` 做整体校验,其中 `readme`/`icon` 两个字段由 [validate-metadata-file.ts](https://link.gitcode.com/i/019806d0b21dfcabd6ab02ff5b46b5b3) 逐个处理。其核心逻辑(第 16~39 行)是一个“先 URL 后文件”的 try/catch 分叉: ```ts if (!input) return let source: string | ArrayBuffer | URL try { // Check if it's a URL. source = new URL(input) return source.toString() } catch { try { // Not a URL; check if it's a local file path. const buffer = await readFile(path.resolve(cwd, input)) const mime = lookupMimeType(path.extname(input)) ?? 'application/octet-stream' return `data:${mime};base64,${buffer.toString('base64')}` } catch { throw new Error( `Invalid "${label}" (must be a URL or a path to a local file): "${input}"` ) } } ``` 对照 metadata-0,可以读出四个实现事实: 1. **相对路径以 `cwd` 为基准解析**:`path.resolve(cwd, input)` 中,`cwd` 由 [validate-metadata-files.ts](https://link.gitcode.com/i/905cb2b039bd1a6e8be3d9d0e55c8087) 传入,默认 `process.cwd()`;在测试场景下则显式传夹具目录(见 [load-agentic-config.test.ts](https://link.gitcode.com/i/13d0a286cf956891de34ff26b1d4736e) 中 `loadAgenticConfig({ cwd: fixtureDir })`)。所以 `./readme.md` 解析的是夹具目录内的文件,而非仓库根目录。 2. **MIME 由扩展名查表得出**:使用 `mrmime` 的 `lookupMimeType(path.extname(input))`,`.md` 查得 `text/markdown`、`.svg` 查得 `image/svg+xml`;查不到时回退 `application/octet-stream`。 3. **本地文件最终变成 Data URI**:`data:${mime};base64,<base64>`,也就是说配置解析完成后,readme/icon 不再依赖文件系统,内容被完整内联进配置对象,可随项目配置序列化、传输。 4. **文件读不到时抛带标签的错误**:错误文案 `Invalid "readme" (must be a URL or a path to a local file)` 中的 `label` 会标明是 `readme` 还是 `icon`,便于定位字段。 ### 解析(部署)阶段:resolveMetadataFile 从源码结构看,本地文件转 Data URI 是“加载/校验”阶段的行为;在真正部署时还有一次 [resolve-metadata-file.ts](https://link.gitcode.com/i/9fc925550712caf17880c24d37b9bc48) 的处理,它对输入的要求更严格——**必须是合法 URL**,然后交由 `uploadFileUrlToStorage` 把文件拷贝进平台存储并返回新的存储 URL(第 15~21 行): ```ts try { const source = new URL(input) return uploadFileUrlToStorage(source.toString()) } catch { throw new Error(`Invalid "${label}" must be a public URL: "${input}"`) } ``` [resolve-metadata-files.ts](https://link.gitcode.com/i/c1eb05e358e343c64df77b2306ec07eb) 会把 `readme` 和 `icon` 各自走一遍该流程,返回结构里 icon 字段改名为 `iconUrl`。这也解释了为什么 Data URI 形式对系统很友好:它本身就是一个合法 URL,两个阶段都能消费。 ## 快照证据:metadata-0 解析后的完整形态 测试通过 `toMatchSnapshot()` 锁定了解析产物,快照([load-agentic-config.test.ts.snap](https://link.gitcode.com/i/89dbea9bdbece01c46535d4329c1b36e#L409-L449) 中 `metadata-0` 用例)给出了可验证的最终结果,摘录关键字段: ```jsonc { "name": "Test Metadata 0", "slug": "test-metadata-0", "readme": "data:text/markdown;base64,IyBUZXN0IE1ldGFkYXRh...", "icon": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTYi...", "origin": { "location": "external", "type": "raw", "url": "https://httpbin.org" }, "defaultRateLimit": { "enabled": true, "interval": 60, "limit": 1000, "mode": "approximate" }, "pricingIntervals": ["month"], "pricingPlans": [ { "name": "Free", "slug": "free", "lineItems": [{ "slug": "base", "usageType": "licensed", "amount": 0 }], "rateLimit": { "enabled": true, "interval": 60, "limit": 1000, "mode": "approximate" } } ], "toolConfigs": [] } ``` 可以核对的事实: - `readme` 字段的 Base64 前缀 `IyBUZXN0IE1ldGFkYXRh` 解码后正是 `# Test Metadata`,与 [readme.md](https://link.gitcode.com/i/4bba8585d92ebc92a406279c43998da6) 首行逐字节对应,证明“整文件读取 → 内联”没有截断;MIME 前缀 `text/markdown` 印证了 mrmime 查表结果。 - `icon` 前缀 `PHN2Zy` 解码为 `<sv`,即 SVG 文件起始 `<svg`,MIME 为 `image/svg+xml`。 - 未显式声明的字段都有平台默认值:`defaultRateLimit`(每分钟 1000 次、approximate 模式)、月度计费区间加一个 `Free` 计划(`base` 行项、licensed、0 元)。这说明元数据夹具与限流、计费默认值是同一条配置管线里被一起补齐的。 ## 边界与失败用例:从负向夹具看校验规则 同一套测试还注册了 `invalid-metadata-0` 与 `invalid-metadata-1` 两个负向夹具([load-agentic-config.test.ts](https://link.gitcode.com/i/aa46069714386a8d438fe136e2eceed1)),快照锁定了它们的报错形态: ```text [Error: Invalid "readme" (must be a URL or a path to a local file): "./not-found.md"] [ZodValidationError: Expected string at "icon"]【免费下载链接】agenticYour API ⇒ Paid MCP. Instantly.项目地址: https://gitcode.com/GitHub_Trending/ag/agentic
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考