@sema-agent/client-core 0.74.0 → 0.74.2
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 +31 -0
- package/README.md +3 -1
- package/dist/approvalsStreamLiveCapability.js +23 -12
- package/dist/deviceExecutorManagementCapability.d.ts +53 -0
- package/dist/deviceExecutorManagementCapability.js +117 -0
- package/dist/engineCapsGenerationGuard.d.ts +6 -0
- package/dist/engineCapsGenerationGuard.js +30 -0
- package/dist/executionLaneCapability.js +23 -12
- package/dist/hitl/frameRouter.d.ts +6 -1
- package/dist/hitl/frameRouter.js +17 -1
- package/dist/hitl/parkResolver.js +10 -2
- package/dist/hitl/toolApprovalWire.d.ts +22 -0
- package/dist/hitl/toolApprovalWire.js +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/sqlEngineCapability.js +31 -17
- package/dist/webSearchBackendCapability.js +23 -12
- package/dist/writeProtectionCapability.js +31 -17
- package/docs/INTEGRATION-CLIENTS.md +89 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,37 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.74.2(2026-09-19)
|
|
53
|
+
|
|
54
|
+
> 主题:**`capabilities.deviceExecutor.management` 四态读口**(CC-69;server 7.88.0 点名本包)。**patch**:型面纯 additive(+6 函数,公面 1046 → 1052;测试钩 49 → 50;零 wire 新键;peer 不动)。
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **`src/deviceExecutorManagementCapability.ts`(CC-69;server ≥7.88.0,契约附录 B.1 `deviceExecutor` 行 + §14)**:「`/v1/devices/*` 的管理动词在不在」的四态读面,与 sql / writeProtection / webSearch.backend / executionLane / approvalsStreamLive 五只兄弟同构六导出 —— `projectDeviceExecutorManagementCapability` / `noteEngineCapsForDeviceExecutorManagement` / `observedDeviceExecutorManagement` / `forgetDeviceExecutorManagementReading` / `deviceExecutorManagementDoctorDetail` / `deviceManagementVerbsAvailable`(+ 测试钩)。sdk 9.7.1 对该位无型 ⇒ 按契约结构读,sdk 补型当拍对表。
|
|
59
|
+
- 🔴 读法:`management` **键缺席 ≠ false**(真字节:7.87.3 车道真开而无此键)⇒ `not_reported`(`why: 'management_absent'`);`deviceExecutor` 键整个不存在(更老 server)⇒ `not_reported`(`why: 'capability_absent'`,只有夹具、无真版本见证);`deviceExecutor: false`(键在、值为布尔 false)⇒ `lane_absent`;对象且 `management` 严格布尔 ⇒ `present`。判在场用 own-property,不用 `in` 判真值;畸形删格。
|
|
60
|
+
- 「管理动词能不能用」判据归包 `deviceManagementVerbsAvailable(reading)`:只有 present ∧ true 才 `'yes'`;present ∧ false 或 `lane_absent` ⇒ `'no'`(明确的否);其余 ⇒ `'unknown'`(端按 501 试探,不预判)。
|
|
61
|
+
- doctor 措辞单源六句;`not_reported` 两句都不暗示「没有管理面」。
|
|
62
|
+
- 门:新 `scripts/run-device-executor-management-capability-test.mjs`(含 test 三形真字节夹具);变异反证八 + 六枚逐格见红。
|
|
63
|
+
|
|
64
|
+
### Changed(记账)
|
|
65
|
+
|
|
66
|
+
- **代际号的取值规则成文**(0.74.0 起的行为,补一句书面承诺):`fleet-row.cycleSeq` / `end.cycleSeq` / 后台通知 `seq` **只认正整数**;坏形(0 / 负数 / 小数 / 非数 / null)与缺席一律按**缺席**处理 —— 键不出,不钳、不编。去重键内部的归一(缺席归一成首周期)只服务去重,不上屏。
|
|
67
|
+
|
|
68
|
+
### Fixed(六只能力位读器族扫)
|
|
69
|
+
|
|
70
|
+
- **抛 getter / Proxy 的 caps 回体不再让上一台引擎的读数留在格里**:六只能力位读器(sql / writeProtection / webSearch.backend / executionLane / approvalsStreamLive / deviceExecutor.management)的 tee 此前把整段投影包在一个只求不抛的 `catch` 里,回体上一只抛出的 getter 会让投影中途退出而**格不动** —— 上一次的 `present` / `lane_absent` 继续答现在(与「投影答 undefined 就删格」的契约相反)。现在投影抛出与投影答 `undefined` 同一处置:删格 ⇒ `unobserved`;陈旧代际的抛体仍不动格;并且投影**之后再核一次代际**(投影会执行回体上不可信的 getter,它可以在中途让这一格换代)—— 换代后无论返回还是抛出,都不动新代际的格;代际只在入口**快照一次**(`opts` 是调用方的对象,回体 getter 改它也绕不过末核),读 opts / 读代际抛出一律不动格、不逃出 tee。
|
|
71
|
+
- **校验与返回同一次读**(sql / writeProtection / deviceExecutor.management):此前对同一属性各读一次,变化的 getter 可以让校验读到合形、返回读到别的形,`present` 里带出非布尔 / 非串。现在读进局部量再校验再返回。
|
|
72
|
+
|
|
73
|
+
## 0.74.1(2026-09-19)
|
|
74
|
+
|
|
75
|
+
> 主题:**审批卡的无决断收口**(CC-67)+ **流内帧腿的结局回交**(CC-68)+ headless 处置成文。**patch**:型面纯 additive(+1 常量,公面 1045 → 1046;`ApprovalCardDecision` +1 联合成员;`ToolApprovalFrameOutcome` / `FsApprovalOutcome` 各 +1;`AskGateWireDeps` +1 可选回调;零 wire 新键;peer 不动)。
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
|
|
79
|
+
- **卡口结局 `{ kind: 'retracted' }`(CC-67)**:宿主把一张**已经没有决断口**的卡撤掉(换会话 / 换引擎 / 跟踪器报 gone)时用它。包见到它**一个字节都不发**:流内帧腿 respond 零次、悬挂 ask 的盲卡 / 全卡同路、durable-park 腿 decide 零次;结局 `decision: 'unresolved'` + `retracted: true`(`FsApprovalOutcome` 为 `kind: 'retracted'`),不计 decided,ask 在引擎上照旧挂着。此前撤卡三形(`aborted` / `failed` / `deny`)在决断链上都落 deny 并真 POST —— 撤一张卡等于替用户 POST 一次他没做过的拒绝,悬挂的子代 ask 会被误拒。🔴 `aborted` 语义**不动**(用户放弃 = 拒,照旧 deny 真 POST);新值不复用老词。常量单源 `RETRACTED_CARD_DECISION_KIND`;park 解析器对 durable 腿的撤卡按 fail-soft 收口并写明真因(run 照旧 parked,别处仍可决)。
|
|
80
|
+
- **`AskGateWireDeps.onToolApprovalOutcome?(frame, outcome)`(CC-68)**:路由把流内帧腿每次决断的结局交回宿主(恰一次;撤卡也回交),宿主据此直接判「这一发落没落定」,孤儿认领回收不必再靠间接判据。缺席零变化;回调抛错 / async reject 被吞。
|
|
81
|
+
- 门:新 `scripts/run-approval-card-retract-test.mjs`(16 格);变异反证六枚逐格见红。
|
|
82
|
+
|
|
52
83
|
## 0.74.0(2026-09-19)
|
|
53
84
|
|
|
54
85
|
> 主题:**peer sdk 地板抬到 `>=9.7.1`** + **审批卡 `readRootCandidate.covers: "exact"` 过境**(CC-64)+ **面板事件周期身份**(CC-66)+ **fleet 行离场读口**(CC-65)+ 三版缺口行更正。**minor**:peer 地板抬升是非 additive 变化(<9.7.1 的宿主装本版会收到 peer 警告);型面本身纯 additive(+1 函数,公面 1044 → 1045;`ReadRootCandidateView` / `EngineAgentPanelEvent` 两臂 / `FleetAgentRowLike` / `FleetLedgerHooks` / `BgTerminalFacts` 各加可选位;零 wire 新键)。
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
|
|
|
35
35
|
|
|
36
36
|
## Scope
|
|
37
37
|
|
|
38
|
-
**Version:** 0.74.
|
|
38
|
+
**Version:** 0.74.2
|
|
39
39
|
|
|
40
40
|
- **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
|
|
41
41
|
B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
|
|
@@ -313,6 +313,8 @@ public-surface guard checks that last one).
|
|
|
313
313
|
| `scripts/run-tool-disclosure-progress-projection-test.mjs` | The two wire arms sdk 9.6.0 adds — `tool_disclosure` (name-only tool census: open-set `policy`, `thresholdPercent` absent ≠ default, `deferred`/`activated` full snapshots) and `tool_progress` (one frame, two beats: Bash ticks carry an output tail with `totalLines`/`totalBytes` that come and go together; other tools carry only `elapsedSeconds`) — project to neutral internal arms plus chrome arms. Required keys missing ⇒ `malformed`; bad optional keys drop only themselves; the sub-flow three-key gate keeps child frames off the leader lane; both arms are `required: false` in the arm table with duties stated (the output tail is untrusted raw and must never be fed back to the model). |
|
|
314
314
|
| `scripts/run-mcp-panel-projection-test.mjs` | The `GET /v1/sessions/:id/mcp` panel reader (`projectMcpPanel`; server >=7.77.0 adds the optional `lastLegMcp` key) and the single wording mint for its "last leg" line. Absence of `lastLegMcp` is one literal sentence that never blames the engine version (a new session, a leg outside the retention window, a leg without a manifest and an older engine all look the same on the wire); a key that is present but unreadable is a different sentence plus a `lastLegMcpUnreadable: true` mark, never folded into absence. The `mcp[]` roster goes through the same reader as the live `wiring_manifest` third section, so a replayed roster and a live one have one shape. The two faces of the panel (`servers[]` and the last-leg roster) may legitimately differ, so the view carries no agreement flag and none of the five sentences mentions `servers`. Required keys are pinned to the SDK `openapi.yaml` component bytes **0.69.0:** `fetchMcpPanel` fetches the panel through the SDK client's own `sessions.mcp` call (same transport and auth as every other read) and projects it; transport failure, an unreadable body and an empty session id all come back as `undefined`, never as a fabricated empty panel 0.71.0 adds section K: `mcpEngineLegPresence(view)` — the engine-side MCP presence tri-state read only off the panel view (`unknown` when the view could not be read, never rendered as "no MCP configured") |
|
|
315
315
|
| `scripts/run-absence-fold-census-test.mjs` | A package-wide census of the "absence folded into a positive outcome" defect shape, so that fixing the six sites this release does not merely move the shape somewhere else. The defect is defined by position, not syntax: a fallback position (the unconditional tail return, the `default:` arm, the literal minted when there is nothing to pass on, the value returned from an error path) may only say `unknown` or stay absent, never a positive word. Detection walks the syntax tree of every source file, so comments, strings and multi-line spellings cannot hide or fake a hit, and covers five forms: the right arm of `??` / `||`, the else arm of a ternary, the first return of an explicit `default:`, a `catch` block or `.catch(() => …)` arrow returning a healthy value, and a function whose last statement returns a positive word after other returns. Every remaining hit must be registered with a written reason, an unregistered hit fails the gate naming the file and line, the registered count must equal the real count so a cleared site cannot leave a spare allowance behind, and the gate proves its own teeth behind a fence (a failed self-proof refuses to report any count): each form injected into an in-memory copy must add exactly one hit, two correct spellings are pinned as non-hits, and samples inside comments or strings do not count. It also pins the headline site: the fleet panel projection no longer mints an `end` with `isError: false` on absence |
|
|
316
|
+
| `scripts/run-device-executor-management-capability-test.mjs` | The engine's device-management self-description (`capabilities.deviceExecutor.management`, engine ≥7.88.0), read the same four-state way as its five sibling capability readers: an absent `management` key is reported as not reported (never folded into `false`; an older engine really ships the lane object without it), an absent `deviceExecutor` key is likewise not reported, `deviceExecutor: false` is the lane being absent, presence is judged by own-property not truthiness, the value must be a strict boolean, the tee never throws and drops stale generations, and the package owns the verdict on whether the `/v1/devices` management verbs are usable (`yes` only when present and true, `no` when present-false or lane-absent, otherwise `unknown`) |
|
|
317
|
+
| `scripts/run-approval-card-retract-test.mjs` | The approval card's **decision-free retraction** and the in-stream frame leg's **outcome hand-back**: a host that must withdraw a card that no longer has a decision channel (session switch, engine switch, a tracker reporting the ask gone) answers `{ kind: 'retracted' }` and the package sends nothing on any of the three legs (in-stream frame, suspended ask, durable park), reporting `decision: 'unresolved'` with a `retracted` flag; `aborted` / `failed` / `deny` keep their meaning (a real deny is still posted), and `onToolApprovalOutcome` hands every in-stream outcome back to the host exactly once, tolerating a throwing or rejecting callback |
|
|
316
318
|
| `scripts/run-panel-cycle-identity-test.mjs` | The **cycle identity** on agent-panel events and the fleet ledger's **departure read-out**: a background agent may be revived under the same id, so `fleet-row` and `end` events now carry the wire's own `cycleSeq` / `startedAt` when present (absent means the row has no notion of generations, never "generation one"), `isStaleEngineAgentPanelEnd` is the single rule for ignoring a late `end` from a previous cycle (only when both sides carry a comparable identity; absence never drops a real terminal), a changed `cycleSeq` is a new cycle for usage stickiness and buffer coalescing, the notification lane carries `cycleSeq` only when the wire really sent `seq`, and `task_remove` frames reach the host through `onTaskRemoved` with `removeReason` / `cycleSeq` verbatim, a stale previous-generation removal leaving the newer row in place |
|
|
317
319
|
| `scripts/run-workflow-size-warning-test.mjs` | The **workflow size warning** verdict shared by every host footer / panel: a three-state result (`warn` / `ok` / `unknown`) read off the optional fleet view keys, where an unknown size is never reported as a normal one (absent `totalCount` / `tokens` without positive over-cap evidence is `unknown`, naming the missing keys), positive evidence on either axis wins regardless of absent keys, the per-agent denominator uses the engine's started count only when it is not below done+failed (a smaller value is a stale reading), otherwise falls back to the done+failed lower bound only when both keys are present — and a lower-bound denominator only yields an upper bound of the projection, which can prove *within cap* (`ok`, flagged) but never *over cap* (`unknown`, with the upper bound exposed) — and the prior is used only when the engine itself reports zero started agents; cap precedence env > explicit guideline > default, prototype keys never act as a guideline, the env reader is pure and does not fall through to the second name on a bad first value; caps, guideline table, env names and the three copy variants are single-sourced |
|
|
318
320
|
| `scripts/run-approvals-stream-live-capability-test.mjs` | The engine's live-approval-push self-description (`capabilities.approvalsStreamLive`, engine ≥7.87.1), read the same four-state way as its four sibling capability readers: an absent key is reported as not reported (never folded into `false`), the value must be a strict boolean, and the one decision the feed consumer needs — whether it must keep pulling suspended asks itself — is answered by `livePendingNeedsReconcile`, which only says no when the engine explicitly says it pushes. |
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* ③ 「要不要对账」的判据归包:{@link livePendingNeedsReconcile} —— 只有 present 且 true 才 false;其余一律 true(少查一次 = 一只等人的 ask 迟迟不出现)。
|
|
14
14
|
*/
|
|
15
15
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
16
|
-
import {
|
|
16
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
17
17
|
/** caps 回体 → 本格读数;畸形一律 `undefined`(= 这一格不写 ⇒ 读口答 `unobserved`)。 */
|
|
18
18
|
export function projectApprovalsStreamLiveCapability(caps) {
|
|
19
19
|
if (caps === null || typeof caps !== 'object')
|
|
@@ -30,21 +30,32 @@ export function projectApprovalsStreamLiveCapability(caps) {
|
|
|
30
30
|
const readingByBase = new Map();
|
|
31
31
|
/** 宿主 caps probe 的读面 tee 落点(与四只兄弟并列)。绝不 throw;畸形 ⇒ 删格;`opts.generation` 关掉旧探测覆盖新读数的竞态。 */
|
|
32
32
|
export function noteEngineCapsForApprovalsStreamLive(baseUrl, caps, opts) {
|
|
33
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
34
|
+
return;
|
|
35
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
36
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
37
|
+
const gen = snapshotCapsGeneration(opts);
|
|
38
|
+
if (gen === null)
|
|
39
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
40
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
41
|
+
return;
|
|
42
|
+
let reading;
|
|
33
43
|
try {
|
|
34
|
-
|
|
35
|
-
return;
|
|
36
|
-
if (opts?.generation !== undefined && opts.generation !== engineCapsGeneration(baseUrl))
|
|
37
|
-
return;
|
|
38
|
-
const reading = projectApprovalsStreamLiveCapability(caps);
|
|
39
|
-
if (reading === undefined) {
|
|
40
|
-
readingByBase.delete(baseUrl);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
readingByBase.set(baseUrl, reading);
|
|
44
|
+
reading = projectApprovalsStreamLiveCapability(caps);
|
|
44
45
|
}
|
|
45
46
|
catch {
|
|
46
|
-
|
|
47
|
+
// 🔴 0.74.2 同形存量(CC-69 复审 R1 族扫):抛 getter / Proxy 的回体 = 畸形,与「投影答 undefined」同一处置 —— 删格,不许留着上一台的读数。
|
|
48
|
+
reading = undefined;
|
|
49
|
+
}
|
|
50
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
51
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
52
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
53
|
+
return;
|
|
54
|
+
if (reading === undefined) {
|
|
55
|
+
readingByBase.delete(baseUrl);
|
|
56
|
+
return;
|
|
47
57
|
}
|
|
58
|
+
readingByBase.set(baseUrl, reading);
|
|
48
59
|
}
|
|
49
60
|
/** 本进程观测到的读数;这一格空缺 ⇒ `{kind:'unobserved'}`。 */
|
|
50
61
|
export function observedApprovalsStreamLive(baseUrl = engineWireTarget()?.baseUrl) {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deviceExecutorManagementCapability — `GET /v1/capabilities.deviceExecutor.management`(server ≥7.88.0;契约附录 B.1
|
|
3
|
+
* `deviceExecutor` 行 + §14)的三端共用读面(0.74.2;与 sql / writeProtection / webSearch.backend / executionLane /
|
|
4
|
+
* approvalsStreamLive 五只兄弟同一套四态词汇)。sdk 对该位无型(9.7.1)⇒ 按契约结构读,sdk 补型当拍对表。
|
|
5
|
+
*
|
|
6
|
+
* ── 这一位答的是哪一个问题 ────────────────────────────────────────────────────────────────
|
|
7
|
+
* 「`/v1/devices/*` 的管理动词在这台 server 上在不在」(present-iff:与该族 501 判据逐字同源)。它挂在 `deviceExecutor`
|
|
8
|
+
* 对象里:`deviceExecutor === false` = 本部署**没有 device 车道**(管理面无从谈起,六动词一律 501 `capability.device_lane_required`);
|
|
9
|
+
* 对象在场但 `management` 键缺席 = 7.88.0 之前的 server,**判不出**,只能按 501 试探。
|
|
10
|
+
*
|
|
11
|
+
* ── 🔴 读法 ─────────────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* ① `management` **键缺席 ≠ false**(真字节:7.87.3 车道真开而无此键)⇒ `not_reported`;`deviceExecutor` 键整个不存在
|
|
13
|
+
* (更老 server)同样 `not_reported`(判别子 `why` 分开记,后者只有夹具、无真版本见证)。
|
|
14
|
+
* ② `deviceExecutor: false` 是**键在、值为布尔 false**(不是键被省掉)⇒ `lane_absent`;判在场用 `hasOwn`,不用 `in` 判真值。
|
|
15
|
+
* ③ `management` 严格布尔;`null` / 串 / 数 / 数组 / 对象 ⇒ 畸形(删格 ⇒ `unobserved`);`deviceExecutor` 非 false 非对象同畸形。
|
|
16
|
+
* ④ 「管理动词能不能用」的判据归包:{@link deviceManagementVerbsAvailable} —— 只有 present ∧ true 才 `'yes'`;
|
|
17
|
+
* present ∧ false 与 `lane_absent` ⇒ `'no'`(明确的否);其余 ⇒ `'unknown'`(别当 no,也别当 yes)。
|
|
18
|
+
*/
|
|
19
|
+
/** 四态读数。`unobserved` 由读口在这一格空缺时铸,不由投影铸。 */
|
|
20
|
+
export type DeviceExecutorManagementReading = {
|
|
21
|
+
kind: 'unobserved';
|
|
22
|
+
}
|
|
23
|
+
/** `why`:`capability_absent` = `deviceExecutor` 键整个不存在(更老 server);`management_absent` = 车道对象在场、位缺席(7.88.0 之前)。 */
|
|
24
|
+
| {
|
|
25
|
+
kind: 'not_reported';
|
|
26
|
+
why: 'capability_absent' | 'management_absent';
|
|
27
|
+
}
|
|
28
|
+
/** `deviceExecutor === false`:本部署没有 device 车道。 */
|
|
29
|
+
| {
|
|
30
|
+
kind: 'lane_absent';
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'present';
|
|
33
|
+
management: boolean;
|
|
34
|
+
};
|
|
35
|
+
/** caps 回体 → 本格读数;畸形一律 `undefined`(= 这一格不写 ⇒ 读口答 `unobserved`)。 */
|
|
36
|
+
export declare function projectDeviceExecutorManagementCapability(caps: unknown): DeviceExecutorManagementReading | undefined;
|
|
37
|
+
/** 宿主 caps probe 的读面 tee 落点(与五只兄弟并列)。绝不 throw;畸形 ⇒ 删格;`opts.generation` 关掉旧探测覆盖新读数的竞态。 */
|
|
38
|
+
export declare function noteEngineCapsForDeviceExecutorManagement(baseUrl: string, caps: unknown, opts?: {
|
|
39
|
+
generation?: number;
|
|
40
|
+
}): void;
|
|
41
|
+
/** 本进程观测到的读数;这一格空缺 ⇒ `{kind:'unobserved'}`。 */
|
|
42
|
+
export declare function observedDeviceExecutorManagement(baseUrl?: string | undefined): DeviceExecutorManagementReading;
|
|
43
|
+
/**
|
|
44
|
+
* 「`/v1/devices/*` 管理动词能不能用」的判据单源(三态):只有引擎明说在场(present ∧ true)才 `'yes'`;
|
|
45
|
+
* 明说不在(present ∧ false)或没有 device 车道 ⇒ `'no'`;老 server / 从没观测 ⇒ `'unknown'`(端按 501 试探,不预判)。
|
|
46
|
+
*/
|
|
47
|
+
export declare function deviceManagementVerbsAvailable(reading: DeviceExecutorManagementReading): 'yes' | 'no' | 'unknown';
|
|
48
|
+
/** doctor 那一行的 detail 串,唯一措辞真源。🔴 `not_reported` 句不许暗示「没有管理面」。 */
|
|
49
|
+
export declare function deviceExecutorManagementDoctorDetail(reading: DeviceExecutorManagementReading): string;
|
|
50
|
+
/** 换代失效口(引擎温切成功后调):清成未观测。空串 ⇒ no-op;绝不 throw。 */
|
|
51
|
+
export declare function forgetDeviceExecutorManagementReading(baseUrl: string | undefined): void;
|
|
52
|
+
/** 测试钩子。 */
|
|
53
|
+
export declare function __resetDeviceExecutorManagementReadingsForTests(): void;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deviceExecutorManagementCapability — `GET /v1/capabilities.deviceExecutor.management`(server ≥7.88.0;契约附录 B.1
|
|
3
|
+
* `deviceExecutor` 行 + §14)的三端共用读面(0.74.2;与 sql / writeProtection / webSearch.backend / executionLane /
|
|
4
|
+
* approvalsStreamLive 五只兄弟同一套四态词汇)。sdk 对该位无型(9.7.1)⇒ 按契约结构读,sdk 补型当拍对表。
|
|
5
|
+
*
|
|
6
|
+
* ── 这一位答的是哪一个问题 ────────────────────────────────────────────────────────────────
|
|
7
|
+
* 「`/v1/devices/*` 的管理动词在这台 server 上在不在」(present-iff:与该族 501 判据逐字同源)。它挂在 `deviceExecutor`
|
|
8
|
+
* 对象里:`deviceExecutor === false` = 本部署**没有 device 车道**(管理面无从谈起,六动词一律 501 `capability.device_lane_required`);
|
|
9
|
+
* 对象在场但 `management` 键缺席 = 7.88.0 之前的 server,**判不出**,只能按 501 试探。
|
|
10
|
+
*
|
|
11
|
+
* ── 🔴 读法 ─────────────────────────────────────────────────────────────────────────────────
|
|
12
|
+
* ① `management` **键缺席 ≠ false**(真字节:7.87.3 车道真开而无此键)⇒ `not_reported`;`deviceExecutor` 键整个不存在
|
|
13
|
+
* (更老 server)同样 `not_reported`(判别子 `why` 分开记,后者只有夹具、无真版本见证)。
|
|
14
|
+
* ② `deviceExecutor: false` 是**键在、值为布尔 false**(不是键被省掉)⇒ `lane_absent`;判在场用 `hasOwn`,不用 `in` 判真值。
|
|
15
|
+
* ③ `management` 严格布尔;`null` / 串 / 数 / 数组 / 对象 ⇒ 畸形(删格 ⇒ `unobserved`);`deviceExecutor` 非 false 非对象同畸形。
|
|
16
|
+
* ④ 「管理动词能不能用」的判据归包:{@link deviceManagementVerbsAvailable} —— 只有 present ∧ true 才 `'yes'`;
|
|
17
|
+
* present ∧ false 与 `lane_absent` ⇒ `'no'`(明确的否);其余 ⇒ `'unknown'`(别当 no,也别当 yes)。
|
|
18
|
+
*/
|
|
19
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
20
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
21
|
+
/** caps 回体 → 本格读数;畸形一律 `undefined`(= 这一格不写 ⇒ 读口答 `unobserved`)。 */
|
|
22
|
+
export function projectDeviceExecutorManagementCapability(caps) {
|
|
23
|
+
if (caps === null || typeof caps !== 'object')
|
|
24
|
+
return undefined;
|
|
25
|
+
const c = caps;
|
|
26
|
+
if (!Object.hasOwn(c, 'deviceExecutor') || c.deviceExecutor === undefined)
|
|
27
|
+
return { kind: 'not_reported', why: 'capability_absent' };
|
|
28
|
+
const d = c.deviceExecutor;
|
|
29
|
+
if (d === false)
|
|
30
|
+
return { kind: 'lane_absent' };
|
|
31
|
+
if (d === null || typeof d !== 'object' || Array.isArray(d))
|
|
32
|
+
return undefined;
|
|
33
|
+
const o = d;
|
|
34
|
+
if (!Object.hasOwn(o, 'management'))
|
|
35
|
+
return { kind: 'not_reported', why: 'management_absent' };
|
|
36
|
+
// 🔴 只读一次(异源对抗复审 R1):校验与返回若各读一次,变化的 getter 会让校验读到布尔、返回读到串。
|
|
37
|
+
const mgmt = o.management;
|
|
38
|
+
if (mgmt === undefined)
|
|
39
|
+
return { kind: 'not_reported', why: 'management_absent' };
|
|
40
|
+
if (typeof mgmt !== 'boolean')
|
|
41
|
+
return undefined;
|
|
42
|
+
return { kind: 'present', management: mgmt };
|
|
43
|
+
}
|
|
44
|
+
const readingByBase = new Map();
|
|
45
|
+
/** 宿主 caps probe 的读面 tee 落点(与五只兄弟并列)。绝不 throw;畸形 ⇒ 删格;`opts.generation` 关掉旧探测覆盖新读数的竞态。 */
|
|
46
|
+
export function noteEngineCapsForDeviceExecutorManagement(baseUrl, caps, opts) {
|
|
47
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
48
|
+
return;
|
|
49
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
50
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
51
|
+
const gen = snapshotCapsGeneration(opts);
|
|
52
|
+
if (gen === null)
|
|
53
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
54
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
55
|
+
return;
|
|
56
|
+
let reading;
|
|
57
|
+
try {
|
|
58
|
+
reading = projectDeviceExecutorManagementCapability(caps);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 🔴 抛 getter / Proxy 的回体 = 畸形(异源对抗复审 R1):与「投影答 undefined」同一处置 —— 删格,不许留着上一台的 yes / no。
|
|
62
|
+
reading = undefined;
|
|
63
|
+
}
|
|
64
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
65
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
66
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
67
|
+
return;
|
|
68
|
+
if (reading === undefined) {
|
|
69
|
+
readingByBase.delete(baseUrl);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
readingByBase.set(baseUrl, reading);
|
|
73
|
+
}
|
|
74
|
+
/** 本进程观测到的读数;这一格空缺 ⇒ `{kind:'unobserved'}`。 */
|
|
75
|
+
export function observedDeviceExecutorManagement(baseUrl = engineWireTarget()?.baseUrl) {
|
|
76
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
77
|
+
return { kind: 'unobserved' };
|
|
78
|
+
return readingByBase.get(baseUrl) ?? { kind: 'unobserved' };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 「`/v1/devices/*` 管理动词能不能用」的判据单源(三态):只有引擎明说在场(present ∧ true)才 `'yes'`;
|
|
82
|
+
* 明说不在(present ∧ false)或没有 device 车道 ⇒ `'no'`;老 server / 从没观测 ⇒ `'unknown'`(端按 501 试探,不预判)。
|
|
83
|
+
*/
|
|
84
|
+
export function deviceManagementVerbsAvailable(reading) {
|
|
85
|
+
if (reading.kind === 'present')
|
|
86
|
+
return reading.management ? 'yes' : 'no';
|
|
87
|
+
if (reading.kind === 'lane_absent')
|
|
88
|
+
return 'no';
|
|
89
|
+
return 'unknown';
|
|
90
|
+
}
|
|
91
|
+
/** doctor 那一行的 detail 串,唯一措辞真源。🔴 `not_reported` 句不许暗示「没有管理面」。 */
|
|
92
|
+
export function deviceExecutorManagementDoctorDetail(reading) {
|
|
93
|
+
switch (reading.kind) {
|
|
94
|
+
case 'unobserved':
|
|
95
|
+
return 'device management face not observed — the engine reports it on /v1/capabilities (deviceExecutor.management); this process has not received a capabilities response yet';
|
|
96
|
+
case 'not_reported':
|
|
97
|
+
return reading.why === 'management_absent'
|
|
98
|
+
? 'device management face not reported by this engine — the device lane is advertised but only newer engines say whether the /v1/devices management verbs exist; this does not say whether they exist, probe them directly'
|
|
99
|
+
: 'device executor capability not reported by this engine — only newer engines advertise the device lane at all; this does not say whether it exists';
|
|
100
|
+
case 'lane_absent':
|
|
101
|
+
return 'no device lane on this deployment — the /v1/devices management verbs are unavailable (capability.device_lane_required)';
|
|
102
|
+
case 'present':
|
|
103
|
+
return reading.management
|
|
104
|
+
? 'device management face on — the /v1/devices management verbs are available on this engine'
|
|
105
|
+
: 'device lane on but the /v1/devices management verbs are off on this deployment';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** 换代失效口(引擎温切成功后调):清成未观测。空串 ⇒ no-op;绝不 throw。 */
|
|
109
|
+
export function forgetDeviceExecutorManagementReading(baseUrl) {
|
|
110
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
111
|
+
return;
|
|
112
|
+
readingByBase.delete(baseUrl);
|
|
113
|
+
}
|
|
114
|
+
/** 测试钩子。 */
|
|
115
|
+
export function __resetDeviceExecutorManagementReadingsForTests() {
|
|
116
|
+
readingByBase.clear();
|
|
117
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 调用方 `opts.generation` 的一次性快照;`null` = 读不出(供给坏了)。 */
|
|
2
|
+
export declare function snapshotCapsGeneration(opts: {
|
|
3
|
+
generation?: number;
|
|
4
|
+
} | undefined): number | undefined | null;
|
|
5
|
+
/** 入口快照的代际是否仍是当代;`gen` 缺席 = 调用方没供代际 = 恒当代;读代际抛出 = 不是。 */
|
|
6
|
+
export declare function capsGenerationStillCurrent(baseUrl: string, gen: number | undefined): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engineCapsGenerationGuard — 六只能力位读器 tee 共用的**代际两问**(0.74.2;不出公面,只供包内 import)。
|
|
3
|
+
*
|
|
4
|
+
* · {@link snapshotCapsGeneration}:从调用方 `opts` 上**一次性**读代际。`opts` 是调用方的对象,回体上的 getter 能在投影中途改它、
|
|
5
|
+
* 也能让这一次读抛出 ⇒ 读不出答 `null`(tee 按「不动格」处置),别把调用方对象再读第二次。
|
|
6
|
+
* · {@link capsGenerationStillCurrent}:入口快照的代际现在还是不是当代。读代际抛出 ⇒ `false`(不动格,与陈旧代际同一处置)。
|
|
7
|
+
*
|
|
8
|
+
* 两只都**带值返回**而不是吞掉:tee 里因此没有一处「只求不抛」的空 catch(failloud 门 §C1)。
|
|
9
|
+
*/
|
|
10
|
+
import { engineCapsGeneration } from './engineCapsCache.js';
|
|
11
|
+
/** 调用方 `opts.generation` 的一次性快照;`null` = 读不出(供给坏了)。 */
|
|
12
|
+
export function snapshotCapsGeneration(opts) {
|
|
13
|
+
try {
|
|
14
|
+
return opts?.generation;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** 入口快照的代际是否仍是当代;`gen` 缺席 = 调用方没供代际 = 恒当代;读代际抛出 = 不是。 */
|
|
21
|
+
export function capsGenerationStillCurrent(baseUrl, gen) {
|
|
22
|
+
if (gen === undefined)
|
|
23
|
+
return true;
|
|
24
|
+
try {
|
|
25
|
+
return gen === engineCapsGeneration(baseUrl);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
27
27
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
28
|
-
import {
|
|
28
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
29
29
|
/**
|
|
30
30
|
* caps 回体 → 本格读数;**畸形一律 `undefined`**(= 这一格不写 ⇒ 读口答 `unobserved`)。
|
|
31
31
|
* 键不在 / `undefined` ⇒ `not_reported`(老 server);`null` / 数组 / 非对象 / 缺任一座 / 座坏形 ⇒ 畸形。
|
|
@@ -54,21 +54,32 @@ const readingByBase = new Map();
|
|
|
54
54
|
* 投影 `undefined`(畸形)⇒ 这一格**被删**而不是留着上一台引擎的旧值;`opts.generation` 关掉「旧探测覆盖新读数」竞态。
|
|
55
55
|
*/
|
|
56
56
|
export function noteEngineCapsForExecutionLane(baseUrl, caps, opts) {
|
|
57
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
58
|
+
return;
|
|
59
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
60
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
61
|
+
const gen = snapshotCapsGeneration(opts);
|
|
62
|
+
if (gen === null)
|
|
63
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
64
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
65
|
+
return;
|
|
66
|
+
let reading;
|
|
57
67
|
try {
|
|
58
|
-
|
|
59
|
-
return;
|
|
60
|
-
if (opts?.generation !== undefined && opts.generation !== engineCapsGeneration(baseUrl))
|
|
61
|
-
return;
|
|
62
|
-
const reading = projectExecutionLaneCapability(caps);
|
|
63
|
-
if (reading === undefined) {
|
|
64
|
-
readingByBase.delete(baseUrl);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
readingByBase.set(baseUrl, reading);
|
|
68
|
+
reading = projectExecutionLaneCapability(caps);
|
|
68
69
|
}
|
|
69
70
|
catch {
|
|
70
|
-
|
|
71
|
+
// 🔴 0.74.2 同形存量(CC-69 复审 R1 族扫):抛 getter / Proxy 的回体 = 畸形,与「投影答 undefined」同一处置 —— 删格,不许留着上一台的读数。
|
|
72
|
+
reading = undefined;
|
|
73
|
+
}
|
|
74
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
75
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
76
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
77
|
+
return;
|
|
78
|
+
if (reading === undefined) {
|
|
79
|
+
readingByBase.delete(baseUrl);
|
|
80
|
+
return;
|
|
71
81
|
}
|
|
82
|
+
readingByBase.set(baseUrl, reading);
|
|
72
83
|
}
|
|
73
84
|
/** 本进程观测到的执行车道;这一格空缺 ⇒ `{kind:'unobserved'}`(**绝不**编一条车道)。 */
|
|
74
85
|
export function observedExecutionLane(baseUrl = engineWireTarget()?.baseUrl) {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import type { AgentEvent } from '@sema-agent/sdk';
|
|
18
18
|
import type { HitlClientLike } from './hitlBridge.js';
|
|
19
|
-
import { type RespondToolApprovalFn, type ToolApprovalFrameLaneOpts } from './toolApprovalWire.js';
|
|
19
|
+
import { type RespondToolApprovalFn, type ToolApprovalFrame, type ToolApprovalFrameLaneOpts, type ToolApprovalFrameOutcome } from './toolApprovalWire.js';
|
|
20
20
|
import type { GateLedger } from './gateLedger.js';
|
|
21
21
|
/**
|
|
22
22
|
* CC `utils/messages.ts` 的 `REJECT_MESSAGE` **逐字**(B7 搬迁差分 2)。deny 后重放 tool_end 的
|
|
@@ -96,6 +96,11 @@ export interface AskGateWireDeps {
|
|
|
96
96
|
* 按下的「不再询问」会被整条丢弃(决断照送 + 一条 `surfaceRuleArmNotSent` 通知)—— 逐位语义见
|
|
97
97
|
* 各自的 JSDoc 与 `docs/INTEGRATION-CLIENTS.md` §5b。 */
|
|
98
98
|
approvalLane?: ToolApprovalFrameLaneOpts;
|
|
99
|
+
/**
|
|
100
|
+
* 0.74.1(CC-68)—— 流内帧腿的**结局回交**:每次 `tool_approval` 帧经卡口决断后调一次(帧 + {@link ToolApprovalFrameOutcome}),
|
|
101
|
+
* 宿主据此直接判「这一发落没落定」(孤儿认领回收不必再靠间接判据)。缺席零变化;抛错 / reject 被吞。
|
|
102
|
+
*/
|
|
103
|
+
onToolApprovalOutcome?: (frame: ToolApprovalFrame, outcome: ToolApprovalFrameOutcome) => void | Promise<void>;
|
|
99
104
|
}
|
|
100
105
|
/** 两族 gate:AskUserQuestion 走问答 overlay(原路);其余(fs 写三件 / Bash / 一等
|
|
101
106
|
* `kind==='tool_approval'`)走 CC 三选卡。 */
|
package/dist/hitl/frameRouter.js
CHANGED
|
@@ -543,7 +543,23 @@ async function routeToolApprovalFrame(ev, ctx) {
|
|
|
543
543
|
const gatedCallId = !fromSubagent ? led.lastPendingFsCall() : undefined;
|
|
544
544
|
// FIX①(2026-08-07):产物是 `{decision, ack?}` —— ack 上的 `rememberApplied`/`updatedInputForwarded`
|
|
545
545
|
// 由 toolApprovalWire 就地收敛成宿主通知(本路由只认决断词,不重复解释 ack)。
|
|
546
|
-
const
|
|
546
|
+
const outcome = await surfaceToolApprovalFrameAndRespond(ev, deps.respondToolApproval, argsOfGatedStart(led, gatedCallId), ctx.signal, deps.approvalLane);
|
|
547
|
+
const { decision } = outcome;
|
|
548
|
+
// 0.74.1(CC-68):结局交回宿主(fail-soft:宿主的回调 bug 不许拆流)。
|
|
549
|
+
if (deps.onToolApprovalOutcome !== undefined) {
|
|
550
|
+
try {
|
|
551
|
+
const out = deps.onToolApprovalOutcome(ev, outcome);
|
|
552
|
+
if (out && typeof out.then === 'function') {
|
|
553
|
+
void Promise.resolve(out).catch((e) => {
|
|
554
|
+
hostLog('debug', `liveHitlAskWire: onToolApprovalOutcome rejected: ${String(e).slice(0, 160)}`);
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
catch (e) {
|
|
559
|
+
// 宿主回调的异常不许拆帧路由;留痕走 hostLog。
|
|
560
|
+
hostLog('debug', `liveHitlAskWire: onToolApprovalOutcome threw: ${String(e).slice(0, 160)}`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
547
563
|
if (decision === 'deny' && !fromSubagent) {
|
|
548
564
|
// 该 call 的报错收口帧 stamp REJECT 文案(vendored `User rejected <op> to <path>` 卡)。
|
|
549
565
|
if (gatedCallId !== undefined)
|
|
@@ -424,7 +424,7 @@ export async function resolvePark(park, ctx) {
|
|
|
424
424
|
else {
|
|
425
425
|
const closing = await surfaceParkGate(park, ctx, park.gatedCallId, witness);
|
|
426
426
|
outcome =
|
|
427
|
-
closing.kind === 'decided' || closing.kind === 'aborted'
|
|
427
|
+
closing.kind === 'decided' || closing.kind === 'aborted' || closing.kind === 'retracted'
|
|
428
428
|
? closing
|
|
429
429
|
: { kind: 'failed', stage: 'orchestration', reason: `${stalledReason}; closing re-read: ${closing.reason}` };
|
|
430
430
|
}
|
|
@@ -490,6 +490,7 @@ export async function resolvePark(park, ctx) {
|
|
|
490
490
|
if (rescan !== undefined &&
|
|
491
491
|
(rescan.kind === 'decided' ||
|
|
492
492
|
rescan.kind === 'aborted' ||
|
|
493
|
+
rescan.kind === 'retracted' || // 0.74.1(CC-67):宿主撤卡也是「人那一侧有了处置」,采信,不再重探
|
|
493
494
|
(rescan.kind === 'failed' && rescan.retryExhausted === true))) {
|
|
494
495
|
// L-80:**不在这里**复位同因计数 —— 复位只在驱动侧观察到 host 进展帧时发生(#357 的闸曾被这一行
|
|
495
496
|
// 每轮绕空:坐标失配序下每轮都「找到新行→决成功→引擎原样重放」,计数永远回不到 2)。
|
|
@@ -557,7 +558,14 @@ export async function resolvePark(park, ctx) {
|
|
|
557
558
|
}
|
|
558
559
|
if (outcome.kind !== 'decided') {
|
|
559
560
|
hostLog('debug', `liveHitlAskWire: gate not decided (${outcome.kind}${'reason' in outcome ? `: ${outcome.reason}` : ''}) — fail-soft to suspended terminal`);
|
|
560
|
-
|
|
561
|
+
// 0.74.1(CC-67):宿主撤卡(无决断收口)⇒ 零 decide,run 照旧 parked;这一轮按 fail-soft 收口并把真因写进去
|
|
562
|
+
// (不是用户中断、不是 decide 失败 —— 是这张卡在这个宿主上已经没有决断口了)。
|
|
563
|
+
const failedReason = outcome.kind === 'failed'
|
|
564
|
+
? outcome.reason
|
|
565
|
+
: outcome.kind === 'retracted'
|
|
566
|
+
? 'the approval card was retracted by the host without a decision (nothing was sent; the run stays parked and remains decidable elsewhere)'
|
|
567
|
+
: undefined;
|
|
568
|
+
return { kind: 'failsoft', events: failsoftEvents(park, ctx, outcome.kind === 'aborted', failedReason) };
|
|
561
569
|
}
|
|
562
570
|
// decide 成功:丢弃该 call 的毒化 HOLD(续流重放会带 isError:false 的解答帧收口卡片),
|
|
563
571
|
// 并记下真实答案供该解答帧 stamp `structured`(否则卡片渲成结果不可用)。
|
|
@@ -118,6 +118,11 @@ export type FsApprovalOutcome =
|
|
|
118
118
|
kind: 'aborted';
|
|
119
119
|
gatedCallId?: string | undefined;
|
|
120
120
|
}
|
|
121
|
+
/** 0.74.1(CC-67):宿主撤卡,零 decide;见 {@link ApprovalCardDecision} 的 retracted 臂。 */
|
|
122
|
+
| {
|
|
123
|
+
kind: 'retracted';
|
|
124
|
+
gatedCallId?: string | undefined;
|
|
125
|
+
}
|
|
121
126
|
/** `retryExhausted`(Inkglow-1085 P0a,0.37.0):decide 出站在**瞬断类**失败上重试一次仍未送达
|
|
122
127
|
* (两发都没拿到引擎的语义答复)—— 在场即真。消费方(parkResolver)据此走**重呈臂**(re-attach
|
|
123
128
|
* 重放 park ⇒ 同一张卡重新交给用户),不合成 `hitl_unanswered` 判死 turn。缺席 = 语义类失败
|
|
@@ -445,7 +450,19 @@ export type ApprovalCardDecision = ApprovalCardAllowDecision | ApprovalCardDenyD
|
|
|
445
450
|
} | {
|
|
446
451
|
kind: 'failed';
|
|
447
452
|
reason: string;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* 0.74.1(CC-67)—— **无决断收口**:宿主把一张**已经没有决断口**的卡撤掉(换会话 / 换引擎 / 跟踪器报 gone),
|
|
456
|
+
* 包见到它**一个字节都不发**(流内帧腿不 respond、durable-park 腿不 decide),不计 decided。
|
|
457
|
+
* 🔴 不复用 `aborted`:那是「用户放弃 = 拒」(照旧 deny 真 POST);撤卡 = 替用户 POST 一次他没做过的拒绝,
|
|
458
|
+
* 悬挂的子代 ask 会被误拒。`reason` 只留痕,不上 wire。
|
|
459
|
+
*/
|
|
460
|
+
| {
|
|
461
|
+
kind: typeof RETRACTED_CARD_DECISION_KIND;
|
|
462
|
+
reason?: string;
|
|
448
463
|
};
|
|
464
|
+
/** 卡口「无决断收口」结局值(单源;见 {@link ApprovalCardDecision})。 */
|
|
465
|
+
export declare const RETRACTED_CARD_DECISION_KIND: "retracted";
|
|
449
466
|
/** 卡口的入参 —— cli `surfaceApprovalCard` 的 `req` 逐字。 */
|
|
450
467
|
export interface ApprovalCardRequest {
|
|
451
468
|
toolName: string;
|
|
@@ -1300,6 +1317,11 @@ export interface ToolApprovalFrameOutcome {
|
|
|
1300
1317
|
* 这只 ask 在引擎上仍然挂着。端应重新出卡(跟踪器 `requeue`)。缺席 = 没发生这件事。
|
|
1301
1318
|
*/
|
|
1302
1319
|
editRefused?: true;
|
|
1320
|
+
/**
|
|
1321
|
+
* 0.74.1(CC-67):宿主用 `{ kind: 'retracted' }` 撤了这张卡 ⇒ 包侧**一个字节都没发**,`decision` 为 `'unresolved'`,
|
|
1322
|
+
* 这只 ask 在引擎上仍然挂着。与 `editRefused` 同款:附加诊断位,不是新的决断态;缺席 = 没发生这件事。
|
|
1323
|
+
*/
|
|
1324
|
+
retracted?: true;
|
|
1303
1325
|
}
|
|
1304
1326
|
/**
|
|
1305
1327
|
* #225 件5:respond 抛错的**结构化原文**(不是新的决断态,见
|
|
@@ -178,6 +178,8 @@ export { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED
|
|
|
178
178
|
* 透传纪律逐字同规)。再导出是给端的 `switch` 一份可数的表 —— 端仍必须带 `default` 臂。
|
|
179
179
|
*/
|
|
180
180
|
export { RULE_OFFERS_ABSENCE_REASONS, DENIAL_LIMIT_KINDS };
|
|
181
|
+
/** 卡口「无决断收口」结局值(单源;见 {@link ApprovalCardDecision})。 */
|
|
182
|
+
export const RETRACTED_CARD_DECISION_KIND = 'retracted';
|
|
181
183
|
// W1(design/161):sessionKey → 注册表;零参 API = DEFAULT_SESSION_KEY 兼容层(cli 装配不动)。
|
|
182
184
|
const cardPortByKey = createSessionSlot();
|
|
183
185
|
const cardPortMissesByKey = new Map();
|
|
@@ -419,6 +421,10 @@ parkGatedCallId) {
|
|
|
419
421
|
switch (card.kind) {
|
|
420
422
|
case 'failed':
|
|
421
423
|
return { kind: 'failed', stage: 'card', gatedCallId, reason: card.reason };
|
|
424
|
+
case 'retracted':
|
|
425
|
+
// 0.74.1(CC-67):撤卡不是决断 —— 零 decide,引擎那头的 ask 照旧挂着(由它的 TTL / 别的决断口结算)。
|
|
426
|
+
hostLog('debug', `liveHitlAskWire: approval card retracted without a decision for ${gatedCallId ?? '(no call)'} — nothing sent`);
|
|
427
|
+
return { kind: 'retracted', gatedCallId };
|
|
422
428
|
case 'aborted':
|
|
423
429
|
// turn 被中断(Esc/Ctrl+C):把挂着的 ask 用一次 **TOOL 级 deny** 结算掉(server
|
|
424
430
|
// `ASSISTANT-WIRE-CONTRACT.md` §4a;0.42.0 撤稿 —— 原文写的是「cancel-by-deny(contract/04
|
|
@@ -1487,6 +1493,12 @@ export async function surfaceToolApprovalFrameAndRespond(frame, respond, streamA
|
|
|
1487
1493
|
surfaceEditRefusedOnBlindAsk();
|
|
1488
1494
|
return { decision: 'unresolved', editRefused: true };
|
|
1489
1495
|
}
|
|
1496
|
+
// 0.74.1(CC-67):宿主撤卡(无决断收口)⇒ **什么都不发**。这张卡已经没有决断口(换会话 / 换引擎 / 跟踪器报 gone),
|
|
1497
|
+
// 替用户 POST 一次 deny 会把悬挂的子代 ask 误拒。结局如实标 `retracted`,ask 在引擎上照旧挂着。
|
|
1498
|
+
if (card.kind === RETRACTED_CARD_DECISION_KIND) {
|
|
1499
|
+
hostLog('debug', `liveToolApprovalWire: ${frame.approvalId} card retracted without a decision${card.reason ? ` (${card.reason})` : ''} — nothing sent`);
|
|
1500
|
+
return { decision: 'unresolved', retracted: true };
|
|
1501
|
+
}
|
|
1490
1502
|
const decision = card.kind === 'allow' ? (card.allowSession ? 'allow_session' : 'allow') : 'deny';
|
|
1491
1503
|
if (card.kind === 'failed') {
|
|
1492
1504
|
hostLog('debug', `liveToolApprovalWire: approval card unavailable (${card.reason}) — fail-closed deny for ${frame.approvalId}`);
|
package/dist/index.d.ts
CHANGED
|
@@ -157,6 +157,7 @@ export * from './writeProtectionCapability.js';
|
|
|
157
157
|
export * from './webSearchBackendCapability.js';
|
|
158
158
|
export * from './executionLaneCapability.js';
|
|
159
159
|
export * from './approvalsStreamLiveCapability.js';
|
|
160
|
+
export * from './deviceExecutorManagementCapability.js';
|
|
160
161
|
export * from './mcpReconnect.js';
|
|
161
162
|
export * from './leaderConflict.js';
|
|
162
163
|
export * from './runTerminal.js';
|
package/dist/index.js
CHANGED
|
@@ -192,6 +192,8 @@ export * from './webSearchBackendCapability.js';
|
|
|
192
192
|
export * from './executionLaneCapability.js';
|
|
193
193
|
// · approvalsStreamLiveCapability(0.73.3 CC-61):capabilities.approvalsStreamLive 四态读面 + feed 消费方「要不要靠对账拉」的判据单源。
|
|
194
194
|
export * from './approvalsStreamLiveCapability.js';
|
|
195
|
+
// · deviceExecutorManagementCapability(0.74.2 CC-69):capabilities.deviceExecutor.management 四态读面 + 管理动词可用性判据单源。
|
|
196
|
+
export * from './deviceExecutorManagementCapability.js';
|
|
195
197
|
// S-381 / core 7.22.0 #857(0.72.9 CC-30;server ≥7.85.0,sdk 尚未声明):会话内 MCP re-dial 的消费口 —— 200 三态按 outcome 分形读、
|
|
196
198
|
// unsupported 恒五键、名册按 toolNames 在场性、失败按 errorCode 分诊、「重连 = 一次交易」措辞单源;能力位 mcpReconnect 三态读。
|
|
197
199
|
export * from './mcpReconnect.js';
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*/
|
|
44
44
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
45
45
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
46
|
-
import {
|
|
46
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
47
47
|
/**
|
|
48
48
|
* caps 回体 → 本格读数;**畸形一律 `undefined`**(= 这一格不写 ⇒ 读口答 `unobserved`)。
|
|
49
49
|
*
|
|
@@ -66,15 +66,19 @@ export function projectSqlEngineCapability(caps) {
|
|
|
66
66
|
if (typeof sql !== 'object')
|
|
67
67
|
return undefined;
|
|
68
68
|
const s = sql;
|
|
69
|
-
|
|
69
|
+
// 🔴 只读一次(0.74.2 CC-69 复审 R1 族扫):校验与返回各读一次,变化的 getter 会让校验读到合形、返回读到别的。
|
|
70
|
+
const engine = s.engine;
|
|
71
|
+
const isolation = s.isolation;
|
|
72
|
+
const txnMode = s.txnMode;
|
|
73
|
+
if (typeof engine !== 'string' || engine === '')
|
|
70
74
|
return undefined;
|
|
71
|
-
if (typeof
|
|
75
|
+
if (typeof isolation !== 'string' || isolation === '')
|
|
72
76
|
return undefined;
|
|
73
77
|
// 🔴 `txnMode`:`null` 是**铸点域内的合法值**(见 SqlEngineCapabilityView 顶注),不是畸形。
|
|
74
78
|
// 但这一位在铸点上**恒在场** ⇒ 键缺席(`undefined`)与非串非 null 仍判载体坏了。
|
|
75
|
-
if (
|
|
79
|
+
if (txnMode !== null && (typeof txnMode !== 'string' || txnMode === ''))
|
|
76
80
|
return undefined;
|
|
77
|
-
return { kind: 'present', view: { engine
|
|
81
|
+
return { kind: 'present', view: { engine, isolation, txnMode } };
|
|
78
82
|
}
|
|
79
83
|
const readingByBase = new Map();
|
|
80
84
|
/**
|
|
@@ -99,22 +103,32 @@ const readingByBase = new Map();
|
|
|
99
103
|
* 有任何东西变坏。🔴 **tee 自己抓号是假判据**(陈旧那一发在这里读到的是新代号,永远像当代的)。
|
|
100
104
|
*/
|
|
101
105
|
export function noteEngineCapsForSqlEngine(baseUrl, caps, opts) {
|
|
106
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
107
|
+
return;
|
|
108
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
109
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
110
|
+
const gen = snapshotCapsGeneration(opts);
|
|
111
|
+
if (gen === null)
|
|
112
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
113
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
114
|
+
return;
|
|
115
|
+
let reading;
|
|
102
116
|
try {
|
|
103
|
-
|
|
104
|
-
return;
|
|
105
|
-
// 陈旧代际的那一发整只丢掉(见本函数顶注的 `opts.generation` 段);不传 ⇒ 照写,零行为变化。
|
|
106
|
-
if (opts?.generation !== undefined && opts.generation !== engineCapsGeneration(baseUrl))
|
|
107
|
-
return;
|
|
108
|
-
const reading = projectSqlEngineCapability(caps);
|
|
109
|
-
if (reading === undefined) {
|
|
110
|
-
readingByBase.delete(baseUrl);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
readingByBase.set(baseUrl, reading);
|
|
117
|
+
reading = projectSqlEngineCapability(caps);
|
|
114
118
|
}
|
|
115
119
|
catch {
|
|
116
|
-
|
|
120
|
+
// 🔴 0.74.2 同形存量(CC-69 复审 R1 族扫):抛 getter / Proxy 的回体 = 畸形,与「投影答 undefined」同一处置 —— 删格,不许留着上一台的读数。
|
|
121
|
+
reading = undefined;
|
|
122
|
+
}
|
|
123
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
124
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
125
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
126
|
+
return;
|
|
127
|
+
if (reading === undefined) {
|
|
128
|
+
readingByBase.delete(baseUrl);
|
|
129
|
+
return;
|
|
117
130
|
}
|
|
131
|
+
readingByBase.set(baseUrl, reading);
|
|
118
132
|
}
|
|
119
133
|
/**
|
|
120
134
|
* 本进程观测到的 SQL 姿态;这一格空缺 ⇒ `{kind:'unobserved'}`(**绝不**折成 `none`)。
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
*/
|
|
39
39
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
40
40
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
41
|
-
import {
|
|
41
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
42
42
|
/** `backend: "none"` —— 唯一带独立语义的词(见文件头);其余词按开集读。 */
|
|
43
43
|
export const WEB_SEARCH_BACKEND_NONE = 'none';
|
|
44
44
|
/**
|
|
@@ -77,21 +77,32 @@ const readingByBase = new Map();
|
|
|
77
77
|
* 那一刻 `engineCapsGeneration(baseUrl)` 抓号、在这里原样交回,陈旧那一发整只丢掉;不传 ⇒ 照写。
|
|
78
78
|
*/
|
|
79
79
|
export function noteEngineCapsForWebSearchBackend(baseUrl, caps, opts) {
|
|
80
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
81
|
+
return;
|
|
82
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
83
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
84
|
+
const gen = snapshotCapsGeneration(opts);
|
|
85
|
+
if (gen === null)
|
|
86
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
87
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
88
|
+
return;
|
|
89
|
+
let reading;
|
|
80
90
|
try {
|
|
81
|
-
|
|
82
|
-
return;
|
|
83
|
-
if (opts?.generation !== undefined && opts.generation !== engineCapsGeneration(baseUrl))
|
|
84
|
-
return;
|
|
85
|
-
const reading = projectWebSearchBackendCapability(caps);
|
|
86
|
-
if (reading === undefined) {
|
|
87
|
-
readingByBase.delete(baseUrl);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
readingByBase.set(baseUrl, reading);
|
|
91
|
+
reading = projectWebSearchBackendCapability(caps);
|
|
91
92
|
}
|
|
92
93
|
catch {
|
|
93
|
-
|
|
94
|
+
// 🔴 0.74.2 同形存量(CC-69 复审 R1 族扫):抛 getter / Proxy 的回体 = 畸形,与「投影答 undefined」同一处置 —— 删格,不许留着上一台的读数。
|
|
95
|
+
reading = undefined;
|
|
96
|
+
}
|
|
97
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
98
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
99
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
100
|
+
return;
|
|
101
|
+
if (reading === undefined) {
|
|
102
|
+
readingByBase.delete(baseUrl);
|
|
103
|
+
return;
|
|
94
104
|
}
|
|
105
|
+
readingByBase.set(baseUrl, reading);
|
|
95
106
|
}
|
|
96
107
|
/** 本进程观测到的部署默认后端;这一格空缺 ⇒ `{kind:'unobserved'}`(**绝不**折成 `none`)。 */
|
|
97
108
|
export function observedWebSearchBackend(baseUrl = engineWireTarget()?.baseUrl) {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
33
33
|
import { engineWireTarget } from './engineWireTarget.js';
|
|
34
|
-
import {
|
|
34
|
+
import { snapshotCapsGeneration, capsGenerationStillCurrent } from './engineCapsGenerationGuard.js';
|
|
35
35
|
/**
|
|
36
36
|
* caps 回体 → 本格读数;**畸形一律 `undefined`**(= 这一格不写 ⇒ 读口答 `unobserved`)。
|
|
37
37
|
*
|
|
@@ -55,13 +55,17 @@ export function projectWriteProtectionCapability(caps) {
|
|
|
55
55
|
if (typeof wp !== 'object' || Array.isArray(wp))
|
|
56
56
|
return undefined;
|
|
57
57
|
const w = wp;
|
|
58
|
-
|
|
58
|
+
// 🔴 只读一次(0.74.2 CC-69 复审 R1 族扫):校验与返回各读一次,变化的 getter 会让校验读到合形、返回读到别的。
|
|
59
|
+
const armed = w.armed;
|
|
60
|
+
const replaced = w.replaced;
|
|
61
|
+
const rows = w.rows;
|
|
62
|
+
if (typeof armed !== 'boolean')
|
|
59
63
|
return undefined;
|
|
60
|
-
if (typeof
|
|
64
|
+
if (typeof replaced !== 'boolean')
|
|
61
65
|
return undefined;
|
|
62
|
-
if (typeof
|
|
66
|
+
if (typeof rows !== 'number' || !Number.isInteger(rows) || rows < 0)
|
|
63
67
|
return undefined;
|
|
64
|
-
return { kind: 'present', view: { armed
|
|
68
|
+
return { kind: 'present', view: { armed, rows, replaced } };
|
|
65
69
|
}
|
|
66
70
|
/**
|
|
67
71
|
* operator 面回体的 `writeProtection` 段 → 读数;不成形 ⇒ `undefined`。
|
|
@@ -124,22 +128,32 @@ const readingByBase = new Map();
|
|
|
124
128
|
* 有任何东西变坏。🔴 **tee 自己抓号是假判据**(陈旧那一发在这里读到的是新代号,永远像当代的)。
|
|
125
129
|
*/
|
|
126
130
|
export function noteEngineCapsForWriteProtection(baseUrl, caps, opts) {
|
|
131
|
+
if (typeof baseUrl !== 'string' || baseUrl === '')
|
|
132
|
+
return;
|
|
133
|
+
// 🔴 代际只在入口**快照一次**(异源对抗复审 R3):opts 是调用方的对象,回体上的 getter 能在投影中途改它;首末两次核对都用这份快照,
|
|
134
|
+
// 读 opts / 读代际抛出 ⇒ 不动格(与陈旧代际同一处置)。
|
|
135
|
+
const gen = snapshotCapsGeneration(opts);
|
|
136
|
+
if (gen === null)
|
|
137
|
+
return; // 调用方 opts 的 getter 抛出 = 供给坏了 ⇒ 不动格
|
|
138
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
139
|
+
return;
|
|
140
|
+
let reading;
|
|
127
141
|
try {
|
|
128
|
-
|
|
129
|
-
return;
|
|
130
|
-
// 陈旧代际的那一发整只丢掉(见本函数顶注的 `opts.generation` 段);不传 ⇒ 照写,零行为变化。
|
|
131
|
-
if (opts?.generation !== undefined && opts.generation !== engineCapsGeneration(baseUrl))
|
|
132
|
-
return;
|
|
133
|
-
const reading = projectWriteProtectionCapability(caps);
|
|
134
|
-
if (reading === undefined) {
|
|
135
|
-
readingByBase.delete(baseUrl);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
readingByBase.set(baseUrl, reading);
|
|
142
|
+
reading = projectWriteProtectionCapability(caps);
|
|
139
143
|
}
|
|
140
144
|
catch {
|
|
141
|
-
|
|
145
|
+
// 🔴 0.74.2 同形存量(CC-69 复审 R1 族扫):抛 getter / Proxy 的回体 = 畸形,与「投影答 undefined」同一处置 —— 删格,不许留着上一台的读数。
|
|
146
|
+
reading = undefined;
|
|
147
|
+
}
|
|
148
|
+
// 🔴 投影之后**再核一次代际**(异源对抗复审 R2):投影会执行回体上不可信的 getter,它可以在中途让这一格换代
|
|
149
|
+
// (invalidate + 新代际的 tee 已写入);此时无论投影返回还是抛出,都不许动新代际的格。
|
|
150
|
+
if (!capsGenerationStillCurrent(baseUrl, gen))
|
|
151
|
+
return;
|
|
152
|
+
if (reading === undefined) {
|
|
153
|
+
readingByBase.delete(baseUrl);
|
|
154
|
+
return;
|
|
142
155
|
}
|
|
156
|
+
readingByBase.set(baseUrl, reading);
|
|
143
157
|
}
|
|
144
158
|
/** 本进程观测到的写保护姿态;这一格空缺 ⇒ `{kind:'unobserved'}`(**绝不**折成 `none`)。 */
|
|
145
159
|
export function observedWriteProtection(baseUrl = engineWireTarget()?.baseUrl) {
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **0.74.
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **0.74.2**(本批发布版 = **patch**:`capabilities.deviceExecutor.management` 四态读口(缺席 ≠ false;`deviceExecutor: false` = 车道缺席;管理动词可用性三态归包);公面 1052;§70。上一版 0.74.1 = **patch**:审批卡无决断收口 + 结局回交;§69。上一版 0.74.0 = **minor**:peer sdk 地板 >=9.7.1 + covers 过境 + 面板周期身份 + 离场读口;§68。上一版 0.73.5 = **patch**:workflow 规模告警判定上收进包(`evaluateWorkflowSize` 三态:未知的规模不当作规模正常;分母口径与帽优先级单源;env 读口纯函数);型面纯 additive、公面 1044、peer 不动;§67。上一版 0.73.4 = **patch**:终帧 `permission_denials` 第三键 ⇐ 同一条流 `tool_start` 入参按 `toolCallId` join(三道闸;join 不上留 sema 载体;🔴 更正 0.73.2「自动升级收口」一句)+ 审批 feed push 侧取件失败的欠账退避重试;型面纯 additive、公面 1033、peer 不动;§66。上一版 0.73.3 = **patch**:CC-61 sdk 9.7.1 提货 + `capabilities.approvalsStreamLive` 四态读口(缺席 = 判不出;`livePendingNeedsReconcile` 只在引擎明说会推时才让对账节拍降兜底)+ CC-60 五条模型面文案锚包侧半场(cursorSemantics 机读位 / result 行注记 / bash 首行两变体与良性槽 / 通知 seed 并集 / parked 臂);型面纯 additive、公面 1032、peer 不动;§65。上一版 0.73.2 = **patch**:CC-59 悬挂 ask 全卡 —— `livePending[].frame`(server ≥7.87.0)两道闸窄读进视图,在场即走流内帧腿同一条路(入参可见、改写可转发),缺席保持盲卡;CC-34 收口(引擎半场随 7.87.0 到货,判据交黑盒);型面纯 additive、公面 1026、peer 不动;§64。上一版 0.73.1 = **patch**:CC-57 `decidePlanReview` outcome 尾句按「决断有没有生效」四态选(单铸点 `planReviewOutcomeTail`;此前本地拒发仍让模型汇报已拒绝)+ CC-56 cancel 的 409 按机器码分家(`cancelConflictFromError` 三形 / 新安全码 `cancel_run_not_running`)与提交面 429 用量窗读口 + 人话;型面纯 additive、公面 1026、peer 不动;§63。上一版 0.73.0 = **minor,型面 BREAKING**:fleet 视图八个数值键改可选 —— CC-52 `FleetTaskView.elapsedMs` / `tokens` / `queuedCount` 与 `FleetWorkflowView.doneCount` / `totalCount` / `failedCount` / `tokens` / `elapsedMs` 不再 `?? 0`(有键 = 真值含真 0,缺键 = 不知道;逐键缺席语义见 §62b)+ 台账补偿链无基数不铸;公面导出名零增减 1019、零 wire 变化、peer 不动;§62。上一版 0.72.14 = **patch**:悬挂的流内 ask 拉半场 —— CC-55 `startApprovalsFeed` 快照加 `livePending` 段并进变化摘要(键缺席 = 未报,不铸空)+ 视图 / 去重账 / 与流内帧腿同链的决断口(入参不可见上卡明说、改写不转发)+ 宿主闸对账节拍 + 待决计数读口(不知道 = null);型面纯 additive、公面 1019、peer 不动;§61。上一版 0.72.13 = **patch**:server 7.86.0 提货 —— CC-46 plan_review `permissionModeAfter` 发口(三选卡双闸:宿主声明只读起步 ∧ 引擎 ≥7.86.0;400 field_conflict 两种处置)+ CC-54 `capabilities.executionLane` 四态读面(键缺席 ≠ 不是本机车道;`toolsRunHere` 判据归包)+ CC-53 detach 版本闸三态;型面 additive(另撤回 0.72.12 的主通道 `absent` 臂,改独立缺席订阅口)、公面 1011、peer 不动;§60;**预告 0.73.0 BREAKING**:fleet 视图数值键改可选。上一版 0.72.12 = **patch**:「缺席被折成正向终态」按类清剿 —— CC-50 M1 头条(fleet 行缺席改发 `absent` 不再铸 `end{isError:false}`)+ 六站一次改齐(缺席 ⇒ `unknown`)+ 结果边界 fail-closed 取舍 + `_sema_outcome` + `Outcome unknown:` 行 + CC-51 M6(default 臂不再谎报 running)+ 普查门 + DS-06;型面 additive、公面 993、peer 不动;行为面三处真变化见 CHANGELOG 取舍段;§59。上一版 0.72.11 = **patch**:core 7.23.0 提货 —— CC-49 通告码 66 → 67 `config.write_protection_unresolved`(operator;兄弟码 `target_view_absent` = 没有视图,这枚 = 有视图解析不出)+ `permission_denials` 自动升级腿通电(`gates[].toolCallId` ⇒ `tool_use_id`;CC-34 引擎半场);型面零变化、公面 989、peer 不动、devDep core ~7.23.0;§58。上一版 0.72.10 = **patch**:CC-41 leader run 终局 `needs_human` + `result.conflict` 三形读面(none 缺席不可分 / unreadable 在场读不懂 / conflict;`salvaged[]` 原样给落盘口;措辞单源不提重试);型面纯 additive、公面 989、peer 不动;§57。上一版 0.72.9 = **patch**:server 7.85.0 提货 —— CC-30 会话内 MCP re-dial 消费口(`reconnectMcpServer` 三态 / unsupported 恒五键 / 交易文案单源)+ CC-39② memory-status `autoConsolidationArmed` 三态 + CC-45 resume 补充句渲保留秒数;型面纯 additive、公面 985、peer 不动;§56。上一版 0.72.8 = **patch**:清账三票 —— `memory:"off"` 请求键(CC-39③,server 7.84.0 S-405)+ `runStream` 第二条中性臂 `Model output error:`(CC-43)+ 注入件撞活 run 自动 steer 零卡(CC-44);型面纯 additive、公面 977、peer 不动;§55。上一版 0.72.7 = **patch**:core 7.22.0 提货 —— 通告码 66 `mcp.server_redialed` + 读器 `readMcpServerRedialed` + `wiring_manifest.readDeny` 第九段 `_sema_readDeny`(缺席 = 没有内置行判这条腿);型面纯 additive、公面 971、peer 不动、devDep core ~7.22.0;§54。上一版 0.72.6 = **patch**:cli L-379 包侧半场 —— `steerFollowIntent` steer 后续听意图三态(tail / after-decision / after-wake)+ `activeRunSelfHealRow` 续听声明第五参;型面纯 additive、公面 969、peer 不动;§53。上一版 0.72.5 = **patch**:server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面(键缺席 = 老引擎判不了 ≠ `none`);型面纯 additive、公面 968、peer 不动;§52。上一版 0.72.4 = **patch**:core 7.21.x 三件经 server 7.82.0 提货 —— `wiring_manifest.autoConsolidation` 第八段 `_sema_autoConsolidation`(缺席 = indeterminate 不折 false);型面纯 additive、公面 962、peer 不动;§51。上一版 0.72.3 = **patch**:core #863 记忆单系统半场 ① —— `projectAgentsForWire` 投影 `agents[].memory`(user|project|local 三词同映射引擎平面 agent:<type>);型面纯 additive、公面 962、零 wire 新键、peer 不动;§50。上一版 0.72.2 = **patch**:workflow 视图两票 —— `LiveWorkflowController.resolution()` 六态(snapshot() 的 null 三义拆开)+ `noteOwnWorkflowRun` own 台账同拍登记;型面纯 additive、公面 961、零 wire 键、peer 不动;§49。上一版 0.72.1 = **patch**:server 7.80.1 提货 —— 409 `conflict.resume_context_unavailable` 结构读数(`staleAfterSec` / `runId`;sdk 9.6.0 尚未带键,经 sdk 今天恒缺席)+ `SkillSpec.baseDir`(只在本机车道带);型面纯 additive、公面 960、peer 不动;§48。上一版 0.72.0 = **minor**:型面 BREAKING —— 39 个零消费导出退出公面(CC-32 退役批,[7419] §45 预告 / cli [7422] 同意 / web-client·desktop 过节拍沉默 = 同意;名单见 §47a S-1);运行期零 BREAKING、公面 956、peer 不动、devDep core ~7.20.1;随批:已退役名账 `removed` + export-liveness 门 G 段 + 冻结账门 ⑧c;§47。上一版 0.71.4 = **patch**:core 7.20.1 提货 —— `ENGINE_NOTICE_CODES` 65 + `wiring_manifest.writeProtection` 第七段 `_sema_writeProtection`;型面纯 additive、公面 995、peer 不动、devDep core `~7.20.1`;§46。上一版 0.71.3 = **patch**:门体系清账批 —— CC-24 export-liveness 门 + 39 个导出退役预告(0.72.0 删,表态制)/ CC-26 `as unknown as` 铸链棘轮 / CC-25 冻结账门 ⑧ 段 / CC-06 B-081 包侧半场(终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` + resume reopen 族 + `routePairingVerdict`);型面纯 additive、公面 986 → 995、peer 不动;§45。上一版 0.71.2 = **patch**:接入方验收两票归包 —— CC-28 B-132 decide 拒体三句去内部车道词 / CC-29 B-133 committedUuids 唯一性(重复 ⇒ 形 f);零型面变化、公面 986、peer 不动;§44。上一版 0.71.1 = **patch**:接入档打回修正 —— CC-27 `ApprovalCardRequest.readRootCandidate?` 帧→卡透传位 + 新导出型 `ReadRootCandidateView`;型面纯 additive、公面 986 不变、peer 不动;§43。上一版 0.71.0 = **minor**:型面 BREAKING 六件 —— peer sdk 地板 >=9.6.0 + agent-types >=0.3.0 / `SkillsListingTruncatedFactsView` 删 `requestedBudgetBytes?`·`laneClamped?` / `WiringManifestMcpEntry` → `WiringManifestMcpEntryView` / `MAX_AGENT_SKILLS` 删 / `decide.workflow_host_not_parked` 退役;运行期零 BREAKING。内容:core 7.20.0 提货(闭集 +5 六十四码)/ 🔴 CC-16 `text_segment_end.committedUuids[]` / CC-08 全五件(tool_disclosure / tool_progress 两 chrome 臂、wiring_manifest tools·hooks·lsp 进切片、tool_roster_delta 接上、context_usage 进切片、`readRootCandidate` 镜像)/ CC-19 `mcpEngineLegPresence` 归包 / CC-20 not_parked clean-cut;公面 986;§42 / 42y 八条)|
|
|
23
23
|
| peer:wire 契约 | `@sema-agent/sdk` **>=9.7.1**(value-level,非 type-only;**0.74.0 抬版**:9.7.x 追平的六处型面是本包 0.73.3 起的编译基线,且 9.6.0 失去物料见证;**0.71.0 曾抬到 >=9.6.0**:`tool_disclosure` / `tool_progress` 两帧型与 `ToolApprovalFrame.readRootCandidate` 自 9.6.0 起;0.69.0 曾抬到 >=9.4.0(`reasoning_end` / `lastLegMcp`),0.60.0 抬到 >=8.4.0;地板由 `scripts/run-sdk-floor-test.mjs` 的 `FLOOR` 与 public-surface 门 C-CC-3「不低于见证到的最低实装版」双钉)| `package.json` `peerDependencies` |
|
|
24
24
|
| peer:会话词汇表 | `@sema-agent/agent-types` **>=0.3.0**(type-only,零运行时;0.71.0 抬版:devDep 与 peer 同步,type-superset 门 ④ 撞名预警对着 0.3.0 的 .d.ts 求值) | 同上 |
|
|
25
25
|
| runtime dep | `diff` ^9.0.0(**唯一**一条;portability 门按**等值**钉死) | `package.json` `dependencies` |
|
|
26
|
-
| 公开导出面 | **
|
|
26
|
+
| 公开导出面 | **1052** 个运行期符号(+ 50 个测试钩;= 0.74.2 的值:相对 0.74.1 +6 —— CC-69 六件,见 §2b 域 9;1046 = 0.74.1 的值:相对 0.74.0 +1 —— `RETRACTED_CARD_DECISION_KIND`,见 §2b 域 3;1045 = 0.74.0 的值:相对 0.73.5 +1 —— `isStaleEngineAgentPanelEnd`,见 §2b 域 4;1044 = 0.73.5 的值:相对 0.73.4 +11 —— CC-58 规模告警十一件,名单见 §2b 域 12;1033 = 0.73.4 的值:相对 0.73.3 +1 —— `TOOL_INPUT_JOIN_MAX_CALLS`,见 §2b 域 1;1032 = 0.73.3 的值:相对 0.73.2 +6 —— CC-61 六件,名单见 §2b 域 9;1026 = 0.73.2 的值(导出名零增减);= 0.73.1 的值:相对 0.73.0 +7 —— CC-56 六件 / CC-57 一件,名单见 §2b 域 3 / 15;1019 = 0.73.0 的值(导出名零增减,BREAKING 在类型面);= 0.72.14 的值:相对 0.72.13 +8 —— CC-55 八件,名单见 §2b 域 3;1011 = 0.72.13 的值:相对 0.72.12 +18 —— CC-46 八件 / CC-54 六件 / CC-53 两件 / CC-50 缺席口两件,名单见 §2b 域 3 / 4 / 9 / 10;993 = 0.72.12 的值(测试钩 45):相对 0.72.11 +4 —— CC-50 `OUTCOME_UNKNOWN_ROW_PREFIX` / `isOutcomeUnknownRowText` / `TASK_NOTIFICATION_TERMINAL_STATUSES` / `isTaskNotificationTerminalStatus`;989 = 0.72.10 的值:相对 0.72.9 +4 —— CC-41 `LEADER_RUN_STATUSES` / `LEADER_REJ_HEAD_DISPLAY_MAX` / `projectLeaderConflict` / `leaderConflictDetail`;985 = 0.72.9 的值:相对 0.72.8 +8 —— CC-30 `MCP_RECONNECT_OUTCOMES` / `MCP_RECONNECT_TRANSACTION_NOTICE` / `projectMcpReconnectResult` / `classifyMcpReconnectFailure` / `reconnectMcpServer` / `projectMcpReconnectCapability` / `mcpReconnectOutcomeDetail`、CC-39② `readAutoConsolidationArmed`;977 = 0.72.8 的值:相对 0.72.7 +6 —— CC-39③ `MEMORY_OFF` / `memoryOffDeclarationField` / `memoryOffDeclared`、CC-43 `MODEL_OUTPUT_ERROR_PREFIX` / `isModelOutputErrorText` / `isModelOutputErrorRowText`;971 = 0.72.7 的值:相对 0.72.6 +2 —— CC-42 core 7.22.0 提货 `MCP_REDIAL_OUTCOMES` / `readMcpServerRedialed`;969 = 0.72.6 的值:相对 0.72.5 +1 —— CC-40 `steerFollowIntent`;968 = 0.72.5 的值:相对 0.72.4 +6 —— CC-31 server 7.82.1 提货 `capabilities.webSearch.backend` 四态读面:`WEB_SEARCH_BACKEND_NONE` / `projectWebSearchBackendCapability` / `observedWebSearchBackend` / `noteEngineCapsForWebSearchBackend` / `forgetWebSearchBackendReading` / `webSearchBackendDoctorDetail`;962 = 0.72.3 的值:相对 0.72.2 +1 —— CC-39① `AGENT_MEMORY_WORDS`;0.72.2 相对 0.72.1 +1 —— CC-37 `noteOwnWorkflowRun`;0.72.1 相对 0.72.0 +4 —— CC-33 server 7.80.1 提货:`RESUME_CONTEXT_UNAVAILABLE` / `resumeContextUnavailableFromError` / `resumeContextUnavailableContent` / `skillBaseDirOf`;0.72.0 相对 0.71.4 −39 —— CC-32 退役批删 export-liveness 登记 retire 的 39 个零消费导出(23 常量 + 16 函数,名单见 §47);995 = 0.71.3 的值:相对 0.71.2 +9 —— CC-06 `readEffectiveReasoning` / `readEffectiveMemoryScopes` / `resumeReopenFromError` / `resumeReopenContent` / `routePairingVerdict` 五函数 + `RESUME_REOPEN_CODES` / `RESUME_ENV_FAILED` / `RESUME_TOOL_UNAVAILABLE` / `RESUME_TOOL_CONTRACT_MISMATCH` 四常量;986 = 0.71.0 的值:相对 0.70.2 −`MAX_AGENT_SKILLS` −`DECIDE_WORKFLOW_HOST_NOT_PARKED` +`projectToolRosterDelta` +`mcpEngineLegPresence`;986 = 0.70.0 的值:相对 0.69.2 **一件 additive(`readSkillsListingTruncated`,§39)、零删除**;985 = 0.69.2 的值:相对 0.69.1 **三件 additive、零删除**(CC-13 `isSubFlowSegmentEnd` / `SEGMENT_END_IDENTITY_KEYS` / `droppedWhySentence`,§38);982 = 0.69.0 未发布版的值(原排 0.68.3,因 peer 地板抬升改 minor)= 相对 0.68.2 **十七件 additive、零删除**:`fetchMcpPanel`(CC-03 补件,§36e)+ `readWorkflowResumeAdmissionIncomplete`(CC-05 core 7.18.0 #755)+ `installCoreValuePorts`/`hasCoreValuePorts`/`hasCoreValuePort`/`coreValuePortMisses`/`CORE_VALUE_PORT_NAMES` + 十读口(CC-07 core 值级端口,§36d);0.68.2 相对 0.68.1 十三件 additive:`SEMA_SEGMENT_ID_KEY`(CC-01 段身份键,§35f)/ `projectMcpPanel`+`mcpPanelLastLegDetail`+`projectMcpSection`(CC-03 `/mcp` 面板读视图,§35g)/ `resolveTextSegmentAuthority`/`createTextSegmentLedger`(L-318 `text_end` 权威段替换的判决单源 + print 形段账,详见 §35b/§35c)/ `memoryCaptureDeclarationField`/`MEMORY_CAPTURE_OFF`(L-316 会话级隐私声明的字面唯一铸点,§35d)/ `engineUrl`/`probeHealth`(L-61 件④ SDK 纯工具面原样转口,§35d)/ `AgentClient`/`isApprovalRequestFrameV1`/`isApprovalRevokeFrameV1`(L-61 存量清零:SDK **wire 面**原样转口,§35e)。`0.68.1`/`0.68.0` 是 **952**,那批是相对 0.67.2 **二十件 additive、🔴 两件删除(BREAKING)**:additive = `TERMINAL_CAUSE_KINDS`/`isTerminalCauseKind`/`RUN_TERMINAL_NOT_SUCCESS_STATUSES`/`RUN_TERMINAL_STATUSES`(L-247 终态词两表分源,详见 §33b)/ `SEMA_SUBAGENT_USAGE_PARTIAL_KEY`/`subagentUsageIsPartial`(L-244 子代下界位自有名,§33g)/ `ASK_UNRESOLVABLE_CAUSES`/`readAskUnresolvable`/`DURABLE_MANDATE_SOURCES`/`readDurableGateUnavailable`(core 7.17.0 #709 ①② 两只通告事实窄读器,§33c)/ `WORKFLOW_PARK_TRUTH_UNREADABLE`/`WORKFLOW_PARK_NOT_PENDING`/`WORKFLOW_PARK_BINDING_BROKEN`/`WORKFLOW_PARK_REQUIRES_RUN_STORE`(四个单码常量 🔧 0.72.0 退役)/`WORKFLOW_PARK_REFUSAL_CODES`/`isWorkflowParkRefusalCode`/`readWorkflowParks`(core 7.17.0 #652 park 真相四码 + parks 三键读器,§33d)/ `ENGINE_STOP_REASONS`/`engineStopReasonToCc`(L-246 A13 停止原词映射下沉,§33g)/ `readCancelRequested`(L-230 读面,§33f);🔴 **删除两件** `TERMINAL_NOT_SUCCESS_STATUSES`/`TERMINAL_STATUSES`(随 L-247 两表分源更名成 `RUN_TERMINAL_*`,clean-cut **不留别名** —— 留一个别名等于让端可以继续按合起来的那张表读,分源就白做了,详见 §33b)。`0.67.0` 是 **934**,那批是相对 0.66.0 **七件 additive、🔴 两件删除**:additive = `CLASSIFIER_DENY_CAUSES`/`isClassifierDenyCause`/`classifierDenyCauseOf`/`classifierDenyCauseDetail`(core 7.14.0 退役 `classifierUnavailable` 之后的**拒绝面**继任读器与措辞,详见 §32b)/ `RULE_STORE_UNREADABLE_KINDS`/`isRuleStoreUnreadableKind`/`ruleStoreUnreadableDetail`(core 7.14.0 #688 C3 的规则店机制位三件,详见 §32d);🔴 **删除两件** `classifierUnavailableOf`/`classifierUnavailableDetail`(随 core 7.14.0 的 Retired keys 表整族退役,clean-cut 不留别名,详见 §32b;同批删的还有**型** `ClassifierUnavailableView`、卡位与帧位 `classifierUnavailable`、以及一条恒真的型面钉 `_askOriginWordsPin`)。`0.66.0` 是 **929**,那批是一件 additive、零删除:`readRunCostFacts`(终局成本事实的唯一读器:`costBreakdown` / `nested` 窄读 + 对账三段与两个判别位,终帧超集键与 chrome 对账臂共用它;详见 §31c);已发的 **0.65.x 十一件 additive、两件删除**:additive = `DECIDE_WORKFLOW_HOST_UNKNOWN`/`DECIDE_WORKFLOW_HOST_NOT_PARKED`/`DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED`/`DECIDE_WORKFLOW_LANE_CODES`/`readDecideReceipt`/`decideAcceptedNotResolved`/`decideRefusalFromError`(B-070 `/decide` 回执读面与三码人话,详见 §30h)/ `TERMINAL_NOT_SUCCESS_STATUSES`/`isTerminalNotSuccess`/`TERMINAL_STATUSES`/`isTerminalStatus`(L-215② 终局词汇单铸谓词,详见 §30j);🔴 **删除两件** `AUTO_MODE_BREAKER_CAUSES`/`classifierBreakerOf`(熔断族随 core 7.12.0 的 Removed(BREAKING) 整只退役,clean-cut 不留别名,详见 §30k②;同批删的还有**型** `ClassifierBreakerView` 与 `ClassifierStatusView.breaker` 一位)。`0.64.2` 是 **919**,那批是一件 additive、零删除:`readDenialLimitFallback`(限额回落卡的窄读器上公面,壳侧同判据副本退役,详见 §29③);`0.64.0` 是 **918**,那批是件①+件② 十三件 additive、零删除:`CLASSIFIER_STATUS_STATES`/`classifierBreakerOf`/`classifierStatusOf`/`classifierStatusDetail`(分类器状态面,详见 §28②)/ `THINKING_FORMATS`/`THINKING_FORMAT_WIRE_TWINS`/`THINKING_DISABLE_PROBE_ORDER`/`MODEL_PROBE_VERDICTS`/`PROBE_PROMPT`/`PROBE_MAX_TOKENS`(两个探针常量 🔧 0.72.0 退役)/`probeRequestBody`/`probeModelCapability`/`applyProbeToEntry`(模型思考能力探测,详见 §28①);`0.63.0` 是 **905**,那批是八件 additive、零删除:`projectServerGateKnobs`/`postureKnobSourceOf`/`postureSourceIsOperatorPinned`/`postureKnobDetail`/`POSTURE_SOURCE_WORDS`(S-178 三根 posture 旋钮读数,详见 §27b)/ `PERSISTED_RULE_BEHAVIORS`/`PERSISTED_RULE_BEHAVIOR_UNKNOWN`/`persistedRuleBehaviorOf`/`persistedRuleBehaviorLabel`/`revokeTargetFromPersistedRule`(三态规则身份,§27c)/ `engineIdentityOf`/`engineIdentityVerdict`/`engineIdentityChanged`/`engineIdentityChangedBy`/`ENGINE_IDENTITY_ANCHORS`(S-179 代际锚,§27d)/ `GATE_DENIED_BY_WORDS`/`gateDeniedByDetail`/`ASK_ORIGIN_WORDS`/`askOriginDetail`(门词汇 +2,§27e)/ `PERMISSION_RULE_ISSUE_CODES`/`RETIRED_PERMISSION_RULE_ISSUE_CODES`/`permissionRuleIssueDetail`(规则 lint 码表,§27f)/ `projectToolRoster`/`toolRosterNames`/`toolShimFromRoster`/`applyToolRosterDelta`(L-161 工具名册,§27g)/ `ENGINE_NOTICE_CODES`/`ENGINE_NOTICE_AUDIENCE`/`noticeAudienceOf`/`engineNoticeInCatalog`/`MCP_INJECTION_DROP_REASONS`/`readMcpInjectionDrop`(L-167 通告码册,§27h)/ `AUTO_MODE_UNAVAILABLE_CAUSES`/`AUTO_MODE_BREAKER_CAUSES`/`classifierUnavailableOf`/`classifierUnavailableDetail`(件⑧ 分类器不可用事实,§27h2);`0.62.0` 是 **869**,那批是五件 additive、**零删除**:`capForDisplay`(呈前消毒 + 封长的共用铸点,详见 §26⑦)/ `SEAT_SEND_MESSAGE_KEY_ORIGINS`(座位载荷逐键出身表,详见 §26③)/ `configureSubagentContentStore`+`subagentContentStoreConfig`+`SUBAGENT_CONTENT_STORE_DEFAULTS`(子代内容账本字节预算,测试钩 `__resetSubagentContentStoreConfigForTests` +1,详见 §26②);`0.61.0` 是 **864**,那批是三件 additive、**零删除**:`projectReadFacePosture`/`readFacePostureDetail`/`readFaceDisagreement`(S-167 READ 容纳面 operator 读器,详见 §25);`0.60.0` 是 **861**,那批是二十五件 additive、**零删除**:`readRunTerminal`/`runTerminalCode`/`runTerminalGateKind`/`runTerminalGateToolName`/`isReviewPark`/`REVIEW_PARK_GATE_KINDS` 六件终局因由读器 + `gateOutcomeOf`/`isDeniedGate`/`gateDeniedBy`/`gateApprover`/`isApprovalWindowExpiredGate`/`isDenialLimitAutoDeniedGate`/`isParkSlaExpiredGate`/`isHumanSettledGate` 八件门记录读器 + `projectWriteProtectionCapability`/`noteEngineCapsForWriteProtection`/`observedWriteProtection`/`forgetWriteProtectionReading`/`writeProtectionDoctorDetail`/`projectWriteProtectionPosture`/`writeProtectionPostureDetail` 七件写保护读面(测试钩 `__resetWriteProtectionReadingsForTests` +1)+ `readWireErrorCode` + 真机边界①的两件 `isGateParkedToolEnd`/`GATE_PARKED_ERROR_CODE` + 异源复审逼出的 `engineCapsGeneration`;`0.59.0` 是 **836**,那批是八件 additive:`RULE_OFFERS_ABSENCE_REASONS`/`DENIAL_LIMIT_KINDS` 两张闭词表再导出 + `engineCapValue` 能力位四态通用读口 + `projectSqlEngineCapability`/`observedSqlEngine`/`noteEngineCapsForSqlEngine`/`forgetSqlEngineReading`/`sqlEngineDoctorDetail` 五件 SQL 姿态读面(测试钩 `__resetSqlEngineReadingsForTests` +1);`0.58.0` 是 **828**,那批是三件 additive:`RULE_OFFER_MATCHES`/`RULE_OFFER_BATCH_MEMBER_KINDS`/`RULE_OFFER_UNCOVERED_REASONS` 三张闭词表再导出 + `RESUME_REFUSAL_CODES`/`RESUME_PLACEMENT_MISMATCH`/`resumeRefusalFromError`/`resumeRefusalContent` 四件文案铸点;`0.57.0` 是 **821**;`0.56.0`/`0.55.0` 是 **815**;已发 `0.54.0`(design/385 十件 additive 含 `AUTHORITY_ENVELOPE_TAGS` 🔧 0.72.0 退役);`0.52.0` 是 **805**(L-69⑨ 两件);`0.51.0` 是 **803**;`0.50.0` 是 **800**(S-81 五件);`0.49.0` 是 **795**;`0.48.0` 是 **794**;npm `0.47.0` 是 **790**,`0.46.0` 是 **787**,`0.44.0` 是 **783**,`0.43.1`/`0.43.0` 是 **776**,`0.42.0` 是 **771**,`0.41.0` 是 **767**,`0.39.0` 是 **766**,`0.38.0` 是 **764**;`0.37.0` 是 **753**,见 `CHANGELOG.md`) | `scripts/public-export-baseline.json` 的 `count` / `testHookCount` —— **别手抄进别处,以该文件为准** |
|
|
27
27
|
| 常驻门 | 以 `scripts/gates-manifest.json` 的 `suites` 长度为准(**本档不抄这个数**) | `scripts/gates-manifest.json`;`npm test` 的名单等值门与它逐名对账 |
|
|
28
28
|
| 沿革档 | 0.29.0 起建 `CHANGELOG.md`;更早批次记账在 `src/index.ts` 文件头 + `docs/REFACTOR-LEDGER.md` | — |
|
|
29
29
|
|
|
@@ -123,7 +123,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
123
123
|
|
|
124
124
|
> 📦 **随包 / 不随包**:npm 包只带 `dist` / `README` / `CHANGELOG` / 本档 / `LICENSE`。本档各处提到的 `docs/type-superset.json`、`scripts/*.json`、`scripts/run-*-test.mjs` 都是**仓内登记物与门,不随包发出** —— 装包的消费者找不到它们是预期;`_sema_` 超集键的**随包契约**就是本档各 §NNz 逐键处置表(键名 / 值域 / 缺席语义逐条在表里)。
|
|
125
125
|
>
|
|
126
|
-
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**
|
|
126
|
+
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**1052** 项)。
|
|
127
127
|
> 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
|
|
128
128
|
> **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
|
|
129
129
|
> 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
|
|
@@ -147,24 +147,24 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
147
147
|
`WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
|
|
148
148
|
**4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
1052 项的内部构成(帮助端估读表大小;0.74.2 +6 函数(CC-69;测试钩 +1);0.74.1 +1 常量(CC-67);0.74.0 +1 函数(CC-66);0.73.5 +8 常量 +3 函数(CC-58);0.73.4 +1 常量(CC-34);0.73.3 +6 函数(CC-61;测试钩 +1);0.73.1 +2 常量 +5 函数(CC-56 / CC-57;测试钩 +1);0.72.14 +1 常量 +7 函数(CC-55);0.72.13 +4 常量 +14 函数(CC-46 / CC-54 / CC-53 / CC-50 缺席口);0.72.12 +2 常量 +2 函数(CC-50);0.72.10 +2 常量 +2 函数(CC-41);0.72.9 +2 常量 +6 函数(CC-30 / CC-39②);0.72.8 +2 常量 +4 函数(CC-39③ / CC-43);0.72.7 +1 常量 +1 函数(CC-42);0.72.6 +1 函数(CC-40);0.72.5 +1 常量 +5 函数(CC-31);0.72.3 +1 常量(CC-39①);0.72.2 +1 函数(CC-37);0.72.1 +1 常量 +3 函数(CC-33);0.72.0 −23 常量 −16 函数(CC-32 退役批);0.71.3 +4 常量 +5 函数(CC-06);0.71.0 −2 常量 `MAX_AGENT_SKILLS` / `DECIDE_WORKFLOW_HOST_NOT_PARKED` +2 函数 `projectToolRosterDelta` / `mcpEngineLegPresence`;0.70.0 起 +1 函数;0.69.2 起 +3:常量 1 / 函数 2):**307** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
|
|
151
151
|
(矩阵、键集、env 名、锚串)而非可调用物;**6** 项是 PascalCase 运行期值
|
|
152
152
|
(`ControlRouter` / `ControlSafetyError` / `HitlBridge` / `HitlSafetyError` / `DecideTransportRetryExhaustedError`);
|
|
153
153
|
**37** 项是 `*For(sessionKey, …)` 的 per-session 变体(0.72.0 −4:`clearArmedGateFor` / `onGateArmedFor` / `registerArmedGateFromQuestionIdFor` / `notePlanReviewAnsweredIfDecisiveFor` 退出公面)(§6;其中 `engineNamespaceKeyFor` 是命名巧合 —— 参数是 baseUrl 不是 sessionKey,见域 14)。
|
|
154
154
|
|
|
155
|
-
### 2b. 域图(16 域,逐域计数之和 =
|
|
155
|
+
### 2b. 域图(16 域,逐域计数之和 = 1052)
|
|
156
156
|
|
|
157
157
|
| # | 域 | 名数 | 承重导出 | 用途 | 实现锚 |
|
|
158
158
|
|---|---|---|---|---|---|
|
|
159
159
|
| 1 | **适配内核(下行主链)** | 63 | `TOOL_INPUT_JOIN_MAX_CALLS`(0.73.4 CC-34:终帧拒绝清单第三键的本流快照上限;§66)· `OUTCOME_UNKNOWN_ROW_PREFIX` / `isOutcomeUnknownRowText`(0.72.12 CC-50:第三条中性终局行「结局不知道」,读结果帧 `_sema_outcome`;§59)· `MODEL_OUTPUT_ERROR_PREFIX` / `isModelOutputErrorText` / `isModelOutputErrorRowText`(0.72.8 CC-43:runStream 第二条中性臂 —— core malformed tool-call 一族的行身份;§55)· `readEffectiveReasoning` · `readEffectiveMemoryScopes`(0.71.3 CC-06:终帧 `_sema_effective_reasoning` / `_sema_effective_memory_scopes` 的窄读器,§45)· `isSubFlowSegmentEnd` · `SEGMENT_END_IDENTITY_KEYS` · `droppedWhySentence`(0.69.2 CC-13:三件出公面,§38)· `adapt` · `createWireToCcAdapter` · `runStream` · `eventToSdkMessage` · `terminalToSdkResult` · `SEMA_SEGMENT_ID_KEY`(0.68.2 CC-01:committed assistant 文本行顶层段身份键的唯一字面量出处,壳只读)· `projectMcpSection`(0.68.2 CC-03:`wiring_manifest.mcp[]` 与 `/mcp` 面板 `lastLegMcp.mcp[]` 共用的同一只条目读器)· `readRunCostFacts`(0.66.0:终局成本事实的**唯一读器** —— `TaskStats.costBreakdown` / `nested` 逐键窄读 + 对账三段(own/nested/compaction)与两个「没定价」判别位;终帧的两个超集键与 chrome 臂 `run_cost_reconciled` **共用它**,两面不会各算各的,详见 §31c)· `TERMINAL_CAUSE_KINDS`/`isTerminalCauseKind`(0.68.0 / L-247:**core 终局因由**闭集,四词 `completed|failed|blocked|paused`)· `RUN_TERMINAL_NOT_SUCCESS_STATUSES`/`isTerminalNotSuccess`/`RUN_TERMINAL_STATUSES`/`isTerminalStatus`(L-215② 终局词汇的**单铸谓词**,0.68.0 随 L-247 **两表分源**更名 —— `killed` 属 server run 行状态面、`paused` 属 core 因由面,合成一张会让两边加词时都读不出该改哪儿;`blocked` 是 agent 自报终态,`suspended`/`needs_review` 刻意不在表里,详见 §33b / §30j)· `SEMA_SUBAGENT_USAGE_PARTIAL_KEY`/`subagentUsageIsPartial`(0.68.0 / L-244:子代用量下界位的**自有名**与唯一判据,与终帧 `_sema_usage_lower_bound` 分名,详见 §33g) · `turnUsageToModelUsage` · `isRunStreamActive` · `ADAPTER_DIVERGENCES` · `readRunTerminal` / `runTerminalCode` / `runTerminalGateKind` / `runTerminalGateToolName` / `isReviewPark` / `REVIEW_PARK_GATE_KINDS`(0.60.0 / engine ≥7.64.0:一次 run **怎么结束的**唯一读器 —— 终局从八个平面键换成一条带标因由 `terminal`,四臂 + `unknown` 防御臂 + `plane` 两代字节标;🔴 不认识的终态词绝不折成成功、本包不提供「因由→五词 status」的兼容投影,详见 §24b)| 引擎 SSE `AgentEvent` → 端要渲的**双面输出**:transcript(`SDKMessage`)+ chrome(瞬态 `ChromeEvent`)。**本包存在的理由** | `src/adapt.ts`、`src/adapt/{arms,wireShapes,panelTasks}.ts`(经 `adapt.ts` 再导出)、`src/adapter/runStream.ts`、`src/adapter/downstream/*`、`src/adapter/types.ts`、`src/runTerminal.ts` |
|
|
160
160
|
| 2 | **seam 公共契约** | 2(其余为 type-only) | `CHROME_ARMS` · `deriveTranscriptId` | 公共词汇 + **id 确定性不变量**(同一条流重放 ⇒ 同一串 id)。`CHROME_ARMS` = 端「我要消费哪些 chrome 臂」的对照清单 | `src/seam.ts` |
|
|
161
|
-
| 3 | **HITL 决断卡链**(§4/§5 主战场) |
|
|
161
|
+
| 3 | **HITL 决断卡链**(§4/§5 主战场) | 178 | `RETRACTED_CARD_DECISION_KIND`(0.74.1 CC-67:卡口无决断收口;§69)· `planReviewOutcomeTail`(0.73.1 CC-57:outcome 尾句六态单铸点;投递口闩;§63)· `readLivePendingRows` / `suspendedSubagentAsks` / `countApprovalsAwaitingDecision` / `createSuspendedAskTracker` / `livePendingRowToApprovalFrame` / `surfaceSuspendedAskAndRespond` / `surfaceEditRefusedOnBlindAsk` + `EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT`(0.72.14 CC-55:悬挂的流内 ask 读面 / 视图 / 去重账 / 决断口;§61)· `planReviewCardOptions` / `planReviewChoiceFromAnswer` / `versionSupportsPlanReviewModeAfter` / `isPlanReviewModeAfter` + `PLAN_REVIEW_APPROVE_AUTO_LABEL` / `PLAN_REVIEW_APPROVE_MANUAL_LABEL` / `PLAN_REVIEW_MODE_AFTER_WORDS` / `PLAN_REVIEW_MODE_AFTER_MIN_ENGINE`(0.72.13 CC-46:plan_review 批准后模式 `permissionModeAfter` 发口与三选卡双闸;§60)· `makeHitlCanUseTool` · `HitlBridge` · `findPendingForTask` · `readDecideReceipt`/`decideAcceptedNotResolved`/`decideRefusalFromError`(B-070:`/decide` 200 = **投递受理**不是「门已解决」;`executionOutcome` 缺席 = 未知,详见 §30h) · `HitlSafetyError` · `bridgeAskUserQuestionGates` · `surfaceToolApprovalFrameAndRespond` / `surfaceFsApprovalAndDecide` · `readToolApprovalRespondAck` · `installApprovalCardPort(For)` · `installHitlHostSurface(For)` · `armPlanReviewApproval` · `reopenPlanReviewCard` · `decidePlanReview` · `startApprovalsFeed` · `pendingRowIsOwnedByThisSession` · `approvalCallKey`/`liveFrameCallKey`/`planReviewQuestionId` · `registerArmedGateFor`/`wasGateArmedFor` · `waitForGateArmed(For)`/`onGateArmed`/`gateArmedWaitMs`(#244 F1 呈现回执事件源) · `planReviewArmedKey(For)`/`notePlanReviewAnswered(For)`/`notePlanReviewAnsweredIfDecisive`(A-024.4 plan 呈现分代) · `toolEndOutputText` · `isAskTool` · `waitForParkRowBirth` · `classifyAskParkRows` / `askParkRowArm` / `classifyAskParkChainFailure` · `readDecisionNoteAudit` / `decisionNoteAuditLine` · `resumeRunningOptions` / `resumeChoiceFromLabels` · `persistedRulesLaneAvailable`/`persistedRulesGovernanceAvailable` · `classifyRulesFailure` · `listAllPersistedRules` · `classifySkippedReason` · `readRulePersistOutcome`(#244 F2:persist-ack 读口与 `readToolApprovalRespondAck` 合成一处) · `parseLocalAllowRule`(durable 腿本地落规则窄化骨架,谓词经 `LocalAllowRuleDeps` 注入) · `readToolApprovalRespondRefusal`(#225 件5,0.42.0:respond 抛错的结构化原文读口 —— 三位各自防御读、各自缺席不铸、**三位皆缺席时整只返 `undefined`**;原样交还零加工,UNTRUSTED-for-display)· `installEditedRuleTextPrechecker` / `hasEditedRuleTextPrechecker` / `precheckEditedRuleText`([5076] 转出口,0.42.0:core 5.57.0 `precheckEditedRuleText` 的**端口注入形** —— 类型面 + 注入口 + 诚实缺席读口。🔴 **不是** value 级 re-export,理由见 §7 缺口 **P-34**;未装 ⇒ 返 `undefined`,绝不编一个 `{ok:true}`)· `surfaceRuleArmNotSent` / `RULE_NOT_SENT_WARN_TEXT` + `surfaceRuleArmRejected` / `RULE_NOT_SENT_REJECTED_WARN_TEXT`(#334,0.43.0:人在卡上按下的「不再询问」被整条丢弃时的诚实告知——**两条刻意分开**:前者=**引擎能力位未确认**(换台引擎/等探测就好),后者=**这次选择没过包内表核/互斥核**(表外文本/坏下标/两臂同场,换引擎也不会变) —— 编辑臂 `respondFreeFormRules` 与批臂 `respondBatchRuleOffers` 两条同形存量共用一条,与 `surfaceRememberNotApplied` 同族纪律:决断照送、只是规则没存,静默丢掉用户明确意图 = 让人以为功能坏了)· `projectCrashConverged`(L-38,0.49.0:`/v1/approvals` additive 键 `crashConverged` 的分桶投影 —— 崩溃收敛的孤儿审批读面,**缺席 ≠ 空数组**、分桶恰一个合取、坏行丢弃并计数,详见 §12;同批把 `ApprovalsResourceLike.list()` 的返回位 additive 放宽成 `ApprovalsListEnvelope`,老形 `{pending}` 仍可赋值)· `readRuleOffers` / `readRuleOfferSupply`(L-103/[C228],0.57.0 additive 导出:「不再询问」候选两代 wire 键的窄读器**公面化** —— 此前只经卡端口出包,不走卡端口架构的宿主只能自己重铸一把,而它承载的是兑付安全判据(原始下标不前移/逐条丢坏/闭集 kind/两代取舍序),详见 §20)· `RULE_OFFERS_ABSENCE_REASONS` / `DENIAL_LIMIT_KINDS`(0.59.0 / sdk 8.3.0 提货:`ruleOffersAbsence` 三词与 `denialLimitFallback.limit` 二词的**运行期**闭词表再导出 —— 与 0.58.0 那三张同一条纪律:端拿它做判定别再手抄字面量。⚠️ **本包自己不拿这两张表做窄读判定**(两处都按开集透传,词表属主是 core、server 已按闭集拒过),再导出只是给端的 `switch` 一份可数的表,端仍必须带 `default` 臂,详见 §23a)· `DecideTransportRetryExhaustedError`(Inkglow-1085 P0a:decide 出站瞬断重试耗尽的 typed 判别 —— HitlBridge 内建单次退避重试,耗尽走重呈臂不判死 turn;端一般只消费行为,不需要 instanceof) · `gateOutcomeOf` / `isDeniedGate` / `gateDeniedBy` / `gateApprover` / `isApprovalWindowExpiredGate` / `isDenialLimitAutoDeniedGate` / `isParkSlaExpiredGate` / `isHumanSettledGate`(0.60.0 / engine ≥7.64.0:`tool_end.gate` 整条门记录的窄读器 + 判定谓词 —— 取代退役的四个正交词 `settledBy`/`resolution`/`autoDenied`/`approver`。🔴 **判定归包**:「是不是审批窗自己走完的拒绝」旧形上是端各自拼的两键合取,而三条窗词现在分得开、合并读回去等于把刚修好的判别力扔掉;⚠️ 公面型一律带 `View` 后缀 —— 本文件的 `GateOutcome`(决断腿结局)与 sdk 的 `GateOutcome`(引擎门记录)**同名不同义**,详见 §24c)· `isGateParkedToolEnd`(「这次调用没在这里结算」的**第二形**谓词:gate 缺席 + `errorCode:"gate.parked"`;端判这件事必须与 `isApprovalWindowExpiredGate` **两形合读**) · `readWireErrorCode`(B-037 候包件②:decide/取件失败上引擎 wire 机器码的单源读口,结构视图读不 `instanceof`;与本包铸的 `code` 是两个命名空间,详见 §24g)| suspended→decide→resume 环。🔴 **D-1 两元组 verbatim 回显**是字节级断言的安全不变量,端**不许重实现它的任何一段**。🔴 键空间边界(web [C1] d3 拦截):`gateIdentity` 四常量两函数只覆盖 HITL questionId/callKey 空间;seat 的 `TOOL_PERMISSION_REQUEST_ID_DOMAINS`(`plan:` 等)是另一键空间,**两者绝不合并**(合并=座位校验器静默拒全部 plan-review 卡) | `src/hitl/hitlBridge.ts`、`toolApprovalWire.ts`、`askGateWire.ts`、`planReviewWire.ts`、`hitlHostSurface.ts`、`gateIdentity.ts`、`armedGateRegistry.ts`、`parkOwnership.ts`、`parkResolver.ts`、`approvalsFeed.ts`、`frameRouter.ts`(**只挑名导出** `toolEndOutputText`/`ENGINE_ABORT_TOOL_RESULT`/`isAskTool`/`HITL_REJECT_MESSAGE`/`HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE`)、`parkRowBirthWait.ts`、`approvalDecisionNoteAudit.ts`、`askParkRowRouting.ts`、`resumeRunningCard.ts`(#265 上收的判定层)、`persistedRulesWire.ts`、`localAllowRule.ts`(#244 F2 规则侧)、`crashConverged.ts`(L-38 崩溃收敛读面)、`src/gateOutcome.ts` |
|
|
162
162
|
| 4 | **子代 wire + 面板侧信道台账** | 89 | `isStaleEngineAgentPanelEnd`(0.74.0 CC-66:面板 end 的周期身份判据;§68)· `subscribeEngineAgentPanelAbsence` / `publishEngineAgentPanelAbsence`(0.72.13:fleet 行缺席上报的**独立订阅口** —— 不上主通道,老消费者结构上收不到;§60 S-5)· `tailEngineSubagent` · `installSubagentActivitySink` · `installSubagentTailMetaSink`(#280 件2:tail meta 帧发布口,`contentFrames` 判别位载体)· `stopEngineTask` + `classifyTaskStopConflict` · `fetchEngineSubagentReport` · `steerEngineSubagent`(0.32.0 未发布 #280 件A:additive 第三参 `childTaskId` —— 端有行上下文时**应当**传,传了就走「台账优先 / 缺席即诚实缺席 + `noteBgOwnerAbsence` 留痕」的 Q3 口径,与 tail·taskOutput·subagentOutput 三腿同姿势、与孪生 resume 腿共用同一个 `resolveOwnerRunId` 判据;**不传**则逐字维持旧行为=回落在飞 run)· `resumeSettledSubagent` + `resolveSubagentResumeContext` + `resolveOwnerRunId` + `classifySubagentResumeFailure` + `subagentResumeAvailable`(#242 批 2 A-028.7:resume 判定半场上收,与 steer 孪生同居;取址三态 = 台账有行用行值 / 指名了行但台账缺席则**诚实缺席绝不回落在飞 run** / 没指名行才回落。出路文案归端)· `recordSubagentOwnerFromProgress` + `getBgParentRunOwner`(A-028.6:「子代 → 宿主 run」**单表**,宿主 run 必须由持 stream-local 值的调用方显式传入,包内绝不从 `activeEngineRunId()` 推断)· `noteBgOwnerAbsence`(#242 批 3 [4000] Q3=B:tail/taskOutput·taskStop/subagentOutput 三腿台账缺席即诚实缺席**绝不回落在飞 run**,缺席 warn 留痕每 (腿,taskId) 一条)· `clearBgTerminalFacts`(#242 批 3 扫码修:复活=新周期,旧周期终态事实作废——fleetLedger 复活两腿按尾段清账,factsAccepted 方向核不再拿上周期终态当先例)· `auditRetainWithoutWake`([4000] Q5:引擎宣示 `subagentResume` + 本端在付 `retainSubagentSessions` + 端未实现 `wakeSubagent` ⇒ 响亮一条;`CLIENT_VERBS.wakeSubagent` 维持 fail-soft)· `subscribeSubagentContent` · `subscribeEngineAgentPanel` · `publishQuestionFrame` / `respondToQuestion` · `configureSubagentContentStore` / `subagentContentStoreConfig` / `SUBAGENT_CONTENT_STORE_DEFAULTS`(0.62.0:子代内容账本的**字节预算** —— 此前只有条数帽而单条无上限,一条 base64 工具结果就能让一个子代槽吃到十几 MB;越限从最早的内容开始丢并留一条可渲染的 `truncated` 记录,总帽淘汰整条最久未用的账本。配置面 fail-loud,详见 §26②)| 驱动与观测委派子代;经 module 级台账喂活体 agent/task 面板。全部**能力位 gate**(§5b) | `src/subagent/*.ts`、`src/subagentContentStore.ts`、`src/engineAgentPanelStore.ts`、`src/engineInlineTaskStats.ts`、`src/engineToolLabelStore.ts`、`src/liveQuestionStore.ts` |
|
|
163
163
|
| 5 | **fleet 投影** | 38 | `createFleetLedger` · `projectTasks` · `projectWorkflows` · `projectFleetAgentRows` · `readEngineActiveBgTasks` · `FLEET_TASK_VIEW_KEYS` · `escapeDisplayControlChars`(不可见字符可见化,行标签/描述消毒的共享底座)· `capForDisplay`(0.62.0:呈前**消毒 + 封长**的共用铸点 —— 先转义、后按转义结果封长,截点避开半截转义 token 与合法代理对;本包该族四处此前各写一份、其中三份顺序是反的,详见 §26⑦)· `wireCycleSeq`(0.38.0 提货补投的 #261 §2 两位之一,另一位 `wireRetiredBy` 🔧 0.72.0 退出公面:代际号 = SendMessage 复活即 +1,**缺席 ≠ 第一代**;`retiredBy` 在场 = 这条终态是对账腿从 durable run 行投影出来的、**不是**发布方亲报 —— 幽灵行与正常收尾唯一的 wire 判据。两位都只在场才落键) | 老 `fleetClient` 那一刀的成品:**帧体归库、连接归端** —— 端持 SSE 连接,库做行投影 + 保留台账 | `src/fleet/fleetProjection.ts`、`src/fleet/fleetLedger.ts`、`src/fleetAgentPanelProjection.ts`、`src/fleetTaskDesc.ts` |
|
|
164
164
|
| 6 | **请求装配(上行唯一构造口)** | 13 | `MEMORY_OFF` / `memoryOffDeclarationField` / `memoryOffDeclared`(0.72.8 CC-39③:`memory:"off"` 请求级整面关的意图位片段;§55)· `buildTaskRequest` · `REQUEST_FIELD_MATRIX` · `unregisteredRequestKeys` · `applyLiveRequestDefaults` · `taskNotificationToPrintFrame` | 两条车道(`interactive`/`print`)出站请求的**唯一**构造器;`unregisteredRequestKeys` 是可执行门 —— 端偷带一个未登记键上 wire 就红 | `src/request/taskRequest.ts`、`src/request/printNotification.ts` |
|
|
165
165
|
| 7 | **通知与 outstanding 台账** | 52 | `noteOwnWorkflowRun`(0.72.2 CC-37:own 台账显式登记口,adapter workflow lane 门在 own-run 正向证明下同拍调;§49)· `installNotificationQueuePort` · `normalizeTaskNotification` · `taskNotificationDedupKeyFromWire` · `registerOutstandingBgTask` / `registerOutstandingWorkflowRun` · `notificationQueuePortMisses` · `subscribeOutstandingWorkflows` · `outstandingDeliverableWorkflowCount` | `task_notification` 归一 + 去重 + 投递进宿主命令队列的**一把闸**;`outstandingDeliverableWorkflowCount()` 是 headless `-p` 的**退出门** · `classifyPeerNotification` / `renderPeerFrameTranscriptText` / `parsePeerFrameText` / `peerFrameDisplayName` + 三张闭集表(design/385,0.54.0:同一条 `task_notification` 车道上三条**引擎注入帧**的类型化投影 —— 判别位=载体在场而非 summary 文本,详见 §17) | `src/notifications.ts`(11 个 module 台账) |
|
|
166
166
|
| 8 | **工具结果卡** | 24 | `structuredToToolUseResult` · `readAsyncLaunchedAgentReceipt` · `wireOutputToBody` · `parseModelFacingBash` · `getPatchFromContents` · `toolEndResultToUserFrame` · `flattenToolOutput` | 铸端要渲的 `tool_result` 卡体,含客户端 diff hunk(唯一 runtime dep 的用处) | `src/toolResult.ts`、`src/printToolResultFrame.ts`、`src/diff/patch.ts` |
|
|
167
|
-
| 9 | **能力/旋钮 wire 门族** |
|
|
167
|
+
| 9 | **能力/旋钮 wire 门族** | 115 | `projectDeviceExecutorManagementCapability` / `noteEngineCapsForDeviceExecutorManagement` / `observedDeviceExecutorManagement` / `forgetDeviceExecutorManagementReading` / `deviceExecutorManagementDoctorDetail` / `deviceManagementVerbsAvailable`(0.74.2 CC-69;§70)· `projectApprovalsStreamLiveCapability` / `noteEngineCapsForApprovalsStreamLive` / `observedApprovalsStreamLive` / `forgetApprovalsStreamLiveReading` / `approvalsStreamLiveDoctorDetail` / `livePendingNeedsReconcile`(0.73.3 CC-61;§65)· `projectExecutionLaneCapability` / `noteEngineCapsForExecutionLane` / `observedExecutionLane` / `forgetExecutionLaneReading` / `executionLaneDoctorDetail` / `toolsRunHereFromExecutionLane`(0.72.13 CC-54:`capabilities.executionLane` 四态读面,键缺席 ≠ 不是本机车道;§60)· `AGENT_MEMORY_WORDS`(0.72.3 CC-39①:`memory: user|project|local` 三词;`projectAgentsForWire` 把它们同映射为 `agents[].memory = { scopes:[agent:<type>], writeScope }`;§50)· `skillBaseDirOf`(0.72.1 CC-33:`SkillSpec.baseDir` 窄读 = server 顶层门同一只结构判据;`skillCommandsToSpecs` 第三参 `{ toolsRunHere }` 只在本机车道带;§48)· `projectAgentsForWire` / `awaitTaskAgentsWire` · `hooksForWire` · `mcpConfigsToSpecs` · `ultracodeForRequest` · `resolveWebSearch` + `buildWebSearchEnv` · `attachmentsForRequest` · `projectEffectiveBody` · `classifySelfOrchestrationRefusal` / `stripSelfOrchestrationIntent` / `projectWorkflowsGate` / `SELF_ORCHESTRATION_RETRY_WITHOUT`(S-81,server 7.57.0:上面两条 stamp 腿的**背面** —— 半配置多租户形态下 server 把带 `selfOrchestration` / `settings.ultracode` 的提交 501 拒掉,判型/去键/caps 闸三处都是判定不是文案,详见 §13) · `engineCapsGeneration`(0.60.0,异源对抗复审 [medium] 逼出:caps 探测的**当代号**读口 —— 代际闸在 probe **返回之后**才跑,而宿主的读面 tee 是在 probe **内部**落地的 ⇒ 一次慢的旧探测能把上一台引擎的读数写回来。宿主在**起探测那一刻**抓号、tee 时交回 `{generation}`,陈旧那一发整只丢掉;不传 = 逐字节同行为,详见 §24e)| 逐功能的「引擎有没有这个能力 + 这个字段怎么上 wire」投影器,由 `buildTaskRequest` 组装。🔴 `hooksForWire()` 是 **fail-closed**:无 `SettingsPort` ⇒ 返回 `undefined`(信任门,不是取值) | 17 个 `src/*WireCaps.ts` + `src/scratchpadWireCaps.ts`、`src/hooksWireCaps.ts`、`src/goalStopHook.ts`、`src/websearch/searchProviderPresets.ts`、`src/selfOrchestrationDenial.ts`(S-81 拒绝判定层) |
|
|
168
168
|
| 10 | **headless / 部署旋钮 wire** | 60 | `probeEngineDetachSupport` / `detachSupportDisclosure`(0.72.13 CC-53:detach 版本闸三态读口 + 披露句;§60)· `parseSandboxArgv` / `sandboxRequestFields` · `parseLimitsArgv` / `limitsForPrint` · `resolveHeadlessFinalVerify` · `resolveHeadlessPermissionMode` · `resolveHeadlessInteractiveTools` · `armDetachCancel` + `detachCancelArm` + `isDetachArmed` · `withHeadlessR1Reconnect` | `-p`/headless 车道的 env+argv 旋钮。🔴 `detachWire` 是**拆**的补偿:判定与 cancel-arm 台账在库,信号路径的裸 fetch 留宿主(`detachCancelArm()` 是取件口) | `src/sandboxWire.ts`、`scenarioWire.ts`、`finalVerifyWire.ts`、`limitsWire.ts`、`interactiveToolsWire.ts`、`headlessPermissionModeWire.ts`、`headlessReconnectWire.ts`、`detachWire.ts` |
|
|
169
169
|
| 11 | **模型目录与预算** | 67 | `routePairingVerdict`(0.71.3 CC-06:`ModelInfo.routePairing` ok / broken / unknown 三态读口,§45)· `resolveModelCatalog` · `loadCatalogWithSources` · `PROVIDER_PRESETS` / `MODEL_FAMILIES` · `defaultMaxTokensFor` · `getLiveModelCatalog` / `setLiveModelCatalogRefresher` · `providerAuthMethods` / `beginDeviceCodeAuth` · `providerCatalogRows` / `providerCatalogRowDetail` / `providerPresetById`(#244 F4 族D A-028.17:46 家表的规范折表层 —— 全表不重排、诚实缺席「model id typed in」,cli 目录/web 向导同一份折表)· `TIER_ORDER` / `CC_TIER_ALIASES` / `isTier` / `resolveTierBinding`(A-028.18:档位词表+校验+fail-open 降档派生单源;settings 存储归宿主)· `resolveEntryVision` / `computeDeleteBlockers` / `computeDeleteWarnings`(0.38.0 #318 件③ 上收:Model Hub 供给面的三端公共判定 —— vision 生效值+来源三态、删除断链核(拒删+指路)、删除降级后果(照删但必说)。**零 IO**,读盘那半场留各端;`doc === null` 的两义在调用方分流) | 三层 provider 目录解析(线上 URL → 包内预设 → 用户覆盖)+ per-model `maxTokens` 封顶。线上腿需注入 `CatalogFetchJson`,缺席 ⇒ 整条不启用(`online.reason='no-fetch-port'`);缓存落盘经 `CatalogCachePort` | `src/model/{catalog,catalogLoader,providerAuth,providerPresets,providerCatalog,tierVocabulary}.ts`、`src/liveModelCatalog.ts`、`src/modelBudgetRule.ts`、`src/sessionModelLatch.ts`、`src/effortWire.ts` |
|
|
170
170
|
| 12 | **workflow 与后台工作视图** | 36 | `evaluateWorkflowSize` / `readWorkflowSizeWarningEnvCaps` / `workflowSizeWarningTextForWidth` + `WORKFLOW_SIZE_WARNING_AGENT_CAP` / `_TOKEN_CAP` / `_TOKENS_PER_AGENT` / `_ENV_NAMES` / `_TEXT_LONG` / `_TEXT_SHORT` / `_TEXT_MIN` / `WORKFLOW_SIZE_GUIDELINE_AGENT_CAPS`(0.73.5 CC-58:规模告警判定三态;§67)· `projectLeaderConflict` / `leaderConflictDetail` + `LEADER_RUN_STATUSES` / `LEADER_REJ_HEAD_DISPLAY_MAX`(0.72.10 CC-41:leader run 终局 `needs_human` + `result.conflict` 三形读面 none / unreadable / conflict,缺席不可分、filesTruncated 只认 true、salvaged 原样给落盘口;§57)· `projectWorkflowRun` · `readWorkflowResumeAdmissionIncomplete`(0.68.3 CC-05:core 7.18.0 `resumeAdmissionIncomplete` 在场 = 不是 resume 基,与 `readWorkflowParks` 同一条投影义务)· `createLiveWorkflowSource` · `ensureWorkflowActivityLedger` · `readWorkflowActivityLedger` · `stopWorkflowActivityLedger` · `resetWorkflowActivityLedgers` · `createBackgroundView` · `projectBackgroundView` · `recordWorkflowAgentTaskId` · `agentDisplayStatus` | 活过一个 turn 的长任务读面:workflow run + 跨 session 后台任务归一表(`assistant.tasks` 与 fleet SSE **两源独立降级**) | `src/workflow.ts`、`src/workflowClient.ts`、`src/workflowMonitor.ts`、`src/agentSession/backgroundView.ts`(+ 纯类型 `src/agentSession/contract.ts`) |
|
|
@@ -8997,7 +8997,8 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
8997
8997
|
|
|
8998
8998
|
### 68b. 缺席语义(逐键)
|
|
8999
8999
|
|
|
9000
|
-
- `covers` 缺席 = 目录出路(老引擎,或这条 ask 的候选本来就是目录)。**不是**「未知」—— 上游承诺缺席即目录。出闭集 ⇒ 整个 `readRootCandidate`
|
|
9000
|
+
- `covers` 缺席 = 目录出路(老引擎,或这条 ask 的候选本来就是目录)。**不是**「未知」—— 上游承诺缺席即目录。出闭集 ⇒ 整个 `readRootCandidate` 键不在卡上。🔴 **谁负责判**:「这一串是不是目录」由 server 判(契约 §4 专条),本包**不自判 dir 形**,只做闭集校验与整座缺席 —— 上游若对目录送了 `"exact"`,本包照传(黑盒 L0 G2-c 实测,已登 KNOWN-LIMITS)。
|
|
9001
|
+
- 🔴 代际号取值规则(0.74.2 成文):`fleet-row.cycleSeq` / `end.cycleSeq` / 通知 `seq` **只认正整数**;坏形(0 / 负数 / 小数 / 非数 / null)与缺席一律按缺席处理,键不出、不钳、不编。
|
|
9001
9002
|
- `end.cycleSeq` / `end.startedAt` 缺席 = 这条终态没有周期身份(流内 close 臂 / 没有代际概念的行 / 老引擎)⇒ `isStaleEngineAgentPanelEnd` 恒 `false` ⇒ 按现行为 settle。**不是第一代**。
|
|
9002
9003
|
- `fleet-row.cycleSeq` 缺席 = 这一行没有代际概念(同步委派子代 / workflow agent / 顶层 run)或老引擎;不补 1。同周期内粘性:后一帧没报,沿用本周期已知值;周期变了(`cycleSeq` 或 `startedAt` 变)不继承。**前代迟到帧**(台账已是更新一代、帧是更早一代;判定与 `isStaleEngineAgentPanelEnd` 同一条规则,含只带 `startedAt` 的帧)在包内整只跳过,端根本收不到;端侧的 `isStaleEngineAgentPanelEnd` 是第二道(流内 close 臂 / 通知车道 / 缓冲重放等包内挡不住的来源)。周期身份推进本身算变化:连续两代终态即使别的键全不变,也先发 `fleet-row{新代}` 再发 `end{新代}`。
|
|
9003
9004
|
- `FleetTaskRemoval.removeReason` 缺席 = 常规清场(server 没说原因);`cycleSeq` 缺席 = 退场帧没带代际 ⇒ 判不出新旧 ⇒ 照删(现行为)。
|
|
@@ -9030,3 +9031,83 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
9030
9031
|
|
|
9031
9032
|
**包侧缺口:** ⓪ CC-67 无决断撤卡口 + CC-68 流内帧腿 outcome 回交(窗 09-22);① CC-69 `capabilities.deviceExecutor.management` 四态读口(server 7.88.0;窗 09-23);② headless(`-p` / SDK-stdio)无卡口 ⇒ 不装审批 feed,悬挂 ask 只进 doctor 面(成文候 CC-67 同批);③ CC-36 托管 MCP 活性三态读口(候 core #874);其余同 §67。
|
|
9032
9033
|
|
|
9034
|
+
## §69 🆕 0.74.1 审批卡无决断收口(CC-67)+ 流内帧腿结局回交(CC-68)+ headless 成文;patch
|
|
9035
|
+
|
|
9036
|
+
> **patch**:型面纯 additive(+1 常量,公面 1045 → 1046;`ApprovalCardDecision` +`retracted` 臂;`ToolApprovalFrameOutcome` +`retracted?`;`FsApprovalOutcome` +`retracted` 臂;`AskGateWireDeps` +`onToolApprovalOutcome?`;零 wire 新键;peer 不动)。票来源:cli L-397 装配直讯两件。
|
|
9037
|
+
|
|
9038
|
+
### 69a. 处置表
|
|
9039
|
+
|
|
9040
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
9041
|
+
|---|---|---|---|
|
|
9042
|
+
| S-1 | 卡口结局 `{ kind: 'retracted', reason? }` | **新增**:三条腿都零发送,结局 `unresolved` + `retracted` | 撤一张已无决断口的卡(换会话 / 换引擎 / tracker `gone`)时回它,**别**回 `aborted`(那仍是拒);`reason` 只留痕 |
|
|
9043
|
+
| S-2 | `onToolApprovalOutcome(frame, outcome)` | **新增**(可选;每次流内帧腿决断后恰一次) | 装上后直接按 `outcome.decision` / `retracted` / `editRefused` 判落没落定;`noteSurfacedByStream` 的孤儿认领据此回收 |
|
|
9044
|
+
| S-3 | headless(`-p` / SDK-stdio) | **成文**:无卡口 ⇒ **不装审批 feed**(挂上去只会白取件,并把一张按不下去的卡记成出过卡);悬挂 ask 只进 doctor / 提示面 | headless 车道不调 `startApprovalsFeed`;要展示悬挂数读 `livePendingNeedsReconcile` 与 feed 摘要之外的 doctor 面 |
|
|
9045
|
+
|
|
9046
|
+
### 69b. 缺席语义(逐键)
|
|
9047
|
+
|
|
9048
|
+
- `ToolApprovalFrameOutcome.retracted` 缺席 = 没发生撤卡(与 `editRefused` 同款附加位)。`decision: 'unresolved'` 本身仍只说「respond 没送达」。
|
|
9049
|
+
- `FsApprovalOutcome.kind === 'retracted'` 时 `gatedCallId` 与别的臂同一缺席纪律。
|
|
9050
|
+
- `onToolApprovalOutcome` 缺席 = 宿主不消费结局,路由行为逐字同旧。
|
|
9051
|
+
|
|
9052
|
+
### 69c. 黑盒判据骨架
|
|
9053
|
+
|
|
9054
|
+
- **G1**:假卡口回 `retracted` ⇒ 流内帧腿 `respond` 零次、`outcome.retracted === true`;修前:`respond(id, 'deny')` 一次。
|
|
9055
|
+
- **G2**:同一卡口回 `aborted` ⇒ 仍 deny 一次(语义不动;负控)。
|
|
9056
|
+
- **G3**:悬挂 ask(盲卡 / 全卡)撤卡 ⇒ 零 respond;durable-park 腿撤卡 ⇒ `decide` 零次、`kind: 'retracted'`。
|
|
9057
|
+
- **G4**:`routeFrame` 带 `onToolApprovalOutcome` ⇒ 每帧恰一次回交;回调抛错不拆流。
|
|
9058
|
+
|
|
9059
|
+
### 69z. 逐键处置表
|
|
9060
|
+
|
|
9061
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
9062
|
+
|---|---|---|---|
|
|
9063
|
+
| 1 | 卡口结局闭集 | **additive +retracted** | `src/hitl/toolApprovalWire.ts` `#ApprovalCardDecision` / `#RETRACTED_CARD_DECISION_KIND` |
|
|
9064
|
+
| 2 | 流内帧腿 / 悬挂 ask / durable-park 三腿 | **consumed(零发送臂)** | 同文件 `#surfaceToolApprovalFrameAndRespond` / `#surfaceFsApprovalAndDecide`;`src/hitl/parkResolver.ts` fail-soft 真因 |
|
|
9065
|
+
| 3 | 路由结局回交 | **additive** | `src/hitl/frameRouter.ts` `#AskGateWireDeps.onToolApprovalOutcome` |
|
|
9066
|
+
|
|
9067
|
+
### 69y. 🔴 三端升级必读(固定段式,[C295])
|
|
9068
|
+
|
|
9069
|
+
1. 换钉 `^0.74.1`:撤卡路径改回 `{ kind: 'retracted' }`;`aborted` 只留给用户真放弃。
|
|
9070
|
+
2. 装 `onToolApprovalOutcome` 后,孤儿认领回收改读结局;不装零变化。
|
|
9071
|
+
3. headless 不装审批 feed。peer 不动。
|
|
9072
|
+
|
|
9073
|
+
**包侧缺口:** ⓪ CC-69 `capabilities.deviceExecutor.management` 四态读口(窗 09-23);① CC-70 面板子代身份归一(窗 09-23);② CC-71 run 记录 `cancelContext` 读口 + 三分成因判定(窗 09-24);③ CC-36 候 core #874;其余同 §68。
|
|
9074
|
+
|
|
9075
|
+
## §70 🆕 0.74.2 `capabilities.deviceExecutor.management` 四态读口(CC-69);patch
|
|
9076
|
+
|
|
9077
|
+
> **patch**:型面纯 additive(+6 函数,公面 1046 → 1052;测试钩 49 → 50;零 wire 新键;peer 不动)。票来源:server 7.88.0 [7636] / [7637] @client-core 点名,表态 [7643]。
|
|
9078
|
+
|
|
9079
|
+
### 70a. 处置表
|
|
9080
|
+
|
|
9081
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
9082
|
+
|---|---|---|---|
|
|
9083
|
+
| S-1 | `capabilities.deviceExecutor.management`(server ≥7.88.0;present-iff) | **consumed**:四态读面六导出 + `deviceManagementVerbsAvailable` | caps probe 落点旁多调一只 `noteEngineCapsForDeviceExecutorManagement`(与五只兄弟同处);要不要渲 `/v1/devices` 管理入口读 `deviceManagementVerbsAvailable(observedDeviceExecutorManagement())`:`'yes'` 渲、`'no'` 不渲、`'unknown'` 按 501 试探(别当 no) |
|
|
9084
|
+
| S-2 | 六只能力位读器的 tee(同形存量族扫) | **fixed**:抛 getter / Proxy 的回体 ⇒ 删格(不留上一台读数);校验与返回同一次读 | 零接线;doctor 面上原本可能残留的陈旧 `present` 现在会变 `unobserved`,那是对的 |
|
|
9085
|
+
|
|
9086
|
+
### 70b. 缺席语义(逐键)
|
|
9087
|
+
|
|
9088
|
+
- `management` 键缺席(车道对象在场)= 7.88.0 之前的 server,**判不出**(真字节:7.87.3 车道真开无此键);**不是** false。
|
|
9089
|
+
- `deviceExecutor` 键整个不存在 = 更老 server,判不出(fixture-only,无真版本见证)。
|
|
9090
|
+
- `deviceExecutor: false`(键在、值 false)= 本部署没有 device 车道 ⇒ 管理动词一律 501 `capability.device_lane_required`,读数 `lane_absent`。
|
|
9091
|
+
- 读口空缺 = 本进程还没拿到 caps 回体 ⇒ `unobserved`。
|
|
9092
|
+
|
|
9093
|
+
### 70c. 黑盒判据骨架
|
|
9094
|
+
|
|
9095
|
+
- **G1**:7.88.0 车道开 ⇒ `present` / `management: true` ⇒ `'yes'`;7.88.0 车道关(`deviceExecutor: false`)⇒ `lane_absent` ⇒ `'no'`;7.87.3 车道开(无 `management` 键)⇒ `not_reported` / `management_absent` ⇒ `'unknown'`(三形真字节:test `repro/srv7880-A-20260919`)。
|
|
9096
|
+
- **G2(fixture-only)**:`deviceExecutor` 键不存在 ⇒ `not_reported` / `capability_absent`。
|
|
9097
|
+
- **G3**:tee 后换代 forget ⇒ `unobserved`;陈旧代际整只丢。
|
|
9098
|
+
|
|
9099
|
+
### 70z. 逐键处置表
|
|
9100
|
+
|
|
9101
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
9102
|
+
|---|---|---|---|
|
|
9103
|
+
| 1 | `capabilities.deviceExecutor.management` | **consumed(四态;sdk 无型结构读)** | `src/deviceExecutorManagementCapability.ts`;engine-caps-ledger 台账同批 |
|
|
9104
|
+
| 2 | `/v1/devices/*` 三动词 / `TaskRequest.deviceId` | **n/a(cli 车 B 的面)** | [7638] |
|
|
9105
|
+
|
|
9106
|
+
### 70y. 🔴 三端升级必读(固定段式,[C295])
|
|
9107
|
+
|
|
9108
|
+
1. 换钉 `^0.74.2`:caps tee 加 `noteEngineCapsForDeviceExecutorManagement`;管理入口按 `deviceManagementVerbsAvailable` 三态渲。
|
|
9109
|
+
2. 不接线零变化(恒 `unobserved` ⇒ `'unknown'`)。
|
|
9110
|
+
3. peer 不动;server <7.88.0 ⇒ `not_reported`。
|
|
9111
|
+
|
|
9112
|
+
**包侧缺口:** ⓪ CC-70 面板子代身份归一(窗 09-23);① CC-71 run 记录 `cancelContext` 读口 + 三分成因判定(窗 09-24);② CC-36 候 core #874;其余同 §69。
|
|
9113
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.2",
|
|
4
4
|
"description": "Client-side session runtime shared by every sema human client (TUI / web / desktop): sema wire frames (AgentEvent) -> CC session vocabulary (SDKMessage) with dual-plane output (transcript/chrome), deterministic transcript ids, lane discipline as a type, and the notification/dedup ledgers. Every CC-skin shape is collected here so the wire itself stays neutral. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|