@kanyun-ai-infra/agenthub 1.12.0 → 1.13.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 CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  本文件从 1.12.0 开始记录;更早的版本见 git 历史中的 `chore(agenthub-sdk): release X.Y.Z` 提交。
4
4
 
5
+ ## 1.13.0
6
+
7
+ - 浏览器实时语音支持可选 `onEnded({ callId, reason })`:识别通话终态帧 `call_ended` 或关闭码 `4000`,清理采集与播放并停止自动接手;时长上限映射为 `duration_limit`,未知原因映射为 `unknown`。回调每通至多一次,本地 `stop()` 不触发;终态到达后可以手动开始新通话。
8
+
9
+ - `NO_RESPONSE` 通知新增可选 `contextReset: true`:表示网关已切换到新的模型会话,模型不再持有此前上下文;平台回合历史不变。
10
+ - 随包类型声明移除内部包名与仓库路径,公开方法签名不因这项注释整理而改变。
11
+
12
+ ### 随共享契约内联的变化
13
+
14
+ - Slack 渠道声明新增可选 `approverUserIds`,用于指定可在线程里批准或拒绝工具调用的用户;最多 64 项且不能重复。slack 声明携带有效的 `approverUserIds` 时,SDK 1.12.1 的 `publishRevision` 会在本地校验时报 `unrecognized_keys`;1.13.0 接受该字段。
15
+
16
+ ### 迁移说明
17
+
18
+ - 使用实时语音的接入方须升级到 `@kanyun-ai-infra/agenthub@1.13.0` 才能获得 `onEnded` 和到达时长上限后停止自动接手的行为。旧 SDK 1.11.0 / 1.12.x 会忽略 `call_ended`,收到关闭码 `4000` 后仍自动重连,最终报 `RECONNECT_EXHAUSTED`;仅升级网关不能修复旧客户端。
19
+ - `onEnded` 是可选回调;无需处理结束通知的接入方也会自动停止重连。`adaptiveConnect: false` 不会关闭这项通话终态处理。
20
+
21
+ ## 1.12.1
22
+
23
+ 修复 1.12.0 的已知问题,只改浏览器实时语音入口 `@kanyun-ai-infra/agenthub/realtime` 的一项检查;主入口与类型声明和 1.12.0 相同。
24
+
25
+ ### 修复
26
+
27
+ - 「地址里不能含票」这项检查改为不区分大小写,票里的 `gatewayUrl` 与初始化时传入的 `gatewayUrl` 两处都改(#5002)。1.12.0 区分大小写,而 URL 解析会把主机名转成小写,票以混合大小写出现在主机名中时会漏检。修复后,票里地址含票时照常回落到初始化地址并发出 `TICKET_GATEWAY_URL_REJECTED`,初始化地址含票时报 `INVALID_GATEWAY_URL`、不建连。握手发出的票仍保持签发时的大小写。
28
+
29
+ ### 迁移说明
30
+
31
+ 无。
32
+
5
33
  ## 1.12.0
6
34
 
7
35
  主要是浏览器实时语音入口 `@kanyun-ai-infra/agenthub/realtime`(开发中,暂不支持线上用户接入)的改动;主入口的方法没有变化,随 contracts 内联带来的变化见下文。
@@ -26,7 +54,7 @@ SDK 构建时把 `@pilot/contracts` 打进 dist,1.11.0 之后 contracts 的改
26
54
 
27
55
  ### 已知问题
28
56
 
29
- - 「地址里不能含票」这项检查区分大小写,而 URL 解析会把主机名转成小写:票以混合大小写出现在票里地址或初始化地址的主机名中时,这项检查会漏检。票里地址仍要过主机检查,只能落在信任的主机上;初始化地址由接入方配置,不随票变化。1.12.1 修复。
57
+ - 「地址里不能含票」这项检查区分大小写,而 URL 解析会把主机名转成小写:票以混合大小写出现在票里地址或初始化地址的主机名中时,这项检查会漏检。票里地址仍要过主机检查,只能落在信任的主机上;初始化地址由接入方配置,不随票变化。**已在 1.12.1 修复**,见上文。
30
58
 
31
59
  ### 回到 1.11.0 的行为
32
60
 
package/README.md CHANGED
@@ -295,6 +295,9 @@ const voice = createRealtimeVoiceClient({
295
295
  },
296
296
  onState: (state) => renderState(state), // listening / thinking / speaking
297
297
  onTurnEnd: ({ turnSeq, turnId }) => finishTurn({ turnSeq, turnId }),
298
+ onEnded: ({ reason }) => showVoiceEnded(
299
+ reason === "duration_limit" ? "通话已结束:达到时长上限" : "通话已结束",
300
+ ),
298
301
  onError: ({ code, retryable }) => showVoiceError({ code, retryable }),
299
302
  });
300
303
 
@@ -314,8 +317,12 @@ stopButton.onclick = () => { void voice.stop(); };
314
317
 
315
318
  `stop()` 立即停止麦克风,发送本轮最终播放回执,再发 `end` 并关闭连接;Worklet 无响应时最多等待 200 ms,使用最后确认的播放统计。页面卸载同步清理。播放回执按 `turnSeq` 归属,`playedMs` 计实际渲染样本,不计排队音频;`firstPlayedAt` 是 Unix 毫秒,尚未播放时为 `null`。`turn_end` 表示业务回合收尾,不是音频 EOF。SDK 记住提前到达的回合终态,在播放排空时发送 final;迟到尾块沿用首次播放时刻并累加 playedMs,再补累计 final。记录保留最近 128 轮,尚在播放队列中的轮不会被淘汰。网关的文本截止不受晚回执影响,晚回执用于录音统计。
316
319
 
320
+ 收到当前通话的 `call_ended` 或专用关闭码 `4000` 时,SDK 停止自动接手、清理计时器、停止麦克风并清空播放,随后调用一次可选的 `onEnded({ callId, reason })`。首期原因是 `duration_limit`,未知原因映射为 `unknown`;关闭码判定不依赖 `wasClean`。只有关闭帧先于 `ready` 到达且没有通话 ID 时,`callId` 缺省;尚未完成的 `start()` 以既有 `REALTIME_STOPPED` 拒绝,不触发 `onError`。本地 `stop()` 不触发 `onEnded`,不等服务端回声。结束后可手动 `start()` 开新通话。`turn_end` 仍只代表一轮结束。
321
+
322
+ SDK 1.13.0 起提供此行为。旧版 1.11.0 / 1.12.0 / 1.12.1 忽略 `call_ended`,收到关闭后仍按原逻辑接手,不能仅靠更新网关修复旧客户端,接入方须升级到 1.13.0。普通 `1000`、`1006` 与 `reconnecting` 保留原恢复行为;若终态 JSON 和关闭帧都未送达,仍可能按网络断线接手。
323
+
317
324
  断线或收到 `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。
325
+ 浏览器子入口同时导出只读 `REALTIME_RECOVERY_REASONS` 和 `RealtimeRecoveryReason` 类型。实时 `NO_RESPONSE` 可重试通知可附带 `reason`:`input_not_received`(本句未获得回答)、`response_incomplete`(回答未完成)、`connection_interrupted`(空闲连接中断)。调用方应显示对应提示并允许重试;旧网关不带 reason 时沿用通用提示,未知 reason 被忽略。reason 不改变 SDK 的 stop/自动接手策略,也不表示丢失输入已被重放。已发布 1.11.0 忽略该可选字段,但仍正常通知 NO_RESPONSE。网关在 GoAway 截止时换新模型会话、无法保留此前对话上下文时,同一通知另带 `contextReset: true`:通话继续,平台回合历史不变,调用方可提示用户模型已不记得之前的对话;已发布 1.11.0 / 1.12.0 忽略该字段。
319
326
 
320
327
  首次建连(第一次收到 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
328