Composio Mastra Provider 测试指南从 wrapTool 到 Schema 兼容性的完整测试体系【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composioComposio 的composio/mastra包将 1000 Composio 工具转换为 Mastra AI 框架的原生createTool格式并内置执行能力。本文基于仓库中 ts/packages/providers/mastra/test/README.md 展开逐层讲解该 provider 的单元测试覆盖范围、测试结构与 Mock 策略并结合 src/index.ts 与各测试文件的源码实现剖析 wrapTool/wrapTools/executeTool 的底层原理、strict 模式、输出 Schema 放宽relaxation以及$ref悬空引用的容错机制。读完本文你将掌握如何运行与扩展这套测试并理解 Mastra 与 Composio 集成时的类型转换、Schema 映射与错误处理全貌。测试目录概览为什么需要一个专属测试 READMEcomposio/mastra的测试位于 ts/packages/providers/mastra/test该目录包含 5 个测试文件覆盖 provider 从身份声明到真实 Schema 编译的完整契约mastra.test.ts主测试套件覆盖 provider 属性、工具包装、工具集合、执行、MCP 转换、strict 模式与类型安全mastra-ref.test.ts针对真实mastra/schema-compat的$ref回归测试mastra-dangling-defs.test.ts针对悬空$ref声明了引用却未定义$defs的容错回归测试output-validation.integration.test.ts验证输出 Schema 放宽后真实第三方 API 响应可通过校验的集成测试relax-output-schema.test.ts对relaxOutputSchema纯函数的逐条规则测试。这套测试的价值在于它不只验证函数不抛错还验证与 Mastra 的集成契约是否正确——包括 Schema 是否经createTool正确传递、工具结果能否通过 Mastra 的validateToolOutput校验、类型推断是否保持安全。Provider 属性测试身份与能力的断言测试套件首先验证 provider 的基础属性见 mastra.test.tsName verification断言provider.name mastra对应 src/index.ts 中readonly name mastra的实现Agentic nature断言provider._isAgentic true确认该 provider 支持工具执行是可行动的agenticprovider而非纯被动数据源。这两条断言为整个集成定下基调MastraProvider继承自BaseAgenticProviderMastraToolCollection, MastraTool, MastraUrlMap是 Composio 统一 Provider 抽象中的Mastra 方言实现。wrapToolComposio 工具到 Mastra createTool 的转换wrapTool是整套集成的核心。测试覆盖以下场景mastra.test.tsBasic wrapping验证createTool以正确的参数被调用返回的对象具有id、description、inputSchema、outputSchema、execute五个关键字段Schema handling验证输入/输出参数通过 Schema 转换器正确映射Edge cases工具缺失description回退为空字符串、缺失inputParameters回退为空对象{}、缺失outputParameters同理时均能优雅处理Execution context测试execute闭包在空参数{}、缺失参数undefined、完整参数三种上下文下的行为——缺失参数会被规范化为{}而不是原样透传undefined对应 issue #2406。底层调用链从 Tool 到 MastraTool对照 src/index.tswrapTool的实际流程是读取tool.inputParameters作为输入 Schemastrict 模式若构造 provider 时传入strict: true调用toStrictJsonSchema将输入 Schema 规范化为 OpenAI structured outputs 契约所有属性进required、对象闭合、可选属性放宽为可接受null若 Schema 无法表达如接受任意键的对象、allOf、prefixItems、未解析的$ref则保留原 Schema 并输出一条logger.warn解引用$ref调用dereferenceJsonSchema以onUnresolved: sentinel模式处理内部$ref指针将悬空引用替换为宽松的对象 Schema{ type: object, additionalProperties: true }兼容层转换applyCompatLayer({ schema, compatLayers: [], mode: jsonSchema })将 JSON Schema 交给mastra/schema-compat处理供 Mastra 内部编译为 Zod输出 Schema 放宽对tool.outputParameters先解引用、再经relaxOutputSchema放宽详见下文创建 Mastra 工具createTool({ id: tool.slug, description, inputSchema, outputSchema, execute })执行包装execute闭包内部先normalizeToolArguments规范化参数兼容模型把工具输入输出成 JSON 字符串的情况issue #2406再在 strict 模式下用omitNullToolArguments剔除工具自身 Schema 不接受null的参数最后调用全局executeTool函数。测试通过 MockcreateTool后取出.mock.calls[0][0].executegetCreatedToolExecute辅助函数来直接驱动execute闭包从而验证参数规范化与版本透传行为——包括工具带version: 20250101_01与不带版本两种情形执行函数均以(tool.slug, inputData)形式调用全局执行器。wrapTools批量包装与集合键映射wrapTools将工具数组归约为以工具 slug 为键的键值集合mastra.test.tsMultiple tools多个工具逐个经wrapTool包装createTool被调用的次数与工具数一致Empty arrays空数组返回空对象{}且不会触发createToolKey mapping集合键严格使用tool.slug如first-tool、second-tool、third-toolDuplicate handling重复 slug 时后者覆盖前者集合仅保留一个键。实现见 src/index.tstools.reduce((acc, tool) { acc[tool.slug] this.wrapTool(tool, executeTool); return acc; }, {})。该返回值直接可传给 MastraAgent的tools字段。executeTool全局执行、Modifiers 与错误传递executeTool是执行层入口测试验证mastra.test.tsGlobal execution调用provider.executeTool(slug, params)会转发到_setExecuteToolFn注入的全局执行函数第三个参数为undefinedModifiers supportbeforeExecute/afterExecute修饰器会原样作为第三个参数传给全局执行函数Error handling当执行函数返回{ data: null, error: { message: Tool execution failed }, successful: false }时executeTool将其原样透传不抛异常、不吞错误。Mastra 集成与类型安全测试集成层测试mastra.test.ts重点验证三件事Compatibility包装结果具备id、description、inputSchema、outputSchema、execute属性其中execute必须是函数且id与工具 slug 一致——这是 MastracreateTool的硬性契约Type safetyMastraTool与MastraToolCollection的类型定义见 src/index.ts在测试中通过类型断言验证MastraToolCollection是字符串键对象而非数组Minimal tools仅含 slug/name/description/tags 的最小工具也能包装成功缺失的 Schema 全部回退为空对象。错误处理执行失败与畸形 Schema错误路径测试mastra.test.ts确保鲁棒性Execution failuresexecute闭包内执行函数rejects时异常向上抛出测试用rejects.toThrow(Execution failed)断言Malformed schemasinputParameters为null、outputParameters为undefined的工具调用wrapTool不会抛异常Schema 回退为空对象。strict 模式测试OpenAI structured outputs 契约strict 模式是MastraProvider的可选能力new MastraProvider({ strict: true })测试覆盖mastra.test.ts默认关闭不传参构造时strict falserequired-nullable 语义开启后可选属性optional_field: { type: string }被改写为{ type: [string, null] }并加入required对象追加additionalProperties: false——即所有属性必填但可选属性放宽为接受 null不可表达的工具保留原 Schema如headers: { type: object, additionalProperties: { type: string } }接受任意键的 map无法表达为闭合对象则整体保留原 Schemanull 参数剔除strict 模式下工具自身 Schema 不接受null的参数如cfg.note: null在执行前被剔除而 Schema 本身声明可空type: [string, null]的参数如clearable: null保留非对象/缺失参数inputParameters为字符串 Schema 或undefined时原样/回退处理不因 strict 模式崩溃wrapTools 联动strict 模式下批量包装仍以 slug 为键且每个工具的 Schema 都应用 required-nullable 改写。输出 Schema 放宽让真实第三方 API 响应通过校验这是整个 provider 最具价值的设计之一。Mastra 会通过validateToolOutput用outputSchema校验每个工具结果不匹配就丢弃数据并替换为错误。而 Composio API 下发的输出 Schema 是严格的可选字段被声明为非空原始类型、对象带additionalProperties: false。真实第三方 APILinear、Notion、Jira、Slack 等常对未设置的字段返回null偶尔还返回多余键导致原本合法的响应被拒、模型看到的工具输出被截断。解决方案是 relax-output-schema.ts 中的relaxOutputSchema纯函数对输出 Schema 做四项只放宽、不收紧的改写所有类型节点可空化type: string→[string, null]已含null的类型数组不重复追加additionalProperties: false或未设置的对象允许额外键改为true若additionalProperties本身是 Schema则递归放宽enum/const放宽为接受nullconst: fixed变为enum: [fixed, null]enum: [open, closed]变为enum: [open, closed, null]删除required真实 API 对未设置的字段是直接省略而非返回null强求字段存在会拒掉合法输出。该函数递归遍历items、anyOf、oneOf、allOf、properties、$defs等所有子 Schema 位置并刻意不处理not关键字——not是否定语义放宽其内层 Schema 反而会收窄父级可接受的值域违背只放宽的不变量relax-output-schema.test.ts 专门回归验证。同时函数不修改输入对象不可变null/undefined原样透传。output-validation.integration.test.ts 用真实mastra/schema-compat跑完整链路relaxOutputSchema → applyCompatLayer → convertSchemaToZod → parse证明严格 Schema 拒绝含null可选字段的真实响应复现 bug放宽后同一响应success true且null与额外键完整保留、无数据截断enum放宽后仍拒绝非法值nopenot关键字下此前合法的值null、数字依旧合法。$ref回归测试解引用与悬空引用容错Schema 中的$ref是另一个真实痛点对应两个回归测试文件mastra-ref.test.ts 使用真实mastra/schema-compat不 Mock验证dereferenceJsonSchema后$defs中User.id的类型信息被保留type: string而非被降级为宽容的原始类型anyOf输出侧definitionsDraft-7 写法同样被保留放宽后为[string, null]包装后的 Schema 中不再残留任何$ref字符串mastra-dangling-defs.test.ts 针对 issue #3307Composio API 下发的部分工具如GMAIL_FETCH_EMAILS声明了$ref: #/$defs/...却从未定义$defs严格解引用会抛异常并让tools.get直接崩溃。Provider 通过onUnresolved: sentinel将悬空分支替换为宽松对象 Schema并保证包装不抛异常、输出 Schema 中无残留$ref每个(toolSlug, ref)对只输出一条logger.warnwarnedDanglingRefs集合去重提示降级为宽松校验并指向 issue 跟踪不同 slug 携带相同 ref 时分别告警告警内容中的用户可控片段slug、toolkit、ref经JSON.stringify转义中和换行/ANSI 转义/控制字节防止日志伪造CWE-117 回归测试同时向 telemetry 发送composio.mastra.wrapTool.danglingRef聚合事件每对一次可被COMPOSIO_DISABLE_TELEMETRYtrue关闭可解析的$ref不触发任何告警与遥测。测试结构Vitest 约定与 Mock 策略按 test/README.md 的说明测试遵循 Vitest 约定Comprehensive mocking对mastra/core具体是createTool与composio/corejsonSchemaToModel即 Schema 转换使用vi.mock()隔离外部依赖Setup and teardownbeforeEach中重新构造MastraProvider、重置 Mock 工具与执行函数、vi.clearAllMocks()保证每个用例干净隔离Detailed assertions成功与失败场景均有详尽断言expect(createTool).toHaveBeenCalledWith({...})全量比对调用参数Type-safe implementations测试内定义MockedMastraTool、CreateToolMockConfig等接口保持类型安全。值得注意的是 Vitest 的 Mock 作用域按文件隔离mastra.test.ts顶层vi.mock(mastra/schema-compat)不会泄漏到mastra-ref.test.ts与mastra-dangling-defs.test.ts因此这两个文件能对真实mastra/schema-compat基于 AJV 的编译链路做端到端验证。此外由于mastra/core的createTool≥1.43会把 JSON Schema 包装进JsonSchemaWrapper测试用getSchema()辅助函数穿透包装层检查真正编译产物的 JSON Schema。运行测试按 test/README.md 与 package.json 的脚本配置# 在 mastra provider 目录内运行等价于 vitest run npm test # 从工作区根目录运行仅过滤 composio/mastra 包 pnpm test --filtercomposio/mastrapackage.json中test: vitest run、typecheck: tsc --noEmit --skipLibCheck可配合使用。注意该包要求node 22.22.3peer 依赖为composio/core 0.10.0、mastra/core ^1.46.0、zod ^3.25 || ^4运行前需确保依赖满足。扩展测试的建议结合上述源码若需为 provider 新增测试可参考以下切入点新的 Schema 关键字放宽规则在relaxOutputSchema中增加规则时先在 relax-output-schema.test.ts 补纯函数用例再在 output-validation.integration.test.ts 补真实编译链路用例保证只放宽不变量新的执行上下文形态在execute闭包新增参数规范化逻辑时参照 issue #2406 的测试模式同时断言对象输入与 JSON 字符串输入两条路径strict 模式边界凡新增strict 模式无法表达的 Schema 形态应断言其保留原 Schema 且只产生一次告警避免日志刷屏$ref场景仿照mastra-dangling-defs.test.ts构造悬空/可解析/恶意 ref 三类 fixture同时验证告警去重、CWE-117 转义与 telemetry 事件计数。小结test/README.md 用一份精炼的清单勾勒了composio/mastra的测试全貌provider 属性、工具包装、集合映射、执行链路、Mastra 集成契约、错误处理与类型安全。而测试文件本身则沉淀了四个真实生产问题的回归保障——模型输出 JSON 字符串参数#2406、严格输出 Schema 截断第三方响应#3047、悬空$ref导致tools.get崩溃#3307与日志注入CWE-117。理解这套测试等于同时理解了 Mastra Provider 的 Schema 转换管线与容错哲学对输入做结构化约束strict 模式对输出做宽容校验relaxation对上游数据缺陷做降级不崩溃。【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考