Continue CLI 产物上传Artifact Upload架构实战基于预签名 URL 的 Agent 会话文件直传方案【免费下载链接】continueopen-source coding agent项目地址: https://gitcode.com/GitHub_Trending/co/continue本指南以 Continue 开源仓库中的 artifact-uploads.md 为骨架结合cnCLI 的源码实现系统讲解 Continue Agent 如何把截图、视频、日志等任意文件上传到 Agent 会话存储agent session storage供用户审查与调试。读完本文你将掌握预签名 URL 两段式上传的整体架构、后端校验规则与存储路径组织、UploadArtifact工具的启用与调用方式、服务级编程式上传接口、以及配套的错误处理与安全设计可直接在 devbox 环境中复现与二次开发。为什么选择预签名 URL四重收益产物上传系统的核心设计是预签名 URLpresigned URL——客户端绕过后端、直接把文件上传到 S3而不是让文件流经后端 API 服务器中转。该设计带来四方面收益安全性后端在上传前掌控一切校验——谁能上传、文件类型与大小是否合法、是否超出存储配额。预签名 URL 由后端签发Agent 无法绕过这些校验直接写入存储。性能文件从 devbox 直传 S3省去经后端 API 服务器中转带来的带宽消耗与额外延迟。可扩展性后端不会成为文件上传的瓶颈数据传输的重活全部由 S3 承担。简洁性预签名 URL 是自带完整凭证的限时地址15 分钟有效无需复杂的令牌管理。在仓库源码中这一职责被封装为独立的ArtifactUploadService其类注释明确描述了三步式架构先向后端 API 请求预签名 URL再用预签名 URL 直传 S3后端在签发 URL 前完成文件大小、类型与存储配额校验ArtifactUploadService.ts。两段式上传流程第一步向后端请求预签名 URLAgent 首先向后端发起预签名上传地址申请接口形态如下POST /agents/artifacts/upload-url Authorization: Bearer CONTINUE_API_KEY Content-Type: application/json { agentSessionId: session-id, filename: screenshot.png, contentType: image/png, fileSize: 1048576 }后端在签发 URL 前执行如下校验链认证 API Key并核验调用者对该会话的所有权校验文件名防路径穿越、扩展名白名单按单文件上限校验大小默认 50MB按内容类型白名单校验 MIME校验会话总存储配额默认 500MB。校验通过时返回{ url: https://s3.amazonaws.com/bucket/sessions/org/abc123/artifacts/screenshot.png?X-Amz-..., key: sessions/org/abc123/artifacts/screenshot.png, expiresIn: 900 }校验失败时返回400 Bad Request { error: File size exceeds maximum allowed (50MB) }在 CLI 侧这个请求由requestPresignedUploadUrl方法完成它拼接new URL(agents/artifacts/upload-url, env.apiBase)发起POST携带agentSessionId、filename、contentType、fileSize四个字段并在Authorization头附带 Bearer 令牌响应非 2xx 或缺少url字段时返回null并记录警告日志ArtifactUploadService.ts。其中env.apiBase默认值为https://api.continue.dev/可通过CONTINUE_API_BASE环境变量覆盖env.ts。第二步直传 S3拿到预签名 URL 后Agent 用PUT方法直接把文件内容上传到 S3PUT presigned-url Content-Type: image/png file-contentsS3 校验预签名 URL 的签名后接受上传这一过程后端完全不参与。CLI 侧的uploadFileToS3方法用fs.readFileSync读取文件为 Buffer再以PUTContent-Type头发送响应非 2xx 时抛出包含状态码与响应体的错误ArtifactUploadService.ts。存储组织会话前缀下的统一归档产物在 S3 中按如下路径结构存放sessions/ user/ userId/ sessionId/ artifacts/ screenshot.png video.mp4 debug.log session.json # Session state (existing) diff.txt # Git diff (existing) org/ organizationId/ sessionId/ artifacts/ ...这一结构的设计要点与既有的session.json、diff.txt文件保持向后兼容按 user/org 隔离数据保障安全性同一会话的全部文件聚合在一起删除会话时可通过前缀一次性递归清理。该目录规划与同目录下的另一份设计文档 storage-sync.md 形成呼应——后者描述cn serve --id模式下session.json与diff.txt定期写入同一sessions/sessionId/前缀的存储同步流程两者共用同一套预签名 URL 直传模式与存储布局产物目录是这一前缀下的扩展。文件类型与大小限制允许的文件类型系统同时校验文件扩展名与 MIME 类型图片.png、.jpg、.jpeg、.gif、.webp视频.mp4、.mov、.avi、.webm文本/日志.log、.txt、.json、.xml、.csv、.html内容类型按白名单校验防止上传可执行文件或其他潜在危险内容。CLI 侧的inferContentType方法内置了与上述清单一一对应的扩展名→MIME 映射如.png → image/png、.mov → video/quicktime、.csv → text/csv未匹配的扩展名回退为application/octet-stream当调用方未显式传入contentType时就依据此映射自动推断ArtifactUploadService.ts。大小限制系统强制两档限制单文件限制50MB可通过ARTIFACT_MAX_FILE_SIZE_MB配置会话总存储限制500MB可通过ARTIFACT_MAX_TOTAL_SIZE_MB配置。后端在签发预签名 URL 之前会先对该会话在 S3 前缀下的所有文件求和据此计算总存储占用防止单个会话过度消耗存储。CLI 用法方式一使用 UploadArtifact 工具推荐UploadArtifact工具在开启 beta 开关后可用cn serve --id agentSessionId --beta-upload-artifact-toolAgent 随后即可调用内建的UploadArtifact工具上传文件// The agent calls this tool with the file path { name: UploadArtifact, parameters: { filePath: /tmp/screenshot.png } }工具执行时会依次校验文件存在且类型允许、检查单文件大小上限50MB、上传到会话存储、返回成功消息或详细错误。工具描述Upload a file (screenshot, video, log) to the session artifacts for user review. Supported formats: images (png, jpg, jpeg, gif, webp), videos (mp4, mov, avi, webm), and text files (log, txt, json, xml, csv, html). Maximum file size: 50MB.If an artifact with the same filename already exists, it will be overwritten with the new file.使用前提必须以--id agentSessionId运行agent 模式必须开启--beta-upload-artifact-tool开关用户必须已认证cn login。源码侧可交叉验证上述行为index.ts 为serve子命令注册了--beta-upload-artifact-tool选项services/index.ts 在服务初始化时据此调用setBetaUploadArtifactToolEnabled(true)开启全局开关tools/index.tsx 则在存在--id传入的 agent ID 且 beta 开关开启时才把uploadArtifactTool追加进可用工具列表。工具实现在 uploadArtifact.ts 中filePath为必填参数要求绝对路径运行时会校验参数非空、--id已提供、文件存在然后委托services.artifactUpload.uploadArtifact完成上传成功时返回提示用户可在会话的 Artifacts 标签页查看失败时针对文件过大存储配额超限类型不允许等场景给出可操作的错误文案uploadArtifact.ts。此外 defaultPolicies.ts 中已把UploadArtifact列入默认允许的工具策略。方式二服务级编程式上传Service API自定义实现可直接调用服务import { services } from ./services/index.js; const result await services.artifactUpload.uploadArtifact({ agentSessionId: process.env.AGENT_SESSION_ID, filePath: /tmp/screenshot.png, accessToken: process.env.CONTINUE_API_KEY, }); if (result.success) { console.log(Uploaded: ${result.filename}); } else { console.error(Failed: ${result.error}); }ArtifactUploadService.uploadArtifact的完整执行路径ArtifactUploadService.ts取path.basename得到文件名 → 校验文件存在 → 读取文件大小 → 未显式传入时按扩展名推断 MIME → 增加uploadsInProgress计数并清空lastError→ 请求预签名 URL → 直传 S3 → 更新服务状态并返回{ success, filename, error? }。整个服务继承自BaseService内部维护uploadsInProgress与lastError状态可供监控与排障使用。多文件批量上传const results await services.artifactUpload.uploadArtifacts( process.env.AGENT_SESSION_ID, [/tmp/screenshot1.png, /tmp/screenshot2.png, /tmp/debug.log], process.env.CONTINUE_API_KEY, ); results.forEach((result) { console.log(${result.filename}: ${result.success ? ✓ : ✗}); });uploadArtifacts内部将每个文件路径映射为一个uploadArtifactPromise 并用Promise.all并行执行返回与入参一一对应的结果数组便于逐文件展示成功/失败状态ArtifactUploadService.ts。环境变量CLI 进行产物上传需要以下环境变量CONTINUE_API_KEY后端认证的 Bearer 令牌CONTINUE_API_BASEAPI 基础地址默认https://api.continue.dev/AGENT_SESSION_ID当前 Agent 会话标识。在 Continue 的 devbox 环境中这些变量会自动注入。其中CONTINUE_API_BASE的默认值已在 env.ts 中确认AGENT_SESSION_ID在编程式示例中作为会话 ID 传入uploadArtifact。错误处理校验错误400文件名非法路径穿越、扩展名不允许文件过大超过单文件限制存储配额超限会话总量超过 500MB内容类型非法。认证错误401/403API Key 缺失或无效用户不拥有该 Agent 会话。上传错误S3 侧上传过程中网络故障预签名 URL 过期15 分钟超时S3 服务错误。所有错误都会被记录日志并以描述性消息返回上传失败不会导致 Agent 崩溃——uploadArtifact返回带error字段的失败结果UploadArtifact工具会把这些失败转译为ContinueError抛出由 Agent 优雅地处理uploadArtifact.ts。服务内部还维护lastError状态便于事后排查最近一次失败的根因。前端访问前端可借助以下接口列出与下载产物。列出产物GET /agents/{agentSessionId}/artifacts Authorization: Bearer API_KEY Response: { artifacts: [ { filename: screenshot.png, size: 1048576, sizeFormatted: 1.0 MB, lastModified: 2025-12-08T10:30:00Z } ] }下载产物GET /agents/{agentSessionId}/artifacts/{filename}/download Authorization: Bearer API_KEY Response: { url: https://s3.amazonaws.com/..., expiresIn: 3600 }前端随后使用返回的预签名下载地址直接从 S3 拉取文件。注意下载 URL 的有效期为 1 小时比上传 URL 的 15 分钟更长以适应浏览器端较长的人工操作链路。安全考量认证所有端点都要求与用户/组织账户绑定的有效 API Key授权签发预签名 URL 前核验会话所有权路径穿越防护文件名经过校验防止../攻击内容校验通过扩展名与 MIME 双重检查限制文件类型限流防滥用单文件与会话总存储双重配额限时 URL上传 URL 15 分钟过期下载 URL 1 小时过期存储隔离文件按 user/org 前缀隔离防止跨租户访问。设计权衡选择不做数据库追踪决策产物以文件形式存于 S3不在数据库中逐条登记。理由实现更简单无需新增数据库表文件即事实来源不存在数据库与 S3 之间的同步问题通过 S3 的 ListObjects 即可快速列出删除会话文件夹时自动完成清理。代价无法跨会话查询产物或在不扫描 S3 的情况下检索元数据。选择同名覆盖决策同一文件名重复上传时后上传者胜出。理由比版本化或自动重命名更简单覆盖常见场景——Agent 重新上传更新后的截图减少存储消耗。代价产物没有版本历史。选择S3 直传预签名 URL决策使用预签名 URL 而非让文件流经后端。理由性能更优后端不成为瓶颈成本更低无后端带宽费用是已被验证的成熟模式StorageSyncService 已在使用同一模式。代价后端无法在上传前检查文件内容依赖签发 URL 时的校验。未来演进方向压缩上传前自动压缩截图/视频保留策略N 天后自动删除产物更多产物类型支持 PDF、压缩包等预览生成为图片/视频生成缩略图流式上传用 multipart upload 支持超大文件元数据为产物附加自定义元数据标签、描述。本文基于仓库中的 artifact-uploads.md 整理对应的服务层实现与工具注册逻辑分别位于 ArtifactUploadService.ts 与 uploadArtifact.ts可通过cn serve --id agentSessionId --beta-upload-artifact-tool在 devbox 中实际体验。【免费下载链接】continueopen-source coding agent项目地址: https://gitcode.com/GitHub_Trending/co/continue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考