Coze Studio 前端上传体系解析:`@coze-arch/uploader-interface` 类型契约包的设计与实战
2026/9/13 2:53:50 网站建设 项目流程

Coze Studio 前端上传体系解析:@coze-arch/uploader-interface类型契约包的设计与实战

【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio

本文围绕 Coze Studio 前端 monorepo 中的 uploader-interface 包 展开:它是一个纯类型定义包,为整个前端文件上传体系(视频、图片、普通对象文件)统一了 STS 临时凭证、上传配置、事件回调与上传结果的结构化契约。读完本文,你能掌握该包导出接口的完整字段语义,理解它如何被 uploader-adapter 适配落地、并在 bot-utils 上传工具 中驱动真实的“获取上传凭证 → 创建 Uploader → 监听进度 → 返回上传结果”全链路。

一、包定位与安装方式

包 README 明确了该包在 monorepo 中的角色:它是 Coze Studio 前端工作区的一部分,提供面向上传场景的接口层能力。从 package.json 可以看到几个关键事实:

  • 包名为@coze-arch/uploader-interface,当前版本0.0.1,许可协议 Apache-2.0;
  • main直接指向 src/index.ts,即 TypeScript 源码即入口;
  • build脚本为exit 0——说明该包不做独立产物构建,由 monorepo 的 workspace 依赖机制在消费方直接引用源码;
  • test使用 Vitest(vitest --run --passWithNoTests),代码质量由 ESLint 保障,与 README 中 Development 一节“TypeScript / Modern JavaScript / Vitest / ESLint”的描述一致。

README 给出的引用方式是标准 Rush workspace 依赖:

{ "dependencies": { "@coze-arch/uploader-interface": "workspace:*" } }

然后执行rush update完成依赖链接。仓库中实际这样消费它的包是 uploader-adapter,它在package.json中声明了对本包的workspace:*依赖。

二、核心类型契约:src/index.ts 逐项解析

该包的全部实现就是这一个入口文件(src/index.ts),导出了一套完整的上传 SDK 契约。下面按“凭证 → 配置 → 任务 → 事件 → 结果 → 实例接口”的顺序拆解。

2.1 STSToken:上传临时凭证

STSToken 定义了对象存储(TOS)临时授权的五个字段:

export interface STSToken { AccessKeyId: string; SecretAccessKey: string; SessionToken: string; ExpiredTime: string; CurrentTime: string; }

其中CurrentTimeExpiredTime让前端可以在本地比较时间戳,判断凭证是否临近过期,从而触发 SDK 的refreshSTSToken方法刷新(见 2.6 节)。这一结构在业务层的真实构造过程可参考 upload-file.ts:bizConfigbotworkflow两个业务各自的getAuthToken都会调用后端GetUploadAuthToken接口,把响应里的auth.access_key_idauth.session_token等字段逐一映射为STSToken结构,同时取出service_idupload_hostschema作为上传宿主参数。

2.2 Config:全局上传配置

Config 是创建 Uploader 实例时的入参,字段可归纳为几组:

必填身份项

字段类型说明
userIdstring当前用户 ID,必填
appIdnumber应用 ID,必填

区域与宿主路由

  • stsToken?: STSToken:可选的全局凭证,单个文件也可在FileOption中单独携带;
  • region?:枚举限定为'cn-north-1' | 'us-east-1' | 'ap-singapore-1' | 'us-east-red' | 'boe' | 'boei18n' | 'US-TTP' | 'gcp',用于选择上传链路区域;
  • videoHost/videoFallbackHost/imageHost/imageFallbackHost:主、备上传网关域名,适配器层会优先取主域名、缺失时回退到 fallback(该回退逻辑有单测覆盖,见 3.2 节);
  • schema?: string:源码注释说明它对应 Tt-uploader 的逻辑——协议 schema 需要根据当前用户的部署环境动态获取,只支持 HTTPS/HTTP,SDK 内部消费该值而不暴露类型定义。

分类型处理管线

  • videoConfig?: VideoConfigspaceName必填 +processAction?);
  • imageConfig?: ImageConfigserviceId必填 +processAction?);
  • objectConfig?: ObjectConfigserviceId?/spaceName?+processAction?);
  • 其中 Action 的name限定为'GetMeta' | 'StartWorkflow' | 'Snapshot' | 'Encryption' | 'AddOptionInfo' | 'CaptionUpload',即上传完成后可串联的云端处理动作(取元信息、启动处理工作流、截帧封面、加密等)。

分片、超时与行为开关(关键项摘录自源码注释)

字段语义
getSliceFunc?: (fileSize: number) => number自定义按文件大小计算分片大小
uploadSliceCount?: number分片上传并发/片数控制
uploadHttpMethod?: string上传 HTTP 方法
uploadTimeout?/gatewayTimeout?上传超时 / 上传网关超时
skipDownload?: boolean跳过下载环节,仅视频上传支持
skipMeta?: boolean跳过元信息获取,仅图片上传支持
skipCommit?: boolean跳过 1005 提交阶段,仅支持 ImageX
enableDiskBreakpoint?: boolean是否启用断点续传
clientEncrypt?: boolean客户端加密开关
instanceId?: string多实例识别
useFileExtension?/useServerCurrentTime?/openExperiment?/noLog?/bizType?文件名扩展名策略、服务器时间基准、实验透传、日志静默、业务类型

UpdateOptions(L115-L141)是Config的全选子集,对应运行时通过setOption热更新配置的能力。

2.3 文件与任务选项

  • FileOption:addFile的入参,核心是file: Blob+stsTokentype限定'video' | 'image' | 'object',另有objectSync?(跨通道同步的源/目标通道与DataTypeBizID)、storeKey?useDirectUpload?serviceType?: 'vod' | 'imagex'(区分点播与 ImageX 服务);
  • ImageFileOption:addImageFile的入参,与FileOption的差异在于file允许Blob | Blob[](批量图片);
  • StartOptions:start的可选参数,提供selectRoute系列字段(路由选择开关、客户端 IP、路由选择超时/缓存时长/文件大小阈值),用于上传前择优路由;
  • StreamTaskOption / StreamSliceOption:流式上传任务(stsToken+ 可选fileSize)与流式分片(fileSlice: Blob+ 序号index),配合addStreamUploadTask/addStreamSlice/completeStreamUpload三个 API 完成边收边传的场景。

2.4 事件系统:README 导出的三个类型只是冰山一角

README 的 API Reference 列出了三个导出类型别名:ProgressEventInfoStreamProgressEventInfoErrorEventInfo。在源码中(L286-L294)它们都指向同一个 BaseEventInfo 基础结构:

interface BaseEventInfo { startTime: number; // 文件开始上传时间戳(毫秒) endTime: number; // 文件上传完成时间戳 stageStartTime: number; // 当前阶段开始时间戳 stageEndTime: number; // 当前阶段结束时间戳 duration: number; // 阶段耗时 = stageEndTime - stageStartTime fileSize: number; // 当前文件大小 key: string; // 文件 key(addFile 时自动生成) oid: string; // 存储文件 ID(preUpload 阶段产生) percent: number; // 整体进度百分比(%) signature: string; // preUpload 阶段取得的签名信息 sliceLength: number; // 每个分片大小(crc32 获取) stage: string; // 当前生命周期阶段,不支持的浏览器为 'browserError' status: 1 | 2 | 3; // 1 运行中 / 2 取消中 / 3 暂停 task: any; // 任务队列实例 type: 'success' | 'error'; uploadID: string; // get initUploadID 取得的 uploadID extra: { error?: any; errorCode?: number; message: string }; }

这组字段完整刻画了上传任务的生命周期:stage+stageStartTime/stageEndTime描述当前处于哪个阶段及耗时,percent描述整体进度,statustype共同表达运行态与成败。基于BaseEventInfo,事件载荷通过 EventPayloadMaps 做了精确映射:

export interface EventPayloadMaps { complete: CompleteEventInfo; // = BaseEventInfo + uploadResult: UploadResult progress: ProgressEventInfo; 'stream-progress': StreamProgressEventInfo; error: ErrorEventInfo; }

四个事件名complete | error | progress | 'stream-progress'BytedUploader.on的泛型参数一一对应,回调函数会拿到精确的EventPayloadMaps[T]类型,业务侧无需再做载荷断言。

2.5 UploadResult:按文件类型归一化的结果结构

UploadResult 把视频、图片、普通文件三种结果平铺在同一接口中,源码注释明确说明了取舍:“不同类型字段有差异,用范式(discriminated union)处理略显繁琐,因此直接全量定义”。按类型分组的字段包括:

  • 视频Vid(视频 VID)、VideoMeta?(UploadResultVideoMeta:时长、宽高、格式、码率、大小、Md5、Uri等;其中Md5注释特别说明“MD5 需下载计算,默认仅在小于 100M 且非 M3U8 文件时返回,强依赖需联系手动配置”)、PosterUri?(封面,需配置截图动作后返回);
  • 图片ImageUribucket/oid格式)、ImageWidth/ImageHeight/ImageMd5FileName(与ImageUri中 oid 段一致);
  • 普通文件ObjectMeta?Md5+Uri)。

Uri字段注释提醒:它是 TOS 中的源文件 URI,格式为bucket/oid,图片场景与ImageUri保持一致。

2.6 BytedUploader:实例能力的完整契约

BytedUploader 以接口形式约定了上传实例的全部 API,可视为对底层tt-uploaderSDK 的“能力契约”:

方法签名要点用途
constructor(config: Config)构造入参即 2.2 节Config创建实例
setOption(options: UpdateOptions)运行时更新配置热更新
addFile(fileOption): string返回文件 key添加视频/图片/对象文件
addImageFile(imageFileOption): string返回文件 key添加(批量)图片
start(key?, startOptions?)可选按 key 启动启动上传
pause(key?)/cancel(key?)/removeFile(key?)均可指定 key暂停 / 取消 / 移除
refreshSTSToken(stsToken)传入新凭证凭证过期刷新
addStreamUploadTask/addStreamSlice/completeStreamUpload流式三件套边接收边上传
on/once/removeListener/removeAllListeners泛型T extends UploadEventName事件订阅与退订

由于on的回调参数类型由EventPayloadMaps精确约束,业务监听complete时拿到的必然是带uploadResultCompleteEventInfo——这是该契约包给前端最大的工程收益:上传全链路的类型安全由类型包统一保证,而非散落在各业务实现里。

三、仓库中的真实消费链:从接口包到可运行上传

3.1 uploader-adapter:把契约落到 tt-uploader

uploader-adapter 是直接依赖本包的适配层。它导入tt-uploaderUploader实现类,同时从@coze-arch/uploader-interface复用ConfigSTSTokenObjectSync类型,并对外转导出ConfigEventPayloadMaps(L74-L77),形成“接口包定义契约 → 适配器提供实现 → 业务只依赖契约”的清晰分层。

getUploader(config, isOversea?)工厂函数做了三件契约之外的落地工作:

  1. 区域路由region: isOversea ? 'ap-singapore-1' : 'cn-north-1'(L39-L52)。同目录 utils.ts 中的REGION_MAP还给出了更完整的区域归一化思路(如us-east-1因“Volcengine 无 va 环境”而映射到ap-singapore-1);
  2. imageHost 归一化:优先config.imageHost,缺失回退config.imageFallbackHost,再缺失取空串;同时按config.schema动态替换协议头,兼容 HTTP 特化场景(L34-L38);
  3. addFile 收窄为图片链路:适配器把uploader.addFile重写为只透传{ file, stsToken }给底层addImageFile,返回的文件 key 即底层生成值(L54-L63)。其导出的CozeUploader = Uploader & { addFile; removeAllListeners }类型,就是业务侧实际使用的上传器类型。

3.2 测试对契约行为的验证

适配器单测tests/index.test.ts 通过 mocktt-uploader验证了上述契约行为,可作为“接口 → 实现”一致性的证据:

  • 构造配置断言:国内默认region: 'cn-north-1'isOversea为 true 时切换ap-singapore-1(L66-L84);
  • addFile确实只透传{ file, stsToken }并返回底层 key(L86-L92);
  • imageHost会剥离https://前缀、缺失时回退imageFallbackHost、两者皆缺时回退空串(L94-L118)。

3.3 业务用法:bot-utils 中的 upLoadFile

bot-utils 的 upload-file.ts 展示了接口契约在业务侧的典型用法(L101-L117):

  • 入口upLoadFile({ biz, file, fileType, getProgress, getUploader, getUploadAuthToken })支持biz: 'bot' | 'workflow',不同业务对应不同 ImageX 服务,各自通过DeveloperApi.GetUploadAuthToken/workflowApi.GetUploadAuthToken(scene 分别为bot_taskimageflow)换取serviceIduploadHoststsTokenschema
  • 文件类型支持'image' | 'object',进度通过getProgress回调上报——这正是 2.4 节progress事件percent字段的落地;
  • 该文件还做了export type BytedUploader = CozeUploader的类型别名导出,让更上层业务只面向契约类型编程。

从源码结构看,整条链路是:uploader-interface(契约)→uploader-adapter(tt-uploader 适配与区域/宿主归一化)→bot-utils upLoadFile(凭证获取与业务编排)→ 各 IDE 功能(bot 素材、workflow 图标等)上传入口。

四、开发与质量保障

该包遵循 monorepo 统一的工程基线(参考 package.json 与 README 的 Development 一节):

  • 测试:Vitest,命令npm run test(即vitest --run --passWithNoTests,纯类型包允许零测试用例通过)与npm run test:cov
  • 静态检查:npm run lint调用eslint ./ --cache,配置文件见 eslint.config.js;
  • TypeScript 工程:tsconfig.json 复用@coze-arch/ts-configworkspace 包;
  • 构建:build为空操作(exit 0),消费方以源码形式引用。

作为 monorepo 的一员,贡献流程遵循仓库整体的贡献指南(见根目录 CONTRIBUTING.md),协议为 Apache-2.0。

五、小结

@coze-arch/uploader-interface虽只有单个入口文件,却以一套完整的 TypeScript 契约约束了 Coze Studio 前端上传体系的全部关键面:STSTokenConfig解决“用什么凭证、走哪条链路”,FileOption/ 流式选项解决“传什么”,EventPayloadMaps解决“过程如何感知”,UploadResult解决“结果如何消费”,BytedUploader则把实例 API 固化为可静态检查的接口。对需要扩展上传能力的开发者而言,最实际的做法是:先对照本包类型定义补齐自己的配置与事件处理,再参考 uploader-adapter 的区域归一化与宿主回退策略实现适配层,最后用 bot-utils/upload-file.ts 的“业务换取上传凭证 → 创建 uploader → 监听 progress/complete”模式接入业务。

【免费下载链接】coze-studioAn AI agent development platform with all-in-one visual tools, simplifying agent creation, debugging, and deployment like never before. Coze your way to AI Agent creation.项目地址: https://gitcode.com/GitHub_Trending/co/coze-studio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询