恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Composio Tool Router 会话文件挂载 E2E 测试实战:List / Upload / Download / Delete 全流程验证

  • 首页
  • 资讯中心
  • /
  • Composio Tool Router 会话文件挂载 E2E 测试实战:List / Upload / Download / Delete 全流程验证

相关资讯

洛雪音乐助手完整指南:免费开源多平台聚合桌面音乐播放器 2026/9/12 15:30:04
AI听声辨人:端侧实时语音分离技术解析 2026/9/12 15:30:04
27. 数据产品- BI - AI 应用4-构建高质量 AI 基座 2026/9/12 15:30:04

最新资讯

毛利率同比怎么分析?毛利率同比分析有哪些注意事项?
头歌实践教学平台:Java面向对象-包装类(二)
如何 5 分钟把文件转 Markdown:MarkItDown 安装、批量转换命令与报错排查完整指南
curl --verbose 选项全解:调试输出语义、文档元数据与 managen 文档流水线
用 Rust 编写 NautilusTrader 交易策略:从结构体定义到订单管理全流程实战
小型语言模型(SLM)技术解析与应用实践

今日推荐

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现
【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)
【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

本周热门

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Composio Tool Router 会话文件挂载 E2E 测试实战:List / Upload / Download / Delete 全流程验证

发布时间:2026/9/12 15:30:05
Composio Tool Router 会话文件挂载 E2E 测试实战:List / Upload / Download / Delete 全流程验证 Composio Tool Router 会话文件挂载 E2E 测试实战List / Upload / Download / Delete 全流程验证【免费下载链接】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 仓库中 ts/e2e-tests/runtimes/node/tool-router-files/README.md 展开深入讲解 Tool Router 会话文件挂载Session Files MountAPI 的端到端测试从创建会话、上传缓冲区、列举文件、下载回验到删除清理的完整链路。你会掌握composio/core中session.experimental.files四个核心操作的调用方式、参数语义、SDK 底层实现以及如何在 Node.js 运行时用 Docker 容器跑通这套 E2E 测试并理解存储不可用时的优雅降级处理。测试背景会话文件挂载 API 是什么Tool Router 会话文件挂载是 Composio Tool Router 会话能力的一部分每个会话在沙箱内挂载一个虚拟文件系统开发者可以围绕该会话执行上传、列举、下载、删除四个文件操作让 Agent 在会话生命周期内持久化中间产物例如工具生成的报告、上传的数据集、临时缓存。该 API 目前通过session.experimental.files暴露属于 SDK 的 experimental 命名空间。从源码注释看官方建议在已有领域化挂载domain-specific mounts出现时优先使用领域化 API该命名空间仅作为兼容别名保留见 ts/packages/core/src/models/Experimental.ts。在 SDK 实现中文件挂载通过 ToolRouterSessionFileMount.ts 中的ToolRouterSessionFilesMount类提供每次创建 Tool Router 会话时session.experimental.files属性即指向该类的实例见 ts/packages/core/src/models/ToolRouterSession.ts。前置条件与运行方式根据 README运行该 E2E 测试需要两个前置条件Docker测试在容器内运行通过e2e-tests/utils的e2e()辅助函数封装指定多个 Node 版本镜像逐一执行。COMPOSIO_API_KEY环境变量用于向真实 Composio API 发起调用。从 e2e.test.ts 可见测试会针对 Node.js 的三个版本22.22.3、24.17.0、25.9.0分别运行并把COMPOSIO_API_KEY注入到容器环境。运行方式有两种# 从仓库根目录推荐 COMPOSIO_API_KEYyour_key pnpm test:e2e:node --filtere2e-tests/node-tool-router-files # 或直接进入该目录运行 Bun 测试 cd ts/e2e-tests/runtimes/node/tool-router-files COMPOSIO_API_KEYyour_key bun test e2e.test.ts测试包定义在 package.json 中包名为e2e-tests/node-tool-router-files依赖composio/coreworkspace 版本与e2e-tests/utils。测试脚本test:e2e/test:e2e:node均指向bun test e2e.test.ts。注意该测试面向真实线上 API属于集成级验证若你的 API Key 对应的项目存储服务未开通或鉴权失败测试会走显式跳过分支而非直接失败详见下文降级处理小节。测试流程五步走README 明确列出测试验证的五个步骤我们结合 fixture 脚本 fixtures/index.mjs 逐一展开。1. 创建最小 Tool Router 会话fixture 使用公开的hackernewstoolkit 创建会话无需认证并关闭连接管理import { Composio } from composio/core; const apiKey process.env.COMPOSIO_API_KEY; if (!apiKey) { console.error(COMPOSIO_API_KEY is required); process.exit(1); } const composio new Composio({ apiKey }); const session await composio.create(e2e-tool-router-files-user, { toolkits: [hackernews], manageConnections: false, });关键点composio.create(user, options)创建的是 Tool Router 会话hackernews为公开 toolkit不需要连接授权适合最小化测试场景。注释特别说明files mount 总是可用files mount is always available即文件挂载能力与连接管理解耦。会话创建后即可通过session.experimental.files获得文件挂载操作入口。2. 上传Uploadfixture 将一段文本编码为字节缓冲区并上传同时指定remotePath与mimetypeconst { files } session.experimental; const testPath e2e-test-upload.txt; const testContent Hello from Tool Router files E2E test; const buffer new TextEncoder().encode(testContent); const uploaded await files.upload(buffer, { remotePath: testPath, mimetype: text/plain, }); if (!uploaded.mountRelativePath || !uploaded.downloadUrl) { throw new Error(Upload failed: missing mountRelativePath or downloadUrl); }上传成功后必须校验返回值mountRelativePath挂载内相对路径与downloadUrl预签名下载地址是后续下载与删除的关键字段。SDK 层面对返回数据用RemoteFileDataSchema做严格解析见 ToolRouterSessionFilesMount.types.ts字段包括expiresAt、mountRelativePath、sandboxMountPrefix、downloadUrl。从 SDK 源码看upload()的完整链路是参数解析 → 输入归一化 → 请求预签名上传 URL → SSRF 校验后 PUT 上传 → 请求预签名下载 URL → 解析为 RemoteFile见 ToolRouterSessionFileMount.ts。upload的输入支持四种形态见 normalizeUploadInput输入类型说明remotePath 规则字符串本地路径通过platform.readFileSync读取本地文件默认取文件名basename字符串http/https URL先经 SSRF 安全抓取再上传默认取 URL 最后一段文件名原生File对象如input[typefile]的files[0]默认取input.nameArrayBuffer/Uint8Array缓冲区字节内容直传必须提供remotePath或mimetype否则抛错其中缓冲区形态有强制约束mimetype与remotePath至少提供一个否则 SDK 会抛出带示例的错误信息When passing a buffer, either mimetype or remotePath (filename) is required。未提供remotePath时SDK 会根据mimetype推断扩展名生成upload-shortId.ext形式的随机文件名。若你提供的是 URL注意 SDK 文档注明 URL 输入需要 Node.js 或 Bun 运行时以做 DNS 校验边缘运行时如 Cloudflare Workers需自行 fetch 后传File或ArrayBuffer。3. 列举List上传成功后fixture 对挂载根目录执行files.list()不传 pathSDK 会归一化为根目录并做最多 5 次、间隔 1 秒的最终一致性重试let listOk false; for (let attempt 0; attempt 5; attempt) { const listResult await files.list(); const found listResult.items?.some( item candidatePaths.includes(item.mountRelativePath) || item.mountRelativePath testPath || item.mountRelativePath?.endsWith(testPath) || item.mountRelativePath?.includes(testPath) ); if (found) { listOk true; break; } await new Promise(r setTimeout(r, 1000)); } if (listOk) console.log(LIST_OK); else console.log(LIST_SKIP); // eventual consistency值得注意的细节fixture 构造了candidatePaths即对 API 返回的mountRelativePath做去除前导斜杠的归一化两个候选路径都参与匹配——因为 API 返回的路径格式可能与上传时传入的remotePath存在前导/差异。匹配逻辑做了多重容错精确匹配、后缀匹配、包含匹配降低服务端路径规范化差异导致的误报。若 5 次重试仍未找到文件输出LIST_SKIP并继续而不是中断测试——体现了对最终一致性的容忍。list()的 SDK 实现中路径归一化在客户端完成path为undefined///时不传mount_relative_prefix即根目录否则去掉前导斜杠后作为前缀查询见 ToolRouterSessionFileMount.ts。list()返回的结构FileListResponse{ items: Array{ lastModified: string; // ISO 时间戳 mountRelativePath: string; // 挂载内相对路径 sandboxMountPrefix: string;// 沙箱内绝对挂载路径如 /mnt/files size: number; // 字节数 }, nextCursor?: string; // 分页游标 }分页参数见 ListOptionsSchemapath目录路径、mountId默认files、cursor上一页nextCursor、limit每页数量1–500。SDK 文档示例展示了基于nextCursor的翻页循环。4. 下载Download下载同样带最终一致性重试最多 5 次遍历候选路径并将内容与上传的原文比对let downloaded; let lastDownloadError; let resolvedPath; for (let attempt 0; attempt 5; attempt) { for (const candidatePath of candidatePaths) { try { const remoteFile await files.download(candidatePath); const content await remoteFile.text(); if (content ! testContent) { throw new Error(Download failed: expected ${testContent}, got ${content}); } downloaded remoteFile; resolvedPath candidatePath; break; } catch (err) { lastDownloadError err; } } if (downloaded) break; if (attempt 4) await new Promise(r setTimeout(r, 1000)); } if (!downloaded) { throw lastDownloadError ?? new Error(Download failed after retries); } console.log(DOWNLOAD_OK);下载校验的核心断言是内容级的不仅要求下载成功还要求await remoteFile.text()与原始文本Hello from Tool Router files E2E test完全一致否则抛出带期望值与实际值的错误信息。这验证了文件挂载的上传→存储→下载闭环数据无损。download()返回RemoteFile对象它封装了挂载文件的元数据与内容访问能力见 RemoteFile.ts属性/方法说明expiresAt预签名下载 URL 的过期时间ISO 8601mountRelativePath挂载内相对路径sandboxMountPrefix沙箱内绝对挂载路径downloadUrl预签名下载地址buffer()获取内容为Uint8Arraytext()获取内容为 UTF-8 字符串blob()获取内容为Blob保留 content-typesave(path?)保存到本地文件系统默认存到~/.composio/files/filename需 Node 运行时Cloudflare Workers 等无文件系统环境会抛错filename从挂载路径提取的文件名SDK 文档示例const buffer await remoteFile.buffer(); await remoteFile.save(/tmp/report.pdf); const text await remoteFile.text();5. 删除Delete最后使用下载步骤中解析出的实际路径resolvedPath优先取 API 返回的路径删除文件await files.delete(resolvedPath ?? candidatePaths[0]); console.log(DELETE_OK);SDK 实现中delete()调用toolRouter.session.files.delete返回FileDeleteResponse包含mountRelativePath与sandboxMountPrefix见 ToolRouterSessionFilesMount.types.ts。SDK 文档对该操作给出了明确警告此操作具有破坏性删除后无法恢复warning This operation is destructive. Deleted files cannot be recovered.。因此生产代码中调用前应确认路径存在且确需移除。测试断言与优雅降级UPLOAD / LIST / DOWNLOAD / DELETE 标记体系e2e.test.ts 通过输出标记断言各阶段结果这套标记体系设计得非常宽容标记含义UPLOAD_OK上传成功UPLOAD_UNAVAILABLE上传因存储未授权被跳过消息含Failed to upload fileUnauthorizedFILES_MOUNT_UNAVAILABLE文件挂载整体不可用存储鉴权失败LIST_OK/LIST_SKIP列举成功 / 最终一致性超时跳过DOWNLOAD_OK/DOWNLOAD_SKIP下载成功 / 上传不可用时跳过DELETE_OK/DELETE_SKIP删除成功 / 上传不可用时跳过ALL_OK/ALL_SKIP全链路成功 / 全链路跳过关键断言逻辑上传必须成功或显式不可用expect(result.stdout).toMatch(/UPLOAD_OK|UPLOAD_UNAVAILABLE|FILES_MOUNT_UNAVAILABLE/)——存储不可用是允许的分支。一旦存储不可用后续操作必须全部输出*_SKIPisStorageUnavailable()检测UPLOAD_UNAVAILABLE或FILES_MOUNT_UNAVAILABLE后list / download / delete / all 四组断言全部转向跳过或存储鉴权失败分支。存储可用时download 与 delete 是硬性要求必须包含DOWNLOAD_OK与DELETE_OK不允许跳过。整体退出码为 0即使整体跳过fixture 也以process.exit(0)结束见 fixture 末尾的 catch 分支保证显式不可用不被视为测试失败。这种设计让 E2E 测试既能严格验证可用环境下的完整链路又不会因租户存储权限差异导致 CI 假失败——测试意图是验证 SDK 行为正确而非验证线上存储服务可用性。源码视角四个操作的底层调用链从 ToolRouterSessionFileMount.ts 可以还原四个操作对客户端 API 的调用关系操作底层 Wire 调用关键安全/校验点listclient.toolRouter.session.files.list(mountId, { session_id, mount_relative_prefix, cursor, limit })参数经 Zod schema 校验limit1–500响应经FileListResponseSchema解析uploadfiles.createUploadURL→ PUTupload_url→files.createDownloadURL用户 URL 与 API 返回的upload_url均过 SSRF 守卫ssrfSafeFetch/ssrfSafeFetchWhereSupporteddownloadfiles.createDownloadURL→ 返回RemoteFile下载走ssrfSafeFetchWhereSupported失败抛出RemoteFileDownloadError含状态码、URL、路径等上下文deletefiles.delete(mountId, { session_id, mount_relative_path })响应经FileDeleteResponseSchema校验值得强调的安全细节上传链路的 SSRF 防护是双重的——normalizeUploadInput中用户传入的 URL 先经ssrfSafeFetch抓取随后 API 返回的upload_url也会在字节发送前经ssrfSafeFetchWhereSupported校验目标地址源码注释明确指出这是对 API 响应来源地址的同样对待见 ToolRouterSessionFileMount.ts。另一个实现细节是默认挂载 IDlist / upload / download / delete 四个操作的 options 都默认mountId: files常量定义在 ts/packages/core/src/utils/constants.tsDEFAULT_TOOL_ROUTER_SESSION_FILES_MOUNT_ID files。这意味着你可以通过mountId参数切换到自定义文件挂载如 SDK 文档示例中的custom-mount。扩展把测试思路迁移到自己的 Agent 项目这套 E2E 测试除了验证 SDK 之外本身就是一个高质量的文件挂载使用范式可直接迁移到业务代码中创建会话composio.create(user, { toolkits, manageConnections })公开 toolkit 无需认证即可测试。上传优先提供remotePath与mimetype缓冲区上传二者至少其一远程 URL 依赖 Node/Bun 运行时的 SSRF 校验能力。列举与分页根目录省略path子目录用/开头或裸路径均可SDK 自动归一化limit范围 1–500配合nextCursor翻页。下载回验用remoteFile.text()/buffer()/blob()在内存中消费需要落盘时用save()Node 环境默认存~/.composio/files/。清理删除用上传/下载返回的mountRelativePath而非自己拼接的路径并牢记删除不可恢复。容错对存储服务的最终一致性做有限重试本测试为 5 次、间隔 1 秒对存储不可用场景提供显式的跳过标记而非崩溃。小结Tool Router 会话文件挂载为 AI Agent 提供了围绕单个会话的持久化文件存储能力。本仓库的 E2E 测试README.md fixtures/index.mjs e2e.test.ts完整覆盖了创建会话、上传、列举、下载、删除五步链路并通过*_OK/*_SKIP/*_UNAVAILABLE标记体系优雅处理了存储服务不可用的边界情况而 ToolRouterSessionFileMount.ts 则展示了其底层实现Zod 参数校验、SSRF 双重防护、预签名 URL 上传下载、RemoteFile内容消费模型。理解这套测试与实现等于掌握了 Composio 会话文件挂载 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创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号