@sema-agent/sdk 23.1.0 → 25.0.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/README.md +201 -4
- package/dist/client.d.ts +6 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -1
- package/dist/client.js.map +1 -1
- package/dist/device/index.d.ts +76 -12
- package/dist/device/index.d.ts.map +1 -1
- package/dist/device/index.js +90 -31
- package/dist/device/index.js.map +1 -1
- package/dist/errors.d.ts +318 -6
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +121 -10
- package/dist/errors.js.map +1 -1
- package/dist/events.d.ts +165 -23
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +19 -0
- package/dist/events.js.map +1 -1
- package/dist/health.d.ts +29 -1
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js.map +1 -1
- package/dist/index.d.ts +38 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -4
- package/dist/index.js.map +1 -1
- package/dist/model-route-env/index.d.ts +129 -0
- package/dist/model-route-env/index.d.ts.map +1 -0
- package/dist/model-route-env/index.js +131 -0
- package/dist/model-route-env/index.js.map +1 -0
- package/dist/registry/errors.d.ts +3 -0
- package/dist/registry/errors.d.ts.map +1 -1
- package/dist/registry/errors.js +3 -2
- package/dist/registry/errors.js.map +1 -1
- package/dist/registry/me-config.d.ts +1 -0
- package/dist/registry/me-config.d.ts.map +1 -1
- package/dist/registry/me-config.js +1 -1
- package/dist/registry/me-config.js.map +1 -1
- package/dist/registry/scope-config-feedback.d.ts +1 -0
- package/dist/registry/scope-config-feedback.d.ts.map +1 -1
- package/dist/registry/scope-config-feedback.js +1 -1
- package/dist/registry/scope-config-feedback.js.map +1 -1
- package/dist/resources/adoption.d.ts +8 -2
- package/dist/resources/adoption.d.ts.map +1 -1
- package/dist/resources/adoption.js.map +1 -1
- package/dist/resources/approvals.d.ts +22 -2
- package/dist/resources/approvals.d.ts.map +1 -1
- package/dist/resources/approvals.js +12 -2
- package/dist/resources/approvals.js.map +1 -1
- package/dist/resources/elicitations.d.ts +2 -1
- package/dist/resources/elicitations.d.ts.map +1 -1
- package/dist/resources/elicitations.js.map +1 -1
- package/dist/resources/fleet.d.ts +65 -6
- package/dist/resources/fleet.d.ts.map +1 -1
- package/dist/resources/fleet.js.map +1 -1
- package/dist/resources/ops.d.ts +113 -0
- package/dist/resources/ops.d.ts.map +1 -1
- package/dist/resources/ops.js +10 -0
- package/dist/resources/ops.js.map +1 -1
- package/dist/resources/principal-inbox.d.ts +62 -0
- package/dist/resources/principal-inbox.d.ts.map +1 -0
- package/dist/resources/principal-inbox.js +51 -0
- package/dist/resources/principal-inbox.js.map +1 -0
- package/dist/resources/questions.d.ts +2 -1
- package/dist/resources/questions.d.ts.map +1 -1
- package/dist/resources/questions.js.map +1 -1
- package/dist/resources/session-sync.d.ts +4 -2
- package/dist/resources/session-sync.d.ts.map +1 -1
- package/dist/resources/session-sync.js +4 -2
- package/dist/resources/session-sync.js.map +1 -1
- package/dist/resources/tool-approvals.d.ts +201 -22
- package/dist/resources/tool-approvals.d.ts.map +1 -1
- package/dist/resources/tool-approvals.js +183 -36
- package/dist/resources/tool-approvals.js.map +1 -1
- package/dist/settings.d.ts +73 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/sse.d.ts +8 -1
- package/dist/sse.d.ts.map +1 -1
- package/dist/sse.js +9 -5
- package/dist/sse.js.map +1 -1
- package/dist/types.d.ts +475 -113
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +11 -5
- package/dist/types.js.map +1 -1
- package/openapi.yaml +1296 -153
- package/package.json +6 -2
package/dist/errors.js
CHANGED
|
@@ -37,6 +37,7 @@ function extraOf(body) {
|
|
|
37
37
|
export class APIError extends Error {
|
|
38
38
|
status;
|
|
39
39
|
errorCode;
|
|
40
|
+
name = "APIError";
|
|
40
41
|
/**
|
|
41
42
|
* 🔴 **错误体上 `error` / `errorCode` 之外的全部键,原样**(K-09 销账,SDK 11.1.0)。`{}` = 这条体上
|
|
42
43
|
* 没有附加键(**不是** `undefined`:「没有附加材料」只该有一种读法)。
|
|
@@ -52,7 +53,7 @@ export class APIError extends Error {
|
|
|
52
53
|
*
|
|
53
54
|
* ⚠️ 既有的具名位({@link retriable}、`retryAfterMs`、各子类的结构化字段)是**先于本格存在**的镜像,
|
|
54
55
|
* 值来自同一张体 —— 它们不因本格而改变,新键也不再因此长出第 N 个属性。例外只由票面裁定开出,开了也仍同在本格:
|
|
55
|
-
* 现有一例 = K-19 `ParkedResumeStartupError.startupCause`(wire 键 `cause`;跨仓请托 [8537] / 认领 [8539] 点名要一个具型的读位;23.0.0
|
|
56
|
+
* 现有一例 = K-19 `ParkedResumeStartupError.startupCause`(wire 键 `cause`;跨仓请托 [8537] / 认领 [8539] 点名要一个具型的读位;23.0.0 起是引擎的成因闭集(core 7.52.0 起六词)
|
|
56
57
|
* `ResumeStartupCause`;值仍原样在 `extra.cause`)。
|
|
57
58
|
* ⚠️ **未清洗**:`message` 是给人看/进日志的那一半,过 `scrub()`;本格是给机器分支的那一半,原样透传
|
|
58
59
|
* (是 server 契约里的机读键,不是自由文本)。要把它打进日志的调用方自己负责清洗。
|
|
@@ -83,6 +84,11 @@ export class APIError extends Error {
|
|
|
83
84
|
* 🔴 **server ≥7.124.0:这一码的体多两只版本键** `writerVersion` / `readerVersion`(每个铸点同律 —— core 原码镜像与 server 自铸的两只读法记号拒都带;形见
|
|
84
85
|
* {@link CheckpointUnsupportedVersionExtra},值经 {@link extra} 到达)。「停驻行的格式比本引擎新」只有这一个来源:`writerVersion` 比 `readerVersion` 新 ⇒ 回到那一版(或更新的一版)去决,不是在本引擎上重试。
|
|
85
86
|
*
|
|
87
|
+
* 🔴 **server ≥7.132.0 一只写点、一条律**:三类续跑拒(server 重放存量体前的拒、准入策略折叠 `resume_blocked_by_policy`、引擎拒的续跑)上 `retriable: true` 在场 ⇔ **有一张待批卡仍在等、
|
|
88
|
+
* run 行留 `suspended`**(server `resumeRefusalWithCard` 一处追加,排在体尾)。由此两处订正:① `resume_blocked_by_policy` 自 7.132.0 起**同带** `retriable: true`(卡同样仍 pending;此前不带);
|
|
89
|
+
* ② **终态 run 的 `POST /v1/runs/:id/steer` 在铸唤醒卡之前拒的路径不带它**(没有卡)—— `checkpoint.unsupported_version` 的 allow 读法 / 模式词读法两臂在那条路径上此前自述 `true`,是错的。
|
|
90
|
+
* 同批:引擎拒的续跑体多三只判别位 `blockedBy` / `field` / `reason`(加性,见 {@link ResumeRefusalExtra});体键序变(`taskId` 移到 `errorCode` 之后、`retriable` 在体尾,键集不变)。
|
|
91
|
+
*
|
|
86
92
|
* 🔴 `undefined` means "the server did not say", NOT "not retriable" — it is a CONDITIONAL field server-side
|
|
87
93
|
* (absent ⇒ key omitted), so reading its absence as an explicit `false` over-reads the wire.
|
|
88
94
|
*
|
|
@@ -94,7 +100,6 @@ export class APIError extends Error {
|
|
|
94
100
|
super(message);
|
|
95
101
|
this.status = status;
|
|
96
102
|
this.errorCode = errorCode;
|
|
97
|
-
this.name = new.target.name;
|
|
98
103
|
}
|
|
99
104
|
}
|
|
100
105
|
/** `auth.*` 前缀族 + 401 状态兜底 —— fail-closed auth(缺/错 SERVICE_AUTH_TOKEN、非属主、
|
|
@@ -108,6 +113,7 @@ export class APIError extends Error {
|
|
|
108
113
|
* 🔴 [2400] CB-3(SDK 4.2.0):状态兜底**只剩 401**。无码 503 已改归 {@link ServiceStateError} —— 那条臂
|
|
109
114
|
* 上真正可达的是中间层的无码 503(「上游暂时不可用」),把它铸成本类等于把「稍后重试」说成「你没权限」。 */
|
|
110
115
|
export class AuthError extends APIError {
|
|
116
|
+
name = "AuthError";
|
|
111
117
|
}
|
|
112
118
|
// ── 附录 A 判据三:稳定前缀族的兜底 typed 面(SDK 1.1.0 × server 3.0.0 起 11 族;server 7.106.0 契约现行 14 族)────────
|
|
113
119
|
// 服务端契约原文(ASSISTANT-WIRE-CONTRACT 附录 A 判据三,server 7.106.0):「前缀族(`auth.` / `request.` /
|
|
@@ -195,17 +201,18 @@ export class AuthError extends APIError {
|
|
|
195
201
|
* (体里同时还有别的毛病而先撞上的是那一个时,`message` 说那个毛病、`field` 照带)。要「去掉这只键重发」的调用方按**码 + `err.extra.field`** 判,**别解析句子**
|
|
196
202
|
* (三口的句子在 7.119.0 收成逐字同一句,≤7.118.x 各说各的)。体里没有这只键的坏体**没有** `field`。本类不为它开具名属性(同上:开形一格)。 */
|
|
197
203
|
export class BadRequestError extends APIError {
|
|
204
|
+
name = "BadRequestError";
|
|
198
205
|
}
|
|
199
206
|
/** [2420] `attachment.*` 族(上传面拒收):`attachment.too_large`(413)携 {@link maxBytes},
|
|
200
207
|
* `attachment.mime_not_allowed`(415)携 {@link allowed}——两键是用户能改正的唯一量(压到多大/换什么类型)。 */
|
|
201
208
|
export class AttachmentRejectedError extends APIError {
|
|
202
209
|
maxBytes;
|
|
203
210
|
allowed;
|
|
211
|
+
name = "AttachmentRejectedError";
|
|
204
212
|
constructor(status, errorCode, message, maxBytes, allowed) {
|
|
205
213
|
super(status, errorCode, message);
|
|
206
214
|
this.maxBytes = maxBytes;
|
|
207
215
|
this.allowed = allowed;
|
|
208
|
-
this.name = "AttachmentRejectedError";
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
/** `not_found.*` 前缀族 —— 资源不存在。⚠️ 也包含**属主门**:server 对非属主一律回 404 同码同文
|
|
@@ -229,12 +236,14 @@ export class AttachmentRejectedError extends APIError {
|
|
|
229
236
|
* 反枚举不变式),永远走不到这两个码 —— 所以它们泄漏的全部信息是「**你自己**这条 run 的状态」,
|
|
230
237
|
* 而那本来就是 `runs.get(taskId)` 直答的东西。 */
|
|
231
238
|
export class NotFoundError extends APIError {
|
|
239
|
+
name = "NotFoundError";
|
|
232
240
|
}
|
|
233
241
|
/** `limit.*` 前缀族 —— 配额 / 限流 / 保留窗(429 限流与成本配额、416 续读点过保留窗)。
|
|
234
242
|
* `retryAfterMs` 来自 `Retry-After` 头(由 transport 喂入)。
|
|
235
243
|
* ⚠️ 429 那两个成员码({@link RateLimitedError} 起)走更具体的子类,见下。 */
|
|
236
244
|
export class LimitExceededError extends APIError {
|
|
237
245
|
retryAfterMs;
|
|
246
|
+
name = "LimitExceededError";
|
|
238
247
|
constructor(status, errorCode, message, retryAfterMs) {
|
|
239
248
|
super(status, errorCode, message);
|
|
240
249
|
this.retryAfterMs = retryAfterMs;
|
|
@@ -253,6 +262,7 @@ export class LimitExceededError extends APIError {
|
|
|
253
262
|
* `capability.snapshot_store_required`(history blob GET)· `capability.policy_purge_required`(同步整族,嵌入方形)。**唯一登记例外**:`a2aServe` 的两条路由不可用时答 404(反指纹)。
|
|
254
263
|
* ⚠️ **按状态码判「没权限 / 不存在 / 不可用」的分支要改按 `errorCode`**:403 可能是「不在名单」也可能(≤7.115.x)是名单空;404 可能是「真不存在」也可能(≤7.115.x)是「这台没挂这一族」。 */
|
|
255
264
|
export class CapabilityUnavailableError extends APIError {
|
|
265
|
+
name = "CapabilityUnavailableError";
|
|
256
266
|
}
|
|
257
267
|
/** `feature.*` 前缀族 —— **面存在,但开关是关的**(501;`feature.metrics_disabled` 是 404)。
|
|
258
268
|
* 处置:提示管理员打开对应开关(`RESOURCE_SUSPEND` / 三个 LIVE HITL 开关 / `STREAM_APPROVAL_ENABLED` /
|
|
@@ -263,6 +273,7 @@ export class CapabilityUnavailableError extends APIError {
|
|
|
263
273
|
* server ≥7.116.0 新增两员(都是 501,开旋钮即可):`feature.memory_consolidation_disabled`(记忆整理两口,`MEMORY_CONSOLIDATION_DRIVER` 关或出厂缺省派生关 ——
|
|
264
274
|
* 没配便宜模型;此前 404)· `feature.config_catalog_disabled`(`CONFIG_CATALOG_ENABLED=false` 时 `GET /v1/config/catalog`;此前 404)。 */
|
|
265
275
|
export class FeatureDisabledError extends APIError {
|
|
276
|
+
name = "FeatureDisabledError";
|
|
266
277
|
}
|
|
267
278
|
/** `internal.*` 前缀族 —— 服务端自己出错(500 / 502)。细节不上 wire。
|
|
268
279
|
* 部分成员**明确可重试**(`internal.cancel_not_terminalized` = 重试 cancel;
|
|
@@ -272,6 +283,7 @@ export class FeatureDisabledError extends APIError {
|
|
|
272
283
|
* (会话规则店读不出)**不在本族**(不以 `internal.` 开头)⇒ 落带码的 {@link APIError},同样不自动重试;按 `.errorCode` 分支,
|
|
273
284
|
* `error` 是引擎 / 店的原句(给运维看,不含盘上路径)。 */
|
|
274
285
|
export class InternalServerError extends APIError {
|
|
286
|
+
name = "InternalServerError";
|
|
275
287
|
}
|
|
276
288
|
/** `state.*` 前缀族 —— 服务端**当前状态**不接受这个请求(503)。开集,下面是本包逐码注过的成员(附录 A 为准;server ≥7.119.0 新增 `state.scenario_assignment_unknown`):
|
|
277
289
|
* · `state.model_roster_pending`(roster 还没拉到)/ `state.no_sandbox_base`(没有可用的 sandbox-base)
|
|
@@ -316,6 +328,7 @@ export class InternalServerError extends APIError {
|
|
|
316
328
|
* {@link import("./types.js").CenterWiringCapability.failMode} / `leaseHealth`。 */
|
|
317
329
|
export class ServiceStateError extends APIError {
|
|
318
330
|
retryAfterMs;
|
|
331
|
+
name = "ServiceStateError";
|
|
319
332
|
/**
|
|
320
333
|
* 等待提示(**毫秒**,单位与 {@link LimitExceededError.retryAfterMs} 同口径)。缺席 = server 这一支
|
|
321
334
|
* **没给**窗(如 `state.sse_connection_cap` 那些「换通道」成员),不是「可以立刻重打」。
|
|
@@ -347,6 +360,7 @@ export class ServiceStateError extends APIError {
|
|
|
347
360
|
export class WorkspaceFileTooLargeError extends APIError {
|
|
348
361
|
sizeBytes;
|
|
349
362
|
limit;
|
|
363
|
+
name = "WorkspaceFileTooLargeError";
|
|
350
364
|
constructor(status, errorCode, message, sizeBytes, limit) {
|
|
351
365
|
super(status, errorCode, message);
|
|
352
366
|
this.sizeBytes = sizeBytes;
|
|
@@ -370,6 +384,7 @@ export class WorkspaceFileTooLargeError extends APIError {
|
|
|
370
384
|
* codeless 503 arm to {@link ServiceStateError}; the status tariff now falls back to AuthError for 401 ONLY.) */
|
|
371
385
|
export class DrainingError extends APIError {
|
|
372
386
|
retryAfterMs;
|
|
387
|
+
name = "DrainingError";
|
|
373
388
|
constructor(status, errorCode, message, retryAfterMs) {
|
|
374
389
|
super(status, errorCode, message);
|
|
375
390
|
this.retryAfterMs = retryAfterMs;
|
|
@@ -393,6 +408,7 @@ export class DrainingError extends APIError {
|
|
|
393
408
|
export class RateLimitedError extends LimitExceededError {
|
|
394
409
|
usedMicroUsd;
|
|
395
410
|
limitMicroUsd;
|
|
411
|
+
name = "RateLimitedError";
|
|
396
412
|
constructor(status, errorCode, message, retryAfterMs,
|
|
397
413
|
/** `limit.cost_quota_exceeded` only —— 本窗口已花费(micro-USD)。缺席 = 服务端没给/给了坏值。 */
|
|
398
414
|
usedMicroUsd,
|
|
@@ -411,6 +427,7 @@ export class RateLimitedError extends LimitExceededError {
|
|
|
411
427
|
* usage window=引擎部署级 token 治理窗(design/166,`USAGE_WINDOWS`)。两类同为 429 但处置来源不同。 */
|
|
412
428
|
export class QuotaExhaustedError extends RateLimitedError {
|
|
413
429
|
detail;
|
|
430
|
+
name = "QuotaExhaustedError";
|
|
414
431
|
constructor(status, errorCode, message, retryAfterMs, detail) {
|
|
415
432
|
super(status, errorCode, message, retryAfterMs);
|
|
416
433
|
this.detail = detail;
|
|
@@ -424,6 +441,7 @@ export class QuotaExhaustedError extends RateLimitedError {
|
|
|
424
441
|
* `errorCode`,不再是 429——按 run 终态处置。 */
|
|
425
442
|
export class UsageWindowExhaustedError extends RateLimitedError {
|
|
426
443
|
retryAfterSec;
|
|
444
|
+
name = "UsageWindowExhaustedError";
|
|
427
445
|
constructor(status, errorCode, message, retryAfterMs,
|
|
428
446
|
/** 响应体的 retryAfterSec(秒,上取整;与 Retry-After 头同源)。缺席=服务端没给。 */
|
|
429
447
|
retryAfterSec) {
|
|
@@ -442,6 +460,7 @@ export class UsageWindowExhaustedError extends RateLimitedError {
|
|
|
442
460
|
* {@link APIError}),全文理由见 `classifyApiError` 里本臂的注。 */
|
|
443
461
|
export class MemoryAdmissionError extends APIError {
|
|
444
462
|
retryAfterSec;
|
|
463
|
+
name = "MemoryAdmissionError";
|
|
445
464
|
constructor(status, errorCode, message,
|
|
446
465
|
/** 仅 transient 形(admission_required)可能在场;terminal 形恒缺席(等待提示在终局拒上是方向性谎言)。 */
|
|
447
466
|
retryAfterSec) {
|
|
@@ -456,6 +475,7 @@ export class MemoryAdmissionError extends APIError {
|
|
|
456
475
|
* `allowlist`, or omit `scenario` entirely to run on the assigned default. */
|
|
457
476
|
export class ScenarioNotAllowedError extends APIError {
|
|
458
477
|
allowlist;
|
|
478
|
+
name = "ScenarioNotAllowedError";
|
|
459
479
|
constructor(status, errorCode, message,
|
|
460
480
|
/** The principal's allowed scenario names (may be empty on an older service / defensive drop). */
|
|
461
481
|
allowlist) {
|
|
@@ -465,6 +485,7 @@ export class ScenarioNotAllowedError extends APIError {
|
|
|
465
485
|
}
|
|
466
486
|
/** errorCode `budget.precall` / `budget.exceeded` — per-task or per-principal cost ceiling. NOT retryable. */
|
|
467
487
|
export class BudgetExceededError extends APIError {
|
|
488
|
+
name = "BudgetExceededError";
|
|
468
489
|
}
|
|
469
490
|
/** 409 — session already has an active run, or an idempotency conflict / session CAS conflict.
|
|
470
491
|
*
|
|
@@ -500,6 +521,7 @@ export class ConflictError extends APIError {
|
|
|
500
521
|
activeTaskId;
|
|
501
522
|
activeTaskStatus;
|
|
502
523
|
pendingGate;
|
|
524
|
+
name = "ConflictError";
|
|
503
525
|
constructor(status, errorCode, message, activeTaskId,
|
|
504
526
|
/** [2255]① server ≥3.21:conflict.session_active_run 携带的真出路材料(ADDITIVE / tolerate-absent)。
|
|
505
527
|
* running ⇒ steer/cancel 两条路;suspended/needs_review ⇒ pendingGate.decidePath 是那一个正确的
|
|
@@ -555,6 +577,7 @@ export class ConflictError extends APIError {
|
|
|
555
577
|
*/
|
|
556
578
|
export class DeviceError extends ConflictError {
|
|
557
579
|
currentRev;
|
|
580
|
+
name = "DeviceError";
|
|
558
581
|
constructor(status, errorCode, message,
|
|
559
582
|
/** `device.rebind_rev_conflict` 的当前 rev(顶层键)—— 壳一跳重定位:直接拿它重发换绑。
|
|
560
583
|
* 其余码上缺席(**守卫式**:非有限数丢弃 ⇒ 缺席,绝不把垃圾当前态)。 */
|
|
@@ -574,6 +597,7 @@ export class DeviceError extends ConflictError {
|
|
|
574
597
|
* NEVER auto-overwrite (a silent clobber is exactly the data loss the classifier exists to prevent). */
|
|
575
598
|
export class SyncConflictError extends ConflictError {
|
|
576
599
|
relation;
|
|
600
|
+
name = "SyncConflictError";
|
|
577
601
|
constructor(status, errorCode, message,
|
|
578
602
|
/** The §7 `fork`/`stale` relation with the exclusive entry sets (untyped at the JSON boundary). */
|
|
579
603
|
relation) {
|
|
@@ -581,12 +605,19 @@ export class SyncConflictError extends ConflictError {
|
|
|
581
605
|
this.relation = relation;
|
|
582
606
|
}
|
|
583
607
|
}
|
|
584
|
-
/**
|
|
585
|
-
*
|
|
586
|
-
*
|
|
608
|
+
/** 409 `approval_stale` — **one code, two causes**, told apart by the body:
|
|
609
|
+
* - **with {@link ApprovalStaleError.terminal}** = the checkpoint you tried to decide is already TERMINAL (someone else resolved it, it was
|
|
610
|
+
* GC'd past its abandonment-TTL, or its SLA deadline fired a resolve-deny). That pending is gone → REFETCH the inbox; do not retry the decide.
|
|
611
|
+
* - **no `terminal` and {@link ApprovalStaleError.currentPending} present** = the binding you echoed is STALE (the `boundCallId` no longer matches the row
|
|
612
|
+
* that is pending now — the card was superseded between your read and your decide). The pending row is still alive: use `currentPending` to
|
|
613
|
+
* re-point (one hop) and decide again; no full inbox re-pull needed.
|
|
614
|
+
* - Neither key = the server could not name a current pending (no pending, a non-tool gate, or the row read failed): REFETCH.
|
|
615
|
+
* Only a wrong `boundInputHash` (with the right `boundCallId`) is NOT this error: it lands in core's bare 409 `approval_binding_mismatch`
|
|
616
|
+
* ({@link ApprovalBindingMismatchError}). DISTINCT from the session-CAS 409. */
|
|
587
617
|
export class ApprovalStaleError extends APIError {
|
|
588
618
|
terminal;
|
|
589
619
|
currentPending;
|
|
620
|
+
name = "ApprovalStaleError";
|
|
590
621
|
constructor(status, errorCode, message, terminal,
|
|
591
622
|
/** S-02(server ≥7.52)—— 本会话**当前** pending 的三件 D-1 坐标(additive 指路键):壳拿它一跳
|
|
592
623
|
* 重定位再 decide,免整队重拉。缺席=无 pending/非工具门/行读失败(server F 类留痕臂)或老 server。
|
|
@@ -633,6 +664,7 @@ function staleCurrentPending(v) {
|
|
|
633
664
|
* 对着 ≤7.123.x 的 server,那一席仍借本码到达:{@link field} 按闭集读,不认识的词读作缺席,原值在 `err.extra.field`。`retriable: true` 形不变(卡仍 pending、run 行重新 park)。 */
|
|
634
665
|
export class ApprovalBindingMismatchError extends APIError {
|
|
635
666
|
field;
|
|
667
|
+
name = "ApprovalBindingMismatchError";
|
|
636
668
|
constructor(status, errorCode, message, field) {
|
|
637
669
|
super(status, errorCode, message);
|
|
638
670
|
this.field = field;
|
|
@@ -643,6 +675,7 @@ export class ApprovalBindingMismatchError extends APIError {
|
|
|
643
675
|
* do NOT treat as ApprovalStaleError. Client action: REFETCH the PendingCheckpoint + re-present, then decide
|
|
644
676
|
* again (retryable). */
|
|
645
677
|
export class ApprovalConcurrentlyReopenedError extends APIError {
|
|
678
|
+
name = "ApprovalConcurrentlyReopenedError";
|
|
646
679
|
}
|
|
647
680
|
/** `steering.*` 族的基类(SDK 1.1.0 —— 从**逐码枚举**改成**前缀分派**,与 `stop.*` / `decide.*` 同形)。
|
|
648
681
|
*
|
|
@@ -655,16 +688,19 @@ export class ApprovalConcurrentlyReopenedError extends APIError {
|
|
|
655
688
|
* 这是有意的 —— 「409」是传输层的巧合,「steer 目标有歧义」才是消费端要分支的东西;按 [clean-cut] 硬切,
|
|
656
689
|
* 不留双继承之类的兼容层。整族一把接:`catch (e instanceof SteeringError)`。 */
|
|
657
690
|
export class SteeringError extends APIError {
|
|
691
|
+
name = "SteeringError";
|
|
658
692
|
}
|
|
659
693
|
/** design/80 D-A — you steered a run that is NOT running (it is durable-`suspended`, terminal, or unknown).
|
|
660
694
|
* Steer is at-most-once and NOT queued. Client action: surface "task isn't running"; if suspended, the path
|
|
661
695
|
* forward is the approval decide, not a steer. */
|
|
662
696
|
export class SteeringNotRunningError extends SteeringError {
|
|
697
|
+
name = "SteeringNotRunningError";
|
|
663
698
|
}
|
|
664
699
|
/** design/80 D-A — the steer text carried a control-plane escape (e.g. `</system-reminder>`) and core rejected
|
|
665
700
|
* it (runtask.ts:489). Client action: it's an injection attempt or a malformed steer — surface it; don't retry
|
|
666
701
|
* verbatim. (The BFF also fences steer text defensively; this is core's authoritative reject.) */
|
|
667
702
|
export class SteeringInvalidContentError extends SteeringError {
|
|
703
|
+
name = "SteeringInvalidContentError";
|
|
668
704
|
}
|
|
669
705
|
/** `steering.ambiguous_target`(子代 steer/resume 面,server `http/routes/runs.ts`)/
|
|
670
706
|
* `steering.ambiguous_label`(workflow agent steer 面,`http/routes/workflows.ts`)—— **这一个 run 里有
|
|
@@ -672,12 +708,14 @@ export class SteeringInvalidContentError extends SteeringError {
|
|
|
672
708
|
* Client action:两个码同一个处置 —— **换一个唯一的定位方式**(子代面用 `parentToolCallId`;workflow 面
|
|
673
709
|
* 用更具体的 label/句柄),原样重试永远同一个结果。`.errorCode` 区分是哪条轴上歧义。 */
|
|
674
710
|
export class SteeringAmbiguousTargetError extends SteeringError {
|
|
711
|
+
name = "SteeringAmbiguousTargetError";
|
|
675
712
|
}
|
|
676
713
|
/** `steering.still_running` —— 你对一个**还在飞**的子代调了 `resume`(revive 只在 settle 之后合法;
|
|
677
714
|
* 也可能是上一次 resume 还没落地)。409。
|
|
678
715
|
* Client action:要么改调 steer(给在跑的它递话),要么等它 settle 再 resume。**与
|
|
679
716
|
* {@link SteeringNotRunningError} 正好互为反面**,两个码塌在一起会让 UI 说反话。 */
|
|
680
717
|
export class SteeringStillRunningError extends SteeringError {
|
|
718
|
+
name = "SteeringStillRunningError";
|
|
681
719
|
}
|
|
682
720
|
/** `steering.queue_full`(server ≥7.3.0 / core 5.14.0 #147)—— 这条 run **确实**挂着,但它 checkpoint 上
|
|
683
721
|
* 已 park 的转向队列**满了**。队列是有界且 **fail-loud** 的:引擎绝不驱逐一条已被接受的指令来腾位子
|
|
@@ -686,6 +724,7 @@ export class SteeringStillRunningError extends SteeringError {
|
|
|
686
724
|
* 只是现在放不下。让它 resume 把已 park 的投递掉(或减少并发转向)之后再发。两个码塌在一起会让 UI
|
|
687
725
|
* 说反话(同 `still_running` 的先例),所以它有自己的类而不是落基类。 */
|
|
688
726
|
export class SteeringQueueFullError extends SteeringError {
|
|
727
|
+
name = "SteeringQueueFullError";
|
|
689
728
|
}
|
|
690
729
|
/** `steering.ledger_unavailable`(server ≥7.110.0,S-928;子代 steer 路由自 server ≥7.111.0 / S-966 起同样可达)—— server 在回 `200 applied`
|
|
691
730
|
* (interrupt{text}:`202 queued-immediate`;子代 steer:`200 applied`)**之前**
|
|
@@ -695,6 +734,7 @@ export class SteeringQueueFullError extends SteeringError {
|
|
|
695
734
|
* 照用,server 侧零受理、零注入 ⇒ 不会重复)。不是改内容(invalid_content / blocked_by_hook)、不是换 key(duplicate_input_id)、
|
|
696
735
|
* 不是等 resume(queue_full)。处置分岔 ⇒ 自己的类(判据二),`.errorCode` 保留。 */
|
|
697
736
|
export class SteeringLedgerUnavailableError extends SteeringError {
|
|
737
|
+
name = "SteeringLedgerUnavailableError";
|
|
698
738
|
}
|
|
699
739
|
/** `steering.duplicate_input_id`(parked 腿 server ≥7.3.0 / core 5.14.0 #147;live 腿 server ≥7.23.0 /
|
|
700
740
|
* core 5.35.0 #257 起同样可达)—— 你带的 `Idempotency-Key` 已经
|
|
@@ -710,6 +750,7 @@ export class SteeringLedgerUnavailableError extends SteeringError {
|
|
|
710
750
|
* 句子是引擎的(7.118.0 改过一次),别按 `message` 匹配。 */
|
|
711
751
|
export class SteeringDuplicateInputIdError extends SteeringError {
|
|
712
752
|
differs;
|
|
753
|
+
name = "SteeringDuplicateInputIdError";
|
|
713
754
|
constructor(status, errorCode, message,
|
|
714
755
|
/** 体 `detail.differs`:{@link STEER_REPLAY_FACETS} 的非空子集(引擎的序)。整体成形或整体缺席 —— 不是数组 / 空 / 含集外词 ⇒ undefined
|
|
715
756
|
* (原值仍在 {@link APIError.extra};与 server 自己的读口同判:读不出就不铸)。 */
|
|
@@ -732,7 +773,11 @@ export const STEER_REPLAY_FACETS = Object.freeze(["text", "trusted", "priority",
|
|
|
732
773
|
* ⚠️ 这一条**必须**是拒:`reason` 自 1.284.0 起在直连门的 HMAC 签名载荷里(ASSISTANT-WIRE-CONTRACT §6.2),
|
|
733
774
|
* 服务端截过的字节与签名方签的字节必然不同 ⇒ MAC 恒不匹配,截断只会把可诊断的 413 变成费解的 401。
|
|
734
775
|
* Client action:缩短该字段后重发(重试原文没有意义);两个上限都是 server 侧常量,别在客户端猜。 */
|
|
776
|
+
/** ⚠️ 同一类也接 `413 request.payload_too_large`(`request.*` 族里唯一的分岔,处置同样是「缩短后重发」)—— server ≥7.132.0:TiDB / MySQL 协议部署上**提交体**超库的单行墙 / 包墙
|
|
777
|
+
* (`min(8 MiB, 库的单行上限 − 64 KiB)`,按体的 JSON 字节判)也落这一码,体带 `wallSource`(墙从哪来,见 {@link PayloadWallRefusalExtra});写续跑输入那一笔被库以「一行装不下」拒的答复同码
|
|
778
|
+
* (活流腿是终帧 `done`,`result.errorCode` 同码)。此前受理、写库那一刻 500。出路:缩小内联图 / 附件,或运维抬库的单行上限。 */
|
|
735
779
|
export class PayloadTooLargeError extends APIError {
|
|
780
|
+
name = "PayloadTooLargeError";
|
|
736
781
|
}
|
|
737
782
|
/** [1833] G13 — `runs.taskStop` 的 409 冲突家族(server `src/http/routes/runs.ts` 的 stop 路由,`errorCode`
|
|
738
783
|
* 判别;design/158 A9 域拆分后已不在 `src/http/server.ts`):
|
|
@@ -741,6 +786,7 @@ export class PayloadTooLargeError extends APIError {
|
|
|
741
786
|
* 恢复赢了)/ `stop.park_arbiter_unreachable`(仲裁店不可达,真相未知——core 1.397 三分)。
|
|
742
787
|
* 开集:未来新 `stop.*` 码同样落到本类(`errorCode` 原样携带),消费方 switch 要留 default。 */
|
|
743
788
|
export class TaskStopConflictError extends ConflictError {
|
|
789
|
+
name = "TaskStopConflictError";
|
|
744
790
|
}
|
|
745
791
|
/** 409 `interrupt.*` 族(core #504 / server ≥7.52 `POST /v1/runs/:id/interrupt`)—— 前缀开集,与 `stop.*`
|
|
746
792
|
* 同形。两个现役码,处置相反所以**都别盲重试**,按 `.errorCode` 分支:
|
|
@@ -750,27 +796,32 @@ export class TaskStopConflictError extends ConflictError {
|
|
|
750
796
|
* 那两条腿返回结果不返回流)⇒ 要 run 级停用 `POST /v1/runs/:id/cancel`;证得出他副本时文案会指路重发。
|
|
751
797
|
* 终态/刚落定臂复用 `steering.not_running`(→ {@link SteeringNotRunningError}),不在本族。 */
|
|
752
798
|
export class InterruptConflictError extends ConflictError {
|
|
799
|
+
name = "InterruptConflictError";
|
|
753
800
|
}
|
|
754
801
|
/** design/80 D-G (direct-connect door, service [84]) — the signed principal JWT (`X-Approval-Principal-Token`)
|
|
755
802
|
* failed to verify against the worker's projected pubkey anchor (bad sig / exp / iss / aud / alg-not-pinned).
|
|
756
803
|
* 401. Client action: re-sign a fresh short-TTL JWT; persistent ⇒ BFF signing key/anchor misaligned. FORWARD-
|
|
757
804
|
* DRAFT: wire codes are service-locked; the BFF signer + live path land at M2. */
|
|
758
805
|
export class PrincipalUnverifiedError extends APIError {
|
|
806
|
+
name = "PrincipalUnverifiedError";
|
|
759
807
|
}
|
|
760
808
|
/** design/80 D-G — the JWT verified but its `cnf.bnd` ≠ SHA256(checkpointToken): the identity assertion was
|
|
761
809
|
* minted for a DIFFERENT decision and lifted onto this one (token-lift). A SAFETY signal. 401. Client action:
|
|
762
810
|
* NEVER retry verbatim; re-mint the JWT bound to THIS checkpointToken. */
|
|
763
811
|
export class PrincipalUnboundError extends APIError {
|
|
812
|
+
name = "PrincipalUnboundError";
|
|
764
813
|
}
|
|
765
814
|
/** ASSISTANT-WIRE-CONTRACT §4b(service main 6cd0164)— 你对一个 human/policy_ask 门调了 resume(CONTINUE)。
|
|
766
815
|
* 409 errorCode `gate_not_resumable`。一个 "continue" 绝不能绕过人审。SEMANTIC(错门), NOT session-CAS ConflictError。
|
|
767
816
|
* Client action: 这条路是 /decide(approve/deny), 不是 resume —— 改走人审 UI。 */
|
|
768
817
|
export class GateNotResumableError extends APIError {
|
|
818
|
+
name = "GateNotResumableError";
|
|
769
819
|
}
|
|
770
820
|
/** ASSISTANT-WIRE-CONTRACT §4c(service main 6cd0164)— 你对一个非 plan_review 门调了 plan_review。
|
|
771
821
|
* 409 errorCode `gate_not_plan_review`。一个 plan 决策绝不能解 tool 审批 / resource_limit。SEMANTIC(错门), NOT ConflictError。
|
|
772
822
|
* Client action: 按 gateKind 选对的决策端点(/decide 或 /resume), 重取 inbox。 */
|
|
773
823
|
export class GateNotPlanReviewError extends APIError {
|
|
824
|
+
name = "GateNotPlanReviewError";
|
|
774
825
|
}
|
|
775
826
|
/** [2400] CB-2(SDK 4.2.0)—— 语义错门守卫的**第三个**成员(与上面两兄弟同形):你对一个**不是工具审批门**
|
|
776
827
|
* 的挂起调了 `/v1/approvals/:sessionId/decide`。409 errorCode `gate_not_tool_approval`
|
|
@@ -781,6 +832,7 @@ export class GateNotPlanReviewError extends APIError {
|
|
|
781
832
|
* 🔴 与 session-CAS `ConflictError` 刻意不同类:两者都是 409,但这一条说的是「你敲错门了」,处置是**换端点**,
|
|
782
833
|
* 不是「重读再试」。 */
|
|
783
834
|
export class GateNotToolApprovalError extends APIError {
|
|
835
|
+
name = "GateNotToolApprovalError";
|
|
784
836
|
}
|
|
785
837
|
// ── design/172 流内审批协议回决端点(#151 车4;POST /v1/tasks/:taskId/asks/:askId/decision)────────────
|
|
786
838
|
// 🔴 已发布:server 7.3.0 上线该端点,SDK 6.7.0 同窗发这四个类。四则响应(§3.2)在 wire 上是**四个不同的处置**,所以是四个类,
|
|
@@ -795,6 +847,7 @@ export class AskDecidedError extends ConflictError {
|
|
|
795
847
|
firstDecision;
|
|
796
848
|
decidedAtMs;
|
|
797
849
|
actor;
|
|
850
|
+
name = "AskDecidedError";
|
|
798
851
|
constructor(status, errorCode, message,
|
|
799
852
|
/** 首决:被接受的那个决议。 */
|
|
800
853
|
firstDecision,
|
|
@@ -813,6 +866,7 @@ export class AskDecidedError extends ConflictError {
|
|
|
813
866
|
* 条款排除了它(一次同意不得被复用到另一次未经确认的征询)。
|
|
814
867
|
* Client action:换一个 key 重发(**不是**换 askId)。 */
|
|
815
868
|
export class AskIdempotencyConflictError extends ConflictError {
|
|
869
|
+
name = "AskIdempotencyConflictError";
|
|
816
870
|
}
|
|
817
871
|
/** 410 `gone.ask_parked` / `gone.ask` —— 窗已关闭,这张卡的结局**已经铸定**,流内回决面对它已不存在。
|
|
818
872
|
*
|
|
@@ -846,6 +900,7 @@ export class AskGoneError extends APIError {
|
|
|
846
900
|
gateBoundCallId;
|
|
847
901
|
gateBoundInputHash;
|
|
848
902
|
endingCause;
|
|
903
|
+
name = "AskGoneError";
|
|
849
904
|
constructor(status, errorCode, message,
|
|
850
905
|
/** `PARKED` | `DENIED` | `VOID`(`gone.ask` 腿携带;`gone.ask_parked` 腿恒 PARKED,可缺席)。具名闭集型 {@link AskGoneState}
|
|
851
906
|
* ({@link toApiError} 只会产出三词之一,越界值在 mapper 里就被丢弃)。 */
|
|
@@ -895,6 +950,36 @@ export const ASK_ROW_ENDING_CAUSES = Object.freeze([
|
|
|
895
950
|
"crashed_before_park",
|
|
896
951
|
"shutdown_before_park",
|
|
897
952
|
]);
|
|
953
|
+
/** 契约包(`@sema-agent/settings-schema/hooks`)分类器的码:`HOOKS_REJECTION_CODES` 六词 ∪ `HOOKS_DROPPED_PIECE_CODES` 五词(镜像;门钉对钉版 server 依赖的契约包运行期常量)。 */
|
|
954
|
+
export const SETTINGS_HOOKS_PIECE_CODES = Object.freeze([
|
|
955
|
+
"guard-outside-hooks", "hooks-is-matcher", "guard-under-unknown-event", "guard-event-not-array", "guard-matcher-invalid", "guard-entry-invalid",
|
|
956
|
+
"hooks-not-object", "unknown-event", "event-not-array", "matcher-invalid", "entry-invalid",
|
|
957
|
+
]);
|
|
958
|
+
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
|
959
|
+
// server ≥7.133.0 —— 受理面拒体的机读位(additive;句子与码不变,**不要解析句子**)
|
|
960
|
+
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
|
961
|
+
/**
|
|
962
|
+
* `400 request.invalid_json` 的 `reason` 闭集(server ≥7.133.0;体 `{ error, errorCode, reason }`,值经 `err.extra.reason` 到达):请求体不是这一口要的 JSON ——
|
|
963
|
+
* `not_json`(体不是合法 JSON)/ `not_object`(体是合法 JSON 但不是对象,而这一口要对象;如 `compact` 口)。**读开集**(未知词按「请求体形不对」处置)。
|
|
964
|
+
* 🔴 **BREAKING(wire 码,server 7.133.0)**:坏 JSON 体恒答 `400 request.invalid_json`。此前同一件事在多数口答 `request.rejected`(状态兜底粗码)、`notify` / `wake` / 权限规则三口答 `request.body_shape`,
|
|
965
|
+
* 一批口读体超限折 400 —— 按那几个码识别「坏 JSON」的代码要改读 `errorCode === "request.invalid_json"` + `reason`(零别名、零开关)。≤7.132.x 的 server 仍是旧码:**本包的读法恒是按 wire 上的 `errorCode` 分,不按版本猜**。
|
|
966
|
+
*/
|
|
967
|
+
export const INVALID_JSON_REASONS = Object.freeze(["not_json", "not_object"]);
|
|
968
|
+
/**
|
|
969
|
+
* `400 request.field_conflict` 的 `detail.kind` 闭集(server ≥7.133.0,**十四词**):一份请求体**自己跟自己矛盾**(两个键不能同带)是哪一类约束。同一个约束的几个拒点同一个词。体 `detail`:
|
|
970
|
+
* `{ kind, fields[], count?, cap? }` —— `fields` = 被点名的请求体坐标(主语在前,至少一个;动态下标用 `agents[1].skills` 形),`count` / `cap` 只在「折叠上限」那一类带(合起来的量与帽)。句子与码不变;老 server 只有一句英文。
|
|
971
|
+
* 每类的坐标闭集:`cascade_verify`(`verify` / `cascade` / `sandboxImageProfile` / `resumeAt` / `suggestNextPrompts`)· `image_profile`(`capabilitiesNeeded` / `sandboxImageProfile`)·
|
|
972
|
+
* `resume_anchor`(`resumeAtMode` / `resumeAt`)· `system_prompt_fold`(`appendSystemPrompt` / `settings.outputStyle`)· `file_history_restore`(`fileHistory` / `restoreFiles` / `rewindFilesTo` / `rewindFiles`)·
|
|
973
|
+
* `skills_disabled`(`disableSkills` / `skills` / `agents[i].skills`)· `existing_session`(`requireExistingSession` / `sessionId`)· `scratchpad_root`(`cwd` / `scratchpadDir`)· `ask_answer`(`decision` / `answer`)·
|
|
974
|
+
* `policy_person_ask`(`decision` / `decidedBy`)· `plan_edit`(`decision` / `editedPlan`)· `plan_mode_after`(`decision` / `permissionModeAfter`)· `bound_call_door`(`boundCallId`)· `remember_decision`(`remember` / `decision`)。
|
|
975
|
+
* 壳按 `detail.kind` 分支、按 `detail.fields` 高亮冲突的两处输入;**读开集**(未知 kind 按「请求体自相矛盾」处置)。
|
|
976
|
+
*/
|
|
977
|
+
export const FIELD_CONFLICT_KINDS = Object.freeze([
|
|
978
|
+
"cascade_verify", "image_profile", "resume_anchor", "system_prompt_fold", "file_history_restore", "skills_disabled", "existing_session",
|
|
979
|
+
"scratchpad_root", "ask_answer", "policy_person_ask", "plan_edit", "plan_mode_after", "bound_call_door", "remember_decision",
|
|
980
|
+
]);
|
|
981
|
+
/** server 自铸的两个条目问题词(闭集,其余 `reason` 是引擎的词原样):`not_in_roster`(受理告知 `warnings[]` 的词)· `home_unresolvable`(设置规则 422 的词)。 */
|
|
982
|
+
export const SERVER_ENTRY_PROBLEM_REASONS = Object.freeze(["not_in_roster", "home_unresolvable"]);
|
|
898
983
|
/** `DENIED` 态的唯一合法结局成因(server 全仓 `DENIED` 只有一个写点)—— {@link ASK_ROW_ENDING_CAUSES} 的首员。导出是因为消费端要拿它做
|
|
899
984
|
* 「路由失败 vs 人拒」的判别与文案分支 —— 手抄一份字符串正是这条界线被抹掉的常见方式。server ≥7.124.0 起它住在 410 体的 `cause` 键上(此前 `deniedReason`)。 */
|
|
900
985
|
export const DENY_REASON_ROUTING_FAILURE = "routing_failure_fail_closed";
|
|
@@ -912,6 +997,7 @@ export const RULE_ENTRY_INERT_REASONS = Object.freeze(["wildcard_all", "namespac
|
|
|
912
997
|
export class AskParkingError extends APIError {
|
|
913
998
|
retryAfterMs;
|
|
914
999
|
retryAfterSec;
|
|
1000
|
+
name = "AskParkingError";
|
|
915
1001
|
constructor(status, errorCode, message,
|
|
916
1002
|
/** `Retry-After` 头解析出的毫秒(transport 统一喂入)。 */
|
|
917
1003
|
retryAfterMs,
|
|
@@ -924,6 +1010,7 @@ export class AskParkingError extends APIError {
|
|
|
924
1010
|
}
|
|
925
1011
|
/** design/80 D-G — the direct-connect door requires the HMAC envelope (`X-Approval-Mac`) and it was absent. */
|
|
926
1012
|
export class ApprovalMacRequiredError extends APIError {
|
|
1013
|
+
name = "ApprovalMacRequiredError";
|
|
927
1014
|
}
|
|
928
1015
|
/** design/80 D-G — the HMAC envelope failed verification (wrong key/kid, or a tampered [token,callId,hash,
|
|
929
1016
|
* decision] tuple). 401. Client action: re-sign with the active HMAC kid; persistent ⇒ key rotation skew.
|
|
@@ -934,6 +1021,7 @@ export class ApprovalMacRequiredError extends APIError {
|
|
|
934
1021
|
* 删除、零双读、混版两向皆 401)对**本包的调用方**零动作 —— 除非它自己就是那个签名器,那时它按 server 的
|
|
935
1022
|
* 契约 §6 改形。**没有直连门的部署完全不受影响**。 */
|
|
936
1023
|
export class ApprovalMacInvalidError extends APIError {
|
|
1024
|
+
name = "ApprovalMacInvalidError";
|
|
937
1025
|
}
|
|
938
1026
|
/** `resume_outcome_invalid` — a plan_review / dry-run-review outcome was REJECTED BY CONTENT SANITIZE
|
|
939
1027
|
* (`editedPlan`/`reason` carried a forbidden tag), or — on the tool-approval gate — one cell of the decision body is not valid:
|
|
@@ -947,6 +1035,7 @@ export class ApprovalMacInvalidError extends APIError {
|
|
|
947
1035
|
* precisely so a UI routes to the right recovery (fix the text and re-submit) instead of the action-binding
|
|
948
1036
|
* flow. Collapsing the two back into one type in the SDK would undo that split. Usually `retriable`. */
|
|
949
1037
|
export class ResumeOutcomeInvalidError extends APIError {
|
|
1038
|
+
name = "ResumeOutcomeInvalidError";
|
|
950
1039
|
}
|
|
951
1040
|
/** `resume_blocked_by_policy` — an admission policy CHANGED between suspend and resume, and the resume is no
|
|
952
1041
|
* longer admissible. Not a race: retrying as-is stays blocked until the policy or the request changes.
|
|
@@ -959,6 +1048,7 @@ export class ResumeOutcomeInvalidError extends APIError {
|
|
|
959
1048
|
* 原因:引擎 7.41 去首尾空白(`"Bash "` 曾是一条有效的拒),7.42 逐字读 —— 不判就是升级后那条拒无声消失。本类按 `errorCode` 判别,三条来路用 `blockedBy` 区分。 */
|
|
960
1049
|
export class ResumeBlockedByPolicyError extends APIError {
|
|
961
1050
|
blockedBy;
|
|
1051
|
+
name = "ResumeBlockedByPolicyError";
|
|
962
1052
|
constructor(status, errorCode, message,
|
|
963
1053
|
/**
|
|
964
1054
|
* **哪一道检查拒的**:被折叠的那只拒绝**直接**出去时会带的 `errorCode`。server ≥7.104.0(S-607)起 wire 上**恒在**:带码的原拒绝 ⇒
|
|
@@ -989,6 +1079,7 @@ export class ResumeBlockedByPolicyError extends APIError {
|
|
|
989
1079
|
* session_not_found。前缀开集:core 未来新码至少落到本类(`.errorCode` 判别),不塌匿名 409。
|
|
990
1080
|
* ⚠️ 与下划线形的 resume_outcome_invalid / resume_blocked_by_policy 是**两族**(那两个在上面,先判)。 */
|
|
991
1081
|
export class SubagentResumeConflictError extends ConflictError {
|
|
1082
|
+
name = "SubagentResumeConflictError";
|
|
992
1083
|
}
|
|
993
1084
|
/** A-075.10 —— resume 族的**时间性拒绝**二码(前码 server ≥7.47.0、后码 ≥7.51.0;亲读 `http/server.ts` 拒绝体铸点):
|
|
994
1085
|
* `resume.usage_window_exhausted`(#449 G1,core 5.60.1:该行账本键上的部署治理窗满了;「什么都没消费、
|
|
@@ -1002,6 +1093,7 @@ export class SubagentResumeConflictError extends ConflictError {
|
|
|
1002
1093
|
export class ResumeRetryLaterError extends SubagentResumeConflictError {
|
|
1003
1094
|
retryAfterMs;
|
|
1004
1095
|
retryAfterSec;
|
|
1096
|
+
name = "ResumeRetryLaterError";
|
|
1005
1097
|
constructor(status, errorCode, message,
|
|
1006
1098
|
/** `Retry-After` 头解析出的毫秒(transport 喂入;该腿 server 今天不发头 ⇒ 通常缺席)。 */
|
|
1007
1099
|
retryAfterMs,
|
|
@@ -1017,10 +1109,12 @@ export class ResumeRetryLaterError extends SubagentResumeConflictError {
|
|
|
1017
1109
|
* ⚠️ [2400] CB-2 起 `wake.` 是**前缀开集**:未来的 `wake.*` 新码至少落到 {@link ConflictError}
|
|
1018
1110
|
* (`.errorCode` 原样携带),不再塌成匿名 409。 */
|
|
1019
1111
|
export class WakeGatePendingError extends ConflictError {
|
|
1112
|
+
name = "WakeGatePendingError";
|
|
1020
1113
|
}
|
|
1021
1114
|
/** 409 `compact.not_running` / `detach.not_running` —— replica-local live-verb 族:run 已终态,或活在
|
|
1022
1115
|
* 另一副本(手动 compact/detach 只对本副本的活流有效)。`.errorCode` 判别是哪个 verb。 */
|
|
1023
1116
|
export class RunNotLiveError extends ConflictError {
|
|
1117
|
+
name = "RunNotLiveError";
|
|
1024
1118
|
}
|
|
1025
1119
|
/** Base of the `decide.*` family — catch this to handle the whole decide door in one place.
|
|
1026
1120
|
* Codes that fall on THIS class rather than a subclass need a human: `row_unrevivable` (damaged row),
|
|
@@ -1040,6 +1134,7 @@ export class DecideError extends APIError {
|
|
|
1040
1134
|
taskId;
|
|
1041
1135
|
rollback;
|
|
1042
1136
|
runId;
|
|
1137
|
+
name = "DecideError";
|
|
1043
1138
|
constructor(status, errorCode, message, taskId,
|
|
1044
1139
|
/** revive legs only — the claim-rollback disposition the server reported. */
|
|
1045
1140
|
rollback,
|
|
@@ -1064,6 +1159,7 @@ export class DecideError extends APIError {
|
|
|
1064
1159
|
* different occupant. The re-fetch then usually shows the card GONE (a 7.104.0 session delete retires its parked children's cards) —
|
|
1065
1160
|
* nothing is left to decide; this form mostly meets cards left behind by a session deleted before 7.104.0. */
|
|
1066
1161
|
export class DecideParkMovedError extends DecideError {
|
|
1162
|
+
name = "DecideParkMovedError";
|
|
1067
1163
|
}
|
|
1068
1164
|
/** `decide.parked_answer_required` / `decide.parked_remember_unsupported` — this park shape does not accept
|
|
1069
1165
|
* the decide you sent (an AskUserQuestion approve without `body.answer` — server 5.12.0/core 5.7.0 RB-459;
|
|
@@ -1072,18 +1168,22 @@ export class DecideParkMovedError extends DecideError {
|
|
|
1072
1168
|
* `decide.parked_answer_unsupported` / `..._question_unsupported` are retired: the answer HAS a hookpoint
|
|
1073
1169
|
* now and a parked question CAN be approved (with an answer). */
|
|
1074
1170
|
export class DecideUnsupportedError extends DecideError {
|
|
1171
|
+
name = "DecideUnsupportedError";
|
|
1075
1172
|
}
|
|
1076
1173
|
/**
|
|
1077
|
-
* Why a parked resume could not start its approved action — the engine's closed set `RESUME_STARTUP_CAUSES` (core 7.51.0), word for word and in
|
|
1174
|
+
* Why a parked resume could not start its approved action — the engine's closed set `RESUME_STARTUP_CAUSES` (core 7.51.0; six words since core 7.52.0), word for word and in
|
|
1078
1175
|
* order. Server ≥ 7.129.0 relays it as the 422 `parked_resume.startup_failed` body's `cause`, screened against this set (a word the engine did
|
|
1079
1176
|
* not say, or one outside the set ⇒ the key is absent). What each word tells the caller to do:
|
|
1080
1177
|
* · `environment` — the leg's infrastructure failed (workspace restore, an abort); the decision is untouched — retrying replays it;
|
|
1081
1178
|
* · `session_gone` — the resumed agent's transcript session is missing;
|
|
1179
|
+
* · `transcript_corrupt` — (core 7.52.0 #1796, server ≥ 7.132.0) the resumed agent's transcript is there but damaged: no header its store wrote, a leaf
|
|
1180
|
+
* or parent entry missing from the log, or a lost tail the checkpoint was cut inside. The row reopens as for `session_gone` (a system retry, the
|
|
1181
|
+
* decision is untouched); only the receipt now says which. Servers ≤ 7.131.x answered `session_gone` / no cause for these;
|
|
1082
1182
|
* · `tool_unavailable` — the approved tool is not available to the resumed leg (gone, or replaced by a different contract) — this approval cannot run, decide afresh;
|
|
1083
1183
|
* · `configuration` — the deployment's configuration refuses the resumed leg; a retry under the same configuration fails the same way;
|
|
1084
1184
|
* · `decision_rejected` — the decision does not fit the checkpoint (another gate's answer, an input the constraints refuse) — correct it and resubmit.
|
|
1085
1185
|
*/
|
|
1086
|
-
export const RESUME_STARTUP_CAUSES = Object.freeze(["environment", "session_gone", "tool_unavailable", "configuration", "decision_rejected"]);
|
|
1186
|
+
export const RESUME_STARTUP_CAUSES = Object.freeze(["environment", "session_gone", "transcript_corrupt", "tool_unavailable", "configuration", "decision_rejected"]);
|
|
1087
1187
|
const isResumeStartupCause = (v) => typeof v === "string" && RESUME_STARTUP_CAUSES.includes(v);
|
|
1088
1188
|
/** `parked_resume.startup_failed` (422 — core code PASSTHROUGH, server 5.12.0/RB-459): the decide was
|
|
1089
1189
|
* accepted and the revive attempted, but the resume failed during startup — the child's session is gone,
|
|
@@ -1103,6 +1203,7 @@ const isResumeStartupCause = (v) => typeof v === "string" && RESUME_STARTUP_CAUS
|
|
|
1103
1203
|
* indistinguishable on the wire (the prose `message` is the engine's text — never branch on it). See {@link startupCause}. */
|
|
1104
1204
|
export class ParkedResumeStartupError extends DecideError {
|
|
1105
1205
|
startupCause;
|
|
1206
|
+
name = "ParkedResumeStartupError";
|
|
1106
1207
|
constructor(status, errorCode, message, taskId, rollback, runId,
|
|
1107
1208
|
/**
|
|
1108
1209
|
* K-19 — the machine-readable CAUSE WORD of this startup failure (client-core [8537] CC-225; server S-818 relays it
|
|
@@ -1128,6 +1229,7 @@ export class ParkedResumeStartupError extends DecideError {
|
|
|
1128
1229
|
}
|
|
1129
1230
|
/** `decide.store_unreachable` — the durable agent store is unreachable. Transient: retry the same decide. */
|
|
1130
1231
|
export class DecideStoreUnreachableError extends DecideError {
|
|
1232
|
+
name = "DecideStoreUnreachableError";
|
|
1131
1233
|
}
|
|
1132
1234
|
/** `decide.workflow_host_unknown` / `decide.workflow_host_not_parked` (409, server >=7.69.0 / S-185) — the
|
|
1133
1235
|
* pending belongs to a **workflow child** that parked on an approval gate, and the deployment could not hand
|
|
@@ -1153,6 +1255,7 @@ export class DecideStoreUnreachableError extends DecideError {
|
|
|
1153
1255
|
* (Grouped by what the caller must do — the same axis as {@link DecideParkMovedError} — rather than by status;
|
|
1154
1256
|
* both are 409 but neither is the "the park moved, refetch the list" doctrine.) */
|
|
1155
1257
|
export class DecideWorkflowHostError extends DecideError {
|
|
1258
|
+
name = "DecideWorkflowHostError";
|
|
1156
1259
|
}
|
|
1157
1260
|
/** `decide.workflow_parks_unreadable` (409, server >=7.75.0 / S-252) — the pending belongs to a **workflow
|
|
1158
1261
|
* child**, and (the 7.75.0–7.117.x reading; a server ≥7.118.0 narrows the triggers — see the 7.118.0 paragraph at the end)
|
|
@@ -1220,6 +1323,7 @@ export class DecideWorkflowHostError extends DecideError {
|
|
|
1220
1323
|
*/
|
|
1221
1324
|
export class DecideWorkflowParksUnreadableError extends DecideError {
|
|
1222
1325
|
readableHolderRunId;
|
|
1326
|
+
name = "DecideWorkflowParksUnreadableError";
|
|
1223
1327
|
constructor(status, errorCode, message, taskId, rollback, runId,
|
|
1224
1328
|
/** server ≥7.118.0, the "record cannot be read" cause only: the readable record that holds this card at the highest generation
|
|
1225
1329
|
* (the body's top-level `readableHolderRunId`; absent when there is none or a tie — never `null`). Where the work can be carried
|
|
@@ -1240,6 +1344,7 @@ export class DecideWorkflowParksUnreadableError extends DecideError {
|
|
|
1240
1344
|
* fork look like a single holder and the decision goes to the branch whose pointer exists (server 7.118.0 known boundary). */
|
|
1241
1345
|
export class DecideWorkflowParkForkedError extends DecideError {
|
|
1242
1346
|
runIds;
|
|
1347
|
+
name = "DecideWorkflowParkForkedError";
|
|
1243
1348
|
constructor(status, errorCode, message, taskId, rollback, runId,
|
|
1244
1349
|
/** The resumed runs that all hold this card (the body's `runIds`, ≥2 on the wire). Whole-or-nothing: absent when the body does
|
|
1245
1350
|
* not carry an array of non-empty strings (the raw value stays on {@link APIError.extra}). */
|
|
@@ -1508,7 +1613,7 @@ function classifyApiError(status, body, retryAfterMs) {
|
|
|
1508
1613
|
// RB-459(server 5.12.0):core 码 422 原样透传——非 decide. 前缀但同一决定面,处置=重查 pending 再决。
|
|
1509
1614
|
if (errorCode === "parked_resume.startup_failed") {
|
|
1510
1615
|
return new ParkedResumeStartupError(status, errorCode, msg, typeof b.taskId === "string" ? b.taskId : undefined, typeof b.rollback === "string" ? b.rollback : undefined, typeof b.runId === "string" ? b.runId : undefined,
|
|
1511
|
-
// K-19 / 23.0.0:wire 键 `cause`
|
|
1616
|
+
// K-19 / 23.0.0:wire 键 `cause` 是引擎的成因闭集(core 7.52.0 起六词;server ≥7.129.0 按引擎 `RESUME_STARTUP_CAUSES` 筛过才发);成员原样读进 `startupCause`,
|
|
1512
1617
|
// 缺席 / 非串 / 集外 ⇒ undefined(不补默认、不改写;原值仍在 `err.extra.cause`)。
|
|
1513
1618
|
isResumeStartupCause(b.cause) ? b.cause : undefined);
|
|
1514
1619
|
}
|
|
@@ -1722,26 +1827,30 @@ function classifyApiError(status, body, retryAfterMs) {
|
|
|
1722
1827
|
* failed. `message` is secret-scrubbed (a registry/proxy may echo an Authorization header into an error body). */
|
|
1723
1828
|
export class ControlError extends Error {
|
|
1724
1829
|
status;
|
|
1830
|
+
name = "ControlError";
|
|
1725
1831
|
constructor(status, message) {
|
|
1726
1832
|
super(message);
|
|
1727
1833
|
this.status = status;
|
|
1728
|
-
this.name = new.target.name;
|
|
1729
1834
|
}
|
|
1730
1835
|
}
|
|
1731
1836
|
/** 401 — missing/invalid registry Bearer (SEMA_REGISTRY_TOKEN). Fail-closed. */
|
|
1732
1837
|
export class ControlAuthError extends ControlError {
|
|
1838
|
+
name = "ControlAuthError";
|
|
1733
1839
|
}
|
|
1734
1840
|
/** 403 — authenticated but the token's role is below what the write needs (editor / publisher per domain).
|
|
1735
1841
|
* Client action: surface "needs a higher role"; do NOT retry with the same token. */
|
|
1736
1842
|
export class ControlForbiddenError extends ControlError {
|
|
1843
|
+
name = "ControlForbiddenError";
|
|
1737
1844
|
}
|
|
1738
1845
|
/** 404 — unknown domain / unknown change id / unknown worker. */
|
|
1739
1846
|
export class ControlNotFoundError extends ControlError {
|
|
1847
|
+
name = "ControlNotFoundError";
|
|
1740
1848
|
}
|
|
1741
1849
|
/** 400 — zod validation failed. `issues` carries the flat `{ path, message }[]` (batch prefixes path with
|
|
1742
1850
|
* `[changeIndex, domain, …]`). Client action: fix the offending field; this is deterministic, do NOT retry. */
|
|
1743
1851
|
export class ControlValidationError extends ControlError {
|
|
1744
1852
|
issues;
|
|
1853
|
+
name = "ControlValidationError";
|
|
1745
1854
|
constructor(status, message, issues) {
|
|
1746
1855
|
super(status, message);
|
|
1747
1856
|
this.issues = issues;
|
|
@@ -1753,6 +1862,7 @@ export class ControlValidationError extends ControlError {
|
|
|
1753
1862
|
* K-17: every 409 EXCEPT the scope-gone one — that is {@link ControlScopeGoneError}, deliberately not this class. */
|
|
1754
1863
|
export class ControlConflictError extends ControlError {
|
|
1755
1864
|
currentVersion;
|
|
1865
|
+
name = "ControlConflictError";
|
|
1756
1866
|
constructor(status, message, currentVersion) {
|
|
1757
1867
|
super(status, message);
|
|
1758
1868
|
this.currentVersion = currentVersion;
|
|
@@ -1767,6 +1877,7 @@ export class ControlConflictError extends ControlError {
|
|
|
1767
1877
|
* reviewed. Client action: stop, keep the intent, have a person confirm the scope is still the one to write. Still a
|
|
1768
1878
|
* {@link ControlError} (`status` 409, scrubbed `message`), so a family-wide catch keeps matching. */
|
|
1769
1879
|
export class ControlScopeGoneError extends ControlError {
|
|
1880
|
+
name = "ControlScopeGoneError";
|
|
1770
1881
|
}
|
|
1771
1882
|
/** Map a control-plane HTTP status + parsed body to the right typed error. Body envelope is `{ error, issues?,
|
|
1772
1883
|
* message?, currentVersion?, errorCode? }`. 🔴 message is scrubbed (Bearer / presigned) before surfacing.
|