@sema-agent/client-core 0.72.5 → 0.72.7
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 +24 -0
- package/README.md +2 -2
- package/dist/adapt/arms.js +4 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +43 -1
- package/dist/adapter/activeRunSelfHeal.js +35 -9
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +8 -0
- package/dist/adapter/downstream/eventToSdkMessage.js +16 -1
- package/dist/engineNoticeCodes.d.ts +17 -1
- package/dist/engineNoticeCodes.js +37 -1
- package/dist/seam.d.ts +3 -1
- package/docs/INTEGRATION-CLIENTS.md +68 -8
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,30 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.72.7(2026-09-18)
|
|
53
|
+
|
|
54
|
+
> 主题:**core 7.22.0 提货**(发车帖 [7502] / 提货单 [7503] @client-core 三条;CC-42)。**patch**:型面纯 additive(一个 `_sema_` 超集键 + 通告闭集 +1 + 读器 +1 + 三词闭集 +1;公面 969 → 971;peer 不动;devDep core `~7.22.0`)。接入面 §54。
|
|
55
|
+
|
|
56
|
+
### Added
|
|
57
|
+
|
|
58
|
+
- **`ENGINE_NOTICE_CODES` +1 = 六十六码**(顺序同源):`mcp.server_redialed`(紧跟 `mcp.revocation_probe_failed`;operator)—— 宿主请这条 run 重拨一台 MCP server 的结果,**一个码管两个方向**(`outcome` 是数据不是两种事件);去重单位 = **每次尝试**,永不按 run 折叠。事实读器 **`readMcpServerRedialed(notice)`** ⇒ `{ server, outcome, added, removed, reason?, sessionId, runId }`:`outcome` 按三词闭集 **`MCP_REDIAL_OUTCOMES`**(`reconnected` / `refused` / `not_declared`,core `McpReconnectResult.outcome` 逐字)读,词表外整只缺席;`added` / `removed` 是**计数**(非负整数)不是工具名;必填格缺一整只缺席;`reason` 开集透传只渲不分支。码册门 G8b 六十六 + G10 八格(红先绿后)。
|
|
59
|
+
- **`wiring_manifest.readDeny` 第九段进切片 ⇒ `_sema_readDeny?: { builtinTiers: string[] }`** + chrome `wiring_manifest.readDeny?`(core #889 C-R60:内置敏感文件读 deny 表出厂 OFF,manifest 新格 = **实质激活档位**,按 `READ_DENY_BUILTIN_TIERS` 顺序、每行都被排除的档位不列名;挨着 `writeProtection`,进 `configFingerprint`)。🔴 缺席 = **没有内置行判这条腿**(未配置部署 / 老 server),**不是**「没有读被 deny 判」(部署与任务级 `readDenyPatterns` 是另一套来源,刻意不上报);空数组铸点**永不发出** ⇒ 判畸形段缺席;档位词**开集**透传(闭集 `ReadDenyBuiltinTier` 五员归 core,本包不手抄);成员非非空串 / 非对象 ⇒ 段缺席其余段照投;多余成员不过境。type-superset +1 = 54;wiring 门 M 段 13 格(红先绿后)。
|
|
60
|
+
|
|
61
|
+
### Notes(零动作,写出来免得被读成漏接)
|
|
62
|
+
|
|
63
|
+
- `SafetyAxis.shell?: boolean`(与 `irreversible` 互斥)、`ParentSpecSeat.memoryOff?: true` 与 `createSubagentResume` deps `currentClamps.memoryOff?: true`:本包不读这三位(ask 门族按 `gateKind` 分臂,不读 `safetyAxis` 成员;resume-clamp 形不镜像)⇒ 零动作;`SAFETY_AXIS_VOCABULARY` 早列 `shell`,零闭集变化。
|
|
64
|
+
- 新导出四个(`McpReconnectResult` / `autoRunOnRecommendationEffective` / `RETENTION_CASCADE_DOMAINS` / `RETENTION_CASCADE_EXEMPT`):本包零 core 值级 import ⇒ n/a;`McpReconnectResult.outcome` 的三词在本包以 `MCP_REDIAL_OUTCOMES` 字面镜像(通告读器用)。`ReadDenyBuiltinTier` 首登记五员零变化、`AUTO_MODE_UNAVAILABLE_CAUSES` 不变 ⇒ 零动作。
|
|
65
|
+
- CC-30(MCP 会话内重连消费口):core 半场 #857 已到,等 server S-381 挂 `POST /v1/sessions/:id/mcp/reconnect`(server [7500] 排 7.84.0)。CC-34:server [7501] 反转对位承诺,根治归 core #897,本包升级腿零改动候。
|
|
66
|
+
|
|
67
|
+
## 0.72.6(2026-09-18)
|
|
68
|
+
|
|
69
|
+
> 主题:**steer 之后谁续听那条 run**(cli L-379 P1 包侧半场;server 7.81.0 S-384 副作用 [7495] ④′)。**patch**:型面纯 additive(+1 函数 `steerFollowIntent` + `activeRunSelfHealRow` 第五个可选参;公面 968 → 969;零 wire 键;peer 不动)。接入面 §53。
|
|
70
|
+
|
|
71
|
+
### Added
|
|
72
|
+
|
|
73
|
+
- **`steerFollowIntent(outcome)`**(`src/adapter/activeRunSelfHeal.ts`):`running-steered` 结局 → 续听意图三态,按 SDK `SteerReceipt.delivery` 判 —— `applied` 与读不出 / 未知词 ⇒ `{ kind: 'tail', taskId }`(run 在跑,现在就 tail 至终局 / park;保守当活);`queued` ⇒ `{ kind: 'after-decision', taskId }`(run 停在待决 checkpoint,答卡后 resume 出的流才是要听的);`parked_for_wake` ⇒ `{ kind: 'after-wake', taskId }`(run 已终局,wake 之前什么都不会发生);其余结局 ⇒ `null`。病形:server 7.81.0 起 plan_review 决断后 run 立刻回 running、撞下一道门活着等卡,壳的跟进注入件撞活 run 被折成 steer,行文案说「watch that run」后 turn 收尾,**没有人 tail 那条 run** ⇒ 它新弹的决断卡永不上屏(实测 400 s 零事件;7.80.1 差分 3.3 s 上屏)。「该不该 tail、什么时候 tail」是三端同一判据,归包。`fromEventId` 包侧算不出(回执不带),壳用自己的 Last-Event-ID 续。🔴 `held-for-decision` 档刻意不加位:宿主答卡后重投注入件,那次提交要么开新 turn 要么再撞 409 回到这里。
|
|
74
|
+
- **`activeRunSelfHealRow(outcome, signal?, copy?, origin?, follow?)` 第五参 `SelfHealFollowDeclaration { following?: boolean }`**:宿主传 `{ following: true }`(= 真的按上面的意图挂上了续听)时,handed-off 三句(注入形 / 用户形 applied / 用户形 delivery 读不出)从「watch that run …」换成事实陈述「sema is following that run and will surface whatever it asks for next」;不传 / false ⇒ 逐字节同 0.72.5。文案与行为同一前提:没接线的端不许替用户说「sema 在看着」。`queued` / `parked_for_wake` 两臂不换句(它们本就不说 watch;续听挂在 decide / wake 之后)。门 `run-terminal-identity-copy-test.mjs` G3 段 +34 格(红先绿后;异源对抗复审一轮 [medium] 真修:注入形对 queued / parked_for_wake 也换了句 ⇒ 只在意图为 tail 时换,加格钉住)。
|
|
75
|
+
|
|
52
76
|
## 0.72.5(2026-09-18)
|
|
53
77
|
|
|
54
78
|
> 主题:**server 7.82.1 提货 —— `capabilities.webSearch.backend` 部署默认 WebSearch 后端四态读面**(CC-31;server S-382 契约附录 B.1;cli [7418] ② 点名 / 本包 [7420] 认领)。**patch**:型面纯 additive(+1 常量 +5 函数,公面 962 → 968;零 wire 新键,本包只读;peer 不动)。接入面 §52。
|
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.72.
|
|
38
|
+
**Version:** 0.72.7
|
|
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
|
|
@@ -348,7 +348,7 @@ public-surface guard checks that last one).
|
|
|
348
348
|
| `scripts/run-rules-side-test.mjs` | The persisted-permission-rules lane's shared decision half. The two capability bits are checked as **two independent gates** — a worker can honestly advertise the rules lane while predating the revoke routes, and that shape must *hide* the governance surface rather than render a dead entry. Failure classification is by **disposition, not cause**: the two 404s (route missing vs. dead ticket) never share a bucket, a 503 `rule_import_retry` means *the ticket is still alive* (the opposite handling of a dead one), and a stale-cursor 400 drops the cursor and re-lists from the top exactly once — never resuming a stale keyset, never surfacing a partial governance list, and never paging past the hard cap. The persist-ack reader is **merged into** `readToolApprovalRespondAck`: the three-state verdict (`persisted` / `refused` / `unknown`) is derived only from an ack that passed the package's structural narrowing, and a half-shaped object such as `{rulePersisted: true}` with no `delivery` reads as `unknown` — the pre-merge shell read would have said `persisted`, which is precisely the double-ledger drift this file closes, so that case is pinned in reverse. The local-allow-rule skeleton pins all five narrowings (whole-tool, tool-name match, literal anchor with the escaped-star counter-example, bare interpreter prefix consulted only for Bash, and the canonical dangerous-pattern overlay) **with their refusal strings byte-for-byte** — the cli's 128-assertion suite anchors the same strings, so a one-character edit here changes observable behaviour on three clients — and asserts the parse is a pure function of its input, because the same call backs both "render the option" and "resolve the selected value" |
|
|
349
349
|
| `scripts/run-park-decision-layer-test.mjs` | The decision layer behind the "stuck behind a card" family, shared by every client. A pending row that is **not in the queue** is three states, not one: a bounded, interruptible re-probe loop distinguishes *a decidable row*, *not born yet* (no positive evidence that anything settled — an empty queue proves nothing) and *settled elsewhere*, always probes at least once so a zero budget keeps the pre-fix semantics verbatim, cuts a hung read face off at the window rather than only noticing afterwards, and reports the honest failure when the window is spent instead of inventing a decision. The decision-note reader is likewise three-state: an explicit `noteRecorded: false` outranks an echoed note body, absence renders **no line at all**, and untrusted note text is flattened and bounded before it ever reaches a renderer. Row routing anchors on the deciding quantity — a row carrying `gateKind: "human"` with `toolName: "Write"` is a tool gate, because `human` is the engine's *generic* "someone must decide", not a synonym for a question — and the queue scan refuses to surface a row it cannot positively prove belongs to this session. A chain that fails after the row vanished is split by whether a card was ever presented: decided-elsewhere, or not-its-turn-yet. A row-level single-flight makes "at most one card per pending item" structural rather than incidental. The resume three-way card pins the option **order** (the zero-effect choice sits at index 0, because the frame carries no default-focus field and a stray Enter must not attach or cancel), renders only options the wired verbs can honour, collapses every ambiguous answer to zero action, omits the liveness line entirely when the engine gave no evidence, and — when there is no card lane at all — prints three real routes and exits on a dedicated code rather than reporting success |
|
|
350
350
|
| `scripts/run-selfheal-reopen-test.mjs` | The 409 active-run self-heal decision chain: `governanceForced` narrows on strict `true` only; triage prefers the wire's `pendingGate.kind` and falls back to the status table (an off-table kind is never guessed into a card arm — hands-off plus the honest wording); a first-sight card makes zero closed/reopened claims and a host presentation receipt of `presented: false` demotes the outcome to reopen-failed; park-row ownership is a fail-closed positive proof (own-run ledger or session id — unprovable is not owned); the three gate-identity key literals live in exactly one mint (`hitl/gateIdentity.ts`, AST string-token scan); the armed-gate presentation ledger is per-session; and the `plan_review` reopen arm shares the arm arm's card body, three-state verdict and delivery pipe, consuming the presentation history once a decision is delivered. The same chain also carries the `running` three-way card: both plan-family gate kinds route to the plan arm and all four ask-family kinds to the ask arm (an off-table kind still never gets guessed into either); the card is offered only for verbs that can actually be honoured and a missing presenter means zero action rather than a silent cancel; a steer is sent **exactly once** with its three delivery outcomes worded apart (a `queued` receipt is the wire correcting the triage input, so the named park word decides which card gets reopened, and an unrecognised park word drives neither arm), and a steer failure is split into *provably not delivered* (4xx) and *delivery unknown*, because telling a user to resend a non-idempotent instruction that may already have landed is how duplicates get made. After a user-chosen cancel, "the session is free" is asserted only from a whitelist of terminal states — park states hold the claim, an unrecognised state word is not a release, a failed read is *unknown* rather than a release, and only a 404 counts as one — and the honest timeout line quotes how long it really waited |
|
|
351
|
-
| `scripts/run-terminal-identity-copy-test.mjs` | Terminal-state **identity**, in both lanes where a stop gets a name. A run stopped by this deployment's own governance knobs — the open-set `limits.*` family, `output.invalid`, and the `blocked` contract terminal a ReportBlocked agent produces — is not a provider failure, and labelling it `API Error:` sends the reader to check the network, the key and the quota when the handle is the `--max-turns` they passed themselves. Those terminals now render a neutral row; the reverse direction is guarded just as hard, because asserting "this is *not* an API error" on a code the package does not recognise is the same misfiling pointed the other way — a real `gateway HTTP 502`, a `conflict.session_active_run` and any unknown code all keep the `API Error:` prefix, and the row keeps its `isApiErrorMessage` class flag so brief-mode visibility filtering does not silently drop it. The second half is who the rejected submission belonged to: the self-heal copy told every caller "Your message was NOT sent … send it again", which is three separate untruths for a system injection (a plan-review outcome, a cron wake-up, a task notification) — not the user's message, and not re-sendable, since a host queue marks those non-editable and non-recallable. The injected form says so instead, and the one sentence that promises re-delivery is pinned to the single disposition that earns it: `selfHealSubmissionDisposition` is the same function the host consults before putting the item back on its queue, so the promise and the behaviour cannot drift apart, and the arms where no card could be surfaced state plainly that nothing was delivered and nothing will retry |
|
|
351
|
+
| `scripts/run-terminal-identity-copy-test.mjs` | Terminal-state **identity**, in both lanes where a stop gets a name. A run stopped by this deployment's own governance knobs — the open-set `limits.*` family, `output.invalid`, and the `blocked` contract terminal a ReportBlocked agent produces — is not a provider failure, and labelling it `API Error:` sends the reader to check the network, the key and the quota when the handle is the `--max-turns` they passed themselves. Those terminals now render a neutral row; the reverse direction is guarded just as hard, because asserting "this is *not* an API error" on a code the package does not recognise is the same misfiling pointed the other way — a real `gateway HTTP 502`, a `conflict.session_active_run` and any unknown code all keep the `API Error:` prefix, and the row keeps its `isApiErrorMessage` class flag so brief-mode visibility filtering does not silently drop it. The second half is who the rejected submission belonged to: the self-heal copy told every caller "Your message was NOT sent … send it again", which is three separate untruths for a system injection (a plan-review outcome, a cron wake-up, a task notification) — not the user's message, and not re-sendable, since a host queue marks those non-editable and non-recallable. The injected form says so instead, and the one sentence that promises re-delivery is pinned to the single disposition that earns it: `selfHealSubmissionDisposition` is the same function the host consults before putting the item back on its queue, so the promise and the behaviour cannot drift apart, and the arms where no card could be surfaced state plainly that nothing was delivered and nothing will retry. Since 0.72.6 the same gate pins the **follow intent** after a steer (L-379): a message handed to a live run only pays off if someone tails that run's own event stream, so `steerFollowIntent` decides from the delivery word whether to tail now, after the pending decision, or only after a wake — and the "watch that run" sentence turns into a factual "sema is following that run" **only** when the host declares it attached that tail, so a shell that did not wire it can never claim it did |
|
|
352
352
|
| `scripts/run-additive-key-passthrough-test.mjs` | The one disease shape behind two legs: a **closed whitelist / flattening arm** dropping a fact that is already on the wire, while both sides of the seam look correct. (1) The `task_progress` projection carries a registered **key ledger** — a frame populated with every key the service really projects is pushed through the shipped `eventToSdkMessage`, and the set of wire keys that survive must equal the registered pass-through list **name for name in both directions**, so quietly forwarding one more key is as red as quietly dropping one. `model` (the child run's model id, minted by core as `prepared.model.id` and projected by the server since 7.52.1) is the key this batch adds, with the same conditional the server itself applies: a non-empty string or no key at all — an empty string is neither a model id nor "unknown". The ledger is also checked against the fenced list in `docs/INTEGRATION-CLIENTS.md` §3d, so a doc that still says seven keys while the code forwards eight is red rather than merely stale. (2) The decide-failure arms carry the server's S-02 `currentPending` pointer key from a 409 `approval_stale` refusal onto the outcome the host reads. The reader is structural rather than `instanceof`, because the client is host-injected and the class identity is not this package's to assume; a half triple never mints (half a pointer cannot relocate anything), an empty string is not presence, and `checkpointToken` never transits. Both the allow and the deny leg are driven end to end through the real durable approval path — as is the accept-session leg, where a refusal carrying the pointer key must now re-raise instead of silently re-sending the human's answer for the **old** card as a plain approve (one decide call, pointer preserved), while a legacy 400 still falls back exactly as before — and all three flattening points must call the one shared reader — the same-shape residue check that makes "fixed one arm and left the twin" red instead of invisible. (3) The same disease growing on the REQUEST side: the `.mcp.json` → server-spec projection rebuilds each server key by key, and the settings schema deliberately leaves some keys parse-transparent — whatever JSON the file carries reaches the engine untouched, because validating them where the whole domain parses all-or-nothing would let one bad declaration take every server down silently. The whitelist had no row for the newest of them, so an operator's per-tool declarations — the ones the write fence reads — were stripped at the package boundary while both sides looked correct. The criterion is not "is that key handled" but the transparent-key table read out of the INSTALLED schema at runtime, reconciled name-for-name against this leg's ledger, so the day upstream adds a third one this turns red and forces an explicit decision. Behaviour is pinned on both transports, by object identity rather than deep equality (a rebuild would be a second judge), and malformed values must transit UNCHANGED rather than be refused here — the engine refuses them loudly and names the server, whereas a package-side judge can only swallow a declared protection quietly. Absence still mints no key, unknown keys still never reach the wire (the fix is the dropped key, not the gate), and the one transparent key this leg deliberately does not forward is a ledger entry with its own exit condition: it belongs to the deployment plane, and the day the request-plane type declares it the entry's premise is gone and the gate says so |
|
|
353
353
|
| `scripts/run-esc-halt-plan-test.mjs` | The Esc stop decision every client shares: fire the **turn-level** halt first, and escalate to a **run-level** cancel in exactly two cases — the engine itself answered with a 409 from the closed code set (it is saying "there is no in-flight turn here; use cancel for a run-level stop"), or that shot came back with no verdict at all *and* the shell can independently prove a permission card was on screen. Everything else does not escalate. The asymmetry is the whole point and every negative control guards the same direction — deciding *not* to escalate costs the user one more choice on a busy-session card (recoverable), deciding to escalate wrongly tears down a run that was alive and takes every in-flight tool with it (not). So: the closed code set is a **frozen** value, not a `ReadonlySet` — type-level immutability does not stop a consumer's `.add()`, and the guard proves it by really trying to mutate the exported value and then checking the verdict did not drift; the escalation gate is the **conjunction** of that closed set and the 409 status, since honouring the code alone lets a 500 that merely quotes it drive a destructive call; `interrupt.not_held` and `steering.not_running` are deliberately outside the set (the first means *this replica* has no live face — the run may be perfectly alive on another); an unreadable code falls to the no-escalation side; a `parked` flag never overrides a verdict the engine did give, and only strict `true` counts when it did not. The first shot is unconditional by construction — it does not consult `parked`, because the 409 it earns is exactly the verdict the gate wants — and the verdict itself is a closed machine-readable reason word, not display copy. A third escalating case was added once tearing the stream stopped reaping the run: with detach armed, a shot that never lands leaves the run going all the way to the end of the turn, so the Esc the user pressed has no effect at all and nothing on screen says so — the old behaviour had a silent backstop (tearing the stream ended the run) and that backstop is gone. The new fact is held to the same three disciplines as `parked`: it is read only where the engine gave no verdict, it is judged **after** `parked` so an existing host's reason word does not change under it, and only strict `true` counts. Absence is proven to be a no-op rather than asserted — the guard carries its own reference implementation of the previous version's table, runs the full grid through both, requires zero divergence when the new field is omitted, and first shows the comparison really does report a difference on the one cell where the two versions are meant to differ |
|
|
354
354
|
| `scripts/run-peer-frame-projection-test.mjs` | The three engine-injected lanes design/385 puts on the **one** `task_notification` carrier, which are not the same kind of thing at all: a delegated child's uplink (`agentMessage`), another session's message drained from this session's own box (`crossSessionMessage`), and a receipt about one of *this* session's own outbound messages (`crossSessionNotice`). The engine renders none of them inside a `<task-notification>` shell, so a client that projects them as the generic completion card shows "background task finished" while the model read a colleague's sentence — two faces describing different events. The discriminator is pinned to the **typed carrier being present**, never to the `summary` text: those carriers can only be minted by the engine's injection legs (the external `notify()` input is a strict subset of the payload and can wear none of them), while `summary` is filled by every notification there is — so anchoring on text would let any background task impersonate a colleague's message by writing `<agent-message from="…">` into its own summary, and a positive control asserts exactly that payload still projects as the generic card. Fail-closed has two tiers rather than one: a broken **required** field (empty `from`, a non-string `body`, a notice `kind` outside the closed set) returns absence so the caller falls back to the generic card — an honest downgrade where the user still sees the notification — while a broken **optional** field drops only itself, because losing an attribution note and losing a colleague's whole message are not the same magnitude. The provenance side record is **required and must agree on four points** (`kind` matches the lane; `from`/`taskId`/`seq` are present and equal the carrier/payload — each equality is anchored on a core mint site and pinned by the cli wire-anchor A-K24), so a carrier signed with a trusted name but a disagreeing provenance falls back to the generic card; peer bodies pass the same authority-envelope neutralization core applies (`<task-notification>` etc. are defused) so a colleague's text can never seed the resume dedup ledger. Lane precedence copies the engine renderer's own order, because the model already read the frame in that order and a client ordering of its own would put a card on screen that disagrees with the frame the model saw. Rendering and parsing of the transcript line live in the same module and are round-tripped in both directions, including a body carrying a forged closing tag (a parser fooled there hands half a message to the next row) and a quote inside the sender label (which must not forge a second attribute); the notice lane is deliberately kept **out** of the parser, since recognising it would mean anchoring the `[Cross-session …]` prefix and a user typing that same line would be rendered as engine speech. Hostile carriers are read as own **data** descriptors only and accessors are never invoked at all — `catch` catches throwing, not never returning — proven by a counting getter that must stay at zero calls, alongside a revoked proxy and a prototype-only carrier; and four legacy payload shapes assert the no-carrier path is byte-identical to before, which is the executable form of "zero difference for an older host" |
|
package/dist/adapt/arms.js
CHANGED
|
@@ -375,6 +375,8 @@ const wiringManifestArm = function* (m) {
|
|
|
375
375
|
const hasWriteProtection = typeof writeProtection === 'object' && writeProtection !== null;
|
|
376
376
|
const autoConsolidation = m._sema_autoConsolidation;
|
|
377
377
|
const hasAutoConsolidation = typeof autoConsolidation === 'object' && autoConsolidation !== null;
|
|
378
|
+
const readDeny = m._sema_readDeny;
|
|
379
|
+
const hasReadDeny = typeof readDeny === 'object' && readDeny !== null;
|
|
378
380
|
const hasTools = typeof tools === 'object' && tools !== null;
|
|
379
381
|
const hasHooks = Array.isArray(hooks);
|
|
380
382
|
const hasLsp = typeof lsp === 'object' && lsp !== null;
|
|
@@ -383,7 +385,7 @@ const wiringManifestArm = function* (m) {
|
|
|
383
385
|
// S-124(0.59.0):🔴 `Array.isArray` 判在场,**不判 `.length`** —— `mcp: []` 是「这条腿一台都
|
|
384
386
|
// 没申报」这句正面事实,按长度判会把它和「老 mint 没报」折成同一件事(core 顶注点名的读法)。
|
|
385
387
|
const hasMcp = Array.isArray(mcp);
|
|
386
|
-
if (!hasGate && !hasAuto && !hasMcp && !hasTools && !hasHooks && !hasLsp && !hasWriteProtection && !hasAutoConsolidation)
|
|
388
|
+
if (!hasGate && !hasAuto && !hasMcp && !hasTools && !hasHooks && !hasLsp && !hasWriteProtection && !hasAutoConsolidation && !hasReadDeny)
|
|
387
389
|
return;
|
|
388
390
|
yield chrome({
|
|
389
391
|
kind: 'wiring_manifest',
|
|
@@ -396,6 +398,7 @@ const wiringManifestArm = function* (m) {
|
|
|
396
398
|
...(hasLsp ? { lsp: lsp } : {}),
|
|
397
399
|
...(hasWriteProtection ? { writeProtection: writeProtection } : {}),
|
|
398
400
|
...(hasAutoConsolidation ? { autoConsolidation: autoConsolidation } : {}),
|
|
401
|
+
...(hasReadDeny ? { readDeny: readDeny } : {}),
|
|
399
402
|
...(typeof m.eventId === 'string' && m.eventId.length > 0 ? { eventId: m.eventId } : {}),
|
|
400
403
|
});
|
|
401
404
|
};
|
|
@@ -513,6 +513,48 @@ export type SelfHealSubmissionDisposition = 'held-for-decision' | 'resending' |
|
|
|
513
513
|
* 「已解锁」证不出,自动重投可能撞回仍锁着的会话。
|
|
514
514
|
*/
|
|
515
515
|
export declare function selfHealSubmissionDisposition(outcome: SelfHealOutcome): SelfHealSubmissionDisposition;
|
|
516
|
+
/**
|
|
517
|
+
* steer 之后**谁续听那条 run、从哪一拍续听**(0.72.6;cli L-379 包侧半场)。
|
|
518
|
+
*
|
|
519
|
+
* ── 病形 ────────────────────────────────────────────────────────────────────────────────────
|
|
520
|
+
* server 7.81.0 起 local 车道的 bg/resume 腿是活审批目标:plan_review 决断后 run **立刻回 running**、撞到
|
|
521
|
+
* 下一道门时**活着等卡**(不再 park → 新流接管)。壳的跟进提交(系统注入件)撞活 run ⇒ 本文件折成 steer ⇒
|
|
522
|
+
* `running-steered` ⇒ 行文案说「watch that run」⇒ 壳 turn 收尾 —— **没有人 tail 那条 run**。那条 run 的
|
|
523
|
+
* 后续(含它新弹出的决断卡)只出现在它自己的 `GET /v1/runs/:id/events` 上,没人听就没人看见:卡永不上屏,
|
|
524
|
+
* 用户被丢在原地(实测 400 s 零事件零卡;7.80.1 差分 3.3 s 上屏)。
|
|
525
|
+
*
|
|
526
|
+
* ── 为什么是包侧判据 ────────────────────────────────────────────────────────────────────────
|
|
527
|
+
* 「该不该 tail、什么时候 tail」由 `delivery` 决定,三端各自猜必漂。判据锚在 SDK `SteerReceipt` 头注逐字:
|
|
528
|
+
* · `applied` —— 注入到活着的 run,下一步就消化 ⇒ **现在就 tail** 至终局 / park。
|
|
529
|
+
* · `queued` —— run 停在待决 checkpoint,消息 park 在上面;答卡后 resume 出的那条流才是要听的
|
|
530
|
+
* ⇒ 续听挂在 **decide 之后**(reopen 那张卡的路径已在本文件里,decide 是壳的事)。
|
|
531
|
+
* · `parked_for_wake` —— run 已终局,消息卡在 `task_done` checkpoint;**wake 之前什么都不会发生** ⇒ 现在
|
|
532
|
+
* tail 只会空等;续听挂在 wake 之后(本客户端不 wake,如实说)。
|
|
533
|
+
* · 读不出 / 未知词 —— **保守当活 ⇒ tail**:不 tail 的代价是卡永不上屏,空 tail 的代价只是多一条订阅。
|
|
534
|
+
* `fromEventId` 包侧算不出(回执不带),壳用自己手上的 Last-Event-ID 续;缺席 = 从 live 起听。
|
|
535
|
+
* 🔴 `held-for-decision` 档**刻意不加位**:宿主答卡后按原优先级重投注入件,那次提交要么开新 turn(自己的流),
|
|
536
|
+
* 要么再撞 409 ⇒ 回到这里 ⇒ `running-steered` ⇒ 本函数。谁听 = 重投那次提交的流。
|
|
537
|
+
*/
|
|
538
|
+
export type SteerFollowIntent = {
|
|
539
|
+
kind: 'tail';
|
|
540
|
+
taskId: string;
|
|
541
|
+
} | {
|
|
542
|
+
kind: 'after-decision';
|
|
543
|
+
taskId: string;
|
|
544
|
+
} | {
|
|
545
|
+
kind: 'after-wake';
|
|
546
|
+
taskId: string;
|
|
547
|
+
};
|
|
548
|
+
/** 结局 → 续听意图;非 `running-steered` 结局(含非对象入参)⇒ `null`。纯函数,不改 {@link SelfHealOutcome} 型面。 */
|
|
549
|
+
export declare function steerFollowIntent(outcome: SelfHealOutcome | null | undefined): SteerFollowIntent | null;
|
|
550
|
+
/**
|
|
551
|
+
* 宿主对 {@link activeRunSelfHealRow} 的**续听声明**:`following: true` = 「我已经按 {@link steerFollowIntent}
|
|
552
|
+
* 挂上了续听」。只有这时 handed-off 那两句才从「watch that run」换成事实陈述 —— 文案与行为同一前提,没接线的端
|
|
553
|
+
* 不许替用户说「sema 在看着」。缺席 / false ⇒ 逐字节同旧。
|
|
554
|
+
*/
|
|
555
|
+
export interface SelfHealFollowDeclaration {
|
|
556
|
+
following?: boolean;
|
|
557
|
+
}
|
|
516
558
|
/**
|
|
517
559
|
* cancel 回执(202 体)/ run 行上的 `cancelRequested`(0.68.0 / L-230;server 7.73.0 S-122 P-45)。
|
|
518
560
|
*
|
|
@@ -638,7 +680,7 @@ export declare const INTERACTIVE_WAY_OUT = "run /clear to keep working in a fres
|
|
|
638
680
|
* wire 真到得了端的两个 additive 键是 `activeTaskStatus` 与 `pendingGate`,各自有真消费点;
|
|
639
681
|
* 不为「说不定哪天上游会发」的键留悬空分支。
|
|
640
682
|
*/
|
|
641
|
-
export declare function activeRunSelfHealRow(outcome: SelfHealOutcome, signal?: ActiveRunBusySignal | null, copy?: ActiveRunSelfHealCopy, origin?: RejectedSubmissionOrigin): string;
|
|
683
|
+
export declare function activeRunSelfHealRow(outcome: SelfHealOutcome, signal?: ActiveRunBusySignal | null, copy?: ActiveRunSelfHealCopy, origin?: RejectedSubmissionOrigin, follow?: SelfHealFollowDeclaration): string;
|
|
642
684
|
/**
|
|
643
685
|
* 非交互车道(headless `-p` 等)对同一事实的诚实说法:那里没有 `/clear`,默认串指的是「别再
|
|
644
686
|
* `--resume` 到这个会话」和引擎自己的 cancel/decide 端点 —— 都是真的存在、真的能做的动作。
|
|
@@ -153,6 +153,17 @@ export function selfHealSubmissionDisposition(outcome) {
|
|
|
153
153
|
return 'not-delivered';
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
+
/** 结局 → 续听意图;非 `running-steered` 结局(含非对象入参)⇒ `null`。纯函数,不改 {@link SelfHealOutcome} 型面。 */
|
|
157
|
+
export function steerFollowIntent(outcome) {
|
|
158
|
+
if (typeof outcome !== 'object' || outcome === null || outcome.kind !== 'running-steered')
|
|
159
|
+
return null;
|
|
160
|
+
const taskId = outcome.taskId;
|
|
161
|
+
if (outcome.delivery === 'queued')
|
|
162
|
+
return { kind: 'after-decision', taskId };
|
|
163
|
+
if (outcome.delivery === 'parked_for_wake')
|
|
164
|
+
return { kind: 'after-wake', taskId };
|
|
165
|
+
return { kind: 'tail', taskId };
|
|
166
|
+
}
|
|
156
167
|
/** 会话作用域位的透传口(缺席即不置键 —— `exactOptionalPropertyTypes` 下 `{session: undefined}`
|
|
157
168
|
* 与「没有这个键」不是一回事,而 SDK 那一侧读的正是「在不在场」)。 */
|
|
158
169
|
function sessionOpts(deps) {
|
|
@@ -1072,15 +1083,19 @@ function lastActivityClause(signal) {
|
|
|
1072
1083
|
* wire 真到得了端的两个 additive 键是 `activeTaskStatus` 与 `pendingGate`,各自有真消费点;
|
|
1073
1084
|
* 不为「说不定哪天上游会发」的键留悬空分支。
|
|
1074
1085
|
*/
|
|
1075
|
-
export function activeRunSelfHealRow(outcome, signal, copy, origin) {
|
|
1086
|
+
export function activeRunSelfHealRow(outcome, signal, copy, origin, follow) {
|
|
1076
1087
|
const override = copy?.rowFor?.(outcome, signal);
|
|
1077
1088
|
if (typeof override === 'string')
|
|
1078
1089
|
return override;
|
|
1090
|
+
// 0.72.6(L-379):宿主声明已挂续听 **且**本结局的续听意图确是「现在 tail」⇒ handed-off 句换成事实陈述;
|
|
1091
|
+
// 不声明 ⇒ 逐字节同旧。🔴 意图为 after-decision / after-wake 时**不换**(异源对抗复审 [medium]:那两形的续听是
|
|
1092
|
+
// 延后登记,不是正在续听;注入形此前没按 delivery 分臂,这里在入口统一收口,两种来源同一前提)。
|
|
1093
|
+
const following = follow?.following === true && steerFollowIntent(outcome)?.kind === 'tail';
|
|
1079
1094
|
// #289 批面② —— 系统注入件的低噪形。整块**前置**于默认串:注入形与用户形是两句完全不同的话,
|
|
1080
1095
|
// 不是在同一句上加定语(见 {@link injectedSubmissionRow} 头注)。缺省 'user' ⇒ 下面逐字节原样。
|
|
1081
1096
|
if (origin === 'injected')
|
|
1082
|
-
return injectedSubmissionRow(outcome);
|
|
1083
|
-
const base = activeRunSelfHealBaseRow(outcome, signal, copy?.wayOut ?? DEFAULT_WAY_OUT);
|
|
1097
|
+
return injectedSubmissionRow(outcome, following);
|
|
1098
|
+
const base = activeRunSelfHealBaseRow(outcome, signal, copy?.wayOut ?? DEFAULT_WAY_OUT, following);
|
|
1084
1099
|
switch (outcome.kind) {
|
|
1085
1100
|
// 这两条是「用户此刻卡住了、而且没有别的把手」的结局 —— wire 给的 decide 入口在这里才有用。
|
|
1086
1101
|
// not-parked(running 形)另挂活性证据([4664] 判别位):「它到底还活着吗」在这一行被问出来。
|
|
@@ -1113,7 +1128,7 @@ export function activeRunSelfHealRow(outcome, signal, copy, origin) {
|
|
|
1113
1128
|
* 一句话说清三件事:是系统件、当时什么挡住了它、接下来会不会自己再来。不给出路半句 —— 用户此刻
|
|
1114
1129
|
* 该做的事是答那张卡,而那张卡就在屏幕上。
|
|
1115
1130
|
*/
|
|
1116
|
-
function injectedSubmissionRow(outcome) {
|
|
1131
|
+
function injectedSubmissionRow(outcome, following = false) {
|
|
1117
1132
|
const handle = 'taskId' in outcome && outcome.taskId ? ` (run ${outcome.taskId})` : '';
|
|
1118
1133
|
switch (selfHealSubmissionDisposition(outcome)) {
|
|
1119
1134
|
case 'held-for-decision':
|
|
@@ -1122,14 +1137,19 @@ function injectedSubmissionRow(outcome) {
|
|
|
1122
1137
|
case 'resending':
|
|
1123
1138
|
return `A system notification was held while the earlier run${handle} was cancelled; sema is delivering it now.`;
|
|
1124
1139
|
case 'handed-off':
|
|
1125
|
-
|
|
1126
|
-
|
|
1140
|
+
// 🔴 「watch that run」只在宿主**没有**挂续听时说(那时确实只能靠用户看);挂上了就说事实 ——
|
|
1141
|
+
// 那条 run 接下来要的东西(含决断卡)会由 sema 从它自己的流上端上来(L-379)。
|
|
1142
|
+
return following
|
|
1143
|
+
? `A system notification was handed to the run that is already working${handle} instead of starting ` +
|
|
1144
|
+
`a new turn — sema is following that run and will surface whatever it asks for next.`
|
|
1145
|
+
: `A system notification was handed to the run that is already working${handle} instead of starting ` +
|
|
1146
|
+
`a new turn — watch that run for what it does with it.`;
|
|
1127
1147
|
case 'not-delivered':
|
|
1128
1148
|
return (`A system notification was NOT delivered: this session is still held by an earlier run${handle} and ` +
|
|
1129
1149
|
`sema could not put a decision for it on screen, so it did not retry. The model was not told about it.`);
|
|
1130
1150
|
}
|
|
1131
1151
|
}
|
|
1132
|
-
function activeRunSelfHealBaseRow(outcome, signal, wayOut) {
|
|
1152
|
+
function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false) {
|
|
1133
1153
|
switch (outcome.kind) {
|
|
1134
1154
|
case 'decision-pending':
|
|
1135
1155
|
return (`This session is held by an earlier turn${outcome.taskId ? ` (run ${outcome.taskId})` : ''} that ` +
|
|
@@ -1197,7 +1217,10 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut) {
|
|
|
1197
1217
|
if (outcome.delivery === 'applied') {
|
|
1198
1218
|
return (`sema handed your message to the run that is already working (${handle}) — the engine applied it to ` +
|
|
1199
1219
|
`that run, so it is picked up at that run's next step. ${textOnly} Nothing was cancelled, and your ` +
|
|
1200
|
-
`message did NOT start a new turn —
|
|
1220
|
+
`message did NOT start a new turn — ` +
|
|
1221
|
+
(following
|
|
1222
|
+
? `sema is following that run and will surface whatever it asks for next.`
|
|
1223
|
+
: `watch that run for what it does with it.`));
|
|
1201
1224
|
}
|
|
1202
1225
|
if (outcome.delivery === 'queued') {
|
|
1203
1226
|
const parked = outcome.status ? `parked (status ${outcome.status})` : 'parked';
|
|
@@ -1228,7 +1251,10 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut) {
|
|
|
1228
1251
|
}
|
|
1229
1252
|
return (`sema handed your message to ${handle}, but the engine did not say how it will be delivered` +
|
|
1230
1253
|
`${outcome.status ? ` (it reported that run as ${outcome.status})` : ''}. ${textOnly} Nothing was ` +
|
|
1231
|
-
`cancelled, and your message did NOT start a new turn —
|
|
1254
|
+
`cancelled, and your message did NOT start a new turn — ` +
|
|
1255
|
+
(following
|
|
1256
|
+
? `sema is following that run and will surface whatever it asks for next before you send it again.`
|
|
1257
|
+
: `watch that run before sending it again.`));
|
|
1232
1258
|
}
|
|
1233
1259
|
case 'running-steer-failed':
|
|
1234
1260
|
// 🔴 明确拒收 vs 送达未知,两句话不能互换(见 outcome 注):对一条**可能已经注入**的非幂等
|
|
@@ -246,6 +246,14 @@ export interface WiringManifestAutoConsolidationView {
|
|
|
246
246
|
/** 恒 `true`(构造期门拒掉了「武装但跑不起来」);在场即武装。 */
|
|
247
247
|
onRecommendation: true;
|
|
248
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* core 7.22.0 #889 C-R60(0.72.7 CC-42):`wiring_manifest.readDeny` 第九段 —— 这条腿**内置敏感文件读 deny 表**的实质激活档位
|
|
251
|
+
* (`READ_DENY_BUILTIN_TIERS` 顺序;每行都被排除掉的档位不列名)。挨着 `writeProtection`,按 operator / governance 投影;进 `configFingerprint`。
|
|
252
|
+
*/
|
|
253
|
+
export interface WiringManifestReadDenyView {
|
|
254
|
+
/** 非空;档位词**开集**透传(闭集 `ReadDenyBuiltinTier` 五员归 core,本包不手抄 —— 上游加档位不判畸形)。 */
|
|
255
|
+
builtinTiers: readonly string[];
|
|
256
|
+
}
|
|
249
257
|
/**
|
|
250
258
|
* CC-08(0.71.0):`wiring_manifest.hooks[]` 一行(sdk 9.6.0 `WiringManifestHookEntry`)—— 这条腿挂了哪些 hook 族、
|
|
251
259
|
* 由 spec 还是 deps 拥有、是否只是观察性的。开集透传 `family` / `owner`;`observational` never-false。
|
|
@@ -1222,7 +1222,8 @@ function wiringManifestSupersetBody(ev) {
|
|
|
1222
1222
|
const lsp = projectLspSection(ev.lsp);
|
|
1223
1223
|
const writeProtection = projectWriteProtectionSection(ev.writeProtection);
|
|
1224
1224
|
const autoConsolidation = projectAutoConsolidationSection(ev.autoConsolidation);
|
|
1225
|
-
|
|
1225
|
+
const readDeny = projectReadDenySection(ev.readDeny);
|
|
1226
|
+
if (modelGate === undefined && autoMode === undefined && mcp === undefined && tools === undefined && hooks === undefined && lsp === undefined && writeProtection === undefined && autoConsolidation === undefined && readDeny === undefined)
|
|
1226
1227
|
return undefined;
|
|
1227
1228
|
return {
|
|
1228
1229
|
...(modelGate !== undefined ? { _sema_modelGate: modelGate } : {}),
|
|
@@ -1233,6 +1234,7 @@ function wiringManifestSupersetBody(ev) {
|
|
|
1233
1234
|
...(lsp !== undefined ? { _sema_lsp: lsp } : {}),
|
|
1234
1235
|
...(writeProtection !== undefined ? { _sema_writeProtection: writeProtection } : {}),
|
|
1235
1236
|
...(autoConsolidation !== undefined ? { _sema_autoConsolidation: autoConsolidation } : {}),
|
|
1237
|
+
...(readDeny !== undefined ? { _sema_readDeny: readDeny } : {}),
|
|
1236
1238
|
};
|
|
1237
1239
|
}
|
|
1238
1240
|
/** 🔴 缺席 = 没编译出判官(第三态),**不折 `spelling-only`**;`targetView` 不在二词 / 非对象 ⇒ 段缺席;多余成员不过境。 */
|
|
@@ -1253,6 +1255,19 @@ function projectAutoConsolidationSection(raw) {
|
|
|
1253
1255
|
return undefined;
|
|
1254
1256
|
return { onRecommendation: true };
|
|
1255
1257
|
}
|
|
1258
|
+
/** 🔴 缺席 = **没有内置行判这条腿**(出厂 OFF 的未配置部署 / 老 server <7.22.0 承载版)—— **不是**「没有读被 deny 判」:部署与任务级
|
|
1259
|
+
* `readDenyPatterns` 是另一套来源,刻意不上报。空数组铸点**永不发出**(「关」与「开到什么都不判」是一件事)⇒ 判畸形段缺席;
|
|
1260
|
+
* 成员非非空串 / 非对象 ⇒ 段缺席(其余段照投);多余成员不过境;数组是新拷贝。 */
|
|
1261
|
+
function projectReadDenySection(raw) {
|
|
1262
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw))
|
|
1263
|
+
return undefined;
|
|
1264
|
+
const tiers = raw.builtinTiers;
|
|
1265
|
+
if (!Array.isArray(tiers) || tiers.length === 0)
|
|
1266
|
+
return undefined;
|
|
1267
|
+
if (!tiers.every((t) => typeof t === 'string' && t.length > 0))
|
|
1268
|
+
return undefined;
|
|
1269
|
+
return { builtinTiers: [...tiers] };
|
|
1270
|
+
}
|
|
1256
1271
|
function projectHooksSection(raw) {
|
|
1257
1272
|
if (!Array.isArray(raw))
|
|
1258
1273
|
return undefined;
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
/** 一条通告是**说给谁听**的。两值,刻意不设第三值(见模块顶注)。 */
|
|
55
55
|
export type NoticeAudience = 'user' | 'operator';
|
|
56
56
|
/**
|
|
57
|
-
* 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.20.1
|
|
57
|
+
* 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.22.0 = 六十六码**(7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
|
|
58
58
|
* 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
|
|
59
59
|
* ⚠️ `EngineNotice.code` 的型面在上游**故意留 `string`**(宿主把自己的通告转发进同一个水槽是
|
|
60
60
|
* 被支持的形),所以本表是**判据**不是型 —— 别拿它去窄化那个字段。
|
|
@@ -226,3 +226,19 @@ export interface SkillsListingTruncatedFactsView {
|
|
|
226
226
|
* 🔴 `kept` 照带不重算:引擎已在铸点算过;本包再算一遍 = 第二份公式,上游改口那天两边各走各的。
|
|
227
227
|
*/
|
|
228
228
|
export declare function readSkillsListingTruncated(notice: unknown): SkillsListingTruncatedFactsView | undefined;
|
|
229
|
+
/** `McpReconnectResult.outcome` 三词(core `src/core/mcp.ts` 逐字);无处置表 —— 成员资格就是全部意义。 */
|
|
230
|
+
export declare const MCP_REDIAL_OUTCOMES: readonly string[];
|
|
231
|
+
/** {@link readMcpServerRedialed} 的读数(core `engine-notice.d.ts` 的 `detail` 逐字同形)。 */
|
|
232
|
+
export interface McpServerRedialedFactsView {
|
|
233
|
+
server: string;
|
|
234
|
+
outcome: string;
|
|
235
|
+
/** 重拨相对于此前挂载**多**了几个命名空间化工具(计数)。 */
|
|
236
|
+
added: number;
|
|
237
|
+
/** 同上,**少**了几个。失败重拨 ⇒ 该 server 的工具全部撤走,这一格就是撤走的数目。 */
|
|
238
|
+
removed: number;
|
|
239
|
+
/** 非 `reconnected` 时的因由(已中性化、封长);渲染用,不分支。 */
|
|
240
|
+
reason?: string;
|
|
241
|
+
sessionId: string;
|
|
242
|
+
runId: string;
|
|
243
|
+
}
|
|
244
|
+
export declare function readMcpServerRedialed(notice: unknown): McpServerRedialedFactsView | undefined;
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
* 出现在本包源码或产物里 => 当场红。
|
|
53
53
|
*/
|
|
54
54
|
/**
|
|
55
|
-
* 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.20.1
|
|
55
|
+
* 引擎**成文码册**的逐字镜像(core `ENGINE_NOTICE_CODES`,**7.22.0 = 六十六码**(7.20.1 六十五 + 7.22.0 一枚 `mcp.server_redialed`(#857,operator;governance-codes.js 元组紧跟 `mcp.revocation_probe_failed`);7.20.0 六十四 + 7.20.1 一枚 `config.write_protection_target_view_absent`;7.19.0 五十九 + 7.20.0 五枚:`config.task_root_not_canonical` / `config.execution_env_capability_invalid` / `config.forward_sink_failed` / `memory.restore_withheld` / `agents.listing_truncated`,均 operator);顺序同源)。
|
|
56
56
|
* 🔴 这是一份**抄件**,不是本包的意见 —— 改它必须同 commit 附 core 坐标,且门会先红。
|
|
57
57
|
* ⚠️ `EngineNotice.code` 的型面在上游**故意留 `string`**(宿主把自己的通告转发进同一个水槽是
|
|
58
58
|
* 被支持的形),所以本表是**判据**不是型 —— 别拿它去窄化那个字段。
|
|
@@ -103,6 +103,8 @@ export const ENGINE_NOTICE_CODES = Object.freeze([
|
|
|
103
103
|
'delegation.ask_unresolvable',
|
|
104
104
|
'mcp.injection_dropped',
|
|
105
105
|
'mcp.revocation_probe_failed',
|
|
106
|
+
// core 7.22.0 #857(0.72.7 提货批 CC-42):宿主请这条 run 重拨一台 MCP server 的结果;一个码管两个方向。
|
|
107
|
+
'mcp.server_redialed',
|
|
106
108
|
'workflow.governance_key_stripped',
|
|
107
109
|
'workflow.agent_option_ignored',
|
|
108
110
|
'memory.session_polluted',
|
|
@@ -190,6 +192,7 @@ export const ENGINE_NOTICE_AUDIENCE = Object.freeze({
|
|
|
190
192
|
'delegation.ask_unresolvable': 'user',
|
|
191
193
|
'mcp.injection_dropped': 'user',
|
|
192
194
|
'mcp.revocation_probe_failed': 'operator',
|
|
195
|
+
'mcp.server_redialed': 'operator',
|
|
193
196
|
'workflow.governance_key_stripped': 'operator',
|
|
194
197
|
'workflow.agent_option_ignored': 'operator',
|
|
195
198
|
'memory.session_polluted': 'user',
|
|
@@ -435,3 +438,36 @@ export function readSkillsListingTruncated(notice) {
|
|
|
435
438
|
...(sessionId !== undefined ? { sessionId } : {}),
|
|
436
439
|
};
|
|
437
440
|
}
|
|
441
|
+
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
442
|
+
// 0.72.7 提货批(core 7.22.0 #857)—— `mcp.server_redialed` 的**事实窄读器**
|
|
443
|
+
// ══════════════════════════════════════════════════════════════════════════════════════════════
|
|
444
|
+
// 宿主请这条 run **重拨**一台 MCP server(run 句柄动词 `reconnectMcpServer`;server 侧的会话腿动词候 S-381),
|
|
445
|
+
// 结果一条 operator 通告。**一个码管两个方向**:`outcome` 是数据不是两种事件;去重单位 = **每次尝试**,永不按 run
|
|
446
|
+
// 折叠(折掉第二条会藏起「它还是没起来」那条)。`added` / `removed` 是**计数**,不是 server 自报的工具名(工具名是
|
|
447
|
+
// server 自著文本,operator 行不是披露通道)。规矩同 {@link readMcpInjectionDrop}:只认自己那一个码;必填格缺一 ⇒
|
|
448
|
+
// 整只缺席;分支键 `outcome` 按闭集读;`reason` 开集透传(非 reconnected 时才有,且**永不是唯一机读事实**)。
|
|
449
|
+
/** `McpReconnectResult.outcome` 三词(core `src/core/mcp.ts` 逐字);无处置表 —— 成员资格就是全部意义。 */
|
|
450
|
+
export const MCP_REDIAL_OUTCOMES = Object.freeze(['reconnected', 'refused', 'not_declared']);
|
|
451
|
+
export function readMcpServerRedialed(notice) {
|
|
452
|
+
if (typeof notice !== 'object' || notice === null || Array.isArray(notice))
|
|
453
|
+
return undefined;
|
|
454
|
+
const n = notice;
|
|
455
|
+
if (n.code !== 'mcp.server_redialed')
|
|
456
|
+
return undefined;
|
|
457
|
+
const d = n.detail;
|
|
458
|
+
if (typeof d !== 'object' || d === null || Array.isArray(d))
|
|
459
|
+
return undefined;
|
|
460
|
+
const o = d;
|
|
461
|
+
const str = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
|
|
462
|
+
const count = (v) => (typeof v === 'number' && Number.isInteger(v) && v >= 0 ? v : undefined);
|
|
463
|
+
const server = str(o.server);
|
|
464
|
+
const outcome = typeof o.outcome === 'string' && MCP_REDIAL_OUTCOMES.includes(o.outcome) ? o.outcome : undefined;
|
|
465
|
+
const added = count(o.added);
|
|
466
|
+
const removed = count(o.removed);
|
|
467
|
+
const sessionId = str(o.sessionId);
|
|
468
|
+
const runId = str(o.runId);
|
|
469
|
+
if (server === undefined || outcome === undefined || added === undefined || removed === undefined || sessionId === undefined || runId === undefined)
|
|
470
|
+
return undefined;
|
|
471
|
+
const reason = str(o.reason);
|
|
472
|
+
return { server, outcome, added, removed, ...(reason !== undefined ? { reason } : {}), sessionId, runId };
|
|
473
|
+
}
|
package/dist/seam.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { ModelUsage, SDKMessage } from '@sema-agent/agent-types';
|
|
10
10
|
import type { EngineTurnUsage } from './adapter/downstream/turnUsageToModelUsage.js';
|
|
11
11
|
import type { RunCostReconcile } from './adapter/downstream/terminalToSdkResult.js';
|
|
12
|
-
import type { WiringManifestAutoMode, WiringManifestModelGate, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, ContextUsageSectionView } from './adapter/downstream/eventToSdkMessage.js';
|
|
12
|
+
import type { WiringManifestAutoMode, WiringManifestModelGate, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, ContextUsageSectionView } from './adapter/downstream/eventToSdkMessage.js';
|
|
13
13
|
import type { ToolRosterView, ToolRosterDeltaView } from './toolRoster.js';
|
|
14
14
|
/**
|
|
15
15
|
* `AbortSignal` 的结构型(B3 扩容,SEAM-GAP-4)。
|
|
@@ -597,6 +597,8 @@ export interface WiringManifestChromeEvent {
|
|
|
597
597
|
writeProtection?: WiringManifestWriteProtectionView;
|
|
598
598
|
/** core 7.21.0 / server 7.82.0(0.72.4 CC-35):第八段 —— 记忆自动整理武装(present-iff 武装 ∧ operator 面;🔴 缺席 = indeterminate,不折 false)。 */
|
|
599
599
|
autoConsolidation?: WiringManifestAutoConsolidationView;
|
|
600
|
+
/** core 7.22.0 #889(0.72.7 CC-42):第九段 —— 内置读 deny 表的实质激活档位(present-iff 有内置行判;🔴 缺席 = 没有这条腿,不是「没有读被 deny 判」)。 */
|
|
601
|
+
readDeny?: WiringManifestReadDenyView;
|
|
600
602
|
/** core 铸的事件身份(uuidv7 形);wire 未必带 ⇒ 缺席时本键不在场。 */
|
|
601
603
|
eventId?: string;
|
|
602
604
|
}
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **0.72.
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **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.6.0**(value-level,非 type-only;**0.71.0 抬版**:`tool_disclosure` / `tool_progress` 两帧型与 `ToolApprovalFrame.readRootCandidate` 自 9.6.0 起;0.69.0 曾抬到 >=9.4.0(`reasoning_end` / `lastLegMcp`),0.60.0 抬到 >=8.4.0;地板由 `scripts/run-sdk-floor-test.mjs` 的 `FLOOR` 与 public-surface 门 C-CC-3「不低于见证到的最低实装版」双钉)| `package.json` `peerDependencies` |
|
|
24
24
|
| peer:会话词汇表 | `@sema-agent/agent-types` **>=0.3.0**(type-only,零运行时;0.71.0 抬版:devDep 与 peer 同步,type-superset 门 ④ 撞名预警对着 0.3.0 的 .d.ts 求值) | 同上 |
|
|
25
25
|
| runtime dep | `diff` ^9.0.0(**唯一**一条;portability 门按**等值**钉死) | `package.json` `dependencies` |
|
|
26
|
-
| 公开导出面 | **
|
|
26
|
+
| 公开导出面 | **971** 个运行期符号(+ 45 个测试钩;= 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
|
|
|
@@ -121,7 +121,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
121
121
|
|
|
122
122
|
## §2 公共导出面地图(按域)
|
|
123
123
|
|
|
124
|
-
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**
|
|
124
|
+
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**971** 项)。
|
|
125
125
|
> 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
|
|
126
126
|
> **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
|
|
127
127
|
> 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
|
|
@@ -145,12 +145,12 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
145
145
|
`WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
|
|
146
146
|
**4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
971 项的内部构成(帮助端估读表大小;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):**282** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
|
|
149
149
|
(矩阵、键集、env 名、锚串)而非可调用物;**6** 项是 PascalCase 运行期值
|
|
150
150
|
(`ControlRouter` / `ControlSafetyError` / `HitlBridge` / `HitlSafetyError` / `DecideTransportRetryExhaustedError`);
|
|
151
151
|
**37** 项是 `*For(sessionKey, …)` 的 per-session 变体(0.72.0 −4:`clearArmedGateFor` / `onGateArmedFor` / `registerArmedGateFromQuestionIdFor` / `notePlanReviewAnsweredIfDecisiveFor` 退出公面)(§6;其中 `engineNamespaceKeyFor` 是命名巧合 —— 参数是 baseUrl 不是 sessionKey,见域 14)。
|
|
152
152
|
|
|
153
|
-
### 2b. 域图(16 域,逐域计数之和 =
|
|
153
|
+
### 2b. 域图(16 域,逐域计数之和 = 971)
|
|
154
154
|
|
|
155
155
|
| # | 域 | 名数 | 承重导出 | 用途 | 实现锚 |
|
|
156
156
|
|---|---|---|---|---|---|
|
|
@@ -168,8 +168,8 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
168
168
|
| 12 | **workflow 与后台工作视图** | 21 | `projectWorkflowRun` · `readWorkflowResumeAdmissionIncomplete`(0.68.3 CC-05:core 7.18.0 `resumeAdmissionIncomplete` 在场 = 不是 resume 基,与 `readWorkflowParks` 同一条投影义务)· `createLiveWorkflowSource` · `ensureWorkflowActivityLedger` · `readWorkflowActivityLedger` · `stopWorkflowActivityLedger` · `resetWorkflowActivityLedgers` · `createBackgroundView` · `projectBackgroundView` · `recordWorkflowAgentTaskId` · `agentDisplayStatus` | 活过一个 turn 的长任务读面:workflow run + 跨 session 后台任务归一表(`assistant.tasks` 与 fleet SSE **两源独立降级**) | `src/workflow.ts`、`src/workflowClient.ts`、`src/workflowMonitor.ts`、`src/agentSession/backgroundView.ts`(+ 纯类型 `src/agentSession/contract.ts`) |
|
|
169
169
|
| 13 | **座位 IPC 契约** | 34 | `LOCAL_SESSIONS_SPEC` · `SEAT_METHOD_NAMES` · `SEAT_EVENT_TYPES` · `isLocalSessionEvent` · `isToolPermissionRequest` · `toolPermissionRequestId` · `SEAT_VALIDATOR_KEY_COVERAGE` · `SEAT_SEND_MESSAGE_KEY_ORIGINS`(0.62.0:座位载荷**逐键出身**登记 —— 每个位要么写明转投哪个引擎请求位、要么写明为什么不上 wire;常驻门对**装在盘上的** sdk 型面逐名核,详见 §26③)| desktop↔web 座位 IPC 契约的**单一真源**(此前两边各一份、名字零重合 ⇒ 编译器永远不会告诉你它们漂了)。🔴 加 verb 忘了加 `LOCAL_SESSIONS_SPEC` **不报错**:preload 不注册 channel、渲染端读到 `undefined` | `src/seatContract.ts`(**零 import**,纯类型 + 常量 + 纯谓词)。🔴 **证据等级标注(0.42.0,test [5087] 的「语料**种类**缺口」/ cli [5088] 认领件)**:该文件里所有以「CC 如何如何」为形的断言(`212 methods` / `854-channel census` / 方法名逐字保留 / `fQe` 逐字段对照 / 一切 `.vite/build/index.chunk-*.js` 坐标)**证据等级 = 桌面 unpack,本地语料库不可复验** —— 本仓手边可复验的参照语料**只覆盖终端 CLI 形态**的静态产物,拿它去 grep 桌面壳里的符号只会零命中,而零命中在这里**既不证真也不证伪**。复核这些断言**不得**拿本仓语料当反证 |
|
|
170
170
|
| 14 | **宿主端口与会话槽** | 41 | `installHost` · `installHostFor` · `installCoreValuePorts` + 十读口 + 三存在性口(0.69.0 CC-07:core 值级面端口注入,Node 宿主装配根装、浏览器 lane 恒缺席)· `hostPortMisses(For)` · `DEFAULT_SESSION_KEY` · `hostEnv` · `unrefTimer` · `parseLocaleTag` / `pickUiLanguage`(#244 F4 族D A-028.20:locale tag 手术单源 + UI 语言判定;与 `resolveRegionHint` 双出口成文 —— 语言偏好域 en/zh ≠ 地址可达域 cn/intl/unknown,`zh-Hant` 前者 zh 后者 intl 是设计)· `engineNamespaceKeyFor` / `mergeSessionMapRecord` / `mergeEngineEntry`(A-028.12:会话 id 映射单一键形 + merge 判定;存储经 `SessionMapStorePort` 归端 —— cli 文件锁/原子写,web localStorage)| 进程/端级装配层(settings/fs/queue/timers/session/log/probe),与 per-turn 的 `AdapterContext` **分层**。头注的判定规则:**这个能力每 turn 都会变吗?** 会 ⇒ `ctx`;不会 ⇒ `installHost` | `src/host.ts`、`src/hostEnv.ts`、`src/sessionSlot.ts`、`src/unrefTimer.ts`、`src/env/{localeGeo,localeTag,uiLanguage}.ts`、`src/sessionMap.ts` |
|
|
171
|
-
| 15 | **控制面与传输** |
|
|
172
|
-
| 16 | **引擎词汇表与包自检** |
|
|
171
|
+
| 15 | **控制面与传输** | 131 | `steerFollowIntent`(0.72.6 CC-40:steer 后续听意图三态 tail / after-decision / after-wake,按 `SteerReceipt.delivery` 判;§53)· `projectWebSearchBackendCapability` / `observedWebSearchBackend` / `noteEngineCapsForWebSearchBackend` / `forgetWebSearchBackendReading` / `webSearchBackendDoctorDetail` + `WEB_SEARCH_BACKEND_NONE`(0.72.5 CC-31:`capabilities.webSearch.backend` 四态读面 —— 键缺席 = 老引擎判不了 ≠ `none` = 引擎明说没有默认后端;与 `sqlEngineCapability` / `writeProtectionCapability` 同构;§52)· `resumeContextUnavailableFromError` / `resumeContextUnavailableContent`(0.72.1 CC-33:409 `conflict.resume_context_unavailable` 读数 `{ code, staleAfterSec?, runId? }` + 三句人话;§48)· `mcpEngineLegPresence`(0.71.0 CC-19:引擎侧 MCP 在场三值,只从面板视图求;§42)· `ControlRouter`(+ `ControlSafetyError`)· `fetchMcpPanel`(0.69.0:经 sdk `sessions.mcp` 取体 + 投视图,不裸 fetch)· `projectMcpPanel` + `mcpPanelLastLegDetail`(0.68.2 CC-03:`GET /v1/sessions/:id/mcp` 面板体防御读视图 + `lastLegMcp` 一行措辞铸点;缺席 = 键不铸、读不懂 = `lastLegMcpUnreadable`、禁与 `servers[]` 对账)· `makeEngineWireClient` + `resolveWireAuth` · `installEngineWireTarget` · `diagnoseSseIdleTear` / `isSseIdleError` · `attemptActiveRunSelfHeal` + `activeRunBusySignal` + `activeRunSelfHealRow` / `activeRunBusyHeadlessRow` · `kickEngineCapsProbe` / `engineCapTrue` / `invalidateEngineCaps(baseUrl, probe?)`(#307 S25:引擎温切后的 caps 生产失效口 —— kick 自带幂等闸,同 baseUrl 重启后不显式失效就永远读到旧引擎那一版能力位;调用方 = 壳的 respawn/restartEngine。🔴 **推荐两参形**:第二参给替代探测则「推进代际 + 注册新探测」在同一同步块内完成,失效与下一次 kick 之间那个「等待者读到未判」的窗按构造不存在;单参形保留给「只丢缓存、这一刻没有替代探测」的调用方,那种情形下读到未判是诚实结局) · `engineCapValue`(S-131,0.59.0:能力位的**四态**通用读口 `unobserved`/`not_reported`/`null`/`value` —— 既有三口把四种「读不出」全折成 fail-closed 一档,对**放行**问题是对的、对**读面/诊断**问题是错的:`null`(引擎明确说没有,正面事实)会与「老引擎不报」「还没探到」在屏上同形。`value` 位刻意不做形校验,形归各能力位自己的窄读器,详见 §23b)· `projectSqlEngineCapability` / `observedSqlEngine` / `noteEngineCapsForSqlEngine` / `forgetSqlEngineReading` / `sqlEngineDoctorDetail`(S-131,0.59.0:`Capabilities.sql`(server ≥7.60.0)的四态读面**从壳侧上收** —— 归层债,0.58.0 时它长在壳里正是因为包侧没有嵌套对象读口。🔴 **导出名与壳侧那份逐字同名 = drift-lock**;`txnMode: null` 是铸点域内的合法值不是畸形;换代失效口清成未观测而不是留旧值,详见 §23b)· `mapBrainStatusToRetry` · `waitForClaimRelease` + `CLAIM_RELEASED_STATES` / `CLAIM_HELD_STATES` · `atMostOnceFailureClass` / `readSteerDelivery` · `clearRunningChoiceOffer`(Inkglow-1085 P0b①:「Do nothing」登记的清口 —— 端的「重新打开操作菜单」入口;登记在场时 attemptActiveRunSelfHeal 不整卡重弹,not-parked 结局带 `alreadyOffered: true` 判别位,端据此降级渲一行)· `INTERACTIVE_WAY_OUT`(默认出路串单源)· `engineSessionParamFor`(design/285 批 0:`?session=` 派生的 **per-key** 形 —— `hostSessionFor(sessionKey)?.currentSessionId()` + [1501] 空串归一;零参 `engineSessionParam()` = 默认槽兼容层,取值链逐字等价)· `normalizeWirePrincipal`(A-028.10:principal 在场性 trim 原语 —— 全空白=缺席不发头,engineWireTarget 两臂/makeEngineWireClient/壳 livePrincipal 同尺)· `readSessionMemoryStatus` / `classifyMemoryStatusFailure` / `readCaptureOptOut` / `readLastCapture`(S-53 会话记忆姿态读面,0.48.0:失败分诊**码优先**——两个 404 分道 `not_found.session` / `not_found.route`,无码 404 不猜落 failed;五键逐键缺席语义两个合读器,`lastCapture` 三态的判别材料是 `committedCount` 不是本键;IO 归宿主注入 `MemoryStatusClientLike`,详见 §11) · `classifyTurnWireError` / `isWireTransportError` / `isPreStreamDrainingReject` / `isResumeAtRejection` / `drainingRetryDelayMs` / `scenarioDenyFromError` + `WIRE_NETWORK_ERROR_PATTERN`(A-028.11/.13:turn 错误分型判定半场,人话文案与渲染归端)· `resumeRetryLaterFromError`(L-102,0.57.0:resume 族**时间性拒绝**二码的判型半场 —— 这一族里唯一**带得出「等多久」**(`retryAfterSec`)的两个码。🔴 闭集**不是**「哪些码可以等」的名单:同族 `resume.row_recycling` 同样可等(窗口自清)只是没有秒数 ⇒ 本读口返回 `null` 只意味着没命中这两码,详见 §21) · `projectWriteProtectionCapability` / `observedWriteProtection` / `noteEngineCapsForWriteProtection` / `forgetWriteProtectionReading` / `writeProtectionDoctorDetail` / `projectWriteProtectionPosture` / `writeProtectionPostureDetail`(S-138,0.60.0:`Capabilities.writeProtection` (engine ≥7.63.0)的**四态**读面 + operator 面行表 —— 与上面 S-131 那一格**同构同纪律**。🔴 三位刻意不合成一个布尔;`not_reported` **不是**「这台部署没有写保护表」(座位缺席恰是缺省表在岗);逐行 name/kind 走**最小披露**只上 operator 面,详见 §24e)· `projectReadFacePosture` / `readFacePostureDetail` / `readFaceDisagreement`(S-167,0.61.0:operator 面 `diagnostics.wiring.readFace`(engine ≥7.65.0)的窄读器 —— 与上面S-138 那一格**同构同纪律**。🔴 三句「答不出来」逐字互异且没有一句等于「没有 READ 档」;`source` 按开集读;与租户面 `capabilities.readFace` 刻意不合流,只带一个纯比较函数,详见 §25)| 上行通道的**监管**半场(submit / steer / kill / 队列命令定序)+ 传输构造、caps 探测、SSE 断流分诊、**409 active-run 自愈** | `src/controlRouter.ts`、`steering.ts`、`sseIdleTriage.ts`、`retryStatus.ts`、`diagnostics.ts`、`engineWireSdk.ts`、`engineWireTarget.ts`、`src/principalWire.ts`、`src/wireErrorTriage.ts`、`engineSessionParam.ts`、`engineCapsCache.ts`、`liveInitToolFace.ts`、`adapter/activeRunSelfHeal.ts`、`src/sessionMemoryStatus.ts`、`src/writeProtectionCapability.ts`、`src/webSearchBackendCapability.ts`、`src/readFacePosture.ts` |
|
|
172
|
+
| 16 | **引擎词汇表与包自检** | 93 | `MCP_REDIAL_OUTCOMES` / `readMcpServerRedialed`(0.72.7 CC-42:通告 `mcp.server_redialed` 事实读器,outcome 三词闭集、added/removed 计数;§54)· `RESUME_CONTEXT_UNAVAILABLE`(0.72.1 CC-33;不进两个 resume 闭集:不可等、也不是换参数)· `RESUME_REOPEN_CODES` / `RESUME_ENV_FAILED` / `RESUME_TOOL_UNAVAILABLE` / `RESUME_TOOL_CONTRACT_MISMATCH` · `resumeReopenFromError` / `resumeReopenContent`(0.71.3 CC-06:resume reopen 族三码闭集 + 读口 + 三句,§45)· `readSkillsListingTruncated`(0.70.0 CC-04:`skills.listing_truncated` 事实读器,§39)· `CONFIG_REFUSAL_CODES` / `isConfigRefusalCode` · `DECIDE_WORKFLOW_LANE_CODES`(+ 三个具名码;`/decide` workflow 车道,三条出路刻意不合并,详见 §30h)· `STOP_CONFLICT_CODES` · `isInterruptedToolEndCode` · `isRewindFamilyCode` · `CLIENT_VERBS` · `compensationSplitViolations` · `DELEGATION_CAP_CODES` / `isDelegationCapCode` / `DELEGATION_CONCURRENCY_CAP` / `DELEGATION_SESSION_CAP`(0.38.0 #318 件④:core 5.48.0 design/323 委派席位到限**两码,处置不对称禁合并** —— 并发帽=**可等**(兄弟结束即有位)/ 会话累计帽=**等也没用**(这条会话的配额用尽))· `CONFIG_DELEGATION_ENTRY_CAPS`(同批入 `CONFIG_REFUSAL_CODES` 识别表)· `delegationCapDispositionOf` / `MCP_SERVER_REVOKED`(0.39.0 载体到货消费件:core 5.50.0 补 `{ error: code, code }` 孪生拼法后两码真上 `tool_end.errorCode`,0.38.0「先立词不落消费分支」的已知局限自此解除;处置轴 `wait-for-slot` / `reuse-existing-or-await-reap` 机器可读(累计帽=retained-window 帐,行回收配额即回,处置=SendMessage 复用,**非**「换会话/永久耗尽」——0.38.0 段该句系勘误),未知 `delegation.*` 码 ⇒ `undefined`;`mcp.server_revoked` = 操作员 mid-session 吊销 server 后的工具面本地闸(被吊销的 server **名**今天不过 wire 境:detail.server 是进程内位,抬升腿只 lift code——归因渲染候 core 补 typed detail,已点名);载体门 = engine-vocab G3 腿锚 core dist 铸点)· `CAPABILITY_SELF_ORCHESTRATION_REQUIRED`(S-81,server 7.57.0:提交面的 selfOrchestration 准入拒绝码。🔴 **复用码** —— 与其它 `capability.*` 501 同体形而处置不同,消费点必须按**恰等**判、绝不放宽成前缀判;判型与「去键重发一次」归 `src/selfOrchestrationDenial.ts`,详见 §13) · `GATE_PARKED_ERROR_CODE`(0.60.0:「门把这次调用 park 了」的机读码单源 —— `frameRouter` 的连坐/中断判据与 `gateOutcome.isGateParkedToolEnd` 读同一个常量;真机黑盒直证 park 短路帧上**没有 `gate`**,这个码是那一形唯一的信号,详见 §24c)| 三端分臂共用的**去字面化** `errorCode` 词表(病根正是三端各抄一份字面);编译期 verb 闭合门;搬迁补偿登记表 | `src/engineErrorCodes.ts`(计数以 `scripts/public-export-baseline.json` 为准,别手抄;A-028.11/.13 补 `DRAINING_ERROR_CODE`/`SCENARIO_NOT_ALLOWED_ERROR_CODE`/`RESUME_AT_ERROR_CODE_PREFIX`;#318 件④ 补 `delegation.*` 族四位 + `config.delegation_entry_caps`;0.39.0 补三新码消费件三位);S-81 补 `capability.self_orchestration_required` 一位;L-102 补 `resume.*` 时间性拒绝二码 + 闭集 `RESUME_RETRY_LATER_CODES` 三位)、`src/classifierVerdictWire.ts`、`src/compensations.ts`、`src/clientSlice.ts`;**0.67.0 补锚**(这三件的导出一直计在本域,而本表此前没有它们的锚行 —— 如实补上,不是搬家):`src/gateVocabulary.ts`(`GATE_DENIED_BY_WORDS`/`gateDeniedByDetail`/`ASK_ORIGIN_WORDS`/`askOriginDetail` + 🆕 `RULE_STORE_UNREADABLE_KINDS`/`isRuleStoreUnreadableKind`/`ruleStoreUnreadableDetail`,详见 §32d)、`src/autoModeUnavailable.ts`(`AUTO_MODE_UNAVAILABLE_CAUSES` + 🆕 `CLASSIFIER_DENY_CAUSES`/`isClassifierDenyCause`/`classifierDenyCauseOf`/`classifierDenyCauseDetail`;🔴 同批**删**`classifierUnavailableOf`/`classifierUnavailableDetail`,详见 §32b)、`src/classifierStatus.ts`(`CLASSIFIER_STATUS_STATES`/`classifierStatusOf`/`classifierStatusDetail`)|
|
|
173
173
|
|
|
174
174
|
🔴 **`engineErrorCodes` 的开集纪律**(该文件头注逐字):这些 `ReadonlySet` / 前缀谓词一律是**识别表**,
|
|
175
175
|
回答的是「我认不认得这个码」,**绝不是**「合法码只有这些」。消费点 `switch` **必须留 `default`**,
|
|
@@ -4631,7 +4631,7 @@ an argument」。audience 答另一问:这条事实**说给谁听**。
|
|
|
4631
4631
|
**签名**
|
|
4632
4632
|
|
|
4633
4633
|
```ts
|
|
4634
|
-
ENGINE_NOTICE_CODES: readonly string[] //
|
|
4634
|
+
ENGINE_NOTICE_CODES: readonly string[] // 66 码,顺序同源(core 7.22.0 +1 mcp.server_redialed;0.72.7)
|
|
4635
4635
|
ENGINE_NOTICE_AUDIENCE: Readonly<Record<string, 'user' | 'operator'>>
|
|
4636
4636
|
noticeAudienceOf(code: unknown): 'user' | 'operator'
|
|
4637
4637
|
engineNoticeInCatalog(code: unknown): boolean
|
|
@@ -8433,3 +8433,63 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
8433
8433
|
3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;server <7.82.1 上本格恒 `not_reported`。
|
|
8434
8434
|
|
|
8435
8435
|
**包侧缺口:** ① CC-39②③(memory-status `consolidation?` 切片判定 / `REQUEST_FIELD_MATRIX` memory 行;候 server 片1b);② CC-30 MCP 会话内重连消费口(候 core #857 + server S-381);③ CC-34 `permission_denials` 自动升级验证(候 server S-394);④ CC-36 托管 MCP 活性三态读口(候 core #874 + server 转发半场);⑤ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑥ `Capabilities.webSearch` 经 sdk 声明(候 sdk 出键;本包按结构读已就位);⑦ `agents.listing_truncated` detail 读器候消费场景(by-design);⑧ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑨ §NNz「declined 键真零命中」机读第二刀(候形式化)。
|
|
8436
|
+
|
|
8437
|
+
## §53 🆕 0.72.6 steer 之后谁续听那条 run(CC-40:`steerFollowIntent` 三态 + `activeRunSelfHealRow` 续听声明;patch)
|
|
8438
|
+
|
|
8439
|
+
> **patch**:型面纯 additive(+1 函数,`activeRunSelfHealRow` 第五个可选参;公面 968 → 969;零 wire 键;peer 不动)。cli L-379(P1)包侧半场;根因 = server 7.81.0 S-384 副作用([7495] ④′ 勘误:local 车道 bg/resume 腿成活审批目标后,plan_review 决断的续跑腿撞下一道门**活着等卡**不再 park,壳原先「park → 新流取卡」的路径从此不成立)。
|
|
8440
|
+
|
|
8441
|
+
### 53a. 处置表
|
|
8442
|
+
|
|
8443
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
8444
|
+
|---|---|---|---|
|
|
8445
|
+
| S-1 | 注入件 / 用户消息撞活 run ⇒ steer ⇒ `running-steered` 之后,那条 run 的后续(含新弹的决断卡)只在它自己的 `GET /v1/runs/:id/events` 上 | **consumed**:`steerFollowIntent(outcome)` ⇒ `tail` / `after-decision` / `after-wake` / `null`,按 `delivery` 判(applied 与读不出 ⇒ tail;queued ⇒ after-decision;parked_for_wake ⇒ after-wake) | `kind: 'tail'` ⇒ **当拍**用既有续听机对 `taskId` tail 至终局 / park(Last-Event-ID 自持;缺席从 live 起);`after-decision` ⇒ 续听挂在答卡之后的 decide 路径上;`after-wake` ⇒ 不 tail、不 wake(本客户端不 wake),照旧渲 parked_for_wake 那句;`null` ⇒ 零动作 |
|
|
8446
|
+
| S-2 | handed-off 行文案「watch that run」 | **consumed**:`activeRunSelfHealRow(…, follow: { following: true })` 时换成「sema is following that run and will surface whatever it asks for next」;不传逐字节同旧 | **只在真挂上续听那一拍**传 `{ following: true }`(文案与行为同前提);`rowFor` 覆盖仍优先 |
|
|
8447
|
+
| S-3 | `held-for-decision` 档「决断后注入件送出去之后那条 run 谁听」 | **declined(不加位)**:宿主答卡后按原优先级重投,那次提交要么开新 turn(自己的流)要么再撞 409 ⇒ self-heal ⇒ `running-steered` ⇒ S-1 | 零动作:重投那次提交的流就是要听的 |
|
|
8448
|
+
| S-4 | server 7.83.0 [7495] ④ leader 终局 `needs_human` + `result.conflict` 渲染面 | **pending → CC-41(0.72.7)**:结构读视图 + 缺席语义 + 三端一句措辞 | 候 0.72.7;`salvaged[]` 落盘口子由 cli 定形 |
|
|
8449
|
+
|
|
8450
|
+
### 53z. 逐键处置表
|
|
8451
|
+
|
|
8452
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
8453
|
+
|---|---|---|---|
|
|
8454
|
+
| 1 | `SteerReceipt.delivery`(applied / queued / parked_for_wake / 读不出 / 未知词) | **consumed** | `steerFollowIntent`;门 `run-terminal-identity-copy-test.mjs` G3a–G3g(未知词按开集保守 tail,不判畸形) |
|
|
8455
|
+
| 2 | decide 200 体 `taskId` / `status`、409 体 `activeTaskId` / `activeTaskStatus`([7495] ④′ 点名的显式信号) | **consumed(既有)** | 本包 `ActiveRunBusySignal` 已读;本段不加新读口 |
|
|
8456
|
+
| 3 | `fromEventId` 续听起点 | **declined** | 回执不带;壳自持 Last-Event-ID |
|
|
8457
|
+
|
|
8458
|
+
### 53y. 🔴 三端升级必读(固定段式,[C295])
|
|
8459
|
+
|
|
8460
|
+
1. 换钉 `^0.72.6`:提交被折成 steer 后读 `steerFollowIntent(outcome)`,`tail` 当拍续听 `taskId`,`after-decision` 挂 decide 之后,`after-wake` 不动;续听真挂上那一拍再给 `activeRunSelfHealRow` 传 `{ following: true }`。
|
|
8461
|
+
2. 不接线的端零变化:不传第五参 ⇒ 文案逐字节同 0.72.5;`held-for-decision` 无新位。
|
|
8462
|
+
3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;零 wire 键。
|
|
8463
|
+
|
|
8464
|
+
**包侧缺口:** ① CC-41 leader `needs_human` + `result.conflict` 渲染面(0.72.7);② CC-39②③(memory-status `consolidation?` 切片判定 / `REQUEST_FIELD_MATRIX` memory 行;候 server 片1b);③ CC-30 MCP 会话内重连消费口(候 core #857 + server S-381);④ CC-34 `permission_denials` 自动升级验证(候 server S-394);⑤ CC-36 托管 MCP 活性三态读口(候 core #874 + server 转发半场);⑥ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑦ `Capabilities.webSearch` 经 sdk 声明(候 sdk 出键);⑧ `agents.listing_truncated` detail 读器候消费场景(by-design);⑨ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑩ §NNz「declined 键真零命中」机读第二刀(候形式化)。
|
|
8465
|
+
|
|
8466
|
+
## §54 🆕 0.72.7 core 7.22.0 提货(CC-42:通告码 66 `mcp.server_redialed` + `wiring_manifest.readDeny` 第九段;patch)
|
|
8467
|
+
|
|
8468
|
+
> **patch**:型面纯 additive(`_sema_readDeny` 超集键 + 通告闭集 +1 + `readMcpServerRedialed` / `MCP_REDIAL_OUTCOMES` 两导出;公面 969 → 971;peer 不动;devDep core `~7.22.0`)。提货单 [7503] @client-core 三条:① 型面三件 ② 通知码镜像 +1 ③ 新导出四个;本包按 wire 形读,server 承载版(7.84.0 候)到货前老 server 上两段恒缺席、老码不出现。
|
|
8469
|
+
|
|
8470
|
+
### 54a. 处置表
|
|
8471
|
+
|
|
8472
|
+
| # | 面 | 本包做了什么 | 端要做什么 |
|
|
8473
|
+
|---|---|---|---|
|
|
8474
|
+
| S-1 | **`mcp.server_redialed`**(operator;`detail: { server, outcome, added, removed, reason?, sessionId, runId }`;去重 = 每次尝试) | `ENGINE_NOTICE_CODES` 镜像 +1(紧跟 `mcp.revocation_probe_failed`)+ audience operator;事实读器 `readMcpServerRedialed(notice)`(`outcome` 按 `MCP_REDIAL_OUTCOMES` 三词闭集读,词表外整只缺席;`added` / `removed` 非负整数计数;`reason` 开集只渲不分支) | 运维通知面按 operator 渲;**每次尝试一条**不折叠(第二条可能说「它还是没起来」);渲 `outcome` 与两个计数,**不**把计数当工具名;措辞用引擎 `message`(单铸律) |
|
|
8475
|
+
| S-2 | **`wiring_manifest.readDeny?: { builtinTiers }`**(#889;present-iff 有内置行判;进 `configFingerprint`) | 切片第九段 `_sema_readDeny` + chrome `wiring_manifest.readDeny?`;空数组 / 成员非非空串 / 非对象 ⇒ 段缺席其余段照投;档位词开集原序透传;多余成员不过境 | 渲「内置读 deny 档位:credentials, …」当且仅当键在场;🔴 **缺席不渲「未开 / 没有读 deny」**(缺席 = 没有内置行判这条腿;`readDenyPatterns` 另一套来源不上报);要老姿态的部署写 `readDenyBuiltinTiers: ["credentials","browser","wallet","agent-config"]`(运维事,端只渲) |
|
|
8476
|
+
| S-3 | `SafetyAxis.shell?` / `ParentSpecSeat.memoryOff?` / `currentClamps.memoryOff?` | **零动作**:本包不读该三位(ask 门族按 `gateKind` 分臂;resume-clamp 形不镜像) | 零动作;若端自己读 `safetyAxis`,`shell` 与 `irreversible` 互斥、读在场永不读缺席 |
|
|
8477
|
+
| S-4 | 新导出四个 / `ReadDenyBuiltinTier` 首登记 / `AUTO_MODE_UNAVAILABLE_CAUSES` 不变 | **n/a**(零 core 值级 import;三词以字面镜像) | 零动作 |
|
|
8478
|
+
| S-5 | #857 引擎半场到位 ⇒ CC-30 / #897 ⇒ CC-34 | **pending**:CC-30 等 server S-381 会话腿动词(7.84.0 候);CC-34 等 core #897 三铸点 + server 透传 | 候 |
|
|
8479
|
+
|
|
8480
|
+
### 54z. 逐键处置表
|
|
8481
|
+
|
|
8482
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
8483
|
+
|---|---|---|---|
|
|
8484
|
+
| 1 | `mcp.server_redialed` + `detail` 七键 | **consumed(镜像 +1 + 读器)** | `src/engineNoticeCodes.ts` `#ENGINE_NOTICE_CODES` / `#NOTICE_AUDIENCE` / `#readMcpServerRedialed` / `#MCP_REDIAL_OUTCOMES`;码册门 G8b 66 + G10 八格 |
|
|
8485
|
+
| 2 | `wiring_manifest.readDeny.builtinTiers` | **consumed(切片第九段)** | `src/adapter/downstream/eventToSdkMessage.ts` `#projectReadDenySection`;`src/adapt/arms.ts` `#wiringManifestArm`;`docs/type-superset.json` `_sema_readDeny`;wiring 门 M 段 13 格 |
|
|
8486
|
+
| 3 | `SafetyAxis.shell` / `memoryOff` 两 typeKey | **declined** | 本包不读该三位 |
|
|
8487
|
+
| 4 | core 导出 +4 | **n/a** | 端口注入,零 core 值级 import |
|
|
8488
|
+
|
|
8489
|
+
### 54y. 🔴 三端升级必读(固定段式,[C295])
|
|
8490
|
+
|
|
8491
|
+
1. 换钉 `^0.72.7`:operator 通知面加 `mcp.server_redialed`(每次尝试一条;`readMcpServerRedialed` 取 outcome + 两计数);operator 面板从 chrome `wiring_manifest.readDeny` 渲激活档位,缺席不渲「未开」。
|
|
8492
|
+
2. `ENGINE_NOTICE_CODES` 66,码册镜像随包;`SafetyAxis.shell` / `memoryOff` 端零动作。
|
|
8493
|
+
3. peer sdk >=9.6.0 / agent-types >=0.3.0 不动;server <7.84.0 上两段恒缺席。
|
|
8494
|
+
|
|
8495
|
+
**包侧缺口:** ① CC-41 leader `needs_human` + `result.conflict` 渲染面(0.72.8);② CC-30 MCP 会话内重连消费口(core #857 已到;候 server S-381 / 7.84.0);③ CC-34 `permission_denials` 自动升级验证(候 core #897 + server 透传);④ CC-39②③(memory-status `consolidation?` 切片判定 / `REQUEST_FIELD_MATRIX` memory 行;候 server 片1b);⑤ CC-36 托管 MCP 活性三态读口(候 core #874 随 #857 定形 7.22.x);⑥ `staleAfterSec` / `runId` 经 sdk 到端(候 sdk 出键);⑦ `Capabilities.webSearch` 经 sdk 声明(候 sdk 出键);⑧ `agents.listing_truncated` detail 读器候消费场景(by-design);⑨ `ClassifierSeat.defaulted?` 候 sdk 出键(by-design);⑩ §NNz「declined 键真零命中」机读第二刀(候形式化)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.72.
|
|
3
|
+
"version": "0.72.7",
|
|
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",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@sema-agent/agent-types": "^0.3.0",
|
|
38
|
-
"@sema-agent/core": "~7.
|
|
38
|
+
"@sema-agent/core": "~7.22.0",
|
|
39
39
|
"@sema-agent/sdk": "^9.6.0",
|
|
40
40
|
"@sema-agent/settings-schema": "^2.0.0",
|
|
41
41
|
"esbuild": "^0.27.4",
|