@sema-agent/client-core 0.74.3 → 0.74.5
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 +27 -0
- package/README.md +3 -3
- package/dist/adapter/downstream/eventToSdkMessage.js +4 -0
- package/dist/engineAgentPanelStore.d.ts +17 -3
- package/dist/engineAgentPanelStore.js +189 -6
- package/dist/fleetAgentPanelProjection.js +11 -1
- package/dist/hitl/approvalOutcomeNote.d.ts +22 -0
- package/dist/hitl/approvalOutcomeNote.js +21 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/notifications.js +3 -2
- package/dist/panelRunningHistory.d.ts +8 -0
- package/dist/panelRunningHistory.js +38 -0
- package/dist/runCancelContext.js +13 -3
- package/docs/INTEGRATION-CLIENTS.md +96 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,33 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.74.5(2026-09-19)
|
|
53
|
+
|
|
54
|
+
> 主题:**core 7.24.0 提货**(CC-85 `compacted.freedTokens?`)+ **首见即终态的行零事件**(CC-86;cli L-415 幽灵完成行)+ **`isNewEngineAgentPanelCycle` 上公面**(CC-87)。**patch**:型面 additive(+2 常量 +2 函数,公面 1061 → 1065;`compact_metadata._sema_freed_tokens?` 超集键;零 wire 新键 —— `freedTokens` 由 core 7.24.0 铸;peer 不动)。接入面 §73。
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **`compact_metadata._sema_freed_tokens?`(CC-85;core 7.24.0 #946)**:`compacted.freedTokens?` 是引擎自己测的结构性差值(夹 ≥ 0),旧的 `tokensBefore` / `tokensAfter` **不是可相减的一对**;在场(有限非负数)才带,缺席 = 没测出来 ⇒ 键不落,渲「未知」不是 0。CC 同名键 `pre_tokens` 一字不动(它是 CC 必填数,`tokensBefore` 缺席仍兜 0 —— 记 KNOWN-LIMITS)。
|
|
59
|
+
- **`approvalOutcomeNoteOf(frame, outcome)`(CC-88;cli 归包候票)**:流内帧腿审批结局 → 宿主便签 `{approvalId, settled, retracted?, detail?}` 的单源映射(三端装配点此前各手拼一份;语义按 cli 1.0.123 现行:`settled = decision !== 'unresolved'`,`retracted` 只在 true 时带键且不含 editRefused,`detail` 三支优先序撤卡句 / 编辑被拒句 / `respondRefusal` 码·文案,空 ⇒ 缺席);两句固定文案作常量出。
|
|
60
|
+
- **`isNewEngineAgentPanelCycle(prev, next)`(CC-87)**:「这一帧是不是新周期」的单源判据(`isStaleEngineAgentPanelEnd` 的对偶;两边都带 `cycleSeq` 只比它,否则比 `startedAt`,任一边判不出 ⇒ 不是新周期);缓冲合并屏障 `launchAnchorChanged` 改为委托它。
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- **反向所有权按 transcriptId 到期(test [7718] 契约层反例)**:0.74.4 的「尾段 → 先发布的 UUID」所有权只按周期键到期,行帧两个周期键全缺(真字节里只有 root 形行如此,子代行恒带)时复活的新一代被改写到旧 UUID ⇒ 消费端一条已结的行又收新帧;现在登记时记 transcriptId,换了 = 新一代子会话,所有权同样到此为止。
|
|
65
|
+
- **首次见到就已终态的 fleet 行零事件(CC-86;cli L-415)**:此前对 prev 缺席且 status 终态的行先发 `fleet-row`(交最终用量)再发 `end` ⇒ 宿主为本会话从没跑过的任务建行随即 settle = 面板幽灵完成行(reattach / resume 后引擎 fleet 列表里的历史终态行全部上屏)。现在只在台账记 settled、不发事件;「首见」= **本进程**从没发布过它在跑(历史作用域 = 面板订阅作用域,不按会话分桶 —— A 会话发的 running 行由 B 会话的终态帧结掉是常态;发布过 running 的行即使台账已回收,迟到终态仍照发 end;历史结掉即删 —— **任何 lane 的 `end` 到漏斗都销账**(通知车道的 end 不经投影;只销当代,前代迟到的 end 不擦新一代)、有界 4096、溢出后转保守不再压制,直到整表重置;共享叶 `src/panelRunningHistory.ts`;异源对抗复审 R1 / R2 三条所抓;R3 四条:父键登记的所有权按 wireId 作转录身份到期 / 归一 end 的退役按**事件自带**周期判(缺席才借钥匙,与递达同一身份)/ 已发布 UUID 的 end 连它名下尾段的历史一起销 / 只在真发布了 running 行帧时记历史,未变的陈旧快照不把结掉的 id 记回去);本会话内起步又结束而面板从没见过 running 的后台任务由通知车道的 `end` 收尸;复活(已 settled 且周期更新)照发。
|
|
66
|
+
|
|
67
|
+
## 0.74.4(2026-09-19)
|
|
68
|
+
|
|
69
|
+
> 主题:**面板键「先发布的键为准」**(CC-83;test [7702] 证伪 0.74.3「面板桥零改」)+ **前代 UUID 的迟到 tick 丢弃**(CC-84;test [7702] W2 tick 腿)+ `readRunCancelContext` 下钻收紧。**patch**:型面 additive(`fleet-row` 臂 +`wireTaskId?` / `taskIdOrigin?`,`end` 臂 `taskIdOrigin` 多一词 `'wire'`,`EngineAgentPanelAbsence` +`wireTaskId?`;公面导出名零增减 1061;零 wire 新键;peer 不动)。接入面 §72。
|
|
70
|
+
|
|
71
|
+
### Fixed
|
|
72
|
+
|
|
73
|
+
- **面板键「先发布的键为准」(CC-83)**:0.74.3 把 tick / end 归一到 fleet 尾段,但 tick 归不了一而按 UUID 原样发出的三种序(行帧前两条 tick / 缓一拍拍数耗尽 / 绑卡 tick 后来了行帧)里,随后的行帧仍按尾段发 ⇒ 按 `ev.taskId` 落表的宿主仍长成两行,UUID 那行永远收不到 end(test [7702] N-3,本包亲核复现)。现在漏斗记「已按 UUID 发布」的子代(transcriptId 与 parentToolCallId 两把钥匙),之后的 `fleet-row` 与 fleet 侧 `end`(投影 / 通知)改写成那把 UUID —— 原尾段进 `wireTaskId`,`taskIdOrigin:'wire'`;常态序(行帧先到)仍归一到尾段。**消费端在任何到达序上只见一把键**;要 fleet 尾段的宿主读 `wireTaskId` / `taskIdOrigin`。
|
|
74
|
+
- **前代 UUID 的迟到 tick 不进复活行(CC-84)**:`end` 有陈旧判据(0.74.0 / 0.74.3),tick 没有 ⇒ 复活(cycle 1 → 2)后前代 UUID 的迟到 tick 归一成当代尾段,把前代的累计数写进复活行(test 读数 toolUses 0 → 99,做对 end 判据的宿主也躲不开)。现在漏斗按钥匙周期对最近行帧周期判(与 `end` 同一只 `isStaleEngineAgentPanelEnd`),前代 tick 丢弃;判不出不丢。
|
|
75
|
+
- **异源对抗复审(0.74.4 R1)三条**:① 尾段 → UUID 的反向所有权此前不带周期 ⇒ 复活的新周期(新 transcriptId)也被改写到旧 UUID、其 tick 却归一到尾段(同一子代再度两键)⇒ 所有权带登记时周期,行帧 / end 更新的周期到了就退出所有权、新周期按常态登记;② 所有权表按容量 FIFO 会把仍活着的已发布键忘掉 ⇒ 改成按生命周期退役(收到 end 后先让位,活着的键不被顶;上限 8192);③ 缺席上报与通知车道清常驻标仍按尾段 ⇒ 侧信道与主通道两把键 ⇒ 缺席事件按所有者 UUID 发(原尾段进新键 `EngineAgentPanelAbsence.wireTaskId?`),通知车道改走 `clearEnginePanelTaskResidentByWire`(尾段的所有者一起清)。**R2 两条**:④ 新周期行帧退出旧所有权时旧 UUID 未退役 ⇒ 同一张卡的退路键把新周期行帧又拉回旧 UUID ⇒ 退出即退役;⑤ 已发布的 UUID 的后续 tick / end 仍会经退路键归一到尾段 ⇒ 前代迟到 tick 进新周期的行 ⇒ **一把已发布的键永远不改写**(它的 tick 留在它自己的键上、它的 end 落在它自己的行上)。**R3 两条**:⑥ 迟到 tick 把已退役的键重置成未退役 ⇒ 退路键又能拉回它 ⇒ 退役位不被后续 tick 重置;⑦ 通知车道按尾段清常驻标时不带周期 ⇒ 前代通知(seq 更旧)清掉当代 UUID 的常驻标 ⇒ `clearEnginePanelTaskResidentByWire(id, cycle?)` 带通知周期,比所有权旧的不清;陈旧 end 过境让消费端判、不退役当代所有权。
|
|
76
|
+
- 门 `run-engine-identity-test.mjs` E2–E5 重钉:引擎产物的 `instanceId` 铸点扫 `main.js` + `boot/*.js`、`/health` 体扫 `http/*.js`(server 7.88.x 把启动拆成 `dist/boot/stage-*.js`、`/health` 搬进 `http/dispatch.js`;铸点仍无条件、体仍带 `instanceId`;此前只扫 `main.js` / `http/server.js` ⇒ 消费端换钉实跑本门假红)。7.88.2 发布字节与 7.89.0 本机树两形实跑绿。
|
|
77
|
+
- **`readRunCancelContext` / `classifyRunAbortCause` 的 `result` 下钻**只认像 run 结果的对象(带 `terminal` / `status` / `cancelContext` 任一键);`TaskResult` 自己的 `result` 键哪天成了对象不再被误当成结果记录(test [7702] §七 ④)。
|
|
78
|
+
|
|
52
79
|
## 0.74.3(2026-09-19)
|
|
53
80
|
|
|
54
81
|
> 主题:**面板子代身份归一**(CC-70;cli L-407 / test 定谳:同一后台子代在 wire 上两把身份)+ **run 记录取消现场读口与成因闭集**(CC-71;cli L-212 (a))+ **workflow 列表行 run 级 errorCode**(CC-72;core 7.23.5 #932)+ **reopen 族第二臂两件**(CC-73;cli L-56)。**patch**:型面纯 additive(+2 常量 +7 函数,公面 1052 → 1061;测试钩 50 → 51;`EngineAgentPanelEvent` 三臂各加可选键;零 wire 新键;peer 不动)。接入面 §71。
|
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.5
|
|
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
|
|
@@ -316,8 +316,8 @@ public-surface guard checks that last one).
|
|
|
316
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
317
|
| `scripts/run-run-cancel-context-test.mjs` | The run record's `cancelContext` side-note (engine ≥7.87.3) read structurally, and the cause of a `turn_aborted{engine_error}` classified from machine-readable evidence only: `cancelled` (code `cancelled`, with the cancel-time context when present) / `engine_error` (any other failure code, passed through verbatim) / `run_still_live` (the record is not terminal — a dropped stream is a client-side fact, not the run's cause) / `unknown` (never guessed). An absent `cancelContext` reads as *not reported*, never as "not cancelled"; `elapsedMs` is never folded to 0. |
|
|
318
318
|
| `scripts/run-suspended-reopen-projection-test.mjs` | The durable `suspended` event's `reopened` key read as three distinct states — `reopened` (with the engine's code, verbatim), `not_reopened` (an explicit `null`), `unstated` (key absent or unreadable) — and carried on the HITL bridge's active gate (`currentGateReopen()`), re-read on every `suspended` and cleared with the gate. |
|
|
319
|
-
| `scripts/run-panel-identity-normalization-test.mjs` | One background subagent has two ids on the wire — the fleet row id tail and the `task_progress` task id (its transcript id). Every panel event goes through one funnel that rewrites the `tick` / `end` task id onto the fleet row's id once a `fleet-row` has registered the key (`transcriptId` first, `parentToolCallId` as the fallback), carrying the original as `wireTaskId` and marking `taskIdOrigin`; an unbound tick whose row has not arrived yet waits one beat (bounded) and is released verbatim on the next tick / `end`, when the buffer is full, or after `MAX_HELD_WIRE_TICK_BEATS` other fleet-row / end / sweep events (a `sweep` itself leaves it alone: there is no row to settle yet); a normalized `end` that carries no cycle identity borrows the registering row's, so a late close of a revived task is recognized as stale; the key table is an LRU (a task that keeps ticking is never evicted by newer registrations); the residency mark migrates with the id and both keys are cleared on settle — except that a stale (previous-cycle) terminal never clears the revived row's mark — so the notification lane can clear it. |
|
|
320
|
-
| `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 |
|
|
319
|
+
| `scripts/run-panel-identity-normalization-test.mjs` | One background subagent has two ids on the wire — the fleet row id tail and the `task_progress` task id (its transcript id). Every panel event goes through one funnel that rewrites the `tick` / `end` task id onto the fleet row's id once a `fleet-row` has registered the key (`transcriptId` first, `parentToolCallId` as the fallback), carrying the original as `wireTaskId` and marking `taskIdOrigin`; an unbound tick whose row has not arrived yet waits one beat (bounded) and is released verbatim on the next tick / `end`, when the buffer is full, or after `MAX_HELD_WIRE_TICK_BEATS` other fleet-row / end / sweep events (a `sweep` itself leaves it alone: there is no row to settle yet); a normalized `end` that carries no cycle identity borrows the registering row's, so a late close of a revived task is recognized as stale; the key table is an LRU (a task that keeps ticking is never evicted by newer registrations); the residency mark migrates with the id and both keys are cleared on settle — except that a stale (previous-cycle) terminal never clears the revived row's mark — so the notification lane can clear it. Once a tick has been delivered verbatim under its UUID, that UUID is the subagent's key: later fleet rows and fleet-side ends are rewritten onto it (the tail kept in `wireTaskId`), so a consumer sees one row in every arrival order; a late tick from a previous cycle is dropped rather than folded into the revived row. |
|
|
320
|
+
| `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 Also the single source for the host-side approval-outcome note (`approvalOutcomeNoteOf`): `settled` is whether the decision was delivered, `retracted` is an independent key present only when the card was retracted, and `detail` is the retraction / edit-refused sentence or the refusal code and message — never a fabricated sentence. |
|
|
321
321
|
| `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 |
|
|
322
322
|
| `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 |
|
|
323
323
|
| `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. |
|
|
@@ -338,6 +338,9 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
338
338
|
// sdk 补上该位的当天,`run-compaction-boundary-projection-test.mjs` F10 行当场红逼复核。
|
|
339
339
|
case 'compacted': {
|
|
340
340
|
const raw = ev;
|
|
341
|
+
// 0.74.5 CC-85(core 7.24.0 #946):引擎自己测的结构性差值,夹 ≥ 0;旧的 tokensBefore / tokensAfter **不是可相减的一对**。
|
|
342
|
+
// 缺席 = 没测出来 ⇒ 键不落(渲「未知」不是 0);在场才带超集键。
|
|
343
|
+
const freedTokens = typeof raw.freedTokens === 'number' && Number.isFinite(raw.freedTokens) && raw.freedTokens >= 0 ? raw.freedTokens : undefined;
|
|
341
344
|
const attachedFiles = raw.attachedFiles;
|
|
342
345
|
const seg = raw.preserved_segment;
|
|
343
346
|
const firstKeptEntryId = typeof seg === 'object' && seg !== null && !Array.isArray(seg)
|
|
@@ -360,6 +363,7 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
360
363
|
...(typeof clampedRatio === 'number' && Number.isFinite(clampedRatio)
|
|
361
364
|
? { _sema_clamped_ratio: clampedRatio }
|
|
362
365
|
: {}),
|
|
366
|
+
...(freedTokens !== undefined ? { _sema_freed_tokens: freedTokens } : {}),
|
|
363
367
|
},
|
|
364
368
|
...(Array.isArray(attachedFiles) && attachedFiles.length > 0 ? { attachedFiles } : {}),
|
|
365
369
|
})));
|
|
@@ -126,6 +126,9 @@ export type EngineAgentPanelEvent = {
|
|
|
126
126
|
* 身份归一的退路(`transcriptId` 缺席时凭它把 task_progress 的 UUID 反查到本行)。
|
|
127
127
|
*/
|
|
128
128
|
parentToolCallId?: string;
|
|
129
|
+
/** 0.74.4 CC-83:先发布的键为准 —— 这个子代已按 UUID 上屏时,行帧的 `taskId` 改写成那把 UUID,原尾段进这里;缺席 = 未改写。 */
|
|
130
|
+
wireTaskId?: string;
|
|
131
|
+
taskIdOrigin?: 'wire';
|
|
129
132
|
} | {
|
|
130
133
|
kind: 'end';
|
|
131
134
|
taskId: string;
|
|
@@ -144,8 +147,8 @@ export type EngineAgentPanelEvent = {
|
|
|
144
147
|
report?: string;
|
|
145
148
|
/** 0.74.3 CC-70:同 tick 臂 —— 归一后才有(流内 close 臂 / 终态 tick 的 `end` 带的是 UUID,改写成 fleet 尾段时记原词)。 */
|
|
146
149
|
wireTaskId?: string;
|
|
147
|
-
/** 0.74.3 CC-70
|
|
148
|
-
taskIdOrigin?: 'fleet-row';
|
|
150
|
+
/** 0.74.3 CC-70:归一时带 `'fleet-row'`;0.74.4 CC-83:尾段被改写成先发布的 UUID 时带 `'wire'`(原尾段进 `wireTaskId`);其余不带。 */
|
|
151
|
+
taskIdOrigin?: 'fleet-row' | 'wire';
|
|
149
152
|
} | {
|
|
150
153
|
/** Exception-path safety net (published by seamQuery after every turn, throw or return):
|
|
151
154
|
* the consumer settles ALL rows it owns that are still running. Idempotent. */
|
|
@@ -161,6 +164,14 @@ export declare function markEnginePanelTaskResident(taskId: string): void;
|
|
|
161
164
|
export declare function clearEnginePanelTaskResident(taskId: string): void;
|
|
162
165
|
export declare function isEnginePanelTaskResident(taskId: string): boolean;
|
|
163
166
|
type Listener = (ev: EngineAgentPanelEvent) => void;
|
|
167
|
+
/**
|
|
168
|
+
* 0.74.5 CC-87 —— 「这一帧是不是**新周期**」的单源判据(`isStaleEngineAgentPanelEnd` 的对偶,壳侧此前各拼一份):
|
|
169
|
+
* · 两边都带 `cycleSeq` ⇒ **只**比它:不等 ⇒ 新周期;
|
|
170
|
+
* · 否则两边都带 `startedAt` ⇒ 不等 ⇒ 新周期;
|
|
171
|
+
* · 任一边判不出 ⇒ **不是**新周期(这一帧没说,不算变化 —— 方向与陈旧判据相同:缺席不制造周期)。
|
|
172
|
+
* 与缓冲合并屏障(`launchAnchorChanged`)同一条规则;消费端在 `fleet-row` 到时拿行上记的身份与帧上的身份调它。
|
|
173
|
+
*/
|
|
174
|
+
export declare function isNewEngineAgentPanelCycle(prev: EngineAgentPanelCycleIdentity | null | undefined, next: EngineAgentPanelCycleIdentity | null | undefined): boolean;
|
|
164
175
|
/** 周期身份的一格(`end` 事件上的,或消费端记在行上的当前周期)。 */
|
|
165
176
|
export interface EngineAgentPanelCycleIdentity {
|
|
166
177
|
readonly cycleSeq?: number;
|
|
@@ -195,8 +206,9 @@ export declare function resolveEnginePanelTaskId(wireTaskId: string, parentToolC
|
|
|
195
206
|
* 0.74.3 CC-70(异源复审 R3 [high]):按 wire 上的子代 id 清常驻标 —— 原键照清;归一到 fleet 尾段的那把键**只在这条终态属当代时**才清:
|
|
196
207
|
* 复活后迟到的前代终态(旧 UUID 的流内 close / 终态 tick)归一后带旧代际,清了尾段键 = 撤掉复活行的 sweep 保护 ⇒ 下一次 sweep 假结它。
|
|
197
208
|
* 判据与 `end` 的陈旧判据同一只(`isStaleEngineAgentPanelEnd`,拿钥匙上的周期对最近一条行帧的周期);判不出 ⇒ 照清(不因缺席留下永久常驻)。
|
|
209
|
+
* `cycle`(0.74.4):调用方(通知车道)带得出这条终态的周期时传进来 —— 尾段归某把 UUID 所有而通知比所有权旧 ⇒ 不清那把 UUID 的常驻标。
|
|
198
210
|
*/
|
|
199
|
-
export declare function clearEnginePanelTaskResidentByWire(wireTaskId: string): void;
|
|
211
|
+
export declare function clearEnginePanelTaskResidentByWire(wireTaskId: string, cycle?: EngineAgentPanelCycleIdentity): void;
|
|
200
212
|
/** 测试钩:清两张钥匙表、缓一拍与周期水位。 */
|
|
201
213
|
export declare function __resetEngineAgentPanelIdentityForTests(): void;
|
|
202
214
|
/** 宿主的唯一发布口(三条 lane 都经这里):先归一身份,再进主通道(订阅者 / 缓冲)。 */
|
|
@@ -210,6 +222,8 @@ export interface EngineAgentPanelAbsence {
|
|
|
210
222
|
lastSeenAtMs: number;
|
|
211
223
|
/** 发出这条上报时已缺席多久(ms;> `ABSENT_SETTLE_MS`)。 */
|
|
212
224
|
absentForMs: number;
|
|
225
|
+
/** 0.74.4 CC-83:`taskId` 被改写成先发布的 UUID 时,原尾段在这里;缺席 = 按尾段发。 */
|
|
226
|
+
wireTaskId?: string;
|
|
213
227
|
}
|
|
214
228
|
type AbsenceListener = (ev: EngineAgentPanelAbsence) => void;
|
|
215
229
|
/** 发布一条缺席上报(由 `projectFleetAgentRows` 的缺席路径调;消费者抛错不反噬投影)。 */
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* Buffering: ticks published before the panel mounts are buffered (bounded) and replayed to the first
|
|
23
23
|
* subscriber, so early frames in a fast turn aren't lost to mount timing.
|
|
24
24
|
*/
|
|
25
|
+
import { retirePanelRowRunning } from './panelRunningHistory.js';
|
|
25
26
|
const _panelToolUsesLanePins = [true, true];
|
|
26
27
|
void _panelToolUsesLanePins;
|
|
27
28
|
/**
|
|
@@ -56,9 +57,23 @@ const buffer = [];
|
|
|
56
57
|
function launchAnchorChanged(prev, next) {
|
|
57
58
|
if (prev.kind !== 'fleet-row' || next.kind !== 'fleet-row')
|
|
58
59
|
return false;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
return isNewEngineAgentPanelCycle(prev, next);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 0.74.5 CC-87 —— 「这一帧是不是**新周期**」的单源判据(`isStaleEngineAgentPanelEnd` 的对偶,壳侧此前各拼一份):
|
|
64
|
+
* · 两边都带 `cycleSeq` ⇒ **只**比它:不等 ⇒ 新周期;
|
|
65
|
+
* · 否则两边都带 `startedAt` ⇒ 不等 ⇒ 新周期;
|
|
66
|
+
* · 任一边判不出 ⇒ **不是**新周期(这一帧没说,不算变化 —— 方向与陈旧判据相同:缺席不制造周期)。
|
|
67
|
+
* 与缓冲合并屏障(`launchAnchorChanged`)同一条规则;消费端在 `fleet-row` 到时拿行上记的身份与帧上的身份调它。
|
|
68
|
+
*/
|
|
69
|
+
export function isNewEngineAgentPanelCycle(prev, next) {
|
|
70
|
+
const pc = cycleSeqOf(prev);
|
|
71
|
+
const nc = cycleSeqOf(next);
|
|
72
|
+
if (pc !== undefined && nc !== undefined)
|
|
73
|
+
return pc !== nc;
|
|
74
|
+
const ps = startedAtOf(prev);
|
|
75
|
+
const ns = startedAtOf(next);
|
|
76
|
+
return ps !== undefined && ns !== undefined && ps !== ns;
|
|
62
77
|
}
|
|
63
78
|
function cycleSeqOf(v) {
|
|
64
79
|
const n = v?.cycleSeq;
|
|
@@ -108,6 +123,12 @@ export function isStaleEngineAgentPanelEnd(end, current) {
|
|
|
108
123
|
// isStaleEngineAgentPanelEnd 才判得出它是前代;
|
|
109
124
|
// · tick 经退路键(parentToolCallId)归一时,顺手把 UUID → 尾段 记进主表(复审 R1 [high]):随后的 end{UUID} 不带 parentToolCallId,
|
|
110
125
|
// 没有这一步它永远归不了一。
|
|
126
|
+
// · 🔴 **先发布的键为准**(0.74.4 CC-83;test [7702] N-3 证伪「零改」:tick 归不了一而原样发出之后,行帧再按尾段发 = 消费端仍两行):
|
|
127
|
+
// 一条 tick 已按 UUID 原样发出(第二拍 / 拍数耗尽 / 绑卡),这个子代在消费端的键就是 UUID —— 之后到的 fleet-row / fleet 侧 end
|
|
128
|
+
// 改写成 UUID(原词进 wireTaskId,taskIdOrigin:'wire'),不再把尾段当第二把键发出去。消费端从此在任何到达序上都只见一把键;
|
|
129
|
+
// 常态序(行帧先到)仍归一到尾段。
|
|
130
|
+
// · 🔴 前代 UUID 的迟到 tick **丢弃**(0.74.4 CC-84;test [7702] W2 tick 腿):钥匙上的周期比最近行帧旧 ⇒ 这条 progress 属已结束的
|
|
131
|
+
// 周期,归一发出去会把前代的累计数写进复活行;end 有陈旧判据(消费端按周期挡),tick 没有 ⇒ 在漏斗里挡。
|
|
111
132
|
/** 钥匙表上限(LRU:命中即续命,真在飞的子代不会被一阵新登记挤掉;超出只退化成「原样发」)。 */
|
|
112
133
|
const MAX_IDENTITY_KEYS = 2048;
|
|
113
134
|
const MAX_HELD_WIRE_TICKS = 64;
|
|
@@ -118,6 +139,82 @@ const fleetIdByParentToolCallId = new Map();
|
|
|
118
139
|
const heldWireTicks = new Map();
|
|
119
140
|
/** 每个 fleet 尾段最近一条行帧带的周期身份(在场才记):清常驻标时用它判「这条终态是不是前代的」(异源复审 R3 [high])。 */
|
|
120
141
|
const latestCycleByFleetId = new Map();
|
|
142
|
+
/**
|
|
143
|
+
* 已按 UUID 原样发出过 tick 的子代(先发布的键为准,CC-83):transcriptId(= UUID)与 parentToolCallId 两把钥匙都记。
|
|
144
|
+
* 🔴 所有权表**按生命周期退役、不按容量改写**(异源复审 0.74.4 R1 [medium]):一把已发布的键在消费端就是一行,容量到了把它忘掉 =
|
|
145
|
+
* 同一子代重新长成两行。所以 `retired`(收到 end)的条目先让位;都没退役时才让最旧的(上限 MAX_OWNERSHIP_KEYS,远大于同时在飞的子代数)。
|
|
146
|
+
*/
|
|
147
|
+
const MAX_OWNERSHIP_KEYS = 8192;
|
|
148
|
+
const publishedWireIds = new Map();
|
|
149
|
+
const publishedWireByParent = new Map();
|
|
150
|
+
/** 尾段 → 已发布的 UUID(CC-83):fleet 侧的 fleet-row / end / 缺席 到时改写成 UUID;带登记时行帧的周期,复活的新周期不继承。 */
|
|
151
|
+
const wireIdByFleetId = new Map();
|
|
152
|
+
function bounded(map, key, value) {
|
|
153
|
+
map.delete(key);
|
|
154
|
+
map.set(key, value);
|
|
155
|
+
if (map.size > MAX_IDENTITY_KEYS) {
|
|
156
|
+
const oldest = map.keys().next().value;
|
|
157
|
+
if (oldest !== undefined)
|
|
158
|
+
map.delete(oldest);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** 所有权表的有界:退役的先让位,都没退役才让最旧的。 */
|
|
162
|
+
function boundedOwnership(map, key, value) {
|
|
163
|
+
map.delete(key);
|
|
164
|
+
map.set(key, value);
|
|
165
|
+
if (map.size <= MAX_OWNERSHIP_KEYS)
|
|
166
|
+
return;
|
|
167
|
+
for (const [k, v] of map) {
|
|
168
|
+
if (v.retired) {
|
|
169
|
+
map.delete(k);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const oldest = map.keys().next().value;
|
|
174
|
+
if (oldest !== undefined)
|
|
175
|
+
map.delete(oldest);
|
|
176
|
+
}
|
|
177
|
+
/** 一条 tick 按 UUID 原样发出去了:从此这个子代的键 = UUID。 */
|
|
178
|
+
function notePublishedWire(ev) {
|
|
179
|
+
// 已退役的键不因一条迟到 tick 复活(异源复审 R3 [high]):退役 = 它的行已结,迟到帧落在它自己的行上,所有权不回来
|
|
180
|
+
boundedOwnership(publishedWireIds, ev.taskId, { retired: publishedWireIds.get(ev.taskId)?.retired ?? false });
|
|
181
|
+
if (ev.parentToolCallId !== undefined && ev.parentToolCallId.length > 0)
|
|
182
|
+
bounded(publishedWireByParent, ev.parentToolCallId, ev.taskId);
|
|
183
|
+
}
|
|
184
|
+
/** 这把 UUID 的子代收到了终态:所有权可退役(容量满时先让位;不删 —— 迟到的同周期行帧 / end 仍要改写到它)。 */
|
|
185
|
+
function retireWire(wireId) {
|
|
186
|
+
const w = publishedWireIds.get(wireId);
|
|
187
|
+
if (w !== undefined)
|
|
188
|
+
w.retired = true;
|
|
189
|
+
for (const o of wireIdByFleetId.values())
|
|
190
|
+
if (o.wireId === wireId)
|
|
191
|
+
o.retired = true;
|
|
192
|
+
}
|
|
193
|
+
/** fleet-row 对应的子代是否已经按 UUID 发布过;transcriptId 命中不看退役(同一子代的迟到行帧),parentToolCallId 只认未退役(复活会沿用同一张卡)。 */
|
|
194
|
+
function publishedWireFor(ev) {
|
|
195
|
+
if (ev.transcriptId !== undefined && publishedWireIds.has(ev.transcriptId))
|
|
196
|
+
return ev.transcriptId;
|
|
197
|
+
if (ev.parentToolCallId !== undefined) {
|
|
198
|
+
const u = publishedWireByParent.get(ev.parentToolCallId);
|
|
199
|
+
if (u !== undefined && publishedWireIds.get(u)?.retired === false)
|
|
200
|
+
return u;
|
|
201
|
+
}
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
/** 尾段今天归哪把 UUID(在场 = 这个子代已按 UUID 上屏;复活的新周期不算)。 */
|
|
205
|
+
function wireOwnerOf(fleetId, current, transcriptId) {
|
|
206
|
+
const o = wireIdByFleetId.get(fleetId);
|
|
207
|
+
if (o === undefined)
|
|
208
|
+
return undefined;
|
|
209
|
+
// 0.74.5(test [7718] 契约层反例):行帧的 transcriptId 换了 = 新一代子会话,即使两个周期键全缺 —— 所有权同样到此为止
|
|
210
|
+
const newTranscript = transcriptId !== undefined && transcriptId !== (o.transcriptId ?? o.wireId); // 父键登记没记 transcriptId 时,wireId 本身就是那一代的转录身份(复审 R3)
|
|
211
|
+
if (newTranscript || (current !== undefined && isStaleEngineAgentPanelEnd(o, current))) {
|
|
212
|
+
wireIdByFleetId.delete(fleetId); // 行帧已是更新的周期:旧 UUID 的所有权到此为止,新周期按常态登记
|
|
213
|
+
retireWire(o.wireId); // 旧周期已过:那把 UUID 退役,退路键(同一张卡)不再把新周期的行帧拉回它(异源复审 R2 [high])
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
return o.wireId;
|
|
217
|
+
}
|
|
121
218
|
function remember(map, key, alias) {
|
|
122
219
|
map.delete(key);
|
|
123
220
|
map.set(key, alias);
|
|
@@ -189,25 +286,44 @@ function normalizedTick(ev, fleetId) {
|
|
|
189
286
|
function asIsTick(ev) {
|
|
190
287
|
const { cardBound: _cardBound, ...rest } = ev;
|
|
191
288
|
void _cardBound;
|
|
289
|
+
notePublishedWire(ev);
|
|
192
290
|
return { ...rest, taskIdOrigin: 'wire' };
|
|
193
291
|
}
|
|
292
|
+
/** 钥匙上的周期比最近行帧旧 = 这条 tick 属已结束的周期(CC-84);判不出 ⇒ 不算陈旧。 */
|
|
293
|
+
function staleWireTick(id) {
|
|
294
|
+
return isStaleEngineAgentPanelEnd(id, latestCycleByFleetId.get(id.taskId));
|
|
295
|
+
}
|
|
194
296
|
function flushHeld(wireTaskId) {
|
|
195
297
|
const held = heldWireTicks.get(wireTaskId);
|
|
196
298
|
if (held === undefined)
|
|
197
299
|
return;
|
|
198
300
|
heldWireTicks.delete(wireTaskId);
|
|
301
|
+
if (publishedWireIds.has(held.ev.taskId)) {
|
|
302
|
+
deliverEngineAgentPanelEvent(asIsTick(held.ev));
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
199
305
|
const id = resolveEnginePanelTaskId(held.ev.taskId, held.ev.parentToolCallId);
|
|
200
|
-
if (id.origin === 'fleet-row')
|
|
306
|
+
if (id.origin === 'fleet-row') {
|
|
307
|
+
if (staleWireTick(id))
|
|
308
|
+
return; // 前代周期的 progress:丢
|
|
201
309
|
rememberResolvedWire(held.ev.taskId, id);
|
|
202
|
-
|
|
310
|
+
deliverEngineAgentPanelEvent(normalizedTick(held.ev, id.taskId));
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
deliverEngineAgentPanelEvent(asIsTick(held.ev));
|
|
203
314
|
}
|
|
204
315
|
/**
|
|
205
316
|
* 0.74.3 CC-70(异源复审 R3 [high]):按 wire 上的子代 id 清常驻标 —— 原键照清;归一到 fleet 尾段的那把键**只在这条终态属当代时**才清:
|
|
206
317
|
* 复活后迟到的前代终态(旧 UUID 的流内 close / 终态 tick)归一后带旧代际,清了尾段键 = 撤掉复活行的 sweep 保护 ⇒ 下一次 sweep 假结它。
|
|
207
318
|
* 判据与 `end` 的陈旧判据同一只(`isStaleEngineAgentPanelEnd`,拿钥匙上的周期对最近一条行帧的周期);判不出 ⇒ 照清(不因缺席留下永久常驻)。
|
|
319
|
+
* `cycle`(0.74.4):调用方(通知车道)带得出这条终态的周期时传进来 —— 尾段归某把 UUID 所有而通知比所有权旧 ⇒ 不清那把 UUID 的常驻标。
|
|
208
320
|
*/
|
|
209
|
-
export function clearEnginePanelTaskResidentByWire(wireTaskId) {
|
|
321
|
+
export function clearEnginePanelTaskResidentByWire(wireTaskId, cycle) {
|
|
210
322
|
residentTaskIds.delete(wireTaskId);
|
|
323
|
+
const owner = wireIdByFleetId.get(wireTaskId); // 传进来的是尾段而尾段归某把 UUID 所有(通知车道)⇒ 那把键下的常驻标一起清
|
|
324
|
+
// 通知带周期(seq)且比所有权登记时的周期旧 = 前代的终态 ⇒ 不清当代 UUID 的常驻标(异源复审 R3 [high])
|
|
325
|
+
if (owner !== undefined && !(cycle !== undefined && isStaleEngineAgentPanelEnd(cycle, owner)))
|
|
326
|
+
residentTaskIds.delete(owner.wireId);
|
|
211
327
|
const id = resolveEnginePanelTaskId(wireTaskId);
|
|
212
328
|
if (id.taskId === wireTaskId)
|
|
213
329
|
return;
|
|
@@ -221,6 +337,9 @@ export function __resetEngineAgentPanelIdentityForTests() {
|
|
|
221
337
|
fleetIdByParentToolCallId.clear();
|
|
222
338
|
heldWireTicks.clear();
|
|
223
339
|
latestCycleByFleetId.clear();
|
|
340
|
+
publishedWireIds.clear();
|
|
341
|
+
publishedWireByParent.clear();
|
|
342
|
+
wireIdByFleetId.clear();
|
|
224
343
|
}
|
|
225
344
|
/** 宿主的唯一发布口(三条 lane 都经这里):先归一身份,再进主通道(订阅者 / 缓冲)。 */
|
|
226
345
|
export function publishEngineAgentPanelEvent(ev) {
|
|
@@ -230,6 +349,16 @@ export function publishEngineAgentPanelEvent(ev) {
|
|
|
230
349
|
ageHeld(ev.kind === 'sweep' ? undefined : ev.taskId);
|
|
231
350
|
switch (ev.kind) {
|
|
232
351
|
case 'fleet-row': {
|
|
352
|
+
// 先发布的键为准(CC-83):这个子代已经按 UUID 上过屏 ⇒ 行帧改写成 UUID 发,并记 尾段 → UUID 供 fleet 侧 end 改写;不登记尾段钥匙。
|
|
353
|
+
const rowCycle = { ...(ev.cycleSeq !== undefined ? { cycleSeq: ev.cycleSeq } : {}), ...(ev.startedAt !== undefined ? { startedAt: ev.startedAt } : {}) };
|
|
354
|
+
const published = wireOwnerOf(ev.taskId, rowCycle, ev.transcriptId) ?? publishedWireFor(ev);
|
|
355
|
+
if (published !== undefined && published !== ev.taskId) {
|
|
356
|
+
const prev = wireIdByFleetId.get(ev.taskId);
|
|
357
|
+
boundedOwnership(wireIdByFleetId, ev.taskId, { wireId: published, retired: prev?.wireId === published ? prev.retired : false, ...(ev.transcriptId !== undefined ? { transcriptId: ev.transcriptId } : prev?.transcriptId !== undefined ? { transcriptId: prev.transcriptId } : {}), ...rowCycle });
|
|
358
|
+
deliverEngineAgentPanelEvent({ ...ev, taskId: published, wireTaskId: ev.taskId, taskIdOrigin: 'wire' });
|
|
359
|
+
ageHeld(undefined);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
233
362
|
const alias = {
|
|
234
363
|
fleetId: ev.taskId,
|
|
235
364
|
...(ev.cycleSeq !== undefined ? { cycleSeq: ev.cycleSeq } : {}),
|
|
@@ -258,9 +387,18 @@ export function publishEngineAgentPanelEvent(ev) {
|
|
|
258
387
|
return;
|
|
259
388
|
}
|
|
260
389
|
case 'tick': {
|
|
390
|
+
// 先发布的键为准也管 tick 自己(异源复审 R2 [high]):这把 UUID 已经是消费端的键,之后的 tick 不再经退路键归一到尾段
|
|
391
|
+
//(否则复活后同一张卡的退路键把前代 UUID 的迟到 tick 拉进新周期的行)。
|
|
392
|
+
if (publishedWireIds.has(ev.taskId)) {
|
|
393
|
+
heldWireTicks.delete(ev.taskId);
|
|
394
|
+
deliverEngineAgentPanelEvent(asIsTick(ev));
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
261
397
|
const id = resolveEnginePanelTaskId(ev.taskId, ev.parentToolCallId);
|
|
262
398
|
if (id.origin === 'fleet-row') {
|
|
263
399
|
heldWireTicks.delete(ev.taskId);
|
|
400
|
+
if (staleWireTick(id))
|
|
401
|
+
return; // CC-84:前代 UUID 的迟到 tick 不进复活行
|
|
264
402
|
rememberResolvedWire(ev.taskId, id);
|
|
265
403
|
deliverEngineAgentPanelEvent(normalizedTick(ev, id.taskId));
|
|
266
404
|
return;
|
|
@@ -284,10 +422,47 @@ export function publishEngineAgentPanelEvent(ev) {
|
|
|
284
422
|
return;
|
|
285
423
|
}
|
|
286
424
|
case 'end': {
|
|
425
|
+
// 先发布的键为准(CC-83):尾段已被改写成 UUID 的子代,fleet 侧(投影 / 通知)的 end{尾段} 也改写成 UUID
|
|
426
|
+
const wireOwner = wireOwnerOf(ev.taskId, ev);
|
|
427
|
+
if (wireOwner !== undefined) {
|
|
428
|
+
const ownerRec = wireIdByFleetId.get(ev.taskId);
|
|
429
|
+
deliverEngineAgentPanelEvent({ ...ev, taskId: wireOwner, wireTaskId: ev.taskId, taskIdOrigin: 'wire' });
|
|
430
|
+
// 前代迟到的 end(比所有权登记时的周期旧)只过境让消费端判陈旧,不退役当代所有权(异源复审 R3)、不销当代 running 历史
|
|
431
|
+
if (!isStaleEngineAgentPanelEnd(ev, ownerRec)) {
|
|
432
|
+
retireWire(wireOwner);
|
|
433
|
+
retirePanelRowRunning(ev.taskId);
|
|
434
|
+
retirePanelRowRunning(wireOwner);
|
|
435
|
+
}
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
if (publishedWireIds.has(ev.taskId)) {
|
|
439
|
+
// 这把 UUID 是先发布的键 ⇒ 它的 end 落在它自己的行上(不归一;一把已发布的键永远不改写)
|
|
440
|
+
flushHeld(ev.taskId);
|
|
441
|
+
deliverEngineAgentPanelEvent(ev);
|
|
442
|
+
retireWire(ev.taskId);
|
|
443
|
+
retirePanelRowRunning(ev.taskId);
|
|
444
|
+
// 这把 UUID 名下的尾段(反向所有权 / 转录别名)在投影里以尾段记的 running 历史一起销(复审 R3 [medium]),各自带周期守卫
|
|
445
|
+
for (const [fleetId, o] of wireIdByFleetId) {
|
|
446
|
+
if (o.wireId === ev.taskId && !isStaleEngineAgentPanelEnd(ev, o))
|
|
447
|
+
retirePanelRowRunning(fleetId);
|
|
448
|
+
}
|
|
449
|
+
const alias = fleetIdByTranscriptId.get(ev.taskId);
|
|
450
|
+
if (alias !== undefined && !isStaleEngineAgentPanelEnd(ev, alias))
|
|
451
|
+
retirePanelRowRunning(alias.fleetId);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
287
454
|
const id = resolveEnginePanelTaskId(ev.taskId);
|
|
288
455
|
if (id.origin === 'fleet-row' && id.taskId !== ev.taskId) {
|
|
289
456
|
flushHeld(ev.taskId); // 同 UUID 还缓着一条 tick ⇒ 先归一放出(行先有最后一拍的数字与名字),再结
|
|
290
457
|
migrateResidency(ev.taskId, id.taskId);
|
|
458
|
+
// 任何 lane 的 end 到漏斗 = 这一行结了 ⇒ running 历史销账(只销当代:前代迟到的 end 不擦新一代;异源复审 0.74.5 R2)
|
|
459
|
+
// 🔴 用与递达**同一个**有效身份判(事件自带的周期优先、缺席才借钥匙;复审 R3 [high]:按钥匙判会把 end{cycle 1} 当成当代)
|
|
460
|
+
const effectiveEnd = {
|
|
461
|
+
...(ev.cycleSeq !== undefined ? { cycleSeq: ev.cycleSeq } : id.cycleSeq !== undefined ? { cycleSeq: id.cycleSeq } : {}),
|
|
462
|
+
...(ev.startedAt !== undefined ? { startedAt: ev.startedAt } : id.startedAt !== undefined ? { startedAt: id.startedAt } : {}),
|
|
463
|
+
};
|
|
464
|
+
if (!isStaleEngineAgentPanelEnd(effectiveEnd, latestCycleByFleetId.get(id.taskId)))
|
|
465
|
+
retirePanelRowRunning(id.taskId);
|
|
291
466
|
deliverEngineAgentPanelEvent({
|
|
292
467
|
...ev,
|
|
293
468
|
taskId: id.taskId,
|
|
@@ -301,6 +476,10 @@ export function publishEngineAgentPanelEvent(ev) {
|
|
|
301
476
|
}
|
|
302
477
|
flushHeld(ev.taskId); // 缓着的 tick 先落行,终态才有行可结
|
|
303
478
|
deliverEngineAgentPanelEvent(ev);
|
|
479
|
+
retireWire(ev.taskId); // 这把 UUID 若是先发布的键,所有权退役(容量满时先让位)
|
|
480
|
+
// 通知车道 / fleet 投影铸的 end(尾段键):running 历史销账,只销当代(前代迟到的 end 带旧 seq / cycleSeq ⇒ 不擦)
|
|
481
|
+
if (!isStaleEngineAgentPanelEnd(ev, latestCycleByFleetId.get(ev.taskId)))
|
|
482
|
+
retirePanelRowRunning(ev.taskId);
|
|
304
483
|
return;
|
|
305
484
|
}
|
|
306
485
|
default:
|
|
@@ -459,6 +638,10 @@ let absenceListener = null;
|
|
|
459
638
|
const absenceBuffer = new Map();
|
|
460
639
|
/** 发布一条缺席上报(由 `projectFleetAgentRows` 的缺席路径调;消费者抛错不反噬投影)。 */
|
|
461
640
|
export function publishEngineAgentPanelAbsence(ev) {
|
|
641
|
+
// 0.74.4 CC-83(异源复审 R1 [medium]):尾段已归先发布的 UUID 所有 ⇒ 缺席也按那把键发(主通道与侧信道同一把键),原尾段进 wireTaskId
|
|
642
|
+
const owner = wireOwnerOf(ev.taskId);
|
|
643
|
+
if (owner !== undefined)
|
|
644
|
+
ev = { ...ev, taskId: owner, wireTaskId: ev.taskId };
|
|
462
645
|
if (absenceListener) {
|
|
463
646
|
try {
|
|
464
647
|
absenceListener(ev);
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
* 就地维护第二份;该函数出过等价性事故,0.1.1 修,见 `workflow.ts` 头注)。
|
|
49
49
|
*/
|
|
50
50
|
import { isStaleEngineAgentPanelEnd, publishEngineAgentPanelAbsence, publishEngineAgentPanelEvent } from './engineAgentPanelStore.js';
|
|
51
|
+
import { __resetPanelRunningHistoryForTests, notePanelRowRunning, panelRowNeverPublishedRunning } from './panelRunningHistory.js';
|
|
51
52
|
import { rowIdTail } from './workflow.js';
|
|
52
53
|
import { TERMINAL_FLEET_TASK_STATUSES } from './fleet/fleetProjection.js';
|
|
53
54
|
import { DEFAULT_SESSION_KEY } from './sessionSlot.js';
|
|
@@ -80,6 +81,8 @@ function currentToolKeyOf(ct) {
|
|
|
80
81
|
}
|
|
81
82
|
/** REF-CC-045(fleet2-07):per-sessionKey 台账(W1 同款 `Map<sessionKey, Map<...>>` 形)。 */
|
|
82
83
|
const seen = new Map();
|
|
84
|
+
// 0.74.5 CC-86:「发布过 running 而尚未结掉」的行 id 在 `panelRunningHistory.ts`(进程级共享叶;写方 = 本投影的非终态帧,
|
|
85
|
+
// 销账方 = 面板漏斗的任何 lane 的 end(通知车道的 end 不经本投影),读方 = 下面的终态分支)。
|
|
83
86
|
function seenFor(sessionKey) {
|
|
84
87
|
let m = seen.get(sessionKey);
|
|
85
88
|
if (!m) {
|
|
@@ -102,6 +105,7 @@ function seenFor(sessionKey) {
|
|
|
102
105
|
*/
|
|
103
106
|
export function resetFleetAgentPanelProjection() {
|
|
104
107
|
seen.clear();
|
|
108
|
+
__resetPanelRunningHistoryForTests();
|
|
105
109
|
}
|
|
106
110
|
/** W1 keyed variant(REF-CC-045):只清**这一个会话**的桶。 */
|
|
107
111
|
export function resetFleetAgentPanelProjectionFor(sessionKey) {
|
|
@@ -180,8 +184,13 @@ export function projectFleetAgentRowsFor(sessionKey, rows, nowMs = Date.now()) {
|
|
|
180
184
|
if (TERMINAL_FLEET_TASK_STATUSES.has(status)) {
|
|
181
185
|
// ② 终态一次性 settle(幂等台账;消费端 settle 也幂等)。0.74.0:去重按**周期** —— 已 settle 的是上一代、这一帧是
|
|
182
186
|
// 更新的一代(中间没见到 running 帧)⇒ 新周期的终态照发,不被上一代的 settled 吞掉。
|
|
187
|
+
// 🔴 0.74.5 CC-86(cli L-415):**首次见到就已终态**的行(prev 缺席)零事件 —— 只在台账记 settled。此前先发 fleet-row
|
|
188
|
+
// (交最终用量)再发 end ⇒ 宿主为本会话从没跑过的任务建行随即 settle = 面板幽灵完成行(reattach / resume 后引擎
|
|
189
|
+
// fleet 列表里的历史终态行全部上屏)。本会话内起步又结束、面板从没见过 running 的后台任务由通知车道的 end 收尸;
|
|
190
|
+
// 复活(prev 已 settled 且这一帧周期更新)不在此列,照发。
|
|
191
|
+
const newbornTerminal = prev === undefined && panelRowNeverPublishedRunning(taskId);
|
|
183
192
|
const settledThisCycle = prev?.settled === true && !rowNewerCycle;
|
|
184
|
-
if (!settledThisCycle) {
|
|
193
|
+
if (!settledThisCycle && !newbornTerminal) {
|
|
185
194
|
// 终态行也把最后一拍的累计工具数/转录锚带上:详情页在行翻终态后仍要显示真计数与
|
|
186
195
|
// 委派 prompt,而终态帧常常是这一行**唯一**带全 usage 的一帧(bg lane 只在活动边界发行帧)。
|
|
187
196
|
if (
|
|
@@ -251,6 +260,7 @@ export function projectFleetAgentRowsFor(sessionKey, rows, nowMs = Date.now()) {
|
|
|
251
260
|
(startedAt !== undefined && prev.startedAt !== startedAt) ||
|
|
252
261
|
(cycleSeq !== undefined && prev.cycleSeq !== cycleSeq) ||
|
|
253
262
|
(currentToolKey !== undefined && prev.currentToolKey !== currentToolKey)) {
|
|
263
|
+
notePanelRowRunning(taskId); // CC-86:真发布了这一行在跑才记历史(未变的陈旧快照零事件也零记账,复审 R3)
|
|
254
264
|
publishEngineAgentPanelEvent({
|
|
255
265
|
kind: 'fleet-row',
|
|
256
266
|
taskId,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* approvalOutcomeNote — 流内帧腿的审批结局回交(`AskGateWireDeps.onToolApprovalOutcome(frame, outcome)`,0.74.1 CC-68)
|
|
3
|
+
* 到宿主「审批结局便签」的**单源映射**(0.74.5 CC-88;此前三端装配点各手拼一份,语义以 cli 1.0.123 现行为准):
|
|
4
|
+
* · `approvalId` = 帧上的原词;
|
|
5
|
+
* · `settled` = `outcome.decision !== 'unresolved'`(respond 送达并落定;**不看** ack 在不在 —— ack 是 server 的回执形,宿主不读);
|
|
6
|
+
* · `retracted` 只在 `outcome.retracted === true` 时带键(**独立判别位**,不折进 detail:撤卡 ≠ 投递失败 —— 释放认领但不扣重出卡预算);
|
|
7
|
+
* `editRefused` **不算** retracted,只折进 detail;
|
|
8
|
+
* · `detail` 三支优先序:撤卡固定句 → 编辑被拒固定句 → `respondRefusal` 的 errorCode / message 过滤非空后 ` · ` 拼接;
|
|
9
|
+
* 拼出空串 ⇒ 键缺席(绝不编一句;不用决断词、不用 ack 摘要)。
|
|
10
|
+
*/
|
|
11
|
+
import type { ToolApprovalFrame, ToolApprovalFrameOutcome } from './toolApprovalWire.js';
|
|
12
|
+
/** 宿主便签形(三端同一形;`retracted` / `detail` 在场才带)。 */
|
|
13
|
+
export interface StreamApprovalOutcomeNote {
|
|
14
|
+
readonly approvalId: string;
|
|
15
|
+
readonly settled: boolean;
|
|
16
|
+
readonly retracted?: true;
|
|
17
|
+
readonly detail?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const APPROVAL_NOTE_RETRACTED_DETAIL = "the card was retracted (this host no longer has a decision port for it)";
|
|
20
|
+
export declare const APPROVAL_NOTE_EDIT_REFUSED_DETAIL = "edits are not accepted on this card";
|
|
21
|
+
/** 帧 + 结局 → 便签(纯函数;结局上的坏形按缺席读,不抛)。 */
|
|
22
|
+
export declare function approvalOutcomeNoteOf(frame: Pick<ToolApprovalFrame, 'approvalId'>, outcome: ToolApprovalFrameOutcome): StreamApprovalOutcomeNote;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const APPROVAL_NOTE_RETRACTED_DETAIL = 'the card was retracted (this host no longer has a decision port for it)';
|
|
2
|
+
export const APPROVAL_NOTE_EDIT_REFUSED_DETAIL = 'edits are not accepted on this card';
|
|
3
|
+
function nonEmpty(v) {
|
|
4
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
5
|
+
}
|
|
6
|
+
/** 帧 + 结局 → 便签(纯函数;结局上的坏形按缺席读,不抛)。 */
|
|
7
|
+
export function approvalOutcomeNoteOf(frame, outcome) {
|
|
8
|
+
const retracted = outcome.retracted === true;
|
|
9
|
+
const refusal = outcome.respondRefusal;
|
|
10
|
+
const detail = retracted
|
|
11
|
+
? APPROVAL_NOTE_RETRACTED_DETAIL
|
|
12
|
+
: outcome.editRefused === true
|
|
13
|
+
? APPROVAL_NOTE_EDIT_REFUSED_DETAIL
|
|
14
|
+
: [nonEmpty(refusal?.errorCode), nonEmpty(refusal?.message)].filter((x) => x !== undefined).join(' · ');
|
|
15
|
+
return {
|
|
16
|
+
approvalId: frame.approvalId,
|
|
17
|
+
settled: outcome.decision !== 'unresolved',
|
|
18
|
+
...(retracted ? { retracted: true } : {}),
|
|
19
|
+
...(detail.length > 0 ? { detail } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -256,6 +256,7 @@ export * from './liveInitToolFace.js';
|
|
|
256
256
|
export * from './model/providerPresets.js';
|
|
257
257
|
export * from './hitl/hitlBridge.js';
|
|
258
258
|
export * from './hitl/suspendedReopen.js';
|
|
259
|
+
export * from './hitl/approvalOutcomeNote.js';
|
|
259
260
|
export { toolEndOutputText, ENGINE_ABORT_TOOL_RESULT } from './hitl/frameRouter.js';
|
|
260
261
|
export { isAskTool } from './hitl/frameRouter.js';
|
|
261
262
|
export * from './hitl/hitlHostSurface.js';
|
package/dist/index.js
CHANGED
|
@@ -444,6 +444,8 @@ export * from './model/providerPresets.js';
|
|
|
444
444
|
export * from './hitl/hitlBridge.js';
|
|
445
445
|
// 0.74.3 CC-73:durable suspended.reopened 三态读口(cli L-56 ②)
|
|
446
446
|
export * from './hitl/suspendedReopen.js';
|
|
447
|
+
// 0.74.5 CC-88:流内帧腿审批结局 → 宿主便签的单源映射(三端手拼退役)
|
|
448
|
+
export * from './hitl/approvalOutcomeNote.js';
|
|
447
449
|
// [C93] P0 直讨(0.17.1):toolEndOutputText 单一真源导出——web/desktop 被点名「两端务必接」的
|
|
448
450
|
// 6.0.0 output content-block 归一,此前 frameRouter 内私有,两端手抄=漂移温床。frameRouter 只
|
|
449
451
|
// 挑名导出这一件(整星导出会把路由内部面全泄进公面)。
|
package/dist/notifications.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { hostEnv } from './hostEnv.js';
|
|
8
8
|
import { unrefTimer } from './unrefTimer.js';
|
|
9
|
-
import {
|
|
9
|
+
import { clearEnginePanelTaskResidentByWire, publishEngineAgentPanelEvent, } from './engineAgentPanelStore.js';
|
|
10
10
|
// L-215②(0.65.0;core [6908]):「非成功终局」的**单铸谓词** —— 面板 settle 的 `isError` 位与
|
|
11
11
|
// 三端自己的后台白名单必须读同一个判据;内联一个 `=== 'failed' || === 'killed'` 就是第二份会漂的台账。
|
|
12
12
|
import { isTaskNotificationTerminalStatus, isTerminalNotSuccess, isTerminalStatus } from './runTerminal.js';
|
|
@@ -922,7 +922,8 @@ export function enqueueBgChildNotification(n) {
|
|
|
922
922
|
// 0.72.13(test 0.72.12 验收 ①;DS-06 同形存量):只对**通知自己的终态词**(completed / failed / killed / cancelled)settle 面板行。
|
|
923
923
|
// 此前对任何 status 都铸 `end`,而 `isError: isTerminalNotSuccess(status)` 对 running / queued / event / 未来词答 false ⇒
|
|
924
924
|
// 面板把一条还在跑 / 认不出状态的行结成 **completed** —— 该谓词的 JSDoc 明禁拿它的 false 当成功。非终态 ⇒ 不 settle、常驻标不摘。
|
|
925
|
-
|
|
925
|
+
// 0.74.4 CC-83:按 wire 词清 —— 尾段若归先发布的 UUID 所有,那把键下的常驻标一起清(主通道与常驻账同一把键)
|
|
926
|
+
clearEnginePanelTaskResidentByWire(n.taskId, typeof n.seq === 'number' && Number.isInteger(n.seq) && n.seq >= BG_FIRST_SEQ ? { cycleSeq: n.seq } : undefined);
|
|
926
927
|
publishEngineAgentPanelEvent({
|
|
927
928
|
kind: 'end',
|
|
928
929
|
taskId: n.taskId,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function notePanelRowRunning(taskId: string): void;
|
|
2
|
+
/** 结掉了(任何 lane 的 end 递达):历史不再需要。 */
|
|
3
|
+
export declare function retirePanelRowRunning(taskId: string): void;
|
|
4
|
+
/** 首见即终态且**确知**没发布过 running(表没溢出且不在表里)⇒ 历史行。 */
|
|
5
|
+
export declare function panelRowNeverPublishedRunning(taskId: string): boolean;
|
|
6
|
+
export declare function __resetPanelRunningHistoryForTests(): void;
|
|
7
|
+
/** 测试 / 诊断读面。 */
|
|
8
|
+
export declare function __panelRunningHistorySize(): number;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* panelRunningHistory — 「本进程**发布过 running 而尚未结掉**的面板行 id」(0.74.5 CC-86;包内共享叶,不出公面)。
|
|
3
|
+
*
|
|
4
|
+
* 写方 = fleet 投影(非终态帧);读方 = fleet 投影的终态分支(首见即终态 ∧ 从没发布过 running ⇒ 历史行,零事件);
|
|
5
|
+
* **结掉的写方 = 面板漏斗的 `end` 递达**(异源复审 0.74.5 R2 [medium]:通知车道的 end 不经投影,只在投影里删会让完成过的 id 永远留在表里、
|
|
6
|
+
* 最终溢出把压制永久关掉)—— 任何 lane 的 end 到漏斗都在这里销账,且**只销当代**(前代迟到的 end 不擦新一代的 running 历史)。
|
|
7
|
+
* 作用域 = 面板订阅作用域(进程级,不按 sessionKey 分桶);有界 4096,溢出后转保守(不再压制)直到整表重置。
|
|
8
|
+
*/
|
|
9
|
+
const MAX_IDS = 4096;
|
|
10
|
+
const ids = new Set();
|
|
11
|
+
let overflowed = false;
|
|
12
|
+
export function notePanelRowRunning(taskId) {
|
|
13
|
+
if (ids.has(taskId))
|
|
14
|
+
return;
|
|
15
|
+
ids.add(taskId);
|
|
16
|
+
if (ids.size > MAX_IDS) {
|
|
17
|
+
overflowed = true;
|
|
18
|
+
const oldest = ids.values().next().value;
|
|
19
|
+
if (oldest !== undefined)
|
|
20
|
+
ids.delete(oldest);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** 结掉了(任何 lane 的 end 递达):历史不再需要。 */
|
|
24
|
+
export function retirePanelRowRunning(taskId) {
|
|
25
|
+
ids.delete(taskId);
|
|
26
|
+
}
|
|
27
|
+
/** 首见即终态且**确知**没发布过 running(表没溢出且不在表里)⇒ 历史行。 */
|
|
28
|
+
export function panelRowNeverPublishedRunning(taskId) {
|
|
29
|
+
return !overflowed && !ids.has(taskId);
|
|
30
|
+
}
|
|
31
|
+
export function __resetPanelRunningHistoryForTests() {
|
|
32
|
+
ids.clear();
|
|
33
|
+
overflowed = false;
|
|
34
|
+
}
|
|
35
|
+
/** 测试 / 诊断读面。 */
|
|
36
|
+
export function __panelRunningHistorySize() {
|
|
37
|
+
return ids.size;
|
|
38
|
+
}
|
package/dist/runCancelContext.js
CHANGED
|
@@ -14,13 +14,24 @@
|
|
|
14
14
|
function nonNegFinite(v) {
|
|
15
15
|
return typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* 记录形两种:顶层 `result`(PersistedTaskResult)或已经是 result 本身。只有 `result` 长得像一份 run 结果(带 terminal / status /
|
|
19
|
+
* cancelContext 任一键)才下钻 —— `TaskResult` 自己也有个 `result` 键(今天是串),哪天成了对象也不该被当成结果记录(test [7702] §七 ④)。
|
|
20
|
+
*/
|
|
21
|
+
function runResultHolder(r) {
|
|
22
|
+
const inner = r.result;
|
|
23
|
+
if (inner === null || typeof inner !== 'object' || Array.isArray(inner))
|
|
24
|
+
return r;
|
|
25
|
+
const o = inner;
|
|
26
|
+
return Object.hasOwn(o, 'terminal') || Object.hasOwn(o, 'status') || Object.hasOwn(o, 'cancelContext') ? o : r;
|
|
27
|
+
}
|
|
17
28
|
/** run 记录(`runs.get` 回体 / `done.result`)→ 取消现场读数;记录非对象 ⇒ `undefined`(判不出,与 not_reported 分开)。 */
|
|
18
29
|
export function readRunCancelContext(record) {
|
|
19
30
|
if (record === null || typeof record !== 'object')
|
|
20
31
|
return undefined;
|
|
21
32
|
const r = record;
|
|
22
33
|
// 记录形两种:顶层 `result.cancelContext`(PersistedTaskResult)或已经是 result 本身。
|
|
23
|
-
const holder = r
|
|
34
|
+
const holder = runResultHolder(r);
|
|
24
35
|
if (!Object.hasOwn(holder, 'cancelContext') || holder.cancelContext === undefined)
|
|
25
36
|
return { kind: 'not_reported' };
|
|
26
37
|
const c = holder.cancelContext;
|
|
@@ -60,8 +71,7 @@ export function classifyRunAbortCause(record) {
|
|
|
60
71
|
return { kind: 'unknown' };
|
|
61
72
|
const r = record;
|
|
62
73
|
const status = typeof r.status === 'string' && r.status.length > 0 ? r.status : undefined;
|
|
63
|
-
const
|
|
64
|
-
const read = readRunTerminal(holder);
|
|
74
|
+
const read = readRunTerminal(runResultHolder(r));
|
|
65
75
|
if (read !== null && read.kind === 'failed') {
|
|
66
76
|
if (read.code === RUN_CANCELLED_CODE) {
|
|
67
77
|
const cc = readRunCancelContext(record);
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **0.74.
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **0.74.5**(本批发布版 = **patch**:core 7.24.0 提货 `_sema_freed_tokens?` + 首见即终态的行零事件(幽灵完成行)+ `isNewEngineAgentPanelCycle` / `approvalOutcomeNoteOf` 上公面;型面 additive、公面 1065、peer 不动;§73。上一版 0.74.4 = **patch**:面板键「先发布的键为准」(tick 归不了一的三序不再两行)+ 前代 UUID 迟到 tick 丢弃 + `readRunCancelContext` 下钻收紧;型面 additive、公面 1061、peer 不动;§72。上一版 0.74.3 = **patch**:面板子代身份归一(tick / end 的 UUID 归到 fleet 尾段,宿主零改)+ run 记录 `cancelContext` 读口与成因四词 + workflow 行 `errorCode` + reopen 第二臂两件;型面纯 additive、公面 1061、peer 不动;§71。上一版 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
|
-
| 公开导出面 | **1061** 个运行期符号(+ 51 个测试钩;= 0.74.3 的值:相对 0.74.2 +9 —— CC-70 / CC-71 / CC-72 / CC-73 八件 + CC-80 `lastFlagValue`,见 §2b 域 3 / 4 / 10 / 15;1052 = 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` —— **别手抄进别处,以该文件为准** |
|
|
26
|
+
| 公开导出面 | **1065** 个运行期符号(+ 51 个测试钩;= 0.74.5 的值:相对 0.74.4 +4 —— `isNewEngineAgentPanelCycle`(CC-87,域 4)+ `approvalOutcomeNoteOf` 与两句固定文案常量(CC-88,域 3);1061 = 0.74.3 / 0.74.4 的值:相对 0.74.2 +9 —— CC-70 / CC-71 / CC-72 / CC-73 八件 + CC-80 `lastFlagValue`,见 §2b 域 3 / 4 / 10 / 15;1052 = 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`(**1065** 项)。
|
|
127
127
|
> 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
|
|
128
128
|
> **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
|
|
129
129
|
> 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
|
|
@@ -147,19 +147,19 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
147
147
|
`WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
|
|
148
148
|
**4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
1065 项的内部构成(帮助端估读表大小;0.74.5 +2 常量 +2 函数(CC-87 / CC-88);0.74.3 +2 常量 +7 函数(CC-70 / CC-71 / CC-72 / CC-73 / CC-80;测试钩 +1);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):**311** 项是 `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 域,逐域计数之和 = 1065)
|
|
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 主战场) |
|
|
162
|
-
| 4 | **子代 wire + 面板侧信道台账** |
|
|
161
|
+
| 3 | **HITL 决断卡链**(§4/§5 主战场) | 183 | `approvalOutcomeNoteOf` / `APPROVAL_NOTE_RETRACTED_DETAIL` / `APPROVAL_NOTE_EDIT_REFUSED_DETAIL`(0.74.5 CC-88:审批结局便签单源;§73)· `decideReceiptReopen` / `suspendedReopenOf`(0.74.3 CC-73:reopen 族第二臂;§71)· `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
|
+
| 4 | **子代 wire + 面板侧信道台账** | 93 | `isNewEngineAgentPanelCycle`(0.74.5 CC-87:新周期单源判据;§73)· `resolveEnginePanelTaskId` / `MAX_HELD_WIRE_TICK_BEATS` / `clearEnginePanelTaskResidentByWire`(0.74.3 CC-70:子代身份归一读口、缓一拍节拍上限、按 wire id 清常驻标(前代终态不清当代);§71)· `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 台账) |
|
|
@@ -9165,3 +9165,92 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
9165
9165
|
3. peer 不动;server <7.87.3 ⇒ `cancelContext` `not_reported`;sdk 未声明 `errorCode` 前 workflow 行按结构读。
|
|
9166
9166
|
|
|
9167
9167
|
**包侧缺口:** ⓪ CC-74 `mcpProbe` 四态读口候 server S-481 发车(走能力位读器通用工厂,见兔子洞自查 ①);① CC-36 候 core #874;② 面板缓冲合同一句:`publishEngineAgentPanelEvent` 无订阅者时按 (kind, taskId) 合并缓冲、下次 `subscribe` 原样回放(先 publish 后 subscribe 会收到过去的事件;归一后的键),来源 test [7646] ④ ⑥;其余同 §70。
|
|
9168
|
+
|
|
9169
|
+
## §72 🆕 0.74.4 面板键「先发布的键为准」(CC-83)+ 前代 tick 丢弃(CC-84);patch
|
|
9170
|
+
|
|
9171
|
+
> **patch**:型面 additive(`fleet-row` 臂 +`wireTaskId?` / `taskIdOrigin?: 'wire'`,`end.taskIdOrigin` 多一词 `'wire'`,`EngineAgentPanelAbsence` +`wireTaskId?`;公面导出名零增减 1061;零 wire 新键;peer 不动)。票来源:test [7702](0.74.3 靶子两红,本包亲核复现 [7704])。🔴 **更正 §71**:「面板桥零改」在 tick 归不了一的序上不成立(0.74.3 那三序仍两行);本版把规则改成「先发布的键为准」,零改的正确形 = **任何到达序消费端只见一把键**。
|
|
9172
|
+
|
|
9173
|
+
### 72a. 处置表
|
|
9174
|
+
|
|
9175
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
9176
|
+
|---|---|---|---|
|
|
9177
|
+
| S-1 | 面板事件的键(所有 lane) | **fixed**:先发布的键为准 —— 已按 UUID 发出过 tick 的子代,后到的 `fleet-row` / fleet 侧 `end` 改写成 UUID(`wireTaskId` = 原尾段,`taskIdOrigin:'wire'`) | 按 `ev.taskId` 落表的宿主零改(任何序一行);要按尾段(= 本地 agentId)对账的宿主:`taskIdOrigin === 'wire' && wireTaskId` 在场时尾段在 `wireTaskId` |
|
|
9178
|
+
| S-2 | 前代 UUID 的迟到 tick | **fixed**:漏斗丢弃(钥匙周期 < 最近行帧周期) | 零改;复活行的计数不再被前代污染 |
|
|
9179
|
+
| S-3 | `readRunCancelContext` 的 `result` 下钻 | **fixed**:只认像 run 结果的对象 | 零改 |
|
|
9180
|
+
|
|
9181
|
+
### 72b. 缺席语义(逐键)
|
|
9182
|
+
|
|
9183
|
+
- `fleet-row.wireTaskId` / `taskIdOrigin` 缺席 = 这条行帧按尾段发(常态);在场(`'wire'`)= 这个子代已按 UUID 上屏,`taskId` 是 UUID、尾段在 `wireTaskId`。
|
|
9184
|
+
- `end.taskIdOrigin`:`'fleet-row'` = UUID 归一到尾段;`'wire'` = 尾段改写成先发布的 UUID;缺席 = 原样。
|
|
9185
|
+
- `EngineAgentPanelAbsence.wireTaskId` 缺席 = 缺席上报按尾段发;在场 = 已改写成所有者 UUID(与主通道同一把键)。所有权按生命周期退役:收到 `end` 后表满时先让位;复活的新周期(行帧周期更新)不继承旧 UUID(旧 UUID 即退役,同一张卡的退路键不再拉回它),按常态归一到尾段。**一把已发布的 UUID 永远不改写**:它之后的 tick 留在它自己的键上、它的 end 落在它自己的行上(前代迟到帧因此进不了复活行);退役位不被迟到 tick 重置。通知车道清常驻标带 `seq` 当周期:比所有权登记时的周期旧 ⇒ 不清当代 UUID 的常驻标(`clearEnginePanelTaskResidentByWire(id, cycle?)`)。
|
|
9186
|
+
- 前代 tick 的「陈旧」判不出(钥匙或最近行帧无周期身份)⇒ 不丢,照归一 —— 只挡有证据的前代。
|
|
9187
|
+
- `suspended.reopened` 键在场而值为 `undefined`(JSON 不可达,只对进程内对象成立)⇒ `unstated`(补 §71 未成文的一形)。
|
|
9188
|
+
- 缓一拍的 16 拍 = **事件计数**(别的 fleet-row / end / sweep),store 无计时器,折不成秒;真机重连成批重发时会在一次事件风暴里耗尽。
|
|
9189
|
+
- W3「外层 `status` 与 `result.status` 矛盾 ⇒ unknown」那格在真 server 7.88.2 上够不着(`result.status` 不存在),只对夹具形 / 未来记录形有意义,不当真机判据。
|
|
9190
|
+
|
|
9191
|
+
### 72c. 黑盒判据骨架
|
|
9192
|
+
|
|
9193
|
+
- **G1(CC-83)**:test [7702] S3 / S4 / S5 三序,零改壳恒 **1 行**且能收到 end;常态序(S1 / S2)仍归一到尾段;0.74.3 红基线三序 = 2 行。
|
|
9194
|
+
- **G2(CC-84)**:复活后前代 UUID 的迟到 tick(六种到达序)⇒ 复活行 `toolUses` 不变;当代 tick 照进。
|
|
9195
|
+
- **G3**:`readRunCancelContext({ status, cancelContext, result: { text } })` ⇒ present(不下钻)。
|
|
9196
|
+
|
|
9197
|
+
### 72z. 逐键处置表
|
|
9198
|
+
|
|
9199
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
9200
|
+
|---|---|---|---|
|
|
9201
|
+
| 1 | `fleet-row.wireTaskId` / `taskIdOrigin` | **additive(在场才带)** | `src/engineAgentPanelStore.ts` 漏斗 fleet-row 臂 |
|
|
9202
|
+
| 2 | tick 陈旧判据 | **fixed(漏斗内,不出公面)** | 同上 tick 臂 / flushHeld;判据复用 `isStaleEngineAgentPanelEnd` |
|
|
9203
|
+
| 3 | `runs.get` 记录 `result` 下钻 | **fixed** | `src/runCancelContext.ts` `runResultHolder` |
|
|
9204
|
+
|
|
9205
|
+
### 72y. 🔴 三端升级必读(固定段式,[C295])
|
|
9206
|
+
|
|
9207
|
+
1. 换钉 `^0.74.4`:面板桥零改;若按尾段对账,读 `wireTaskId`(`taskIdOrigin:'wire'` 时)。
|
|
9208
|
+
2. 不接线零变化 —— 除面板:三种非常态序不再两行;复活行计数不再被前代 tick 污染。
|
|
9209
|
+
3. peer 不动。
|
|
9210
|
+
|
|
9211
|
+
**包侧缺口:** ⓪ CC-74 mcpProbe 候 server S-481;① RH-2 第二步(收 end 铸点 / 删投影侧代际比较)候 clay 排序;② CC-81 sdk 9.8.0 换钉随下一 minor;③ CC-36 候 core #874;其余同 §71。
|
|
9212
|
+
|
|
9213
|
+
## §73 🆕 0.74.5 core 7.24.0 提货(CC-85)+ 首见即终态零事件(CC-86)+ `isNewEngineAgentPanelCycle`(CC-87);patch
|
|
9214
|
+
|
|
9215
|
+
> **patch**:型面 additive(+2 常量 +2 函数,公面 1061 → 1065;`compact_metadata._sema_freed_tokens?`;零 wire 新键;peer 不动)。票来源:core 7.24.0 [7707] / [7708](CC-85,表态 [7711])、cli L-415(CC-86)、cli 归包候票(CC-87 / CC-88,语义 = cli 1.0.123 现行手拼)。CC-70 / CC-83 的验收锚 = core 仓接入档(INTEGRATION-CORE)§1.6a 身份表(handle = 注册表 task_id;session id = 转录 / run id;`task_progress.taskId === transcriptId`;互不派生)。
|
|
9216
|
+
|
|
9217
|
+
### 73a. 处置表
|
|
9218
|
+
|
|
9219
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
9220
|
+
|---|---|---|---|
|
|
9221
|
+
| S-1 | `compacted.freedTokens?`(core ≥7.24.0) | **consumed**:`compact_metadata._sema_freed_tokens?`(在场才带) | 压缩行渲它;缺席渲「未知」不渲 0,旧对 `pre_tokens` 不再与任何数相减 |
|
|
9222
|
+
| S-2 | 首见即终态的 fleet 行 | **fixed**:零事件,只记 settled | 零改;reattach 后历史终态行不再上屏;壳侧不做时序补偿 |
|
|
9223
|
+
| S-3 | 「这一帧是不是新周期」判据 | **exported** `isNewEngineAgentPanelCycle(prev, next)` | 面板桥在 `fleet-row` 到时用它判是否重置行(壳侧手拼退役) |
|
|
9224
|
+
| S-5 | 流内帧腿审批结局 → 宿主便签 | **exported** `approvalOutcomeNoteOf(frame, outcome)` → `{approvalId, settled, retracted?, detail?}`(settled = decision ≠ unresolved;retracted 独立键;detail 三支:撤卡句 / 编辑被拒句 / respondRefusal 码·文案;空 ⇒ 缺席) | `onToolApprovalOutcome` 里改调它喂便签口,删各自手拼 |
|
|
9225
|
+
| S-4 | `ListAgentsRow.state` 新值 `unknown` / `RouteRefusalDetail` URL 展示串 / `TaskOutput` 正文 `errorCode` | **n/a**(本包无读口 / 按结构面 details 读) | 壳的面 |
|
|
9226
|
+
|
|
9227
|
+
### 73b. 缺席语义(逐键)
|
|
9228
|
+
|
|
9229
|
+
- `_sema_freed_tokens` 缺席 = 引擎没测出来(老 core,或本次压缩没算出);**不是 0**。`pre_tokens` 仍是 CC 必填数,`tokensBefore` 缺席时兜 0(KL-21)。
|
|
9230
|
+
- 首见即终态的行:台账记 settled,缺席口不上报它;复活帧(周期更新)照常发 `fleet-row` + `end`;**本进程发布过 running** 的行(含台账已回收的;不按会话分桶,与面板订阅同作用域)迟到终态仍照发 end —— 「首见」= 本进程从没发布过它在跑;历史结掉即删(任何 lane 的 `end` 到漏斗都销账,只销当代)、有界 4096、溢出后转保守(不再压制)直到整表重置。
|
|
9231
|
+
- 反向所有权(0.74.4「先发布的键为准」)按 transcriptId 到期:行帧两个周期键全缺时,transcriptId 换了同样视为新一代(test [7718])。
|
|
9232
|
+
- `StreamApprovalOutcomeNote.retracted` 缺席 = 未撤卡(不是 false);`detail` 缺席 = 没有可说的(不编句)。
|
|
9233
|
+
- `isNewEngineAgentPanelCycle` 任一边判不出 ⇒ `false`(缺席不制造周期,与陈旧判据同向)。
|
|
9234
|
+
|
|
9235
|
+
### 73c. 黑盒判据骨架
|
|
9236
|
+
|
|
9237
|
+
- **G1(CC-85)**:core 7.24.0 真压缩一次 ⇒ `compact_boundary.compact_metadata._sema_freed_tokens` 在场且 ≥ 0;core 7.23.x ⇒ 键缺席。
|
|
9238
|
+
- **G2(CC-86)**:reattach / resume 后引擎 fleet 列表含历史终态行 ⇒ 面板零幽灵完成行(0.74.4 红基线:每条历史行一行 completed);本会话内 running → 终态照常 end。
|
|
9239
|
+
- **G3(CC-87)**:`isNewEngineAgentPanelCycle({cycleSeq:1},{cycleSeq:2}) === true`、`({startedAt:1},{startedAt:2}) === true`、`({cycleSeq:1},{startedAt:2}) === false`。
|
|
9240
|
+
|
|
9241
|
+
### 73z. 逐键处置表
|
|
9242
|
+
|
|
9243
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
9244
|
+
|---|---|---|---|
|
|
9245
|
+
| 1 | `compacted.freedTokens?` | **consumed(超集键)** | `src/adapter/downstream/eventToSdkMessage.ts` compacted 臂 |
|
|
9246
|
+
| 2 | fleet 行首见即终态 | **fixed** | `src/fleetAgentPanelProjection.ts` 终态分支 `newbornTerminal` |
|
|
9247
|
+
| 3 | 新周期判据 | **exported** | `src/engineAgentPanelStore.ts` `isNewEngineAgentPanelCycle` |
|
|
9248
|
+
| 4 | 审批结局便签映射 | **exported** | `src/hitl/approvalOutcomeNote.ts`;语义 = cli 1.0.123 现行手拼 |
|
|
9249
|
+
|
|
9250
|
+
### 73y. 🔴 三端升级必读(固定段式,[C295])
|
|
9251
|
+
|
|
9252
|
+
1. 换钉 `^0.74.5`:压缩行读 `_sema_freed_tokens`;面板桥的新周期判据改调 `isNewEngineAgentPanelCycle`;`onToolApprovalOutcome` 改调 `approvalOutcomeNoteOf`。
|
|
9253
|
+
2. 不接线零变化 —— 除面板:历史终态行不再上屏(行为面修正)。
|
|
9254
|
+
3. peer 不动;core <7.24.0 ⇒ `_sema_freed_tokens` 缺席。
|
|
9255
|
+
|
|
9256
|
+
**包侧缺口:** ① CC-74 mcpProbe 候 server S-481;② CC-81 sdk 9.8.0 换钉 + K-04 `FleetWorkflowRow.errorCode?`(sdk 9.9.0,窗 10-03)随下一 minor;③ RH-2 第二步候排序;④ CC-36 候 core #874;其余同 §72。
|
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.5",
|
|
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",
|