Composio TypeScript SDK Tools API 完全指南:工具检索、执行与版本管控
【免费下载链接】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
导读
Tools类是 Composio TypeScript SDK 的核心组件之一,负责从 1000+ 工具包中列出、检索并执行各类工具,是构建 AI Agent 时连接"意图"与"行动"的关键桥梁。本文以 ts/docs/api/tools.md 为骨架,结合 Tools 类实现、工具类型定义与错误定义等源码,系统讲解get、execute、getRawComposioTools、getRawComposioToolBySlug四个核心方法,深入剖析ToolListParams过滤组合、important自动过滤规则、工具版本钉扎机制(Version Pinning)以及修饰器(Modifier)扩展点。读完本文,你将能够在实际项目中正确检索工具、安全执行工具,并避免因版本漂移引发的生产事故。
一、Tools 类概览:SDK 中的工具管理入口
在 Composio SDK 中,Tools类是统一封装工具相关能力的门面(Facade)。从源码看,它持有四个关键依赖(见 Tools.ts 构造器):
client:Composio 底层 API 客户端(@composio/client),负责与 Composio 后端通信;provider:当前使用的 AI 框架 Provider(如 OpenAI、Anthropic、LangChain),负责将工具包装成该框架认识的格式;toolkitVersions:在 SDK 初始化时通过new Composio({ toolkitVersions: {...} })注入的版本配置,默认值来自CONFIG_DEFAULTS;autoUploadDownloadFiles:是否启用自动文件上传/下载(对应dangerouslyAllowAutoUploadDownloadFiles配置)。
构造时,Tools会将execute绑定到自身实例,并通过provider._setExecuteToolFn()把执行函数注入 Provider——这正是 Agent 框架最终能回调执行工具的内部机制(源码位置)。
二、检索工具:get 方法与两种重载
get方法将工具从 Composio API 拉取后,按当前 Provider 的格式进行包装(如转成 OpenAI 的 function calling schema、LangChain 的 StructuredTool 等),返回给上层 Agent 使用。它有两种重载形态(类型签名)。
2.1 重载一:按过滤器批量获取
// 从 github 工具包获取重要工具(自动应用 important 过滤) const importantGithubTools = await composio.tools.get('default', { toolkits: ['github'] }); // 获取有限数量的工具(不会自动应用 important) const githubTools = await composio.tools.get('default', { toolkits: ['github'], limit: 10 }); // 关键词搜索工具(不会自动应用 important) const searchTools = await composio.tools.get('default', { search: 'user' }); // 带 Schema 修改的工具获取 const customizedTools = await composio.tools.get('default', { toolkits: ['github'] }, { modifySchema: ({ toolSlug, toolkitSlug, schema }) => { return { ...schema, description: 'Custom description' }; } });参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
userId | string | 获取工具所针对的用户 ID |
filters | ToolListParams | 指定检索条件的过滤对象(详见第三章) |
options | ProviderOptions | 可选 Provider 选项,含modifySchema等修饰器 |
2.2 重载二:按 slug 获取单个工具
// 按 slug 获取指定工具 const tool = await composio.tools.get('default', 'GITHUB_GET_REPO'); // 获取单个工具并修改其 Schema const customTool = await composio.tools.get('default', 'GITHUB_GET_REPOS', { modifySchema: ({ toolSlug, toolkitSlug, schema }) => { return { ...schema, description: 'Enhanced GitHub repository tool' }; } });返回结果:两种重载都会返回按当前 Provider 格式包装后的工具集合。从实现上看,get内部先调用原始检索方法(单工具走getRawComposioToolBySlug,批量走getRawComposioTools),再通过wrapToolsForProvider交给 Provider 包装,同时绑定executeToolFn作为该工具的默认执行回调(实现细节)。
补充:请求超时支持:
get的options中还支持传入signal实现超时/取消(与修饰器共用同一个 options 对象)。源码会先剥离signal,避免一个已过期的AbortSignal.timeout()污染后续所有工具调用(见实现注释)。例如:await composio.tools.get('default', { search: 'email' }, { signal: AbortSignal.timeout(5_000) })。
三、过滤参数 ToolListParams:五种互斥组合
ToolListParams是工具检索的过滤核心。它由多个互斥的联合类型组成,每次只能选择其中一种组合,不能混用(例如tools与toolkits同时出现会在运行时抛出ValidationError,校验逻辑)。源码中的完整定义(types/tool.types.ts)比文档中列出的四种多出一种tags组合与authConfigIds组合:
| 组合 | 必填 | 可选 | 用途 |
|---|---|---|---|
ToolsOnlyParams | tools: string[] | — | 按工具 slug 精确获取指定工具 |
ToolkitsOnlyParams | toolkits: string[] | limit、search、tags、important | 从指定工具包批量获取 |
ToolkitScopeOnlyParams | toolkits: [string](仅限单个)+scopes: string[] | limit、search、tags、important | 按 OAuth 权限范围过滤 |
SearchOnlyParams | search: string | — | 跨工具包按名称/描述搜索 |
TagsOnlyParams | tags: string[] | toolkits、limit | 按标签过滤 |
AuthConfigIdsOnlyParams | authConfigIds: string[] | limit、search、tags | 按认证配置过滤 |
3.1 按 scopes 过滤工具
scopes参数用于按工具所需的 OAuth 权限范围过滤:
// 只获取需要这些 scope 的工具 const scopedTools = await composio.tools.get('default', { toolkits: ['github'], scopes: ['read:repo', 'write:repo'], }); // 搜索并配合 scope 过滤 const searchedScopedTools = await composio.tools.get('default', { search: 'repository', scopes: ['read:repo'], limit: 10, });scopes的典型价值在于:让返回的工具与用户已授权的权限级别对齐,避免把需要更高权限的工具暴露给当前用户。
3.2 按 tools 与 search 组合使用
// 按 slug 精确获取 const specificTools = await composio.tools.get('default', { tools: ['GITHUB_GET_REPO', 'GITHUB_LIST_ISSUES'], }); // 跨工具包(或指定工具包内)搜索 const searchResults = await composio.tools.get('default', { search: 'repository', toolkits: ['github'], // 可选 limit: 10, });3.3 源码中的校验与默认行为
在getRawComposioTools实现中(ts/packages/core/src/models/Tools.ts#L487-L583)有以下重要细节:
- 必须提供
tools、toolkits、search、authConfigIds中的至少一个,否则抛出ValidationError; - 当提供
tools时,SDK 会自动把limit置为9999,确保所有指定工具都被取回; - 所有过滤器最终会被序列化为 API 请求参数(
tool_slugs、toolkit_slug、tags、scopes、search、auth_config_ids、important),并自动携带toolkit_versions,即初始化时配置的版本钉扎。
四、important 过滤器的自动应用规则
当只提供toolkits(未提供tools、tags、search、limit,且未显式设置important: false)时,SDK会自动应用important: true,只返回该工具包中最常用、最核心的工具,避免一次性拉取全部工具造成的信息过载。源码中的判定逻辑(ts/packages/core/src/models/Tools.ts#L505-L515):
const shouldAutoApplyImportant = 'toolkits' in queryParams.data && !('tools' in queryParams.data) && !('tags' in queryParams.data) && !('search' in queryParams.data) && !('limit' in queryParams.data) && // 提供 limit 则不自动应用 queryParams.data.important !== false;自动应用的条件一览:
- ✅ 提供了
toolkits - ✅ 未提供
tools - ✅ 未提供
tags - ✅ 未提供
search - ✅ 未提供
limit - ✅ 未显式设置
important: false
示例验证:
// 自动应用 important: true —— 只返回 GitHub 重要工具 const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'] }); // 提供 limit 时不自动应用 —— 返回前 50 个(含非重要工具) const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'], limit: 50 }); // 提供 tags 时不自动应用 const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'], tags: ['important'] }); // 提供 search 时不自动应用 const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'], search: 'repository' }); // 显式关闭自动应用 —— 返回全部 GitHub 工具 const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'], important: false }); // 即使带 limit 也显式启用 important —— 返回前 20 个重要工具 const tools = await composio.tools.getRawComposioTools({ toolkits: ['github'], limit: 20, important: true });为什么提供limit会阻止自动应用important?当你指定limit时,说明你期望拿到精确数量的工具;如果此时自动叠加important过滤,当该工具包内重要工具数量不足时,返回结果就会少于你要求的数量。因此 SDK 选择在提供limit时不再自动过滤,保证数量精确。
五、执行工具:execute 方法与版本钉扎机制
execute方法用于手动执行一个指定工具:
// 带钉扎版本执行(工作流与手动执行 REQUIRED) const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, version: '12082025_00', // 必须指定具体版本 });⚠️重要:手动执行工具(尤其在构建工作流时),必须提供具体版本。当版本解析为
latest时方法会直接抛错,以确保新版本发布后工具参数不发生错配。可通过dangerouslySkipVersionCheck: true绕过此限制,但不推荐在生产环境使用。
5.1 execute 的参数详解
| 参数 | 类型 | 说明 |
|---|---|---|
slug | string | 要执行的工具 slug/ID(如GITHUB_GET_ISSUES) |
body | ToolExecuteParams | 传给工具的参数(含 userId、arguments、version 等) |
modifiers | ExecuteToolModifiers | 可选修饰器,用于转换请求或响应 |
5.2 为什么手动执行强制要求钉扎版本?
- 工具的参数 Schema 会随版本变化;
- 工作流中使用
'latest'可能在工具更新后触发运行时错误; - 钉扎版本能保证工作流的稳定性与可预测性;
- 版本校验能防止 Schema 错配导致的生产问题。
5.3 三种版本处理方式
方式 1:在 execute 调用中指定具体版本(推荐)
const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, version: '12082025_00', // 显式指定版本 });方式 2:在 SDK 初始化时配置工具包版本(生产推荐)
const composio = new Composio({ toolkitVersions: { github: '12082025_00', slack: '10082025_01' } }); // 之后执行时无需再传 version,自动使用初始化时钉扎的版本 const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, });方式 3:使用dangerouslySkipVersionCheck: true(不推荐生产)
const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, dangerouslySkipVersionCheck: true, // 绕过版本校验并使用 'latest' });⚠️警告:
dangerouslySkipVersionCheck: true会绕过版本校验并允许使用'latest'。当工具 Schema 变更时,这可能导致意外行为与参数错配。仅在开发或测试阶段使用此标志;生产环境务必钉扎具体版本以保证工作流稳定。
5.4 版本解析的底层原理
execute的版本解析实际发生在 executeComposioTool 中:
const toolkitVersion = body.version ?? getToolkitVersion(tool.toolkit?.slug ?? 'unknown', this.toolkitVersions); // 版本为 latest 且未跳过校验时,直接抛错 if (toolkitVersion === 'latest' && !body.dangerouslySkipVersionCheck) { throw new ComposioToolVersionRequiredError(); }优先级为:execute 调用中的body.version> SDK 初始化时的toolkitVersions配置 > 环境变量 > 默认'latest'。
版本配置的合并逻辑位于 utils/sdk.ts 的getToolkitVersionsFromEnv:初始化时,SDK 会读取COMPOSIO_TOOLKIT_VERSION_<TOOLKIT_SLUG>形式的环境变量(如COMPOSIO_TOOLKIT_VERSION_GITHUB=12082025_00),与用户传入的toolkitVersions对象合并——用户传入值优先于环境变量,若两者皆空则回退为'latest'。此外,toolkitVersions支持两种形态:一个全局字符串(应用于所有工具包)或一个{ 工具包slug: 版本 }映射对象(类型定义)。
关于版本检索还有一点细节:getRawComposioToolBySlug支持在options.version中显式传版本(走 API 的version参数),否则使用初始化配置的toolkit_versions(实现)。
5.5 用修饰器扩展执行流程
const result = await composio.tools.execute( 'GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, version: '12082025_00', // 始终指定版本 }, { beforeExecute: ({ toolSlug, toolkitSlug, params }) => { // 在执行前修改参数 return params; }, afterExecute: ({ toolSlug, toolkitSlug, result }) => { // 在执行后转换结果 return result; }, } );修饰器在源码执行管线中的位置(executeWithTool):先应用beforeExecute修饰器(含文件上传修饰器)→ 调用后端执行 → 应用afterExecute修饰器(含文件下载修饰器)。此外还支持beforeFileUpload修饰器用于自定义文件上传行为。若传入的修饰器不是函数,会抛出ComposioInvalidModifierError(错误定义)。
源码补充:
execute走的是禁用重试的客户端(clientWithoutRetries)。这是因为工具执行属于非幂等写操作,若读超时后静默重试,可能重复产生副作用(例如重复发送邮件)——相关设计说明见 Tools.ts 注释 与执行调用点。
5.6 返回结果与异常
返回类型Promise<ToolExecuteResponse>,其结构(Zod 定义):
interface ToolExecuteResponse { data: Record<string, unknown>; // 工具执行返回的数据 error: string | null; // 错误信息(如有) successful: boolean; // 执行是否成功 logId?: string; // 用于调试的日志 ID sessionInfo?: unknown; // 会话信息 }可能抛出的异常:
ComposioToolNotFoundError:未找到对应 slug 的工具(定义);ComposioToolExecutionError:执行过程中出错(定义);ComposioToolVersionRequiredError:版本解析为latest且未跳过校验(定义)。
错误处理还有一个值得注意的机制:handleToolExecutionError会将后端返回的特定错误码(如1803对应ComposioConnectedAccountNotFoundError)映射为更精确的 SDK 错误类型,其余情况统一包装为ComposioToolExecutionError(映射表)。
六、直接访问原始工具:getRawComposioTools
getRawComposioTools直接从 Composio API 列出工具,不做 Provider 格式包装,返回 SDK 层的ToolList(Array<Tool>),适合需要直接操作原始 Schema 与元数据的场景(如 CLI 工具、自定义 Agent 框架集成)。
// 从工具包获取重要工具(自动应用 important 过滤) const importantGithubTools = await composio.tools.getRawComposioTools({ toolkits: ['github'] }); // 获取有限数量(不会自动应用 important) const limitedTools = await composio.tools.getRawComposioTools({ toolkits: ['github'], limit: 10 }); // 按 slug 获取指定工具 const specificTools = await composio.tools.getRawComposioTools({ tools: ['GITHUB_GET_REPOS', 'HACKERNEWS_GET_USER'] }); // 带 Schema 变换 const customizedTools = await composio.tools.getRawComposioTools({ toolkits: ['github'], limit: 5 }, { modifySchema: ({ toolSlug, toolkitSlug, schema }) => { return { ...schema, customProperty: `Modified ${toolSlug} from ${toolkitSlug}`, tags: [...(schema.tags || []), 'customized'] }; } }); // 关键词搜索 const searchResults = await composio.tools.getRawComposioTools({ search: 'user management' });参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
query | ToolListParams | 过滤条件(必填) |
options | GetRawComposioToolsOptions | 可选配置,含modifySchema(TransformToolSchemaModifier类型) |
返回:Promise<ToolList>—— 匹配查询条件的工具列表。该列表经过transformToolCases的 snake_case → camelCase 转换(如input_parameters→inputParameters、available_versions→availableVersions,转换逻辑),并会应用默认 Schema 修饰器(如自动上传模式下将文件上传字段折叠为{ type: 'string', format: 'path' },见 applyDefaultSchemaModifiers)。
七、直接访问单个原始工具:getRawComposioToolBySlug
getRawComposioToolBySlug按 slug 获取单个原始工具,直接暴露其完整 Schema 与元数据,同样不经过 Provider 包装。
// 基础用法 const tool = await composio.tools.getRawComposioToolBySlug('GITHUB_GET_REPOS'); // 带 Schema 变换 const customizedTool = await composio.tools.getRawComposioToolBySlug( 'SLACK_SEND_MESSAGE', { modifySchema: ({ toolSlug, toolkitSlug, schema }) => { return { ...schema, description: `Enhanced ${schema.description} with custom modifications`, customMetadata: { lastModified: new Date().toISOString(), toolkit: toolkitSlug } }; } } ); // 访问工具属性 const githubTool = await composio.tools.getRawComposioToolBySlug('GITHUB_CREATE_ISSUE'); console.log({ slug: githubTool.slug, name: githubTool.name, toolkit: githubTool.toolkit?.name, version: githubTool.version, availableVersions: githubTool.availableVersions });参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
slug | string | 工具唯一标识(如'GITHUB_GET_REPOS') |
options | GetRawComposioToolBySlugOptions | 可选配置,含modifySchema、version |
返回:Promise<Tool>—— 包含完整 Schema 与元数据的工具对象。当工具不存在时,该方法会将底层错误包装为ComposioToolNotFoundError抛出(源码)。
八、实战场景组合
8.1 工作流:先检索后执行
import { Composio } from '@composio/sdk'; // 初始化并钉扎版本(生产推荐) const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY, toolkitVersions: { github: '12082025_00', slack: '10082025_01' } }); // 1. 检索 github 工具包中与 issue 相关的工具 const issueTools = await composio.tools.getRawComposioTools({ toolkits: ['github'], search: 'issue', limit: 20 }); // 2. 取其中某个工具的 Schema 检查参数 const getIssuesTool = await composio.tools.getRawComposioToolBySlug('GITHUB_GET_ISSUES'); console.log(getIssuesTool.inputParameters); // 3. 手动执行(版本来自初始化配置) const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', arguments: { owner: 'composio', repo: 'sdk' }, }); console.log(result.successful, result.data);8.2 生产环境的版本管控清单
- 初始化时配置
toolkitVersions,集中管理所有工具包版本; - 或通过环境变量
COMPOSIO_TOOLKIT_VERSION_<TOOLKIT_SLUG>注入版本(用户配置优先); - 避免在手动执行时使用
'latest';确需临时调试时显式传version字段; - 仅在开发/测试环境使用
dangerouslySkipVersionCheck: true; - 对返回结果统一检查
successful字段,并利用logId关联后端日志排查问题。
九、小结
Tools类为 Composio TS SDK 提供了从"检索"到"执行"的完整工具闭环:get负责按 Provider 包装工具供 Agent 使用,getRawComposioTools/getRawComposioToolBySlug提供无包装的原始 Schema 访问,execute负责带版本管控的安全执行。其背后是ToolListParams的互斥过滤组合、important自动过滤规则、以及贯穿检索与执行全链路的版本钉扎机制。理解这些设计,能帮助你在构建生产级 AI Agent 时做到工具选择精准、版本管控严格、执行行为可预期。
延伸阅读:关于工具包版本的详细配置方式,可参考 TypeScript SDK 快速上手文档;工具执行相关的修饰器与文件上传下载机制,可深入阅读 Tools.ts 实现 与 工具类型定义;SDK 使用流程概览见 ts/docs/core-concepts.md 与 ts/docs/README.md。
【免费下载链接】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),仅供参考