ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

@composio/core 技术演进深度解析:Composio TypeScript SDK 核心包的安全、Schema 与会话工程

@composio/core 技术演进深度解析:Composio TypeScript SDK 核心包的安全、Schema 与会话工程 composio/core 技术演进深度解析Composio TypeScript SDK 核心包的安全、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/core是 Composio TypeScript SDK 的公共核心包承担工具Tools、工具包Toolkits、连接账户Connected Accounts、触发器Triggers、Tool Router 会话与文件传输等全部底层能力并为 Anthropic、OpenAI、LangChain、Mastra 等 provider 包提供共享实现。本文以 ts/packages/core/CHANGELOG.md 为骨架从版本 0.1.0 演进到 0.18.1 的完整变更记录中梳理出 SSRF 防护、敏感文件上传拦截、工具 Schema 严格化、请求取消、Tool Router 会话等几条主线并结合 src 目录 中的真实实现逐一验证。读完本文你将理解 Composio 核心包如何处理用户提供的 URL 与文件路径这类高危险输入如何在 JSON Schema 与各 LLM provider 的严格模式之间做适配以及 SDK 层的错误契约与请求生命周期控制是如何设计的。一、包定位被所有 TypeScript provider 共享的运行时核心从 package.json 可以看到composio/core当前版本为0.18.1其关键约束与依赖如下维度取值说明最低 Node 运行时22.22.30.18.0 起声明为所有已发布 TypeScript 包的硬性下限模块格式ESM-only0.12.0 起移除 CommonJS 入口不再发行.cjs产物直接依赖composio/client、composio/json-schema-to-zod、openai、zod-to-json-schema、undici、pusher-js等工具 schema 转换与推送事件订阅依赖peerDependencieszod 3.25.76 5自定义工具同时支持 Zod v3 与 v40.12.0 修复最值得注意的是条件导出设计#platform、#files、#file_tool_modifier、#config_defaults、#ssrf_guard五个内部入口按workerd/edge-light/node三种运行时分发不同实现。这是 Cloudflare Workers 兼容性的基础——0.5.0 起composio/core支持 Workers 并通过端到端测试0.6.0 进一步将文件工具修饰器按 Node.js 与 Workers 拆分、移除node:buffer改用Uint8Array、移除触发器中的node:crypto以支持边缘运行时。从源码结构看src 目录 按职责划分为errors/统一错误体系、models/Tools、Toolkits、Triggers、ConnectedAccounts、Sessions、ToolRouter 等业务模型、utils/SSRF 防护、敏感路径拦截、JSON Schema 工具、取消机制等、platform/node / workerd 平台抽象与provider/BaseProvider、ComposioProvider、OpenAIProvider。二、安全防护贯穿多个版本的主线工程CHANGELOG 中安全相关条目占比最高是理解这个包演进的核心线索。2.1 SSRF 防护从用户 URL 到 API 响应 URL 的全面覆盖SSRF 防护经历了三个阶段0.14.0composio.files.upload(url)与工具执行中的自动文件上传此前对用户提供的 URL 直接fetch()无任何防护。修复后先解析主机名拒绝私网、loopback、link-local含云元数据端点169.254.169.254、CGNAT 与保留地址拒绝非http(s)协议并手动跟随重定向使每一跳重新校验阻断公网 URL 重定向进内网的攻击。被阻断时抛出ComposioBlockedInternalUrlError仅 Node 生效。0.14.1Tool Router 会话的 URL 上传upload_url接入同一防护并增加流式 100 MiB 响应上限。0.17.0防护扩展到来自 API 响应的 URL——工具执行下载s3Url、S3 预签名上传new_presigned_url、Tool Router 会话文件下载RemoteFile.buffer()/blob()/text()/save()全部走同一套守卫防止响应命名私网地址时被 SDK 代为抓取。实现位于 src/utils/ssrfGuard.node.ts几个关键设计校验的是解析后的地址而非主机名字符串assertSafeFetchTarget()用node:dns/promises的lookup(host, { all: true, verbatim: true })拿到全部 A/AAAA 记录再逐条用isBlockedIp()判定避免十进制/八进制/十六进制 IP 混淆绕过。DNS-rebindingTOCTOU窗口关闭0.18.0校验通过的地址通过createPinnedDispatcher()固定为实际连接目标主机名不会在校验与建连之间被二次解析每次重定向跳转都会重新校验并重新固定。请求仍携带原始主机名的Host头与 TLS SNI因此证书校验行为不变。重定向语义手动实现重定向被限制在301/302/303/307/308304/305不跟随每跳按 Fetch 标准改写方法与请求体头如303后除HEAD外一律变GET并丢弃 body跨源重定向会剥离authorization、cookie、proxy-authorization凭据头。每次重定向的中间响应体被显式cancel()释放0.15.0 起全面处理这类已知会被放弃的未读响应体。代理残差如实保留当有效调度器是调用方提供的dispatcher、全局ProxyAgent/EnvHttpProxyAgent或NODE_USE_ENV_PROXY环境代理模式时只做连接前校验而不固定地址——因为固定会绕过代理而代理会自行解析主机名。这与 Python 版防护的_proxy_applies行为一致。边缘运行时Workers不阻断会话文件传输因为 Worker 无法解析 DNS 且其fetch不发生在调用方网络内。错误类型定义在 src/errors/SsrfErrors.tsComposioBlockedInternalUrlError携带url与resolvedIp元数据并给出三条possibleFixes改用公网 http(s) URL、不要指向 localhost/私网、内网来源请先自行下载再传 File/Blob。2.2 敏感文件上传拦截默认阻断凭据路径自动文件上传面临LLM 让 Agent 把.env、SSH 私钥上传给第三方工具的风险。防护分两次落地0.6.11默认阻断常见凭据目录.ssh、.aws等与凭据样式文件名.env、默认 SSH 私钥名可通过sensitiveFileUploadProtection: false关闭用fileUploadPathDenySegments扩展黑名单新增beforeFileUpload钩子与ComposioSensitiveFilePathBlockedError、ComposioFileUploadAbortedError。0.14.0将守卫导出到包根assertSafeFileUploadPath、isBlockedSensitiveFileUploadPath、BUILTIN_FILE_UPLOAD_PATH_DENY_SEGMENTS并让文件系统访问走#platform抽象新增realpathSync平台方法使模块不携带静态node:*导入、可被composio/cli等下游包共享。0.15.0按目标文件系统实际的大小写敏感性匹配路径段防止大小写不敏感挂载绕过黑名单、同时避免在大小写敏感挂载上误伤不同路径。0.18.0阻断被符号链接解析隐藏的敏感目录/文件名。实现见 src/utils/sensitiveFileUploadPaths.tsexport const BUILTIN_FILE_UPLOAD_PATH_DENY_SEGMENTS: readonly string[] [ .ssh, .aws, .azure, .gnupg, .kube, .docker, .claude, // 可能包含 API 密钥与助手读取的项目上下文 .password-store, keychains, // 如 ~/Library/Keychains ];此外还有两个文件名级规则SECRET_LIKE_BASENAME匹配.env、.netrc、.pgpassDEFAULT_PRIVATE_KEY_BASENAME匹配id_rsa、id_ed25519等公开钥id_rsa.pub放行。normalizePath()同时返回书写路径与符号链接解析后的路径并分别匹配——因为.aws可能被符号链接藏进看似无辜的目录而~/.claude - /state/claude这类 dotfile 管理器布局会把敏感段从解析路径中藏掉。2.3 遥测与日志脱敏凭据不离开进程边界0.14.0错误遥测此前原样发送error.message/error.stack现在先经脱敏器剥离 URL 查询串、AuthorizationBearer/Basic 凭据与形如keyvalue的密钥对。0.15.0补上 JSON payload 场景——{api_key: ...}这种序列化错误文本因旧规则要求分隔符紧贴键名而漏脱敏现已修复。0.18.0遥测请求增加超时上限避免卡死的遥测端点让 SDK 调用无限挂起0.11.0 起遥测批次与错误发送已改为延迟执行不等遥测网络请求返回。0.18.1脱敏下沉到SDK 日志边界凡是凭据形状的值在进入日志前一律被改写。2.4 其他安全修复0.14.1Cloudflare Workers/Edge 路径辅助函数中用于裁剪首尾斜杠的回溯正则被替换为索引遍历循环消除长斜杠串上的多项式时间 ReDoSCodeQLjs/polynomial-redos。0.18.0tools.execute与tools.proxyExecute属非幂等写操作现通过maxRetries: 0的兄弟客户端禁用静默重试防止读超时后的重试重复副作用如重复发送同一封邮件读操作保留默认重试。三、工具 Schema 工程JSON Schema 与 LLM Provider 之间的适配层工具 schema 的解析与转换是composio/core的另一条主线也是与composio/json-schema-to-zod深度协作的领域。3.1 OpenAI structured outputs 严格模式0.18.0OpenAI 的 strict tool calling 要求每一层嵌套对象、anyOf分支、数组元素、内联$ref/$defs的对象都把所有属性列入required且additionalProperties: false。0.18.0 之前嵌套或可选参数的工具会产生 API 以 400 拒绝的 schema。修复后可选参数不再被丢弃而是保留并放宽为接受nullOpenAI 文档化的可选字段模拟方式严格 provider 会在执行工具前丢弃工具自身 schema 不接受的null参数。严格模式无法表达的工具任意键对象、allOf、prefixItems、未解析的$ref改为不启用严格模式发送并发出指明工具名与路径的警告而不是被错误地收窄。composio/core新增导出toStrictJsonSchema()与omitNullToolArguments()实现见 src/utils/jsonSchema.tsremoveNonRequiredProperties对其他调用方保持原样。Python 侧OpenAIResponsesProvider增加对应的strictTrue构造参数同样在包装的工具上发出strict: true。3.2 自由形态对象与组合关键字的保留0.16.0ToolSchema.parse此前会拒绝裸的{ type: object }根、丢弃根级patternProperties、拒绝 schema 形式的additionalProperties。0.16.0 修复后自由形态根可正常解析两个约束原样保留ToolSchema类型的properties变为可选。这对下游至关重要——所有 provider 在解析后都会读取inputParameters声明动态键的工具此前规则在模型看到之前就被剥离了。示例const tool ToolSchema.parse({ slug: MY_TOOL, inputParameters: { type: object, properties: { name: { type: string } }, additionalProperties: { type: number }, }, // ... }); // 现在 tool.inputParameters.additionalProperties 是 { type: number }同版本还修复了嵌套 JSON Schema 节点携带properties却无显式type时补写type: object使工具 schema 兼容 Google Gemini 这类严格 OpenAPI 3.0 消费者。3.3 JSON Schema 属性的递归类型化0.15.0JSONSchemaProperty从composio/core再导出可通过Tool.input_parameters/Tool.output_parameters触达从事实上的any变为具体递归接口。运行时行为不变但消费方若未收窄就做schema.properties.foo.type或schema.default.someField这类索引访问可能遇到新类型错误——properties条目现在是可能 undefineddefault/enum值为unknown。升级时需要用可选链或显式类型守卫收窄。3.4$ref指针处理从崩溃到哨兵降级0.9.0新增dereferenceJsonSchema助手在把工具参数交给mastra/schema-compat前内联展开内部$ref#/$defs/...、#/definitions/...避免 AJV 的cant resolve reference错误并让$defs里的类型信息在 JSON Schema → Zod → JSON Schema 往返中不被降级为宽松的anyOf外部http(s)指针保持不动。0.11.0Composio API 会发出引用未声明$defs的悬空指针如GMAIL_FETCH_EMAILS的outputParameters引用#/$defs/FetchEmailsResponse但从未声明。此前会导致composio.tools.get(...)直接抛JsonSchemaRefResolutionError。修复后dereferenceJsonSchema接受{ onUnresolved?: throw | sentinel }默认仍是throw自建/自定义工具拼错的$ref继续硬报错传入sentinel时用循环断开的哨兵{ type: object, additionalProperties: true }替换并附默认description提示让 LLM 知道该分支不透明。MastraProvider.wrapTool对输入输出参数都选择sentinel模式并每对(toolSlug, ref)只发一次警告警告文本经过JSON.stringify中和换行/ANSI 转义/控制字节防日志注入。3.5 属性键消毒与参数规范化0.12.0sanitizeSchemaPropertyKeys(schema, policy)处理部分 provider 对input_schema属性键的字符/长度限制——递归改写违规键为合规别名覆盖properties、数组items/prefixItems、组合关键字allOf/anyOf/oneOf、not/if/then/else、additionalProperties/patternProperties/$defs/contains并记录 schema 形状的反向映射执行前恢复原始参数名。composio/anthropic已接入。0.11.0normalizeToolArguments统一处理模型把工具调用参数以 JSON 字符串而非对象下发的情况Vercel AI SDK 的COMPOSIO_MULTI_EXECUTE_TOOL最常见。对象原样通过、JSON 字符串被解析、空/null变{}、无法解析为对象时抛类型化ComposioInvalidToolArgumentsError取代了此前各 provider 各自为政的守卫。0.12.0composio/core/utils/json-schema子路径导出jsonSchemaToZodShape并修复 Zod v4 对象 schema 被降级为空 schema 的问题自定义工具现在能正确转换 zod/v3 与 Zod v4。四、文件上传/下载机制从默认开启到显式 opt-in自动文件上传经历了默认开启 → 默认关闭的安全转向0.8.0分水岭移除旧autoUploadDownloadFiles构造选项新增dangerouslyAllowAutoUploadDownloadFiles默认false。开启后 SDK 把file_uploadableschema 折叠为{ type: string, format: path }交给模型执行时暂存本地路径/URL。配套参数在 0.8.0 引入fileUploadDirs?: string[] | false本地上传路径的 fail-closed 白名单undefined默认[home/.composio/temp]false拒绝所有本地路径fileDownloadDir?file_downloadable结果的 S3 下载暂存目录beforeFileUpload修饰器新增source: path | url | file参数。关闭自动上传时执行带file_uploadable输入的工具会每个 slug 发一次一次性警告指引用composio.files.upload()手动暂存。0.18.0空字符串的 file-uploadable 参数被从执行请求中省略此前会转发给后端并收到 Input should be a valid dictionary or instance of FileUploadable且该行为在开关关闭时同样生效避免空值被当作上传尝试。0.18.1S3 自动下载封顶100 MiB每次调用可配置防止超大或流式响应耗尽内存文件下载的传输层失败被映射进 SDK 错误契约并释放流式响应体。文件上传/下载还覆盖组合 schema0.5.3 修复anyOfschema 中的上传下载0.11.0 进一步按运行时值形状选择分支支持anyOf(file, arrayfile)的列表逐文件处理。五、请求生命周期控制取消、重试与统一错误契约5.1 按请求取消0.12.0此前一个慢速tools.get/tools.execute无法取消——100 秒的搜索会无限期阻塞调用方 Agent。0.12.0 为公开 SDK 方法追加ComposioRequestOptions{ signal?: AbortSignal }尾参与类型化ComposioRequestCancelledErrortry { const tools await composio.tools.get( user_1, { search: send email, limit: 50 }, { signal: AbortSignal.timeout(5_000) } ); } catch (err) { if (err instanceof ComposioRequestCancelledError) { return; } throw err; }signal 转发到底层composio/clientfetch任何中止错误APIUserAbortError、AbortError、DOMException(nameAbortError)统一归一化为ComposioRequestCancelledError且 catch-and-wrap 路径tools.execute、tools.getRawComposioToolBySlug、toolkits.get会原样重抛而非改写为执行/未找到/获取失败错误。取消已接入 Tools、Toolkits、AuthConfigs、ConnectedAccounts、Triggers、MCP、ToolRouter 及其 Session 的几乎所有方法。自定义工具的合作式取消原生工具执行由 SDK 取消 fetch自定义工具是用户代码SDK 无法抢占于是提供两个机制执行前若signal.aborted则直接抛ComposioRequestCancelledError不调用用户代码同时把同一AbortSignal暴露为SessionContext.signal长任务实现可将它接入自己的fetchimport { experimental_createTool } from composio/core; const longRunningFetch experimental_createTool(LONG_RUNNING_FETCH, { name: Long-running fetch, description: Fetches a URL with cooperative cancellation, inputParams: z.object({ url: z.string() }), execute: async (input, ctx) { const resp await fetch(input.url, { signal: ctx.signal }); // 中途可被 session.execute(...) 中止 return { result: await resp.json() }; }, });5.2 统一错误体系基类 src/errors/ComposioError.ts 提供code统一前缀TS-SDK::、statusCode、cause、meta、possibleFixes与prettyPrint()友好输出还实现堆栈合并Caused by:链。0.18.0 修复了三个子类ComposioToolVersionRequiredError、JsonSchemaToZodError、JsonSchemaRefResolutionError漏写this.name导致遥测中错误类型错归为一类的问题。错误按域拆分为 errors 目录 下的多个文件工具、工具包、认证配置、连接账户、触发器、SSRF、远程文件、文件修饰器等各自携带对应 HTTP 状态码与可操作修复建议。六、Tool Router 会话与执行引擎演进Tool Router会话化工具执行从 0.3.0 的 alpha 一路成长为核心能力会话生命周期0.9.0 明确composio.create()每次新建会话隔离与可观测性composio.use()恢复既有会话多轮对话并新增session.update()局部更新会话配置0.13.0 增加一等公民composio.sessions.create()composio.create()保留为别名、triggers.parse()、triggers.setWebhookSubscription()。MCP 改为 opt-in0.13.0会话默认返回原生工具托管 MCP 端点仅在{ mcp: true }创建时出现在类型上运行时对象不变session.mcp仍存在。workbench/沙箱0.6.7 加workbench.enablefalse时从会话排除COMPOSIO_REMOTE_WORKBENCH、COMPOSIO_REMOTE_BASH_TOOL0.8.1 加workbench.sandboxSizestandard1 vCPU/1 GB、medium2/2、large4/4、xlarge8/80.13.0 将解析后的 workbench 配置暴露到Session.workbench支持创建时关闭并在客户端探测为composio/experimental/workbench自有沙箱打基础同时sandbox成为代码执行配置的首选键、workbench保留为别名。Provider 会话执行0.17.0OpenAI 与 Anthropic 的工具调用助手可经提供的 Tool Router 会话执行会话 meta-tools 保留会话上下文而 provider 参数归一化不受影响原有 user-ID 调用继续直接执行。自定义 provider 若重写executeToolCall/handleToolCalls可能需要适配方法现在接受会话目标。0.14.0 新增的EveProvider让session.tools()返回 eve 原生defineTool(ctx, next)钩子可改写、拒绝或转换 Tool Router meta-tool 调用。并行工具调用修复0.14.0OpenAIProvider.handleToolCalls此前每条助手消息只执行第一个工具调用默认开启的并行调用会被丢弃并留下未应答的tool_call_id。现在按模型返回顺序串行执行全部调用并行指模型一轮发出多个调用而非并发每个tool_call_id恰好应答一次工具消息顺序确定只处理第一个 choice避免n 1时重复执行。会话文件0.6.5 增加会话文件支持0.13.1 增加会话删除 APIRemoteFile下载走 SSRF 守卫0.17.0URL 上传强制 100 MiB 流式上限0.14.1。七、连接账户、认证与触发器SHARED 连接与 ACL0.9.1 → 0.10.0connectedAccounts.link()支持accountType: SHARED默认PRIVATEget()/list()返回accountTypeupdateAcl()通过PATCH写{ allowAllUsers, allowedUserIds, notAllowedUserIds }。ACL 判定规则为拒绝优先notAllowedUserIds命中即拒绝 →allowAllUsers true放行 →allowedUserIds命中放行 → 否则默认拒绝。限制每个 ACL 列表最多 1000 条、每个userId1256 字符SDK 在输入边界强制。配套错误类ComposioSharedAccessDeniedError403、ComposioAclOnlyForSharedError400对 PRIVATE 连接写 ACL、ComposioSharedConnectionNotAccessibleError400。0.10.0 将创建/PATCH/authorize 面的accountType/aclConfigForShared收拢进experimental命名空间与实验性线格式对齐。link 迁移0.9.0 / 0.8.1Composio 在 2026-07-03 全组织切换前把托管 OAuth 连接创建从initiate()迁往link()。0.8.1 为link()补齐allowMultiple选项与活动连接守卫默认false时用户在该 auth config 已有ACTIVE连接则抛ComposioMultipleConnectedAccountsError0.9.0 为initiate()增加类型化ComposioLegacyConnectedAccountsEndpointRetiredError与一次性弃用警告0.9.1 依据响应的Deprecation头精确告警自定义 OAuth 与 API key/bearer/basic 等非重定向方案不再误报。触发器0.13.0 增加triggers.parse()解析并可验证 webhook 请求与 webhook 订阅管理0.14.0 改为由后端从user_id解析连接省去一次connectedAccounts.list()调用缺失连接不再抛客户端错误0.18.1 修复触发器订阅忽略authConfigId过滤器的问题。0.6.0 起verifyWebhook()为异步Web Crypto API兼容 Workers支持 v1/v2/v3 格式。工具包版本管理0.2.0 起手动执行工具要求显式 toolkit 版本否则抛ComposioToolVersionRequiredError含 4 条可选项可用dangerouslySkipVersionCheck跳过Agentic provider 内部自动启用以保持兼容版本可通过参数、初始化配置或COMPOSIO_TOOLKIT_VERSION_GITHUB这类环境变量指定0.14.0 修复版本 pin 的大小写不敏感解析normalizeToolkitSlug统一写读两侧0.18.1 修复自定义 toolkit 子 slug 映射与裸别名归属。八、跨运行时、依赖与工程实践依赖刷新节奏composio/json-schema-to-zod从 0.1.1 跟进到 0.3.2OpenAI 运行时依赖在 0.15.0 升到 v7Zod v4 支持于 0.2.2 引入经zod/v3子路径0.12.0 用picocolors约 0.8 kB gzipped替换chalk缩小打包体积。遥测纪律composio/core与logger一起公开再导出telemetry实例0.11.0provider 可发聚合信号而无需触碰包内部遥测遵守COMPOSIO_DISABLE_TELEMETRYtrue0.2.3/0.1.44 修复遥测方法与请求头、禁用开关。平台细节0.2.6 起缺少 API key 时抛错而非process.exit0.1.21 增加 SDK 内主机名支持0.2.4/0.2.1 为触发器类型获取增加 toolkit 版本参数与isDeprecated/isNoAuth/availableVersions等元数据字段。测试包内测试位于 test 目录覆盖错误、模型、provider、telemetry、工具与各类 utils可通过pnpm --filter composio/core testvitest与pnpm --filter composio/core typecheck运行验证对应 package.json 脚本。结语一条清晰的演进主线回看 CHANGELOG.md 的 40 余个版本composio/core的演进有三条始终如一的方针安全默认值SSRF 守卫从用户 URL 扩展到 API 响应 URL、敏感文件上传从默认开启转为默认阻断、遥测层层脱敏、非幂等写禁重试Schema 严格化与宽容化并存对 OpenAI 严格模式做全深度归一化同时对自由形态对象、悬空$ref、MCP 空 schema 采取宽容降级保证模型拿到的 schema 可用会话与执行的可控性按请求取消、会话原生工具优先、workbench/sandbox 可配置。对于在其上构建 Agent 的开发者理解这些机制有助于正确配置dangerouslyAllowAutoUploadDownloadFiles、fileUploadDirs与版本 pin也有助于在ComposioBlockedInternalUrlError、ComposioRequestCancelledError出现时快速定位根因。【免费下载链接】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),仅供参考
返回列表