@kanyun-ai-infra/agenthub 1.14.0 → 1.16.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 +45 -0
- package/README.md +5 -0
- package/dist/index.cjs +207 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -11
- package/dist/index.d.ts +62 -11
- package/dist/index.js +207 -29
- package/dist/index.js.map +1 -1
- package/dist/realtime.cjs +89 -2
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +50 -0
- package/dist/realtime.d.ts +50 -0
- package/dist/realtime.js +89 -2
- package/dist/realtime.js.map +1 -1
- package/package.json +1 -1
- package/skills/agenthub-sdk/SKILL.md +168 -26
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
本文件从 1.12.0 开始记录;更早的版本见 git 历史中的 `chore(agenthub-sdk): release X.Y.Z` 提交。
|
|
4
4
|
|
|
5
|
+
## 1.16.0
|
|
6
|
+
|
|
7
|
+
Revision 读面改为宽容读者:服务端给 `workloads.get` / `getRevision` / `getVersion` 的响应新增字段时,已发布的客户端不再报错。这一版同时接受可选的 `sequence`,服务端读面带出后即可读取,无需再次升级 SDK。
|
|
8
|
+
|
|
9
|
+
### 新增与变化
|
|
10
|
+
|
|
11
|
+
- `PlatformRevision` 新增可选字段 `sequence`(正整数):每个 Agent(workload)内从 1 递增的人类可读版本序号,号可以不连续。当前服务端读面尚未返回该字段;在它上线前该字段恒为 `undefined`。
|
|
12
|
+
- `workloads.get` / `getRevision` / `getVersion` 的响应解析改为宽容读者:schema 未声明的字段被忽略(不报错,也不出现在结果里)。此前 revision 响应是 strict,服务端多一个字段就会让所有已发布客户端抛 `MALFORMED_PLATFORM_RESPONSE`。
|
|
13
|
+
- 请求 schema 不变:`publishRevision` / `applyRevisionManifest` 仍拒绝未知字段,行为与 1.15.0 相同。
|
|
14
|
+
|
|
15
|
+
### 迁移说明
|
|
16
|
+
|
|
17
|
+
- 无需迁移。升级是可选的,用于获得对服务端后续新增响应字段的兼容性;`sequence` 在服务端读面上线前读不到。
|
|
18
|
+
|
|
19
|
+
## 1.15.0
|
|
20
|
+
|
|
21
|
+
浏览器实时语音入口新增播放对齐、页面工具执行与播放输出节点;其余为随共享契约内联的变化。
|
|
22
|
+
|
|
23
|
+
### 新增(`@kanyun-ai-infra/agenthub/realtime`)
|
|
24
|
+
|
|
25
|
+
- `onTranscriptPlayed(transcript)`:assistant 转写片段在音频实际播放到该片段时逐段触发,载荷带墙钟 `playedAt`。依赖网关在转写帧上带 `audioOffsetMs`;没有偏移的旧网关不触发此回调,被用户打断清空的片段也不触发。
|
|
26
|
+
- `onPlaybackState(state)`:`speaking` / `listening`,按实际可闻的播放状态触发,与按模型生成进度的 `onState` 区分。队列播干、播放被打断或通话停止时回到 `listening`。
|
|
27
|
+
- `onTranscript` 的 assistant 帧新增可选 `audioOffsetMs`:该片段在本轮音频中的起始毫秒数,用于把字幕或画面切到正在播放的位置。
|
|
28
|
+
- `onToolCall(call)`:执行 `voice.realtime.tools` 声明的模型工具调用;`call` 含 `callId`、`name`、`args`,可选 `turnSeq`。返回值作为工具结果回传(JSON,至多 32 KiB)。未提供处理函数回 `tool_unavailable`,处理函数抛错回 `tool_failed`,结果超限回 `tool_result_too_large`;页面不答时网关 10 秒后自行以 `tool_timeout` 答复,不会把模型卡死。
|
|
29
|
+
- `outputNode(context)`:把播放输出接到页面自建的音频节点(如变调等后处理),由页面继续接到 `context.destination`。缺省直连输出。
|
|
30
|
+
- 新导出类型:`RealtimeTranscriptPlayed`、`RealtimePlaybackState`、`RealtimeToolCall`。
|
|
31
|
+
|
|
32
|
+
### 随共享契约内联的变化
|
|
33
|
+
|
|
34
|
+
- agent 定义的 `voice.realtime` 新增可选 `tools`(1–16 个):每项含 `name`(匹配 `^[A-Za-z_][A-Za-z0-9_]{0,63}$`,重名拒绝)、`description`(1–1024 字符)与可选 `parameters`(JSON Schema 子集,嵌套至多 6 层、节点至多 128、序列化至多 8 KiB)。`publishVersion` / `applyManifest` 的本地校验接受该字段;不声明时行为不变。
|
|
35
|
+
- `voice.realtime` 新增可选 `greetOnConnect`:开启时网关在首通建立上游会话后替 agent 发一次初始文本回合,模型按 system prompt 主动开口;缺省或 `false` 关闭,只对首通生效,重连与接手不重发。
|
|
36
|
+
|
|
37
|
+
### 会话
|
|
38
|
+
|
|
39
|
+
- `sessions.create` 带 `memorySubjects` 的请求现在可以领取预热池:声明的业务主体替换池模板铸出的主体;`idempotencyScope` / `idempotencyKey` 与 `memorySubjects` 不再使请求失去领取资格。本次只有注释与文档变化,领取行为由服务端决定;服务端未升级时请求仍照旧冷启。
|
|
40
|
+
|
|
41
|
+
### 其他
|
|
42
|
+
|
|
43
|
+
- 语音开关的文档措辞改为 kill switch `voice_turns_disabled`(及同类 `*_DISABLED`),公开方法签名不变。
|
|
44
|
+
- 随包 `SKILL.md` 补充实时语音接入走查。
|
|
45
|
+
|
|
46
|
+
### 迁移说明
|
|
47
|
+
|
|
48
|
+
- 使用 `onTranscriptPlayed`、`onPlaybackState`、`onToolCall` 或 `outputNode` 的接入方须升级到 `@kanyun-ai-infra/agenthub@1.15.0`。1.14.0 没有这些回调;旧 SDK 在声明工具的 agent 上会忽略 `tool_call`,模型要等网关 10 秒超时答复后才继续。
|
|
49
|
+
|
|
5
50
|
## 1.14.0
|
|
6
51
|
|
|
7
52
|
### 随共享契约内联的语音变化
|
package/README.md
CHANGED
|
@@ -151,6 +151,11 @@ Agents 和 runtime templates 都是 **project-scoped**。Version 必须在同一
|
|
|
151
151
|
|
|
152
152
|
> 本文一律用主词汇 **agent / version**;它们是底层 wire 名 `workload` / `revision`
|
|
153
153
|
> 的别名,SDK 两套都接受,规范名与别名同传会抛 `ALIAS_CONFLICT`,细节见下方「完整参考」。
|
|
154
|
+
>
|
|
155
|
+
> 读面响应是**宽容读者**:`agents.get` / `getVersion` / `getRevision` 的响应出现 SDK
|
|
156
|
+
> 未声明的字段时会被忽略,不会报错;服务端新增字段不需要客户端升级。1.16.0 起
|
|
157
|
+
> `PlatformRevision` 接受可选的 `sequence`(每个 Agent 内从 1 递增的版本序号,号可
|
|
158
|
+
> 不连续);服务端读面返回它之前,该字段为 `undefined`。
|
|
154
159
|
|
|
155
160
|
## 记忆(agenthub.memories)
|
|
156
161
|
|
package/dist/index.cjs
CHANGED
|
@@ -498,7 +498,8 @@ var EXECUTOR_FORMAT_REGISTRY = {
|
|
|
498
498
|
// `declaredMcpTools` allowlist. approvals: none (`bypassPermissions`).
|
|
499
499
|
capabilities: { resume: true, structuredOutput: false, toolFiltering: true, approvals: false },
|
|
500
500
|
// Today's behaviour: Claude Code runs every model the platform offers.
|
|
501
|
-
allowedModels: { kind: "any" }
|
|
501
|
+
allowedModels: { kind: "any" },
|
|
502
|
+
mcpMode: "native"
|
|
502
503
|
},
|
|
503
504
|
pi: {
|
|
504
505
|
descriptor: { kind: "harness", adapterId: "pi", protocolVersion: "1" },
|
|
@@ -519,7 +520,10 @@ var EXECUTOR_FORMAT_REGISTRY = {
|
|
|
519
520
|
},
|
|
520
521
|
// Provisional until #3843 / #3670: no model family decided yet, so none
|
|
521
522
|
// is offered (fails closed; pi is not publishable before then anyway).
|
|
522
|
-
allowedModels: { kind: "idPrefixes", idPrefixes: [] }
|
|
523
|
+
allowedModels: { kind: "idPrefixes", idPrefixes: [] },
|
|
524
|
+
// Pi's MCP goes through managed MCP only (owner 2026-09-28): no rush
|
|
525
|
+
// direct references, no self-loaded MCP client extension.
|
|
526
|
+
mcpMode: "bridge"
|
|
523
527
|
}
|
|
524
528
|
};
|
|
525
529
|
var ReservedExecutorValueSchema = import_zod5.z.never();
|
|
@@ -580,6 +584,10 @@ var RecordImageCapabilityDeclarationRequestSchema = import_zod5.z.object({
|
|
|
580
584
|
declaration: ImageCapabilityDeclarationSchema,
|
|
581
585
|
source: import_zod5.z.enum(IMAGE_CAPABILITY_DECLARATION_SOURCES)
|
|
582
586
|
}).strict();
|
|
587
|
+
var FrozenSessionExecutorSchema = import_zod5.z.object({
|
|
588
|
+
format: import_zod5.z.string().min(1),
|
|
589
|
+
protocolVersion: import_zod5.z.string()
|
|
590
|
+
});
|
|
583
591
|
var SESSION_ENVIRONMENT_OUTDATED = "SESSION_ENVIRONMENT_OUTDATED";
|
|
584
592
|
var SessionEnvironmentOutdatedPayloadSchema = import_zod5.z.object({
|
|
585
593
|
code: import_zod5.z.literal(SESSION_ENVIRONMENT_OUTDATED),
|
|
@@ -3576,6 +3584,9 @@ var CreateSessionRequestSchema = import_zod10.z.object({
|
|
|
3576
3584
|
*
|
|
3577
3585
|
* 解析只发生一次、在会话创建事务内,结果冻结进 `sessions.memory_subjects`;写侧
|
|
3578
3586
|
* (抽取写回)与读侧(召回)之后都只读那一列(I7 写读同源)。
|
|
3587
|
+
*
|
|
3588
|
+
* 带它的请求**照样能领预热池**:领取收尾在同一条 UPDATE 里按这份声明重算冻结列(替换池模板
|
|
3589
|
+
* 铸的业务主体,`[]` = 只剩 agent 主体);绑不进去就退冷启,不会交出没有声明主体的会话。
|
|
3579
3590
|
*/
|
|
3580
3591
|
memorySubjects: import_zod10.z.array(SessionMemorySubjectDeclarationSchema).max(MAX_SESSION_MEMORY_SUBJECTS).optional(),
|
|
3581
3592
|
/**
|
|
@@ -3596,8 +3607,9 @@ var CreateSessionRequestSchema = import_zod10.z.object({
|
|
|
3596
3607
|
* `PILOT_END_USER_ID`、记忆主体(见下)、create 响应 `data.session.user`。
|
|
3597
3608
|
*
|
|
3598
3609
|
* **带它不吃池**:请求携带本字段即退出预热领用资格
|
|
3599
|
-
* (`canServeFromPrewarmPool
|
|
3600
|
-
*
|
|
3610
|
+
* (`canServeFromPrewarmPool`)——池里暖好的会话在调用方出现之前就冻结了身份,领用时
|
|
3611
|
+
* 换不掉。已知访客换 agent 应冷启带既有 id。(`memorySubjects` 不受这条限制:它在领取
|
|
3612
|
+
* 收尾时绑定,见该字段。)
|
|
3601
3613
|
*
|
|
3602
3614
|
* **不隐含记忆声明**:本字段本身不使这个 id 成为任何记忆主体;要让记忆落到它
|
|
3603
3615
|
* 名下,冷启路径须同时在 `memorySubjects` 里声明它(池路径由
|
|
@@ -4154,13 +4166,32 @@ var WorkloadManifestErrorCodeSchema = import_zod4.z.enum([
|
|
|
4154
4166
|
// the `statusForManifestError` default) and additive-widening note as the
|
|
4155
4167
|
// four codes above.
|
|
4156
4168
|
"EXECUTOR_NOT_APPLICABLE_TO_LIVE",
|
|
4169
|
+
// HX-T7 (spec `pilot-v2-executor-host-contract.md` §6): a bridge-mode
|
|
4170
|
+
// executor's Revision whose frozen snapshot carries a non-platform MCP
|
|
4171
|
+
// source (rush `enabledMcpServers`). The bridge never connects those
|
|
4172
|
+
// entries, so publishing would silently drop them; the remediation is
|
|
4173
|
+
// managed MCP. Thrown by `applyRevisionManifest` (400, the
|
|
4174
|
+
// `statusForManifestError` default) and by the stage-binding gate (422,
|
|
4175
|
+
// control-plane `WorkloadStageServiceErrorCode`). Additive widening = patch.
|
|
4176
|
+
"EXECUTOR_NON_PLATFORM_MCP_UNSUPPORTED",
|
|
4177
|
+
// EXP-1c (spec `pilot-v2-executor-identity.md` §3, #3668 D6a): the merged,
|
|
4178
|
+
// normalised executor format's registry entry declares a worker contract
|
|
4179
|
+
// kind the Revision does not match (today every entry declares
|
|
4180
|
+
// `managed_agent`, so this fires on a `self_managed` Revision that
|
|
4181
|
+
// inherits a non-default executor — the revision-level snapshot key is
|
|
4182
|
+
// schema-blocked for self_managed, so the reachable channel is workload
|
|
4183
|
+
// `spec.defaults.executor` inheritance). Thrown by `applyRevisionManifest`
|
|
4184
|
+
// (400, the `statusForManifestError` default), judged in
|
|
4185
|
+
// `assertExecutorPublishGate` after EXP-1. Additive widening = patch.
|
|
4186
|
+
"EXECUTOR_NOT_APPLICABLE_TO_SELF_MANAGED",
|
|
4157
4187
|
// `format: live` publish admission (#4625 PR-1, spec
|
|
4158
4188
|
// pilot-v2-managed-agent-profile.md §11 MAP-VL3), both thrown by
|
|
4159
4189
|
// `applyRevisionManifest` and mapped to 400 by the default branch of
|
|
4160
4190
|
// `statusForManifestError`. Additive widening = patch (see
|
|
4161
4191
|
// `WORKLOAD_SLUG_TAKEN` above).
|
|
4162
4192
|
// - `LIVE_AGENTS_DISABLED` — the Revision's snapshot is `format: live` while
|
|
4163
|
-
// `
|
|
4193
|
+
// the kill switch `live_agents_disabled` is on (before #5069: `live_agents_enabled`
|
|
4194
|
+
// off). Same criterion as before; it used to throw
|
|
4164
4195
|
// the generic `MANIFEST_VALIDATION_ERROR`. Pipeline join reports the same
|
|
4165
4196
|
// condition earlier as `FILE_AGENT_LIVE_DISABLED`.
|
|
4166
4197
|
// - `LIVE_REVISION_UNSUPPORTED` — the merged, frozen live snapshot carries a
|
|
@@ -4515,7 +4546,79 @@ var RealtimeVoiceNameSchema = import_zod4.z.enum([
|
|
|
4515
4546
|
"Sadaltager",
|
|
4516
4547
|
"Sulafat"
|
|
4517
4548
|
]);
|
|
4518
|
-
var
|
|
4549
|
+
var RealtimeToolParameterSchema = import_zod4.z.lazy(
|
|
4550
|
+
() => import_zod4.z.object({
|
|
4551
|
+
type: import_zod4.z.enum(["string", "number", "integer", "boolean", "array", "object"]).optional(),
|
|
4552
|
+
description: import_zod4.z.string().max(1024).optional(),
|
|
4553
|
+
enum: import_zod4.z.array(import_zod4.z.string().max(256)).max(64).optional(),
|
|
4554
|
+
nullable: import_zod4.z.boolean().optional(),
|
|
4555
|
+
items: RealtimeToolParameterSchema.optional(),
|
|
4556
|
+
properties: import_zod4.z.record(import_zod4.z.string().max(64), RealtimeToolParameterSchema).optional(),
|
|
4557
|
+
required: import_zod4.z.array(import_zod4.z.string().max(64)).max(32).optional()
|
|
4558
|
+
}).strict()
|
|
4559
|
+
);
|
|
4560
|
+
function toolParameterProblem(parameters) {
|
|
4561
|
+
if (parameters === void 0) return void 0;
|
|
4562
|
+
let nodes = 0;
|
|
4563
|
+
let problem;
|
|
4564
|
+
const visit = (node, depth) => {
|
|
4565
|
+
var _a, _b;
|
|
4566
|
+
if (problem !== void 0) return;
|
|
4567
|
+
nodes += 1;
|
|
4568
|
+
if (depth > 6) {
|
|
4569
|
+
problem = "tool parameters nest deeper than 6 levels";
|
|
4570
|
+
return;
|
|
4571
|
+
}
|
|
4572
|
+
if (nodes > 128) {
|
|
4573
|
+
problem = "tool parameters contain more than 128 nodes";
|
|
4574
|
+
return;
|
|
4575
|
+
}
|
|
4576
|
+
if (node.type === "array" && node.items === void 0) {
|
|
4577
|
+
problem = "an array parameter must declare items";
|
|
4578
|
+
return;
|
|
4579
|
+
}
|
|
4580
|
+
if (node.required !== void 0) {
|
|
4581
|
+
const declared = new Set(Object.keys((_a = node.properties) != null ? _a : {}));
|
|
4582
|
+
const missing = node.required.find((name) => !declared.has(name));
|
|
4583
|
+
if (missing !== void 0) {
|
|
4584
|
+
problem = `required parameter ${missing} is not declared in properties`;
|
|
4585
|
+
return;
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
for (const child of Object.values((_b = node.properties) != null ? _b : {})) visit(child, depth + 1);
|
|
4589
|
+
if (node.items !== void 0) visit(node.items, depth + 1);
|
|
4590
|
+
};
|
|
4591
|
+
visit(parameters, 1);
|
|
4592
|
+
if (problem !== void 0) return problem;
|
|
4593
|
+
if (new TextEncoder().encode(JSON.stringify(parameters)).length > 8192)
|
|
4594
|
+
return "tool parameters exceed 8192 bytes";
|
|
4595
|
+
return void 0;
|
|
4596
|
+
}
|
|
4597
|
+
var WORKLOAD_MANIFEST_REALTIME_TOOLS_MAX_LENGTH = 16;
|
|
4598
|
+
var WorkloadManifestRealtimeToolSchema = import_zod4.z.object({
|
|
4599
|
+
name: import_zod4.z.string().regex(
|
|
4600
|
+
/^[A-Za-z_][A-Za-z0-9_]{0,63}$/,
|
|
4601
|
+
"tool name must be an identifier of at most 64 chars"
|
|
4602
|
+
),
|
|
4603
|
+
description: import_zod4.z.string().min(1).max(1024),
|
|
4604
|
+
parameters: RealtimeToolParameterSchema.optional()
|
|
4605
|
+
}).strict();
|
|
4606
|
+
var WorkloadManifestRealtimeToolListSchema = import_zod4.z.array(WorkloadManifestRealtimeToolSchema).min(1).max(WORKLOAD_MANIFEST_REALTIME_TOOLS_MAX_LENGTH).superRefine((tools, ctx) => {
|
|
4607
|
+
const names = /* @__PURE__ */ new Set();
|
|
4608
|
+
for (const [index, tool] of tools.entries()) {
|
|
4609
|
+
if (names.has(tool.name))
|
|
4610
|
+
ctx.addIssue({
|
|
4611
|
+
code: "custom",
|
|
4612
|
+
path: [index, "name"],
|
|
4613
|
+
message: "tool names must be unique"
|
|
4614
|
+
});
|
|
4615
|
+
names.add(tool.name);
|
|
4616
|
+
const problem = toolParameterProblem(tool.parameters);
|
|
4617
|
+
if (problem !== void 0)
|
|
4618
|
+
ctx.addIssue({ code: "custom", path: [index, "parameters"], message: problem });
|
|
4619
|
+
}
|
|
4620
|
+
});
|
|
4621
|
+
var RealtimeVoiceWireSchema = import_zod4.z.object({
|
|
4519
4622
|
provider: import_zod4.z.literal("vertex-gemini-live"),
|
|
4520
4623
|
model: import_zod4.z.enum(["gemini-3.8-live", "gemini-live-2.5-flash-native-audio"]),
|
|
4521
4624
|
voice: RealtimeVoiceNameSchema,
|
|
@@ -4526,7 +4629,20 @@ var WorkloadManifestRealtimeVoiceSchema = import_zod4.z.object({
|
|
|
4526
4629
|
return false;
|
|
4527
4630
|
}
|
|
4528
4631
|
}, "language must be a BCP-47 language tag").optional(),
|
|
4529
|
-
turnDetection: import_zod4.z.object({ silenceMs: import_zod4.z.number().int().positive() }).strict().optional()
|
|
4632
|
+
turnDetection: import_zod4.z.object({ silenceMs: import_zod4.z.number().int().positive() }).strict().optional(),
|
|
4633
|
+
/**
|
|
4634
|
+
* 接通即开讲(#5221):开启时网关在通话首次建立上游会话后替 agent 发一次初始文本回合,
|
|
4635
|
+
* 模型按 system prompt 主动开口。缺省 / `false` 关闭,行为与声明前一致。只对首通生效:
|
|
4636
|
+
* 上游重连与带原 callId 的接手不重发。
|
|
4637
|
+
*/
|
|
4638
|
+
greetOnConnect: import_zod4.z.boolean().optional()
|
|
4639
|
+
}).strict();
|
|
4640
|
+
var WorkloadManifestRealtimeVoiceSchema = RealtimeVoiceWireSchema.extend({
|
|
4641
|
+
/**
|
|
4642
|
+
* Declared client tools. Optional and absent by default: an agent without it behaves exactly
|
|
4643
|
+
* as before, and the claim to an older gateway carries no tools key at all.
|
|
4644
|
+
*/
|
|
4645
|
+
tools: WorkloadManifestRealtimeToolListSchema.optional()
|
|
4530
4646
|
}).strict();
|
|
4531
4647
|
var WorkloadManifestVoiceSchema = import_zod4.z.object({
|
|
4532
4648
|
realtime: WorkloadManifestRealtimeVoiceSchema.optional(),
|
|
@@ -8884,6 +9000,20 @@ var EnvironmentRepointRecordSchema = import_zod59.z.object({
|
|
|
8884
9000
|
actor: import_zod59.z.string().nullable(),
|
|
8885
9001
|
createdAt: import_zod59.z.coerce.date()
|
|
8886
9002
|
}).strict();
|
|
9003
|
+
var EnvironmentExecutorWarningRevisionSchema = import_zod59.z.object({
|
|
9004
|
+
revisionId: import_zod59.z.string().uuid(),
|
|
9005
|
+
/** Which pointer of the slot carries the Revision. */
|
|
9006
|
+
arm: import_zod59.z.enum(["stable", "canary"]),
|
|
9007
|
+
format: import_zod59.z.string(),
|
|
9008
|
+
protocolVersion: import_zod59.z.string(),
|
|
9009
|
+
/** `absent` = judged as ENVCAP-3 (no readable declaration for the image). */
|
|
9010
|
+
declaration: import_zod59.z.enum(["absent", "present"]),
|
|
9011
|
+
/** Where the judged image came from; `kind` discriminates the remaining keys. */
|
|
9012
|
+
capabilitySource: import_zod59.z.object({ kind: import_zod59.z.string() }).passthrough()
|
|
9013
|
+
}).strict();
|
|
9014
|
+
var EnvironmentExecutorWarningSchema = import_zod59.z.object({
|
|
9015
|
+
revisions: import_zod59.z.array(EnvironmentExecutorWarningRevisionSchema).min(1)
|
|
9016
|
+
}).strict();
|
|
8887
9017
|
var EnvironmentReferenceSchema = import_zod59.z.object({
|
|
8888
9018
|
workloadId: import_zod59.z.string().uuid(),
|
|
8889
9019
|
workloadSlug: import_zod59.z.string(),
|
|
@@ -9691,7 +9821,7 @@ var VOICE_ERROR_CODES = {
|
|
|
9691
9821
|
REALTIME_CAPACITY_EXCEEDED: 409,
|
|
9692
9822
|
/** The platform concurrency store (realtime Redis) is unavailable; retry. */
|
|
9693
9823
|
REALTIME_ADMISSION_UNAVAILABLE: 503,
|
|
9694
|
-
/** `
|
|
9824
|
+
/** 紧急关闭 `voice_turns_disabled` 打开时任何语音回合派发被拒(VT-1)。 */
|
|
9695
9825
|
VOICE_TURNS_DISABLED: 400,
|
|
9696
9826
|
/** 语音附件时长 >60 秒或大小 >2MB(VA-3,上限只在语音路径)。 */
|
|
9697
9827
|
VOICE_INPUT_TOO_LONG: 400,
|
|
@@ -9918,12 +10048,13 @@ var PlatformRevisionSchema = import_zod66.z.object({
|
|
|
9918
10048
|
workloadSlug: WorkloadManifestNameSchema.optional(),
|
|
9919
10049
|
version: WorkloadManifestNameSchema,
|
|
9920
10050
|
runtimeSnapshotHash: import_zod66.z.string().nullable().optional(),
|
|
9921
|
-
createdAt: import_zod66.z.string().optional()
|
|
9922
|
-
|
|
10051
|
+
createdAt: import_zod66.z.string().optional(),
|
|
10052
|
+
sequence: import_zod66.z.number().int().positive().optional()
|
|
10053
|
+
}).strip();
|
|
9923
10054
|
var GetPlatformWorkloadResponseSchema = PlatformWorkloadSchema.extend({
|
|
9924
10055
|
kind: WorkloadKindSchema,
|
|
9925
10056
|
defaultRevision: PlatformRevisionSchema.nullable()
|
|
9926
|
-
});
|
|
10057
|
+
}).strip();
|
|
9927
10058
|
var GetPlatformRevisionResponseSchema = PlatformRevisionSchema;
|
|
9928
10059
|
var GetPlatformSessionResponseSchema = import_zod66.z.object({
|
|
9929
10060
|
id: import_zod66.z.string().uuid(),
|
|
@@ -11617,8 +11748,10 @@ var EvalTriggerSchema = import_zod82.z.enum([
|
|
|
11617
11748
|
]);
|
|
11618
11749
|
var EvalSeveritySchema = import_zod82.z.enum(["gate", "soft"]);
|
|
11619
11750
|
var EvalGraderTypeSchema = import_zod82.z.enum(["transcript", "file", "llm", "script", "reply"]);
|
|
11751
|
+
var EvalLlmToolsSchema = import_zod82.z.enum(["full", "calls", "none"]);
|
|
11620
11752
|
var EvalPassPolicySchema = import_zod82.z.enum(["all", "any"]);
|
|
11621
11753
|
var EvalSuitePurposeSchema = import_zod82.z.enum(["regression", "capability"]);
|
|
11754
|
+
var EvalSuiteGateDowngradeSchema = import_zod82.z.enum(["allow", "never"]);
|
|
11622
11755
|
var EVAL_SKIP_REASON_MAX = 2048;
|
|
11623
11756
|
var EvalSuiteSkipSchema = import_zod82.z.object({ reason: import_zod82.z.string().min(1).max(EVAL_SKIP_REASON_MAX) }).strict();
|
|
11624
11757
|
var EvalSkippedSuiteSchema = import_zod82.z.object({ path: import_zod82.z.string().min(1), reason: import_zod82.z.string().min(1) }).strict();
|
|
@@ -11687,6 +11820,10 @@ var EvalFileShorthandExpectSchema = import_zod82.z.object({
|
|
|
11687
11820
|
matches: import_zod82.z.string().optional()
|
|
11688
11821
|
// 正则字符串
|
|
11689
11822
|
}).strict();
|
|
11823
|
+
var EvalFileToolSourceSchema = import_zod82.z.object({
|
|
11824
|
+
name: import_zod82.z.string().min(1),
|
|
11825
|
+
part: import_zod82.z.enum(["input", "output", "both"]).optional()
|
|
11826
|
+
}).strict();
|
|
11690
11827
|
var EvalFileGraderSchema = import_zod82.z.object({
|
|
11691
11828
|
type: import_zod82.z.literal("file"),
|
|
11692
11829
|
label: EvalGraderLabelSchema,
|
|
@@ -11696,7 +11833,12 @@ var EvalFileGraderSchema = import_zod82.z.object({
|
|
|
11696
11833
|
files: import_zod82.z.array(EvalFileEntrySchema).min(1).optional(),
|
|
11697
11834
|
// 简写形式
|
|
11698
11835
|
path: EvalRelativePathSchema.optional(),
|
|
11699
|
-
expect: EvalFileShorthandExpectSchema.optional()
|
|
11836
|
+
expect: EvalFileShorthandExpectSchema.optional(),
|
|
11837
|
+
/**
|
|
11838
|
+
* #5215:内容来源 = 工具产物而非工作区文件。与 `path` / `files` 恰用其一,
|
|
11839
|
+
* 且必须搭配 `expect`(suite 级 superRefine 校验)。
|
|
11840
|
+
*/
|
|
11841
|
+
tool: EvalFileToolSourceSchema.optional()
|
|
11700
11842
|
}).strict();
|
|
11701
11843
|
var EvalLlmGraderSchema = import_zod82.z.object({
|
|
11702
11844
|
type: import_zod82.z.literal("llm"),
|
|
@@ -11708,6 +11850,14 @@ var EvalLlmGraderSchema = import_zod82.z.object({
|
|
|
11708
11850
|
}),
|
|
11709
11851
|
dimensions: import_zod82.z.array(import_zod82.z.string().min(1)).optional(),
|
|
11710
11852
|
threshold: import_zod82.z.number().min(0).max(1),
|
|
11853
|
+
/**
|
|
11854
|
+
* #5215:判官材料是否带工具调用。缺省 `none`(只判回复文本,与既有 suite 的
|
|
11855
|
+
* 判分材料逐字节一致)。optional 字段叠加为增量变更、不升 apiVersion;老
|
|
11856
|
+
* worker 会以 `Unrecognized key` strict 拒(发布次序 = control-worker 先行)。
|
|
11857
|
+
* 工具段改变判分输入,但声明值在 case 对象里、进 `case_definition_digest`,
|
|
11858
|
+
* 因此不升 `engineVersion`(换值即换基线桶,不靠 engineVersion 区分)。
|
|
11859
|
+
*/
|
|
11860
|
+
tools: EvalLlmToolsSchema.optional(),
|
|
11711
11861
|
// 上界对齐 eval_grader_results.grader_version(PG int4,B1 硬列):graderVersion
|
|
11712
11862
|
// 是**作者可写**的单调整数,时间戳当版本号(Date.now() ≈ 1.7e12)一次就越界——
|
|
11713
11863
|
// 越界在解析期 400 告知作者,而不是等写明细行时 22003 连累父行回滚、整个 run
|
|
@@ -11754,12 +11904,17 @@ var EvalScriptGraderSchema = import_zod82.z.object({
|
|
|
11754
11904
|
expect: EvalScriptExpectSchema.optional()
|
|
11755
11905
|
}).strict();
|
|
11756
11906
|
var EvalReplyExpectSchema = import_zod82.z.object({
|
|
11907
|
+
/** 字面子串,不是正则。 */
|
|
11757
11908
|
includes: import_zod82.z.string().min(1).optional(),
|
|
11909
|
+
/** 字面子串,不是正则;「不许出现某段话」的确定写法见 `notMatches`。 */
|
|
11758
11910
|
excludes: import_zod82.z.string().min(1).optional(),
|
|
11759
11911
|
equals: import_zod82.z.string().optional(),
|
|
11760
11912
|
// 正则字符串;无效正则不在 schema 层拒——按 file grader 的 safeRegex 姿势在
|
|
11761
11913
|
// 判分侧判"不匹配",交给断言侧报 failed(不 errored)。
|
|
11762
|
-
matches: import_zod82.z.string().min(1).optional()
|
|
11914
|
+
matches: import_zod82.z.string().min(1).optional(),
|
|
11915
|
+
// 正则字符串,不允许匹配(`excludes` 的正则版)。无效正则**判 failed**而不是
|
|
11916
|
+
// passed:编译不出来时「没有匹配」是假的,绝不能因此绿灯(#5209)。
|
|
11917
|
+
notMatches: import_zod82.z.string().min(1).optional()
|
|
11763
11918
|
}).strict();
|
|
11764
11919
|
var EvalReplyGraderSchema = import_zod82.z.object({
|
|
11765
11920
|
type: import_zod82.z.literal("reply"),
|
|
@@ -12003,12 +12158,28 @@ var EvalSuiteSchema = import_zod82.z.object({
|
|
|
12003
12158
|
kind: import_zod82.z.literal(EVAL_SUITE_KIND),
|
|
12004
12159
|
purpose: EvalSuitePurposeSchema.optional(),
|
|
12005
12160
|
// U2,默认 regression
|
|
12161
|
+
gateDowngrade: EvalSuiteGateDowngradeSchema.optional(),
|
|
12162
|
+
// #5216,默认 allow
|
|
12006
12163
|
skip: EvalSuiteSkipSchema.optional(),
|
|
12007
12164
|
// §4 声明跳过(带必填理由)
|
|
12165
|
+
/**
|
|
12166
|
+
* #5215:pipeline 面按 **advisory** 跑——照常建 eval run 并后台执行,但不进
|
|
12167
|
+
* eval step 的等待、不进 conclusion 折叠,**不挡门禁**。结果仍挂在结论的
|
|
12168
|
+
* `evalRunIds` 下,流水线详情可见。缺省 false。与 `skip` 互斥(拒绝组合:
|
|
12169
|
+
* 一个说「不跑」一个说「跑但不判」,语义冲突)。
|
|
12170
|
+
*/
|
|
12171
|
+
advisory: import_zod82.z.boolean().optional(),
|
|
12008
12172
|
defaults: EvalSuiteDefaultsSchema.optional(),
|
|
12009
12173
|
cases: import_zod82.z.array(EvalCaseSchema).min(1)
|
|
12010
12174
|
}).strict().superRefine((suite, ctx) => {
|
|
12011
12175
|
var _a, _b;
|
|
12176
|
+
if (suite.advisory === true && suite.skip != null) {
|
|
12177
|
+
ctx.addIssue({
|
|
12178
|
+
code: import_zod82.z.ZodIssueCode.custom,
|
|
12179
|
+
path: ["advisory"],
|
|
12180
|
+
message: "`advisory: true` and `skip` are mutually exclusive \u2014 skip means the suite does not run in the pipeline at all; advisory means it runs but is excluded from the gate"
|
|
12181
|
+
});
|
|
12182
|
+
}
|
|
12012
12183
|
const seen = /* @__PURE__ */ new Set();
|
|
12013
12184
|
suite.cases.forEach((c, ci) => {
|
|
12014
12185
|
var _a2, _b2, _c, _d, _e;
|
|
@@ -12131,11 +12302,15 @@ var EvalSuiteSchema = import_zod82.z.object({
|
|
|
12131
12302
|
if (g.type === "file") {
|
|
12132
12303
|
const hasFiles = g.files != null;
|
|
12133
12304
|
const hasShorthand = g.path != null && g.expect != null;
|
|
12134
|
-
|
|
12305
|
+
const hasTool = g.tool != null && g.expect != null;
|
|
12306
|
+
const sourceCount = [hasFiles, hasShorthand, hasTool].filter(Boolean).length;
|
|
12307
|
+
const strayPath = g.path != null && g.expect == null;
|
|
12308
|
+
const strayTool = g.tool != null && g.expect == null;
|
|
12309
|
+
if (sourceCount !== 1 || strayTool || strayPath && !hasFiles) {
|
|
12135
12310
|
ctx.addIssue({
|
|
12136
12311
|
code: import_zod82.z.ZodIssueCode.custom,
|
|
12137
12312
|
path: ["cases", ci, "graders", gi],
|
|
12138
|
-
message: "file grader must use
|
|
12313
|
+
message: "file grader must use exactly one of `files[]`, `{path, expect}` or `{tool, expect}` (tool = assert on a tool call's input/output instead of a workspace file); a bare `path` without `expect` is ignored only when `files[]` is present (legacy tolerance)"
|
|
12139
12314
|
});
|
|
12140
12315
|
}
|
|
12141
12316
|
}
|
|
@@ -12173,12 +12348,12 @@ var EvalSuiteSchema = import_zod82.z.object({
|
|
|
12173
12348
|
}
|
|
12174
12349
|
const e = g.expect;
|
|
12175
12350
|
const hasEquals = e.equals != null;
|
|
12176
|
-
const hasOthers = e.includes != null || e.excludes != null || e.matches != null;
|
|
12351
|
+
const hasOthers = e.includes != null || e.excludes != null || e.matches != null || e.notMatches != null;
|
|
12177
12352
|
if (hasEquals && hasOthers) {
|
|
12178
12353
|
ctx.addIssue({
|
|
12179
12354
|
code: import_zod82.z.ZodIssueCode.custom,
|
|
12180
12355
|
path: ["cases", ci, "graders", gi, "expect"],
|
|
12181
|
-
message: "reply grader `expect.equals` is mutually exclusive with includes/excludes/matches"
|
|
12356
|
+
message: "reply grader `expect.equals` is mutually exclusive with includes/excludes/matches/notMatches"
|
|
12182
12357
|
});
|
|
12183
12358
|
}
|
|
12184
12359
|
if (!hasEquals && !hasOthers) {
|
|
@@ -12998,15 +13173,13 @@ var OnlineSessionPreconditionSchema = import_zod83.z.union([
|
|
|
12998
13173
|
fileExistsPrecondition,
|
|
12999
13174
|
toolCalledPrecondition
|
|
13000
13175
|
]);
|
|
13001
|
-
var
|
|
13002
|
-
error: "threshold is only valid on llm graders \u2014 boolean graders (transcript/reply/file/script) pass or fail, there is no score to threshold"
|
|
13003
|
-
}).optional();
|
|
13176
|
+
var optionalBooleanThreshold = import_zod83.z.number().min(0).max(1).optional();
|
|
13004
13177
|
var OnlineTranscriptGraderSchema = EvalTranscriptGraderSchema.pick({
|
|
13005
13178
|
type: true,
|
|
13006
13179
|
label: true
|
|
13007
13180
|
}).extend({
|
|
13008
13181
|
precondition: OnlineTurnPreconditionSchema.optional(),
|
|
13009
|
-
threshold:
|
|
13182
|
+
threshold: optionalBooleanThreshold,
|
|
13010
13183
|
expect: EvalTranscriptExpectSchema.pick({
|
|
13011
13184
|
completed: true,
|
|
13012
13185
|
forbiddenTools: true,
|
|
@@ -13018,10 +13191,10 @@ var OnlineTranscriptGraderSchema = EvalTranscriptGraderSchema.pick({
|
|
|
13018
13191
|
}).strict();
|
|
13019
13192
|
var OnlineReplyGraderSchema = EvalReplyGraderSchema.pick({ type: true, label: true }).extend({
|
|
13020
13193
|
precondition: OnlineTurnPreconditionSchema.optional(),
|
|
13021
|
-
threshold:
|
|
13194
|
+
threshold: optionalBooleanThreshold,
|
|
13022
13195
|
expect: EvalReplyExpectSchema.pick({ excludes: true, matches: true })
|
|
13023
13196
|
}).strict();
|
|
13024
|
-
var OnlineLlmToolsSchema =
|
|
13197
|
+
var OnlineLlmToolsSchema = EvalLlmToolsSchema;
|
|
13025
13198
|
var onlineLlmFields = EvalLlmGraderSchema.pick({
|
|
13026
13199
|
type: true,
|
|
13027
13200
|
label: true,
|
|
@@ -13042,7 +13215,7 @@ var OnlineFileGraderSchema = import_zod83.z.object({
|
|
|
13042
13215
|
type: import_zod83.z.literal("file"),
|
|
13043
13216
|
label: EvalGraderLabelSchema,
|
|
13044
13217
|
precondition: OnlineSessionPreconditionSchema,
|
|
13045
|
-
threshold:
|
|
13218
|
+
threshold: optionalBooleanThreshold,
|
|
13046
13219
|
path: EvalRelativePathSchema,
|
|
13047
13220
|
expect: EvalReplyExpectSchema.pick({ excludes: true }).required()
|
|
13048
13221
|
}).strict();
|
|
@@ -13053,7 +13226,7 @@ var OnlineScriptGraderSchema = EvalScriptGraderSchema.pick({
|
|
|
13053
13226
|
timeout: true
|
|
13054
13227
|
}).extend({
|
|
13055
13228
|
precondition: OnlineSessionPreconditionSchema,
|
|
13056
|
-
threshold:
|
|
13229
|
+
threshold: optionalBooleanThreshold,
|
|
13057
13230
|
expect: EvalScriptExpectSchema.optional()
|
|
13058
13231
|
}).strict();
|
|
13059
13232
|
var OnlineTurnGraderSpecSchema = import_zod83.z.discriminatedUnion("type", [
|
|
@@ -13727,7 +13900,12 @@ var RealtimeClaimResponseSchema = import_zod87.z.object({
|
|
|
13727
13900
|
credentialSource: import_zod87.z.enum(REALTIME_CREDENTIAL_SOURCES).optional(),
|
|
13728
13901
|
config: import_zod87.z.object({
|
|
13729
13902
|
systemPrompt: import_zod87.z.string(),
|
|
13730
|
-
voice:
|
|
13903
|
+
voice: RealtimeVoiceWireSchema,
|
|
13904
|
+
/**
|
|
13905
|
+
* Client-executed tools frozen with the call. Stripped by readers that do not know it, which
|
|
13906
|
+
* is the intended rolling-deploy story: an older gateway answers the call without tools.
|
|
13907
|
+
*/
|
|
13908
|
+
tools: WorkloadManifestRealtimeToolListSchema.optional(),
|
|
13731
13909
|
recording: import_zod87.z.boolean().default(false),
|
|
13732
13910
|
upstream: RealtimeUpstreamCredentialSchema.optional()
|
|
13733
13911
|
})
|
|
@@ -15464,13 +15642,13 @@ var SessionsResource = class {
|
|
|
15464
15642
|
* The codes and their statuses are the server's voice error-code table.
|
|
15465
15643
|
*
|
|
15466
15644
|
* **`VOICE_TURNS_DISABLED` is NOT one of them on this path**, despite being
|
|
15467
|
-
* in that table: it answers a NON-empty-text turn while
|
|
15468
|
-
* is
|
|
15645
|
+
* in that table: it answers a NON-empty-text turn while the kill switch
|
|
15646
|
+
* `voice_turns_disabled` is on, and this method always sends `text: ""`. The switch being on is
|
|
15469
15647
|
* refused one step earlier as the ordinary empty-text `400`
|
|
15470
15648
|
* `VALIDATION_ERROR` (issue path `["text"]`).
|
|
15471
15649
|
*
|
|
15472
15650
|
* **Four different causes produce that one 400, and the body does not
|
|
15473
|
-
* distinguish them**: the switch
|
|
15651
|
+
* distinguish them**: the switch on; the agent not declaring `voice.input`;
|
|
15474
15652
|
* an extension outside the voice set; and an attachment that never looks like
|
|
15475
15653
|
* audio at all — raw bytes passed without `contentType` upload as
|
|
15476
15654
|
* `application/octet-stream` and fail the empty-text rule in
|