多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Agentic 平台校验层:@agentic/platform-validators 如何统一解析项目、部署与工具标识符

Agentic 平台校验层:@agentic/platform-validators 如何统一解析项目、部署与工具标识符 Agentic 平台校验层agentic/platform-validators 如何统一解析项目、部署与工具标识符【免费下载链接】agenticYour API ⇒ Paid MCP. Instantly.项目地址: https://gitcode.com/GitHub_Trending/ag/agenticagentic/platform-validators是 AgenticYour API ⇒ Paid MCP. Instantly.平台的共享校验包负责把username/project-slug这类字符串标识符可靠地拆解为命名空间、项目 slug、部署版本和工具名。理解它的标识符语法、解析正则与黑白名单机制你就能看懂 Agentic 的 API 路由、Marketplace 页面和网关请求解析是如何按 ID 取数的也能在自建类似平台时参考这套严格的校验设计。包定位与安装packages/validators/readme.md 开篇即说明该包定位Core schemas and validators shared across the Agentic platform.安装方式很简单npm i agentic/platform-validatorsreadme 同时给了一个实用提示普通用户通常不需要直接使用这个包面向公众的入口是 agentic/cli、agentic/platform 和 agentic/platform-tool-client。从 package.json 可以确认包的元数据版本8.4.4、License 为AGPL-3.0、engines.node 18依赖仅agentic/platform-core、paralleldrive/cuid2、email-validator与type-fest是一个纯函数式、无副作用sideEffects: false的轻量校验库。导出面由 src/index.ts 定义包含五块内容命名空间黑名单、三个标识符解析器project / deployment / tool、工具名黑名单、类型定义以及一组isValidXxx校验函数。三类标识符语法总览readme 的 Identifiers 一节是整个包的骨架定义了 Agentic 平台三层资源的 ID 体系项目标识符Project Identifier格式username/project-slug或team-slug/project-slug示例agentic/search部署标识符Deployment Identifieragentic/search—— 省略版本时隐式等价于latest最近一次发布的部署agentic/searchlatest—— 最近发布的部署agentic/searchdev—— 最近推送push的部署agentic/searchdeploymentHash—— 指定部署哈希agentic/searchversion—— 指定 semver 版本的已发布部署示例agentic/search、agentic/searchlatest、agentic/search1.0.0工具标识符Tool Identifier格式${deploymentIdentifier}/tool_name示例agentic/search/search、agentic/searchlatest/search、agentic/search1.0.0/search工具命名规范Tool Names必须以字母或下划线开头只允许字母、数字、下划线所有工具应保持 camelCase 或 snake_case 一致readme 还特别提示了跨平台的兼容性约束OpenAI / Anthropic / Google / MCP 对工具名的限制各不相同因此 Agentic 选择了一条所有平台都接受的最保守规则见下文正则。源码级解析实现类型定义解析结果的类型层级src/types.ts 定义了三个解析结果类型恰好对应三层 ID 的包含关系export type ParsedProjectIdentifier { projectIdentifier: string projectNamespace: string projectSlug: string } export type ParsedDeploymentIdentifier ParsedProjectIdentifier { deploymentIdentifier: string deploymentHash?: string deploymentVersion?: string } // 且要求 deploymentHash / deploymentVersion 二选一 export type ParsedToolIdentifier ParsedDeploymentIdentifier { toolName: string }同时定义了所有解析器共享的选项ParseIdentifierOptions { strict?: boolean; errorStatusCode?: number }。项目解析器单一正则parse-project-identifier.ts 只有一条核心正则const projectIdentifierRe /^([a-z0-9-]{1,256})\/([a-z0-9-]{1,256})$/从源码结构看它约束了命名空间与 slug 均只允许小写字母、数字、连字符[a-z0-9-]长度 1~256大写、下划线、斜杠嵌套等一律拒绝——测试用例 parse-project-identifier.test.ts 明确列出了username/Foo-Bar、username/foo_bar、username/foo-bar缺前缀等失败场景。解析失败时抛出HttpError来自 packages/platform-core默认状态码由errorStatusCode控制缺省400。这意味着解析器可以直接嵌在 HTTP 层使用抛出的错误天然带有状态码语义。部署解析器三级正则的优先级parse-deployment-identifier.ts 依次尝试三条正则// 1. 无版本后缀 → 隐式 latest /^([a-z0-9-]{1,256})\/([a-z0-9-]{1,256})$/ // 2. 8 位小写字母数字哈希精确部署 /^([a-z0-9-]{1,256})\/([a-z0-9-]{1,256})([a-z0-9]{8})$/ // 3. 版本号semver 形态数字、点、字母、连字符 /^([a-z0-9-]{1,256})\/([a-z0-9-]{1,256})([\d.a-z-])$/几个实现细节值得注意无版本后缀的输入被规范化为deploymentIdentifier: ns/sluglatest且deploymentVersion: latest即省略即 latest在解析层就完成了语义补齐哈希正则固定 8 位小写字母数字与 validators.ts 中的deploymentHashRe /^[a-z0-9]{8}$/保持一致也对应 readme 中deploymentHash的短哈希描述dev这类保留标签走的是版本号正则[\d.a-z-]允许dev从源码结构看dev 最近推送的部署这层路由语义由上层API 层在拿到deploymentVersion后再做解析校验层只负责语法。工具解析器在部署 ID 后追加工具名parse-tool-identifier.ts 用同样的隐式 latest / 哈希 / 版本号三级结构尾部加上工具名约束const toolNameRe /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/即工具名以字母或下划线开头、总长最长 64 字符首字符 0~63。readme 中必须字母或下划线开头、仅允许字母数字下划线的规范就是这条正则的可读版本额外允许连字符[a-zA-Z0-9_-]是从源码可见的放宽。非严格模式URL 容错与向上兼容解析utils.ts 提供了coerceIdentifierexport function coerceIdentifier(identifier?: string): string | undefined { if (!identifier) return try { const { pathname } new URL(identifier) identifier pathname } catch {} identifier identifier.replace(/^\//, ) identifier identifier.replace(/\/$/, ) return identifier }从源码结构看非严格模式strict: false做了两件 readme 未展开的事接受完整 URL如果输入本身是一个可解析的 URL就取其pathname。测试用例success(https://gateway.agentic.so/username/foo-bar, { strict: false })证实了这一点——网关转发来的完整地址也能被解析层级向上回退parseProjectIdentifier在非严格模式下会先尝试parseDeploymentIdentifier后者又先尝试parseToolIdentifier见各解析器文件开头的try { return parseXxx(...) } catch {}逻辑。也就是说更具体的 ID 可以被更高层的解析器降维接受。这解释了为什么三层解析器互相 import 形成调用链。strict默认为true严格模式下 URL 形式如https://example.com/username/foo-bar会直接失败测试用例中有专门的一组error(https://...)断言。校验函数与黑名单单字段校验器validators.ts 暴露了平台各处复用的细粒度校验函数函数对应正则用途isValidNamespace/isValidUsername/isValidTeamSlugnamespaceRe /^[a-z0-9-]{1,256}$/用户/团队命名空间三者规则完全一致isValidProjectSlugprojectSlugRe /^[a-z0-9-]{1,256}$/项目 slugisValidDeploymentHashdeploymentHashRe /^[a-z0-9]{8}$/8 位短哈希isValidToolNametoolNameRe /^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$/工具名isValidPassword/^.{3,1024}$/3~1024 位任意字符isValidEmail基于email-validator邮箱isValidCuid基于paralleldrive/cuid2内部主键 cuid2isValidProjectIdentifier/isValidDeploymentIdentifier内部 try/catch 调用对应解析器布尔化封装isValidXxxIdentifier系列本质上是解析成功即有效保证校验与解析永远不会出现口径不一致——这是值得借鉴的设计单一事实来源就是那几条正则。两个黑名单命名空间黑名单namespace-blacklist.ts 包含约百余项分两类易混淆的保留词admin、root、sudo、mcp、sse、api、user、free、paid、tool、openapi、support、privacy以及404、429、500等状态码字符串——这些命名空间会污染 URL 语义或指向平台自身路由粗口过滤词。isNamespaceAllowed在格式校验isValidNamespace通过之后额外检查黑名单。工具名黑名单tool-name-blacklist.ts 非常短只有mcp和sse两项源码注释解释了原因// TODO: if we separate mcp endpoint from REST endpoint, we may be able to have // tools named mcp. would be nice not to impose a blacklist.即这两个名字是平台保留的端点路径工具名若叫mcp会与 MCP 端点冲突。isToolNameAllowed同样要求格式合法且不在黑名单。在平台中的真实使用位置这些解析器并不是孤立工具而是贯穿了 API、网关和 Web 三层。从仓库引用关系parseProjectIdentifier/parseDeploymentIdentifier/parseToolIdentifier的调用方可以看到API 层apps/api/src/api-v1/projects/create-project.ts、apps/api/src/api-v1/deployments/create-deployment.ts 在创建资源时先解析并校验标识符apps/api/src/lib/projects/try-get-project-by-identifier.ts 与 apps/api/src/lib/deployments/try-get-deployment-by-identifier.ts 则是按 ID 查库的入口解析出projectNamespaceprojectSlug/deploymentHash/deploymentVersion后作为数据库查询条件网关层apps/gateway/src/lib/resolve-edge-request.ts 负责把边缘请求路径上的标识符解析为具体部署apps/gateway/src/lib/resolve-origin-tool-call.ts 解析工具标识符后转发到对应的 origin 适配器——这正是 readme 里agentic/search1.0.0/search 这类字符串被实际消费的链路Web 层Marketplace 与 App 的项目页面路由 apps/web/src/app/marketplace/projects/[namespace]/[project-slug]/page.tsx 直接使用namespace/project-slug两个动态段与ParsedProjectIdentifier的两个字段一一对应。测试如何保证规则稳定测试文件 parse-project-identifier.test.ts、parse-deployment-identifier.test.ts 和 parse-tool-identifier.test.ts 采用success / error 双辅助函数 快照的模式每个成功用例都同时断言解析结果、各isValidXxx反查一致性和toMatchSnapshot()快照存放在 src/snapshots下失败用例覆盖缺前缀、大写、下划线、尾斜杠、多余层级、完整 URL 等边界非严格模式单独一组验证https://gateway.agentic.so/username/foo-bar与/username/foo-bar均可解析。这套正则 快照 正反用例穷举的组合使得标识符语法一旦发布就几乎不会意外漂移——对任何以字符串 ID 为核心的平台npm、Docker Hub 式 registry 设计都是可参考的实践。小结与复用建议三层标识符项目 → 部署 → 工具是层层嵌套的字符串语法ns/slug[8位哈希|semver][/toolName]是完整形态省略版本即latest是解析层自动补齐的语义所有字段约束集中为 5 条正则namespace/slug、8 位哈希、semver 尾部、工具名、密码isValid*与parse*共用同一正则杜绝口径分裂解析失败统一抛带状态码的HttpError默认 400strict: false时支持 URL 输入与更具体 ID 向下兼容的回退解析mcp、sse等保留词通过命名空间/工具名黑名单保护平台自身路由。如果你在自己的 API 网关或 MCP 网关中需要把路径解析为资源 版本 方法packages/validators/src/下每个文件都不长解析器各约 50~80 行值得直接阅读并按需移植这套设计。注意以上结论均基于当前仓库agentic/platform-validatorsv8.4.4的源码与测试dev的最近推送部署路由语义由上层 API 实现校验层仅负责语法匹配。【免费下载链接】agenticYour API ⇒ Paid MCP. Instantly.项目地址: https://gitcode.com/GitHub_Trending/ag/agentic创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表