@kanyun-ai-infra/agenthub 1.16.0 → 1.17.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,35 @@
2
2
 
3
3
  本文件从 1.12.0 开始记录;更早的版本见 git 历史中的 `chore(agenthub-sdk): release X.Y.Z` 提交。
4
4
 
5
+ ## 1.17.0
6
+
7
+ 浏览器实时语音入口 `@kanyun-ai-infra/agenthub/realtime`:终止错误带上网关终止码,新增默认关闭的自动重开,以及拉取式的音量电平。主入口的方法没有变化。
8
+
9
+ ### 新增(`@kanyun-ai-infra/agenthub/realtime`)
10
+
11
+ - `onError` 的 `RealtimeVoiceError` 新增可选 `gatewayCode`:网关终止通话时给出的码,只在 `GATEWAY_ERROR` 出口与 `REOPENING` 通知上出现。取值为 11 个终止码的闭集:`write_queue_full`、`control_timeout`、`control_rejected`、`generation_expired`、`upstream_unavailable`、`resume_store_unavailable`、`renew_rejected`、`execution_expired`、`no_response`、`renew_abandoned`、`realtime_turn_lost`;未知码不带该字段。`code` 仍是 `GATEWAY_ERROR`,按旧码分支的页面不用改。`retryable: true` 且已有通话 ID 的错误仍走自动接手,不落到这里;`no_response` 的可重试提示仍以 `NO_RESPONSE` 上报,不带 `gatewayCode`。
12
+ - 新选项 `reopenOnce`(默认 `false`):开启后,SDK 对「新通话还有机会」的终止错误自动重开一次——新票、新 WebSocket、新通话 ID,复用麦克风与 `AudioContext`,每次 `start()` 最多一次。重开前发一次 `onError({ code: "REOPENING", retryable: true, gatewayCode })`;重开后的通话再次终态按普通终态处理,不再重开。
13
+ - 可重开:`no_response`、`renew_abandoned`、`realtime_turn_lost`,以及 `ready` 之前到达的可重试 `upstream_unavailable`、`resume_store_unavailable`、`write_queue_full`、`control_timeout`、`control_rejected`。
14
+ - 不重开:`generation_expired`、`renew_rejected`、`execution_expired`(通话已被接管或执行许可到期)、`call_ended`、本地 `stop()`、未知码。
15
+ - 新方法 `audioLevels()`:返回 `RealtimeVoiceLevels { input, output }`,两侧都是最近 2048 个采样(48 kHz 下约 42.7 ms,采样率不同时时长随之变化)的线性 RMS,范围 [0, 1],不做平滑。`input` 是麦克风信号,`output` 是 SDK 播放出的信号,在 `outputNode` 之前取样:不传 `outputNode` 时即用户听到的声音;页面经 `outputNode` 再做增益或处理时,读数不含这部分处理。拉取式接口,页面在自己的 `requestAnimationFrame` 里调用,SDK 不新增定时器或回调。通话外与 `stop()` 之后返回 `undefined`;`ready` 之前与断线接手期间采集暂停,`input` 为 0。
16
+ - 新导出类型 `RealtimeVoiceLevels`。
17
+ - 电平分析节点串联在音频链路上:`source → 输入分析器 → worklet → 输出分析器 → outputNode/destination`。两个分析节点都是直通,送往网关的 PCM 与播放音频不变。
18
+
19
+ ### 随共享契约内联的变化
20
+
21
+ - 工作台与发布板读模型新增可选的 Revision 序号与版本串:`WorkbenchRecentChange` 的 `revisionVersion` / `revisionSequence`,槽位摘要(含灰度摘要)的 `revisionSequence`,以及 `ReleaseBoardRow.defaultRevision` / `latestRevision` 的 `sequence`。旧服务端的响应缺这些字段,解析行为不变。
22
+ - `Environment` 的 `envVars` 新增拒绝 `PILOT_WORKLOAD_SLUG` 的大小写变体(如 `pilot_workload_slug`),在 SDK 客户端校验时就报错;大写形式此前已被 `PILOT_` 前缀规则拒绝。会话配置值与 secret `envKey` 不受影响。
23
+
24
+ ### 随包文档
25
+
26
+ - `SKILL.md` 实时段补充音量电平、网关终止码与 `reopenOnce`。
27
+
28
+ ### 迁移说明
29
+
30
+ - **类型破坏**:`RealtimeVoiceClient` 新增了必选方法 `audioLevels()`。自己实现或 mock 这个接口的代码升级后会报类型错误,要补上该方法;通过 `createRealtimeVoiceClient` 工厂拿到的客户端不受影响。
31
+ - **音频接线变化**:麦克风源不再直接接 worklet,中间多了一个直通的分析节点。页面如果通过拦截 `AudioNode.prototype.connect`、按 `source → worklet` 这条连线识别上行的分接写法,升级后上行(麦克风)拿不到,下行照旧。正路是改用 `audioLevels()`。
32
+ - `reopenOnce` 默认关闭时,终止行为与 1.16.0 一致,只多一个 `gatewayCode` 字段。
33
+
5
34
  ## 1.16.0
6
35
 
7
36
  Revision 读面改为宽容读者:服务端给 `workloads.get` / `getRevision` / `getVersion` 的响应新增字段时,已发布的客户端不再报错。这一版同时接受可选的 `sequence`,服务端读面带出后即可读取,无需再次升级 SDK。
package/dist/index.cjs CHANGED
@@ -1557,7 +1557,16 @@ var ModelCallsPullResponseSchema = import_zod16.z.object({
1557
1557
  activeCalls: count(),
1558
1558
  sessionActiveCalls: count(),
1559
1559
  droppedRecords: count(),
1560
- truncated: import_zod16.z.boolean().optional()
1560
+ truncated: import_zod16.z.boolean().optional(),
1561
+ /**
1562
+ * Metering faults the pod-agent INSTANCE has swallowed so far (not scoped to
1563
+ * the session or query: pre-warm and earlier sessions count too).
1564
+ * `observer` = the store's own guard caught a throw; `hook` = the
1565
+ * forwarder's fail-open wrapper caught one (at most one per call). pod-agent
1566
+ * console logs never reach Octopus, so the host's sweep turns an increase
1567
+ * into a worker-side warn. Absent from an older pod-agent.
1568
+ */
1569
+ meteringFaults: import_zod16.z.object({ observer: count(), hook: count() }).optional()
1561
1570
  });
1562
1571
  var ModelCallsBlockSchema = import_zod16.z.object({
1563
1572
  accounting: label(),
@@ -3027,6 +3036,7 @@ var PROTECTED_WORKER_ENV_KEYS = /* @__PURE__ */ new Set([
3027
3036
  "PILOT_RUNTIME_BINDING_ID",
3028
3037
  "PILOT_STAGE",
3029
3038
  "PILOT_WORKLOAD_ID",
3039
+ "PILOT_WORKLOAD_SLUG",
3030
3040
  "PILOT_WORKSPACE_SNAPSHOT",
3031
3041
  // Managed-agent prewarming — seed toolbox, projected via the typed startWorker
3032
3042
  // request, never via business env.
@@ -3480,7 +3490,18 @@ var PodAgentStartWorkerRequestSchema = import_zod10.z.object({
3480
3490
  * Strict `z.string().uuid()` rejects it (version nibble 0) and rejected every
3481
3491
  * such start request at the pre-flight check in control-worker.
3482
3492
  */
3483
- projectId: import_zod10.z.union([import_zod10.z.string().uuid(), import_zod10.z.literal(PLATFORM_DEFAULT_PROJECT_ID)]).optional()
3493
+ projectId: import_zod10.z.union([import_zod10.z.string().uuid(), import_zod10.z.literal(PLATFORM_DEFAULT_PROJECT_ID)]).optional(),
3494
+ /**
3495
+ * Observability provenance (obs sandbox inject) — the workload's human-readable
3496
+ * slug (`workloads.slug`, unique within the owner project), forwarded into the
3497
+ * spawned child as `PILOT_WORKLOAD_SLUG` for the `pilot.workload_slug` OTel
3498
+ * resource attribute (Octopus LLM-dashboard agent dimension). control-plane
3499
+ * resolves it from the `workloads` catalog at `startWorker` time, alongside
3500
+ * `projectId`. Optional — omitted → pod-agent omits the env var. Injected ONLY
3501
+ * via this typed field, never via user `env` (guarded by
3502
+ * `PROTECTED_WORKER_ENV_KEYS` → `PILOT_WORKLOAD_SLUG`).
3503
+ */
3504
+ agentSlug: import_zod10.z.string().min(1).max(100).optional()
3484
3505
  // NOTE: `agentWorkerBundleUrl` (v2 hot-deploy) was REMOVED here — #1070 P2
3485
3506
  // retired the OSS bundle path; agent-worker is now baked into the sandbox
3486
3507
  // image and pod-agent always spawns the baked dist. This schema keeps zod's
@@ -9217,8 +9238,7 @@ var ManagedAgentProfileV1RuntimeSchema = import_zod60.z.object({
9217
9238
  // rejects the profile instead of dropping the selection (why:
9218
9239
  // `.agents/notes/proposed/architecture/
9219
9240
  // 2026-09-28-executor-keys-reserved-until-gates.md`).
9220
- // The profile→defaults projection and the form selector are #3843; the
9221
- // publish-side gate (EXP) judging the frozen executor is already live in
9241
+ // The publish-side gate (EXP) judging the frozen executor lives in
9222
9242
  // `applyRevisionManifest`, so a pi selection cannot reach a Revision while
9223
9243
  // its publishable switch is off.
9224
9244
  executor: ProfileExecutorSchema.optional()
@@ -10766,6 +10786,11 @@ var SlotCanarySummarySchema = import_zod75.z.object({
10766
10786
  revisionId: import_zod75.z.string(),
10767
10787
  /** canary revision 的人可读版本短名;revision 行缺失时 null(降级显示 id 前缀)。 */
10768
10788
  revisionLabel: import_zod75.z.string().nullable(),
10789
+ /**
10790
+ * canary 版本在该 Agent 内的落库序号(#5057 PR-B)。主显 `#n`、原串进
10791
+ * `title`。optional = 旧服务端响应没有它(滚动发版兼容)。
10792
+ */
10793
+ revisionSequence: import_zod75.z.number().int().nullable().optional(),
10769
10794
  /** 0..99;0 = 冻结观察态(仅名单命中仍入 canary)。 */
10770
10795
  percentage: import_zod75.z.number().int(),
10771
10796
  /** ldap 名单人数(徽章"名单 N 人";0 = 无名单)。 */
@@ -10777,6 +10802,12 @@ var SlotSummarySchema = import_zod75.z.object({
10777
10802
  revisionId: import_zod75.z.string().nullable(),
10778
10803
  /** 人可读的版本标识(revision name/number);无部署时 null。 */
10779
10804
  revisionLabel: import_zod75.z.string().nullable(),
10805
+ /**
10806
+ * 槽位所指 Revision 在该 Agent 内的落库序号(#5057 PR-B)。UI 主显 `#n`、
10807
+ * `revisionLabel` 留在 `title` 与复制按钮。optional = 旧服务端 / 未报告的
10808
+ * 生产方(滚动发版兼容)。
10809
+ */
10810
+ revisionSequence: import_zod75.z.number().int().nullable().optional(),
10780
10811
  environmentId: import_zod75.z.string().nullable(),
10781
10812
  environmentName: import_zod75.z.string().nullable(),
10782
10813
  environmentVersion: import_zod75.z.number().int().nullable(),
@@ -10796,6 +10827,34 @@ var SlotSummarySchema = import_zod75.z.object({
10796
10827
  */
10797
10828
  canary: SlotCanarySummarySchema.nullable().optional()
10798
10829
  });
10830
+ var AttentionReasonKindSchema = import_zod75.z.enum([
10831
+ "startup_failed",
10832
+ "required_gate_failed",
10833
+ "repeated_revision_failure",
10834
+ "runtime_failed",
10835
+ "unhealthy_instance",
10836
+ "warm_pool_underfilled"
10837
+ ]);
10838
+ var AttentionReasonBasisSchema = import_zod75.z.enum(["window", "current"]);
10839
+ var AttentionReasonSchema = import_zod75.z.object({
10840
+ kind: AttentionReasonKindSchema,
10841
+ count: import_zod75.z.number().int().nonnegative(),
10842
+ basis: AttentionReasonBasisSchema
10843
+ });
10844
+ var AttentionSeveritySchema = import_zod75.z.enum(["ok", "info", "warn", "critical"]);
10845
+ var WorkloadAttentionSchema = import_zod75.z.object({
10846
+ workloadId: import_zod75.z.string(),
10847
+ workloadSlug: import_zod75.z.string(),
10848
+ workloadDisplayName: import_zod75.z.string(),
10849
+ severity: AttentionSeveritySchema,
10850
+ score: import_zod75.z.number(),
10851
+ reasonDetails: import_zod75.z.array(AttentionReasonSchema)
10852
+ });
10853
+ var ProjectAttentionSummarySchema = import_zod75.z.object({
10854
+ severity: AttentionSeveritySchema,
10855
+ workloadCount: import_zod75.z.number().int().nonnegative(),
10856
+ reasonDetails: import_zod75.z.array(AttentionReasonSchema)
10857
+ });
10799
10858
  var WorkbenchStageDriftKindSchema = import_zod75.z.enum([
10800
10859
  /** test 指向新于 production(待晋级)。 */
10801
10860
  "test_ahead",
@@ -10851,8 +10910,15 @@ var WorkbenchRecentChangeSchema = import_zod75.z.object({
10851
10910
  * 降级为无 slug,而不是整个 DTO 校验失败。
10852
10911
  */
10853
10912
  subjectSlug: import_zod75.z.string().nullable().optional(),
10854
- /** 一句话变更描述(如 "production → rev-12" / "环境 v3 创建")。 */
10913
+ /** 一句话变更描述(如 "production → #12" / "环境 v3 创建")。 */
10855
10914
  detail: import_zod75.z.string(),
10915
+ /**
10916
+ * workload 类变更指到的 Revision 原版本串与序号(#5057 PR-B)。环境类变更、
10917
+ * 以及旧服务端都缺席;`detail` 已按可读序号拼好,这两个字段供 UI 把 `#n`
10918
+ * 主显、把原版本串放进 `title`。optional = 滚动发版兼容(同 subjectSlug)。
10919
+ */
10920
+ revisionVersion: import_zod75.z.string().nullable().optional(),
10921
+ revisionSequence: import_zod75.z.number().int().nullable().optional(),
10856
10922
  occurredAt: import_zod75.z.string()
10857
10923
  });
10858
10924
  var WorkbenchSessionStatsSchema = import_zod75.z.object({
@@ -10946,7 +11012,13 @@ var ReleaseBoardRowSchema = import_zod75.z.object({
10946
11012
  * 新消费方一律读 `latestRevision`(前端回退链 latestRevision ?? defaultRevision
10947
11013
  * 只为兼容旧服务端缺字段,不表示两者同义)。
10948
11014
  */
10949
- defaultRevision: import_zod75.z.object({ id: import_zod75.z.string(), version: import_zod75.z.string(), createdAt: import_zod75.z.string() }).nullable(),
11015
+ defaultRevision: import_zod75.z.object({
11016
+ id: import_zod75.z.string(),
11017
+ version: import_zod75.z.string(),
11018
+ /** 落库序号(#5057 PR-B);optional = 旧服务端。 */
11019
+ sequence: import_zod75.z.number().int().nullable().optional(),
11020
+ createdAt: import_zod75.z.string()
11021
+ }).nullable(),
10950
11022
  /**
10951
11023
  * Workload 最近发布的 Revision(createdAt 最新;并列时 id 大者,保证确定性)。
10952
11024
  * 发布板用它判断"有新版本尚未部署到 test"(latestRevision.id ≠
@@ -10962,6 +11034,8 @@ var ReleaseBoardRowSchema = import_zod75.z.object({
10962
11034
  latestRevision: import_zod75.z.object({
10963
11035
  id: import_zod75.z.string(),
10964
11036
  version: import_zod75.z.string(),
11037
+ /** 落库序号(#5057 PR-B);optional = 旧服务端。 */
11038
+ sequence: import_zod75.z.number().int().nullable().optional(),
10965
11039
  createdAt: import_zod75.z.string(),
10966
11040
  /** 真实发布时间;optional 仅用于新旧服务端滚动窗口兼容。 */
10967
11041
  publishedAt: import_zod75.z.string().optional()
@@ -13429,6 +13503,85 @@ var SessionWorkspaceSnapshotRecordSchema = import_zod83.z.object({
13429
13503
  path: ["capturedAtTurn"],
13430
13504
  message: "capturedAtTurn must equal envelope.capturedAtTurn (the row key is the envelope's own cursor)"
13431
13505
  });
13506
+ var OnlineGraderSummaryItemSchema = import_zod83.z.object({
13507
+ key: import_zod83.z.string(),
13508
+ type: import_zod83.z.string(),
13509
+ level: import_zod83.z.enum(["turn", "session"]),
13510
+ threshold: import_zod83.z.number().nullable()
13511
+ }).strict();
13512
+ var OnlineSetInspectionSchema = import_zod83.z.object({
13513
+ kind: import_zod83.z.enum(["absent", "invalid", "unreadable", "ok"]),
13514
+ graderSummary: import_zod83.z.array(OnlineGraderSummaryItemSchema),
13515
+ digest: import_zod83.z.string().nullable(),
13516
+ error: import_zod83.z.string().nullable()
13517
+ }).strict();
13518
+ var OnlineConfigViewSchema = import_zod83.z.object({
13519
+ agentId: import_zod83.z.string().uuid(),
13520
+ stage: import_zod83.z.string(),
13521
+ enabled: import_zod83.z.boolean(),
13522
+ tier1Rate: import_zod83.z.number(),
13523
+ alertEnabled: import_zod83.z.boolean(),
13524
+ alertWindowHours: import_zod83.z.number().int(),
13525
+ alertMinSamples: import_zod83.z.number().int(),
13526
+ dailyCandidateCap: import_zod83.z.number().int(),
13527
+ updatedAt: import_zod83.z.string(),
13528
+ last7dScoreRows: import_zod83.z.number().int(),
13529
+ lastGradedAt: import_zod83.z.string().nullable()
13530
+ }).strict();
13531
+ var OnlineStatusDotSchema = import_zod83.z.object({
13532
+ lit: import_zod83.z.boolean(),
13533
+ mismatch: import_zod83.z.array(
13534
+ import_zod83.z.object({
13535
+ agentId: import_zod83.z.string().uuid(),
13536
+ stage: import_zod83.z.string(),
13537
+ kind: import_zod83.z.enum(["absent", "invalid"]),
13538
+ error: import_zod83.z.string().nullable()
13539
+ }).strict()
13540
+ ),
13541
+ alerts: import_zod83.z.array(
13542
+ import_zod83.z.object({
13543
+ agentId: import_zod83.z.string().uuid(),
13544
+ stage: import_zod83.z.string(),
13545
+ graderKey: import_zod83.z.string(),
13546
+ metric: import_zod83.z.number(),
13547
+ threshold: import_zod83.z.number(),
13548
+ samples: import_zod83.z.number().int()
13549
+ }).strict()
13550
+ )
13551
+ }).strict();
13552
+ var EvalOnlineOverviewResponseSchema = import_zod83.z.object({
13553
+ configs: import_zod83.z.array(OnlineConfigViewSchema),
13554
+ statusDot: OnlineStatusDotSchema
13555
+ }).strict();
13556
+ var EvalOnlineConfigDetailResponseSchema = import_zod83.z.object({
13557
+ config: OnlineConfigViewSchema.nullable(),
13558
+ inspection: OnlineSetInspectionSchema
13559
+ }).strict();
13560
+ var EvalOnlineConfigUpsertResponseSchema = import_zod83.z.object({
13561
+ ok: import_zod83.z.literal(true),
13562
+ graderSummary: import_zod83.z.array(OnlineGraderSummaryItemSchema).nullable()
13563
+ }).strict();
13564
+ var EvalOnlineTrendResponseSchema = import_zod83.z.object({
13565
+ rangeDays: import_zod83.z.number().int(),
13566
+ dailyFromDay: import_zod83.z.string(),
13567
+ graders: import_zod83.z.array(
13568
+ import_zod83.z.object({
13569
+ graderKey: import_zod83.z.string(),
13570
+ graderType: import_zod83.z.string(),
13571
+ level: import_zod83.z.enum(["turn", "session"]),
13572
+ points: import_zod83.z.object({
13573
+ day: import_zod83.z.string(),
13574
+ metric: import_zod83.z.number(),
13575
+ judged: import_zod83.z.number().int()
13576
+ }).strict().array(),
13577
+ switches: import_zod83.z.object({
13578
+ day: import_zod83.z.string(),
13579
+ graderRevisionId: import_zod83.z.string().uuid(),
13580
+ graderSetDigest: import_zod83.z.string()
13581
+ }).strict().array()
13582
+ }).strict()
13583
+ )
13584
+ }).strict();
13432
13585
  var PIPELINE_COMMIT_SHA_RE = /^[0-9a-f]{7,64}$/i;
13433
13586
  var CommitShaSchema = import_zod84.z.string().regex(PIPELINE_COMMIT_SHA_RE, {
13434
13587
  message: "commitSha must be 7-64 hexadecimal characters"
@@ -14146,6 +14299,19 @@ var REALTIME_RECOVERY_REASONS = Object.freeze([
14146
14299
  "response_incomplete",
14147
14300
  "connection_interrupted"
14148
14301
  ]);
14302
+ var REALTIME_TERMINAL_ERROR_CODES = Object.freeze([
14303
+ "write_queue_full",
14304
+ "control_timeout",
14305
+ "control_rejected",
14306
+ "generation_expired",
14307
+ "upstream_unavailable",
14308
+ "resume_store_unavailable",
14309
+ "renew_rejected",
14310
+ "execution_expired",
14311
+ "no_response",
14312
+ "renew_abandoned",
14313
+ "realtime_turn_lost"
14314
+ ]);
14149
14315
  var PILOT_PERMISSION_MODES = ["manual", "auto", "accept_edits", "bypass"];
14150
14316
  var PilotPermissionModeSchema = import_zod90.z.enum(PILOT_PERMISSION_MODES);
14151
14317
  var PilotPlanSegmentJobSchema = import_zod91.z.object({ tenantId: import_zod91.z.string().min(1), planId: import_zod91.z.string().uuid() }).strict();