Composio 跨 SDK 一致性(Cross-SDK Parity)工作流:TypeScript 与 Python 双端契约对齐、生成客户端升级与验证实战
【免费下载链接】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
本篇技术指南围绕 Composio 仓库中维护 TypeScript 与 Python 两套 SDK 的核心方法论展开,系统讲解双端公共契约的对比维度、生成客户端(@composio/client/composio-client)升级的标准操作流程、camelCase 与 snake_case 命名边界,以及"以最小验证证明行为未回归"的落地手段。读完本文,你将能独立完成一次涉及双 SDK 的变更:从契约比对、客户端版本同步,到 import/typecheck/test 验证全链路。
一、什么是 Cross-SDK Parity,何时启用该流程
Composio 同时发布 TypeScript 与 Python 两套 SDK,二者共享同一套后端 API 契约。任何只改一端、而另一端"看起来还能用"的变更,都会在用户侧造成行为漂移。仓库为此在 .agents/skills/cross-sdk-parity/SKILL.md 中定义了cross-sdk-parity技能,并在 parity-workflow.md 中沉淀了标准执行流程。
该技能明确给出了启用条件:
- 一次变更同时影响两个 SDK 的行为;
- 生成客户端的版本 pin(
@composio/client/composio-client)发生移动; - 需要对比 TypeScript 与 Python 的行为差异;
- 后端 API 契约发生了变更(如新增端点、字段或错误语义)。
同时它也划清了边界:单语言、仅内部实现的改动不需要走该流程(Do not use for single-language internal-only changes)。这避免了为纯内部重构付出双端同步的额外成本。
二、对比公共契约:七个用户可感知的等价维度
parity-workflow 文档要求:在改动前,先逐项对比两个 SDK 中"用户会当作等价物来使用"的概念。以下是文档列出的完整清单,并结合仓库源码给出每一维度的可验证锚点。
1. Tools 与 Toolkits
两端的工具与工具包 API 必须暴露相同的能力集合与调用方式:
- Python 侧由
composio.tools、composio.toolkits暴露,底层模型定义在 python/composio/sdk.py 与python/composio/core/models/; - TypeScript 侧对应 ts/packages/core/src/models/Tools.ts、ts/packages/core/src/models/Toolkits.ts,并在 ts/packages/core/src/index.ts 中统一导出。
对比时关注:get_tools的参数形态、工具 schema 的返回结构、toolkit 版本的解析规则(Python 侧支持toolkit_versions字典、字符串或环境变量,见 python/composio/sdk.py 中SDKConfig的定义)。
2. Sessions 与 Tool Router 行为
这是两个 SDK 历史上命名分歧最大的区域,也是 parity 工作流重点校验的对象:
- TypeScript 侧,ts/packages/core/src/composio.ts 中
composio.sessions是规范入口,composio.toolRouter被显式标记为@deprecated的兼容别名("toolRouter was renamed to sessions"),同时保留顶层composio.create/composio.use快捷方式; - Python 侧,python/composio/sdk.py 中
composio.sessions同样为规范入口(内部即ToolRouter实例),composio.tool_router是@deprecated别名,返回同一对象。
两端的 deprecated 提示语几乎逐字对应("do not generate new code against it"),这正是公共契约对齐的典型产物:新增代码一律使用sessions,旧名称仅为兼容而保留。
3. Connected Accounts(连接账户)
- Python:
composio.connected_accounts,异常语义见 python/composio/exceptions.py(如ConnectedAccountNotFoundError、ComposioMultipleConnectedAccountsError、ComposioSharedAccessDeniedError等); - TypeScript:
composio.connectedAccounts,错误类集中在 ts/packages/core/src/errors/ConnectedAccountsErrors.ts。
对比时应校验:initiate/link的流程、ACL 字段(allow_all_users、allowed_user_ids)在两端的处理是否一致——例如 Python 侧ComposioAclOnlyForSharedError明确规定 ACL 仅对SHARED连接有意义,TS 侧必须有等价的约束行为。
4. Auth Configs(认证配置)
两端都暴露 auth config 的创建、读取、更新能力(Pythoncomposio.auth_configs,TScomposio.authConfigs)。对比要点包括:各认证方案的必填字段、patch的字段级更新语义、以及 API 版本切换后的兼容行为(仓库 changelog 中多次出现 auth-config 相关变更,例如 01-14-26 的 patch 语义调整,可作为回归对照样本)。
5. Provider Wrappers(模型提供商封装)
两端都提供针对 OpenAI、Anthropic、LangChain、CrewAI、Gemini 等框架的 provider 封装:
- Python 端 provider 目录位于 python/providers/;
- TypeScript 端位于 ts/packages/providers/。
对比维度:provider 初始化参数、工具类型转换(如 OpenAIChatCompletionToolParam)、tool_router与 provider 的协作方式。从 python/composio/sdk.py 可见 Python 侧通过泛型TTool/TToolCollection从 provider 自动推断工具类型,TS 侧同样在Composio<TProvider>泛型中体现,两端需保持推断规则一致。
6. Error Shapes 与状态处理
错误形态是用户感知最强的契约维度。Python 侧 python/composio/exceptions.py 定义了一棵完整的异常树:
- 基类
ComposioError; HTTPError携带status_code(对应 HTTP 状态码处理);NotFoundError、ValidationError、ToolkitError、TriggerError等语义分支;- 尤其值得注意的是
TriggerTypeNotFound的 docstring 明确写着 "Mirrors the TypeScript SDK'sComposioTriggerTypeNotFoundError"——这是双端错误类刻意对齐的源码级证据。
TypeScript 侧对应 ts/packages/core/src/errors/ 下的ComposioError、ToolErrors.ts、ToolkitErrors.ts、TriggerErrors.ts、ValidationErrors.ts等文件。对比时应逐类检查:同名错误是否语义等价、status_code是否一致、HTTP 4xx/5xx 的归类是否相同。
7. Docs 示例与 Changelog 文本
文档示例是"事实上的契约测试":两端文档中同一功能(如 session 创建、工具执行)的代码示例必须行为等价,changelog 对同一变更(尤其是 SDK 更新条目)的表述应一致,避免用户按 TS 文档写 Python 代码时踩坑。仓库的 changelog 位于 docs/content/changelog/,双端 SDK 发布通常同步记录(如 06-25-26 的 "sdk-012-and-python-016"、08-07-26 的 "sdk-releases" 等条目)。
三、生成客户端升级(Generated Client Bumps)
Composio 两个 SDK 都依赖后端生成的 API 客户端包:TypeScript 为@composio/client,Python 为composio-client。当后端契约变化导致生成客户端发布新版本时,两端必须按固定流程同步升级。这是 parity-workflow 中操作步骤最密集的部分。
TypeScript 侧升级流程
- 验证最新版本:执行
npm view @composio/client version,确认远端已发布的目标版本号。 - 更新 catalog pin:修改 pnpm-workspace.yaml 中
catalog段落的@composio/client版本。以当前仓库为例,该处 pin 为@composio/client: 0.1.0-alpha.76。需要注意的是,仓库还配置了minimumReleaseAge: 4320(分钟,即 3 天)的发布冷却期,并将@composio/client显式列入minimumReleaseAgeExclude,说明生成客户端允许绕过冷却门槛、优先跟进。 - 刷新 lockfile:执行
pnpm install --lockfile-only,仅更新 pnpm-lock.yaml 的解析结果而不触碰node_modules,保证 CI 的 frozen-lockfile 校验通过。 - 添加 changesets:为所有受影响的已发布包(如
@composio/core、@composio/cli等依赖该客户端 catalog 的包)补充 changeset 条目,供发布流水线生成版本变更记录。
Python 侧升级流程
- 验证最新版本:执行
pip index versions composio-client,确认 PyPI 上可用的版本列表。 - 更新 pyproject.toml:修改 python/pyproject.toml 的
dependencies,当前仓库中 pin 为composio-client==1.43.0(精确等号锁定)。 - 更新 setup.py:同步修改 python/setup.py 的
install_requires。当前仓库中同样是composio-client==1.43.0。注意pyproject.toml与setup.py两处 pin 必须保持一致,否则按不同构建入口安装会得到不同依赖版本。 - 刷新根 lockfile:执行
uv lock --upgrade-package composio-client,只升级该包并重算根目录 uv.lock,避免连带升级无关依赖。 - 导入检查:在依赖同步完成后,执行
uv run --package composio python -c "import composio",确认 SDK 可正常导入、无缺失依赖或循环导入问题。该命令通过--package composio将运行环境解析到python/下的 SDK 包。
四、命名规范:camelCase 与 snake_case 的边界
parity-workflow 明确了两端公共 API 的命名约定:
- TypeScript 公共 API 使用 camelCase:如
composio.connectedAccounts、composio.authConfigs、composio.sessions.create(...); - Python 公共 API 使用 snake_case:如
composio.connected_accounts、composio.auth_configs、composio.sessions.create(...); - 后端 wire 名称(后端 API 传输时的原始字段名)仅在生成客户端要求保留时才原样保留,SDK 层不得随意透出与语言惯例不符的命名。
这条规则在仓库中有清晰的落地证据:
- python/composio/core/models/custom_tool_types.py 中
ToolRouterSessionProxyExecuteResponse明确以 snake_case 拼写响应字段; - python/composio/core/models/triggers.py 的字段映射注释显示,模型层会显式接受
snake_case或camelCase两种 wire 键并做归一化; - python/composio/core/models/webhook_events.py 说明 webhook payload 以原始 snake_case 到达,而 SDK client 层需要做对应的转换——这正是"wire 名称只在生成客户端层保留"的典型场景。
对 Agent 与维护者而言,这条约定的实操含义是:在新增公共方法或字段前,先判断它属于"语言侧 API"(遵循各自语言惯例)还是"wire 透传"(保留后端原名),并确保两端文档示例与之一致。
五、验证:用最小检查对证明行为未回归
parity-workflow 的验证原则非常明确:
Run the smallest checks that prove both SDKs still expose the intended behavior. Prefer an import/typecheck/test pair over relying on version bumps alone.
即:优先跑一组"导入 + 类型检查 + 测试"的最小检查对,而不是只依赖版本号升级就宣告完成。版本号只能证明依赖解析成功,无法证明行为契约仍成立。
仓库中的双端一致性测试
仓库已经在 python/tests/test_cross_sdk_compatibility.py 内置了专门的跨 SDK 兼容性测试,核心思路是双端共享同一份 fixture,并断言其字节级一致:
- Webhook 契约 fixture 一致性:对
golden-signatures.json、v1-github-push.json、v2-github-push.json、v3-github-push.json四个文件,逐一断言 TypeScript 与 Python 两侧的 JSON 内容完全相同(ts_content == py_content)。这两份 fixture 分别位于 ts/packages/core/test/fixtures/webhook/ 与 python/tests/fixtures/webhook/。 - JSON Schema 转换语料一致性:断言双端的
object-cases.json逐字节相同(ts_path.read_bytes() == py_path.read_bytes()),保证两端对同一 schema 的转换结果不会漂移。
fixture 目录的定位逻辑在 python/tests/conftest.py 的get_ts_fixtures_dir/get_py_fixtures_dir等辅助函数中:Python 侧指向python/tests/fixtures/webhook,TypeScript 侧通过parent.parent.parent跨到ts/packages/core/test/fixtures/webhook。
最小检查对的组成
一次典型的双端验证应包括:
- Python:
import composio导入检查 + 相关 pytest 用例(如pytest python/tests/test_cross_sdk_compatibility.py)确认契约数据一致; - TypeScript:类型检查(tsc)确认公共类型签名未破坏 + 对应单元测试确认运行时行为;
- 行为级抽查:对涉及 session 创建、工具执行、错误分类的改动,至少在两端各跑一条最小调用路径,观察返回结构与错误形状是否对齐。
六、可落地的检查清单
把 parity-workflow 的核心步骤压缩为一份可执行的 checklist,供双端改动时逐项打勾:
- 列出本次改动涉及的用户可感知概念(tools/toolkits、sessions/Tool Router、connected accounts、auth configs、provider wrappers、error shapes、docs 示例);
- 逐一对比两端对应 API 的签名、命名与错误语义,旧别名(
toolRouter/tool_router)保持兼容且提示 deprecated; - 若生成客户端版本移动:TS 侧执行
npm view @composio/client version→ 更新 pnpm-workspace.yaml catalog →pnpm install --lockfile-only→ 添加 changesets; - Python 侧执行
pip index versions composio-client→ 同步更新 python/pyproject.toml 与 python/setup.py 两处 pin →uv lock --upgrade-package composio-client→uv run --package composio python -c "import composio"; - 遵守命名边界:TS 公共 API 用 camelCase,Python 公共 API 用 snake_case,wire 名称只在生成客户端层保留;
- 运行最小检查对:双端 import/typecheck + 跨 SDK fixture 一致性测试(python/tests/test_cross_sdk_compatibility.py),确认行为而非仅凭版本号;
- 核对 docs 示例与 changelog 文本,确保两端描述同步。
遵循这套工作流,可以让 TypeScript 与 Python 两套 SDK 在用户感知层面始终保持等价,任何一次生成客户端升级或后端契约变更,都能以最小的验证成本确认双端行为未回归。
【免费下载链接】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),仅供参考