@kanyun-ai-infra/agenthub 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +62 -11
- package/dist/index.cjs +2934 -1892
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +299 -42
- package/dist/index.d.ts +299 -42
- package/dist/index.js +3149 -2109
- package/dist/index.js.map +1 -1
- package/dist/realtime.cjs +575 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +83 -0
- package/dist/realtime.d.ts +83 -0
- package/dist/realtime.js +547 -0
- package/dist/realtime.js.map +1 -0
- package/package.json +15 -4
- package/skills/agenthub-sdk/SKILL.md +445 -48
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @kanyun-ai-infra/agenthub 变更记录
|
|
2
|
+
|
|
3
|
+
本文件从 1.12.0 开始记录;更早的版本见 git 历史中的 `chore(agenthub-sdk): release X.Y.Z` 提交。
|
|
4
|
+
|
|
5
|
+
## 1.12.0
|
|
6
|
+
|
|
7
|
+
主要是浏览器实时语音入口 `@kanyun-ai-infra/agenthub/realtime`(开发中,暂不支持线上用户接入)的改动;主入口的方法没有变化,随 contracts 内联带来的变化见下文。
|
|
8
|
+
|
|
9
|
+
### 新增
|
|
10
|
+
|
|
11
|
+
- `getTicket()` 可以返回 `client.sessions.createVoiceTicket()` 的整个响应对象 `{ ticket, gatewayUrl, expiresAt }`,SDK 按票里的 `gatewayUrl` 建连(#4902)。票里的地址必须通过形状与主机检查才会被使用:协议为 `wss:`(初始化地址本身是 `ws:` 时也接受 `ws:`,供本地测试),路径为 `/`,不含 URL 凭据、查询串、片段和票,主机为初始化地址的主机或在 `trustedGatewayHosts` 内。没有该字段或检查不通过时,连初始化时传入的 `gatewayUrl`,并通过 `onError` 发出可重试通知 `TICKET_GATEWAY_URL_MISSING` 或 `TICKET_GATEWAY_URL_REJECTED`。`getTicket()` 仍可只返回票字符串,行为与 1.11.0 相同。
|
|
12
|
+
- 首次建连(第一次收到 ready 之前)的 WebSocket 若在 open 之前关闭,SDK 依次等待 500 ms、1 s、2 s,每次重新取票再连,最多重试 3 次,每次发出可重试通知 `CONNECT_RETRYING`;3 次后仍被拒报 `CONNECTION_FAILED`(#4902)。浏览器拿不到握手的 HTTP 状态码,网关排空或满额的 503 与 401 等拒绝无法区分,都按此重试。`getTicket()` 抛错、票格式错误、open 之后的失败、10 s 内未完成建连不重试。这部分重试与 ready 之后的 5 次通话接手额度分开计数。
|
|
13
|
+
- 新选项 `adaptiveConnect`(缺省 `true`)与 `trustedGatewayHosts`;新导出类型 `RealtimeVoiceTicket`(#4902)。
|
|
14
|
+
- `NO_RESPONSE` 通知可带可选的 `reason`:`input_not_received`、`response_incomplete`、`connection_interrupted`;新导出 `REALTIME_RECOVERY_REASONS` 与 `RealtimeRecoveryReason` 类型。旧网关不带 `reason`,SDK 的接手与停止策略不变(#4950)。
|
|
15
|
+
|
|
16
|
+
### 随 `@pilot/contracts` 内联的变化(非穷尽)
|
|
17
|
+
|
|
18
|
+
SDK 构建时把 `@pilot/contracts` 打进 dist,1.11.0 之后 contracts 的改动随本版一起发出。SDK 接口能碰到的有:
|
|
19
|
+
|
|
20
|
+
- `client.bindings.bindProjectRepo`:`repoUrl` 去掉空白后为空时,在客户端就被拒(`BindProjectRepoRequestSchema` 新增校验,#4875)。1.11.0 会照发,服务端去掉空白后存空值,等于解绑。
|
|
21
|
+
- `RevisionManifestInput`、`PublishPlatformRevisionRequestSchema`(及类型 `PublishPlatformRevisionRequest`):slack 渠道的 `inbound.allowedBotIds`(#4975;wecom 渠道没有这个字段,声明会被拒);agent 的 `promoteGate`(`"required"` 或 `"advisory"`,#4876)。均为可选字段。
|
|
22
|
+
- `WorkbenchDTOSchema`(及类型 `WorkbenchDTO`):配额用量里单列的实时语音会话容量 `voiceActiveSessions`(#4921),可选字段。
|
|
23
|
+
- eval 运行结果的判分证据 `evidence` 保留新的可选字段 `judgeIdentity`(#4862)。
|
|
24
|
+
|
|
25
|
+
主入口的方法没有变化。完整差异以 1.11.0 与 1.12.0 发布包的 `dist/index.js` 对比为准。
|
|
26
|
+
|
|
27
|
+
### 已知问题
|
|
28
|
+
|
|
29
|
+
- 「地址里不能含票」这项检查区分大小写,而 URL 解析会把主机名转成小写:票以混合大小写出现在票里地址或初始化地址的主机名中时,这项检查会漏检。票里地址仍要过主机检查,只能落在信任的主机上;初始化地址由接入方配置,不随票变化。1.12.1 修复。
|
|
30
|
+
|
|
31
|
+
### 回到 1.11.0 的行为
|
|
32
|
+
|
|
33
|
+
创建客户端时传 `adaptiveConnect: false`:只连初始化时传入的 `gatewayUrl`,首次建连被拒立即报 `CONNECTION_FAILED`,与 1.11.0 一致。也可以锁定 `@kanyun-ai-infra/agenthub@1.11.0`。
|
|
34
|
+
|
|
35
|
+
### 迁移说明
|
|
36
|
+
|
|
37
|
+
- 初始化 `gatewayUrl` 在接入方自有域名下(不在 `.zhenguanyu.com` 下)时,票里的平台网关地址不在缺省信任集内:每次建连都会收到 `TICKET_GATEWAY_URL_REJECTED`,并继续连初始化地址,平台按池下发的地址不会被跟随。需要跟随时,在 `trustedGatewayHosts` 里显式列出平台网关所在的域名,例如 `[".zhenguanyu.com"]`。
|
|
38
|
+
- 主机检查不比较端口:主机通过后,票里地址的端口可以与初始化地址不同。
|
|
39
|
+
- 先升级到 1.12.0,再把 `getTicket()` 改成返回对象:1.11.0 收到对象会报 `INVALID_TICKET`。
|
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ npx rush-ai skill install @kanyun/agenthub-sdk
|
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
skill 内容和这份 README 保持同步;改了 public API 时必须同步改 skill。公开方法与示例见
|
|
28
|
-
[AgentHub API 与 SDK 文档](https://agenthub.zhenguanyu.com/docs/api-and-sdk
|
|
28
|
+
[AgentHub API 与 SDK 文档](https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk)。剩下的正文是给人类读者的完整参考。
|
|
29
29
|
|
|
30
30
|
## 安装
|
|
31
31
|
|
|
@@ -37,8 +37,8 @@ pnpm add @kanyun-ai-infra/agenthub
|
|
|
37
37
|
需要 Node 18+,因为 SDK 使用全局 `fetch`。
|
|
38
38
|
|
|
39
39
|
如果调用方是 Java、Python 或 Shell(curl),请优先看
|
|
40
|
-
<https://agenthub.zhenguanyu.com/docs/api-and-sdk
|
|
41
|
-
或 <https://agenthub.zhenguanyu.com/docs/api-and-sdk#rest-flow>(curl)。
|
|
40
|
+
<https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#multi-language>(Python / Java)
|
|
41
|
+
或 <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#rest-flow>(curl)。
|
|
42
42
|
|
|
43
43
|
## 快速开始
|
|
44
44
|
|
|
@@ -233,19 +233,20 @@ https://octopus.zhenguanyu.com/#/trace-explorer?env=<test|online>&time=<起-止,
|
|
|
233
233
|
## 完整参考
|
|
234
234
|
|
|
235
235
|
下面这些内容日常写业务代码用不到,需要时查
|
|
236
|
-
[AgentHub 文档站](https://agenthub.zhenguanyu.com/docs/api-and-sdk) 对应小节
|
|
236
|
+
[AgentHub 文档站](https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk) 对应小节
|
|
237
237
|
(这份 README 会随 npm 包分发到别的项目里,下面全部是可以直接点开的网址,不是仓库内相对路径):
|
|
238
238
|
|
|
239
239
|
| 你想找 | 链接 |
|
|
240
240
|
| --- | --- |
|
|
241
|
-
| 资源方法速查(projects / agents / stages / environments / sessions / files / profiles) | <https://agenthub.zhenguanyu.com/docs/api-and-sdk
|
|
241
|
+
| 资源方法速查(projects / agents / stages / environments / sessions / files / profiles) | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk> |
|
|
242
242
|
| 记忆接口(写入 / 读回 / 确认 / 清空 / 策略)逐端点字段、outcome 与 REST 对照 | <https://agenthub.zhenguanyu.com/v1/docs/agent-memory#api> |
|
|
243
|
-
| "
|
|
244
|
-
| Client
|
|
245
|
-
|
|
|
246
|
-
|
|
|
247
|
-
|
|
|
248
|
-
| 调用方是
|
|
243
|
+
| "部署 test → 晋级 production → 回滚"的 Stage 序列 | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#stages> |
|
|
244
|
+
| Client 配置全部选项与错误类型 | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#client> |
|
|
245
|
+
| 获取 token、地址与 Header | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#setup> |
|
|
246
|
+
| Project 默认运行模板(`defaultRuntimeTemplateRefName`) | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#projects> |
|
|
247
|
+
| Dry run(`agents.create` 只校验不落库) | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#agents> |
|
|
248
|
+
| 调用方是 Java / Python(最后手段,官方只推荐这份 TS SDK) | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#multi-language> |
|
|
249
|
+
| 调用方是 Shell(curl) | <https://agenthub.zhenguanyu.com/v1/docs/api-and-sdk#rest-flow> |
|
|
249
250
|
|
|
250
251
|
## 错误
|
|
251
252
|
|
|
@@ -271,3 +272,53 @@ try {
|
|
|
271
272
|
throw err;
|
|
272
273
|
}
|
|
273
274
|
```
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
## 实时语音(浏览器)
|
|
278
|
+
|
|
279
|
+
**开发中,暂不支持线上用户接入。**
|
|
280
|
+
|
|
281
|
+
从 `@kanyun-ai-infra/agenthub/realtime` 导入 `createRealtimeVoiceClient`。浏览器只持有短期通话票;接入方后端调用 `client.sessions.createVoiceTicket(sessionId, options?)` 换票,`options` 可传 `signal: AbortSignal`,返回 `{ ticket, gatewayUrl, expiresAt }`。`getTicket()` 推荐返回整个响应对象,SDK 按票里的 `gatewayUrl` 建连;也可以只返回 `ticket` 字符串,此时连初始化时传入的 `gatewayUrl`。不能把平台 token 放进前端。主入口不加载浏览器代码。转写 `role` 为 `user` 或 `assistant`。
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { createRealtimeVoiceClient } from "@kanyun-ai-infra/agenthub/realtime";
|
|
285
|
+
|
|
286
|
+
const voice = createRealtimeVoiceClient({
|
|
287
|
+
gatewayUrl: "wss://your-voice-gateway.example/", // 票里没有可用地址时连这里
|
|
288
|
+
getTicket: async () => {
|
|
289
|
+
const response = await fetch("/api/voice-ticket", { method: "POST" });
|
|
290
|
+
if (!response.ok) throw new Error("无法取得通话票");
|
|
291
|
+
return response.json(); // 后端原样转发 createVoiceTicket 的 { ticket, gatewayUrl, expiresAt }
|
|
292
|
+
},
|
|
293
|
+
onTranscript: ({ role, text, final, turnSeq, turnId }) => {
|
|
294
|
+
renderTranscript({ role, text, final, turnSeq, turnId });
|
|
295
|
+
},
|
|
296
|
+
onState: (state) => renderState(state), // listening / thinking / speaking
|
|
297
|
+
onTurnEnd: ({ turnSeq, turnId }) => finishTurn({ turnSeq, turnId }),
|
|
298
|
+
onError: ({ code, retryable }) => showVoiceError({ code, retryable }),
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// 在点击等用户手势中调用;start 在网关 ready 后完成,失败时拒绝 Promise。
|
|
302
|
+
startButton.onclick = () => { void voice.start().catch(() => {}); };
|
|
303
|
+
interruptButton.onclick = () => voice.interrupt();
|
|
304
|
+
stopButton.onclick = () => { void voice.stop(); };
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
示例中的 `/api/voice-ticket`、按钮与渲染函数由接入方提供。`getTicket()` 每次连接都返回新票(无填充的 base64url 字符串),票只放在 WebSocket 握手子协议中;`gatewayUrl` 使用 `wss:`,本地测试可用 `ws:`,不含查询串、片段或 URL 凭据。SDK 不记录票,也不传播取票回调或网关的原始异常文本。
|
|
308
|
+
|
|
309
|
+
票里的 `gatewayUrl` 通过以下检查才会被使用:协议为 `wss:`(初始化地址本身是 `ws:` 时也接受 `ws:`,供本地测试);路径为 `/`;不含 URL 凭据、查询串、片段,也不含票;主机等于初始化地址的主机,或在 `trustedGatewayHosts` 内。`trustedGatewayHosts` 的每一项是完整主机名或以 `.` 开头的后缀;缺省为空,只有初始化地址本身在平台域名 `.zhenguanyu.com` 下时,缺省信任该域名下的主机。SDK 不按上一级域名推断,避免把 `.co.uk`、`.github.io` 这类公共后缀整体放行;网关在其他域名下时,由接入方显式列出。票会随握手发给被连接的主机,这项检查防止被篡改或配错的票把票和麦克风音频引到别处。票里没有该字段或未通过检查时,SDK 连初始化地址,并以可重试通知 `TICKET_GATEWAY_URL_MISSING` 或 `TICKET_GATEWAY_URL_REJECTED` 上报;`getTicket()` 返回字符串时不上报。
|
|
310
|
+
|
|
311
|
+
项目开启录音后,通话会被录音,保存 14 天;默认不录。接入页面应在开始前说明录音与保存期限。一期实时通话与文字回合上下文不互通。
|
|
312
|
+
|
|
313
|
+
采集需要 HTTPS 安全上下文(本地 localhost 可用)与麦克风权限。SDK 使用 AudioWorklet 将音频转为 16 kHz 单声道 PCM16,每帧 20 ms;播放接收 24 kHz PCM16,按轮排队,收到打断即清空。页面 CSP 需允许 `blob:` AudioWorklet 模块。支持目标为桌面 Chrome / Edge / Safari、iOS Safari 和微信内置浏览器;需要宿主提供 `AudioContext`、`AudioWorklet` 与 `getUserMedia`,缺失时通过 `onError` 报错。小程序和 App 内 WebView 不在本期范围,具体设备仍需接入方验收。
|
|
314
|
+
|
|
315
|
+
`stop()` 立即停止麦克风,发送本轮最终播放回执,再发 `end` 并关闭连接;Worklet 无响应时最多等待 200 ms,使用最后确认的播放统计。页面卸载同步清理。播放回执按 `turnSeq` 归属,`playedMs` 计实际渲染样本,不计排队音频;`firstPlayedAt` 是 Unix 毫秒,尚未播放时为 `null`。`turn_end` 表示业务回合收尾,不是音频 EOF。SDK 记住提前到达的回合终态,在播放排空时发送 final;迟到尾块沿用首次播放时刻并累加 playedMs,再补累计 final。记录保留最近 128 轮,尚在播放队列中的轮不会被淘汰。网关的文本截止不受晚回执影响,晚回执用于录音统计。
|
|
316
|
+
|
|
317
|
+
断线或收到 `reconnecting` 时保留播放队列、暂停采集,换新票并带原 `callId` 重连。每通话最多自动接手 5 次,退避从 250 ms 增至 4 s;取票与 WebSocket upgrade 最多等待 10 s,open 后另等 ready 最多 30 s,音频初始化最多 30 s。WebSocket 握手已验票,SDK 立即处理下行消息;转写、状态回调与播放可能早于 start() 完成。ready 只控制麦克风上行和 start() 完成,interrupted 始终立即清空播放。`no_response` 仅以 `NO_RESPONSE` 可重试通知上报,不主动接手通话。无法恢复时释放资源并报不可重试错误,可由用户重新开始。主动 stop 后再次 start 是新通话。
|
|
318
|
+
浏览器子入口同时导出只读 `REALTIME_RECOVERY_REASONS` 和 `RealtimeRecoveryReason` 类型。实时 `NO_RESPONSE` 可重试通知可附带 `reason`:`input_not_received`(本句未获得回答)、`response_incomplete`(回答未完成)、`connection_interrupted`(空闲连接中断)。调用方应显示对应提示并允许重试;旧网关不带 reason 时沿用通用提示,未知 reason 被忽略。reason 不改变 SDK 的 stop/自动接手策略,也不表示丢失输入已被重放。已发布 1.11.0 忽略该可选字段,但仍正常通知 NO_RESPONSE。
|
|
319
|
+
|
|
320
|
+
首次建连(第一次收到 ready 之前)的 WebSocket 若在 open 之前关闭,SDK 依次等待 500 ms、1 s、2 s,每次重新取票再连,最多重试 3 次,每次以可重试通知 `CONNECT_RETRYING` 上报;第 3 次重试仍被拒时报 `CONNECTION_FAILED`。浏览器不暴露握手的 HTTP 状态码,网关排空或满额时的 503 与 401 等其他拒绝无法区分,因此都按此重试;票是一次性的,网关可能已经兑票,所以每次重试都重新取票。以下情况不重试:`getTicket()` 抛错、票格式错误、open 之后的协议不符或网关的不可重试错误、open 之后 ready 之前断开、10 s 内未完成取票与 upgrade。首次建连重试与通话接手的 5 次额度分开计数。`CONNECT_RETRYING` 与 `TICKET_GATEWAY_URL_*` 都是 `retryable: true` 的通知,与 `RECONNECTING` 一样不表示通话失败。
|
|
321
|
+
|
|
322
|
+
`adaptiveConnect` 缺省为 `true`;设为 `false` 时只连初始化地址,首次建连被拒立即报 `CONNECTION_FAILED`,与 1.11.0 一致。
|
|
323
|
+
|
|
324
|
+
仓库内运行本地浏览器冒烟:`pnpm --filter @kanyun-ai-infra/agenthub run smoke:realtime`。该入口先按依赖顺序构建 SDK 及 contracts,再用本地假网关和无头 Chrome 验证采集、播放、打断、回执与停止;运行前需安装仓库依赖及 Chrome,不需要通话凭据。
|