安装和使用 Qoder Cloud Agents TypeScript SDK,了解类型、异步调用、流式响应、取消、分页和自定义 fetch。
Qoder Cloud Agents TypeScript SDK 可用于 TypeScript 和 JavaScript 应用,提供 Forward、Managed 客户端、请求与响应类型、异步分页和 SSE 流式读取。包同时提供 ES Modules 和 CommonJS 入口。
需要 Node.js 20.12 或更高版本:
将包版本和锁文件纳入版本控制。本文示例运行在 Node.js 服务端。
将个人访问令牌(PAT)保存到环境变量:
使用 Forward 客户端创建模板和身份,发起会话并发送消息。以下代码可保存为
使用 Managed 客户端创建 Agent 和环境,发起会话并发送消息:
也可以从
显式配置优先于环境变量。默认 PAT 模式先读取
时间单位为毫秒。单次调用的请求配置通常位于方法的最后一个参数;有查询或请求体参数的方法需要先传入该参数,不能将两者混用。
传入新的
使用
设置
多个客户端可以共享同一凭证实例和缓存。中国站需要同时设置
请求与响应类型从对应模式的子路径导入,字段保留 API 的 snake_case 命名:
字段是否接受
普通流在 EOF 时结束。需要在可恢复的断连后继续订阅时,显式使用
将
使用
默认最多重试 2 次,即最多尝试 3 次。自动重试要求请求可安全重放:
在这些规则内,SDK 处理服务端重试提示和等待时间。部分接口有更严格的规则。通过客户端的
写请求通过请求配置中的
默认超时为 10 分钟。
应用也可以持有
信号取消会结束该调用的等待、重试及响应体读取。自定义中间件或外部凭证组件自己的工作,也应遵循其取消和资源管理约定。
列表方法支持异步迭代,按需读取后续页:
需要逐页处理时,读取
也可以使用
普通请求返回
使用
这里记录的是收到响应时的耗时,不代表 SSE 消费完成。中间件属于 API 请求链路,不应当作覆盖所有外部连接的全局拦截器。
额外 Header 和 Query 使用请求配置中的
安装
需要 Node.js 20.12 或更高版本:
基本用法
将个人访问令牌(PAT)保存到环境变量:
.mjs 文件直接运行,也可用于支持 ES Modules 的 TypeScript 项目:
qca-sdk/forward、qca-sdk/managed 导入对应客户端。CommonJS 项目使用 require('qca-sdk'),并把 await 调用放入异步函数。
后续片段中未重新创建的 client 指已配置的 Forward 客户端。sess_example 等 ID 需要替换为当前凭证可访问的真实 ID。更多接入说明见 Managed 快速入门和 Forward API 参考。
客户端配置
| 配置 | Forward | Managed |
|---|---|---|
| 客户端 | ForwardClient | ManagedClient |
| Base URL 环境变量 | QODER_FORWARD_BASE_URL | QODER_BASE_URL |
| Global 默认地址 | https://api.qoder.com/api/v1/forward | https://api.qoder.com/api/v1/cloud |
| CN 地址 | https://api.qoder.com.cn/api/v1/forward | https://api.qoder.com.cn/api/v1/cloud |
QODER_ACCESS_TOKEN,再读取 QODER_PAT。SDK 不自动加载 .env 文件。Base URL 需要包含完整 API 前缀,与账号、凭证及资源所在区域一致。
复用配置
withOptions() 创建同类型的新客户端,保留没有覆盖的配置,原客户端保持原配置:
defaultHeaders、defaultQuery 或 middleware 时,会替换对应的整个配置值。单次请求配置仍优先于派生客户端的默认值。
鉴权
PAT
使用 pat 显式传入个人访问令牌,或使用环境变量。访问令牌保存在受信任的服务端环境中,前端应用通过自己的业务服务访问 QCA。
Service Account
设置 QODER_SA_KEY 后,显式创建凭证组件。组件负责置换、缓存 SAT(服务账号令牌),并在后续请求需要时更新:
region: 'cn' 和 CN Base URL。仅访问 Managed 时可以申请 qca.access scope;权限及工作空间绑定需在服务端配置。
普通客户端不会因为环境中存在 QODER_SA_KEY 就自动启用置换,SA Key 也不能直接作为业务接口的访问令牌。SA 鉴权失败不会回退到 PAT。
应用自行管理 SAT 时使用 { authMode: 'sa', accessToken: token }。accessToken 也接受返回令牌或 Promise<string> 的函数,在每次请求尝试前重新求值。静态 SAT 的更新由应用负责;不要同时配置 accessToken、pat 和 credential 等多个来源。更多说明见认证文档。
请求与响应类型
请求与响应类型从对应模式的子路径导入,字段保留 API 的 snake_case 命名:
| JavaScript 值 | JSON 对象字段的行为 |
|---|---|
省略属性,或值为 undefined | 不发送该字段 |
null | 发送 null |
false、0、'' | 原样发送 |
| 空数组、空对象 | 发送 []、{} |
null,以及如何处理该值,以对应接口定义为准。联合类型应通过其判别字段或属性检查收窄后再读取具体字段。
服务端新增的未知响应字段会保留,但不一定已经包含在当前 TypeScript 类型声明中。需要使用它们时,先检查实际值,再声明应用所需的扩展类型。TypeScript 类型本身不等于运行时数据校验。
流式响应
streamEvents() 返回可异步迭代的 SSE 流。使用 for await...of 读取,并在 finally 中释放连接:
resumableStream():
evt_checkpoint 替换为有效的恢复位置;首次订阅可省略 last_event_id。resumableStream() 直接返回异步可迭代对象,创建时不需要 await。示例中的 AbortSignal 将整个订阅限制为 60 秒;达到期限的取消会按取消错误向调用方传播。
恢复流保留最近交付事件的 SSE 游标,并在重连时继续使用。它不会重新发送业务请求,也不保证“恰好一次”处理。同一事件的多个增量可能共用 ID,不应仅按 ID 丢弃所有重复帧。
没有游标时从当前事件流尾部开始;补读历史需要有效的历史恢复位置。HTTP 请求重试次数不等于整个订阅的重连上限。具体事件含义和任务完成条件见对应 API 定义。
关闭流或取消本地 HTTP 请求只结束当前订阅,不会自动停止云端已经开始的执行。
错误处理与 Request ID
使用 instanceof 区分调用方取消、超时、HTTP 错误等情况:
APIError 覆盖 HTTP、连接、超时和取消错误。没有收到 HTTP 响应时,status、headers 和 response 可能为 undefined,不能假设它们始终存在。客户端配置错误属于更广泛的 QoderError。
常见 HTTP 子类包括 BadRequestError(400)、AuthenticationError(401)、PermissionDeniedError(403)、NotFoundError(404)、ConflictError(409)、RateLimitError(429)和 InternalServerError(5xx)。
普通 JSON 对象响应的 _request_id 来自响应头,缺失时为 null。它是不可枚举属性,不会出现在 JSON.stringify() 或对象展开结果中。HTTP 错误通过 request_id 提供标识;需要与分页或流一起读取响应元数据时,使用 .withResponse()。单个流事件和嵌套对象不自动携带这份元数据。
重试与幂等性
默认最多重试 2 次,即最多尝试 3 次。自动重试要求请求可安全重放:
| 请求 | 默认可重试情况 |
|---|---|
| GET、HEAD,或携带幂等键的请求 | 连接错误、超时、408、429、5xx |
| 未携带幂等键的其他请求 | 429 |
| 409 响应 | 不自动重试 |
请求体为不可重复读取的 ReadableStream | 不自动重放 |
maxRetries 配置默认次数,或在单次调用的请求配置中覆盖:
idempotencyKey 传入幂等键。同一次逻辑操作的所有重试复用同一个键,新的操作使用新的键。
超时与取消
默认超时为 10 分钟。timeout 控制每次底层 fetch 等待响应到达的时间:计时在调用 fetch 前开始,收到响应头后结束,不包含此前的凭证获取、中间件执行和后续响应体读取。
因此,SSE 或下载读取可能超过 timeout。需要控制整个操作的总时长时,传入 AbortSignal:
AbortController,在用户取消时调用 abort():
分页
列表方法支持异步迭代,按需读取后续页:
.data,并先检查是否存在下一页:
for await (const currentPage of page.iterPages()) 遍历页面。getNextPage() 在没有下一页时抛出错误,不返回 null;自动迭代会在末页正常结束。分页器保留筛选条件和请求配置。
高级配置
原始响应
普通请求返回 APIPromise。直接 await 得到解析后的数据;.withResponse() 同时返回数据、原始响应和 Request ID:
.asResponse() 在不读取响应体的情况下返回原始 Response,调用方负责消费或取消响应体:
自定义 fetch 和中间件
使用 fetch 注入 HTTP 实现。代理、TLS 和连接池设置由所选实现负责。中间件用于观察或调整每次 API 请求尝试:
headers、query。类型尚未覆盖的请求字段可以放入参数对象;只有服务端已经支持的字段才能生效。普通调用优先使用已有的类型化方法。