@sema-agent/client-core 0.50.0 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +96 -0
- package/README.md +2 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +17 -1
- package/dist/adapter/activeRunSelfHeal.js +45 -7
- package/dist/classifierVerdictWire.d.ts +39 -0
- package/dist/classifierVerdictWire.js +111 -0
- package/dist/hitl/askGateWire.d.ts +3 -2
- package/dist/hitl/askGateWire.js +82 -6
- package/dist/hitl/frameRouter.d.ts +13 -0
- package/dist/hitl/frameRouter.js +32 -3
- package/dist/hitl/gateLedger.d.ts +54 -0
- package/dist/hitl/gateLedger.js +54 -0
- package/dist/hitl/hitlHostSurface.d.ts +29 -2
- package/dist/hitl/parkResolver.d.ts +56 -1
- package/dist/hitl/parkResolver.js +167 -50
- package/dist/hitl/toolApprovalWire.d.ts +3 -0
- package/dist/hitl/toolApprovalWire.js +1 -0
- package/dist/hooksWireCaps.js +66 -2
- package/docs/INTEGRATION-CLIENTS.md +189 -7
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| peer:wire 契约 | `@sema-agent/sdk` **>=7.4.0**(value-level,非 type-only;0.48.0 抬版,四条硬理由见 `CHANGELOG.md` 0.48.0 段末的地板影响面账) | `package.json` `peerDependencies` |
|
|
24
24
|
| peer:会话词汇表 | `@sema-agent/agent-types` **>=0.2.0**(type-only,零运行时) | 同上 |
|
|
25
25
|
| runtime dep | `diff` ^9.0.0(**唯一**一条;portability 门按**等值**钉死) | `package.json` `dependencies` |
|
|
26
|
-
| 公开导出面 | **
|
|
26
|
+
| 公开导出面 | **805** 个运行期符号(+ 41 个测试钩;= 工作树当下的值 —— 已发的 `0.51.0` 是 **803**,再加 L-69⑨ 两件未发 additive 导出;`0.49.0` 是 **795**,再加 S-81 五件未发 additive 导出;`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
|
|
|
@@ -113,7 +113,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
113
113
|
|
|
114
114
|
## §2 公共导出面地图(按域)
|
|
115
115
|
|
|
116
|
-
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**
|
|
116
|
+
> 全集真源 = `scripts/public-export-baseline.json` 的 `names`(**805** 项)。
|
|
117
117
|
> 本节**不逐名抄**,只给「域 → 承重导出 → 用途 → 实现锚」。承重导出 = 一个端为了让这个域干活
|
|
118
118
|
> **必须**直接调到的那几个符号;其余是它们的类型、变体与辅助位。
|
|
119
119
|
> 单一入口:`import { … } from '@sema-agent/client-core'`(`exports` 只有 `.` 一个;
|
|
@@ -123,7 +123,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
123
123
|
|
|
124
124
|
`public-export-baseline.json` 由 **`dist/index.js` 的运行期导出**生成(生成口径自述见
|
|
125
125
|
`scripts/run-client-core-typeshape-test.mjs`,双向精确集合门在 `scripts/run-public-surface-test.mjs`)。
|
|
126
|
-
实测:
|
|
126
|
+
实测:805 项 **100% 是运行期导出,零 type-only**。
|
|
127
127
|
|
|
128
128
|
**推论(端必须知道)**:
|
|
129
129
|
- barrel 导出的**类型**面比 707 大得多,且**不被这道门看守** —— `AdapterContext` / `SeamEvent` /
|
|
@@ -137,18 +137,18 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
137
137
|
`WorkflowsGateUnknownDenial` 四形**不在**基线里,`src/selfOrchestrationDenial.ts` 对基线贡献
|
|
138
138
|
**4** 项运行期导出(三个函数 + `SELF_ORCHESTRATION_RETRY_WITHOUT`)。
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
805 项的内部构成(帮助端估读表大小):**238** 项是 `SCREAMING_SNAKE` 常量数据表/词汇表
|
|
141
141
|
(矩阵、键集、env 名、锚串)而非可调用物;**5** 项是 PascalCase 运行期值
|
|
142
142
|
(`ControlRouter` / `ControlSafetyError` / `HitlBridge` / `HitlSafetyError` / `DecideTransportRetryExhaustedError`);
|
|
143
143
|
**41** 项是 `*For(sessionKey, …)` 的 per-session 变体(§6;其中 `engineNamespaceKeyFor` 是命名巧合 —— 参数是 baseUrl 不是 sessionKey,见域 14)。
|
|
144
144
|
|
|
145
|
-
### 2b. 域图(16 域,逐域计数之和 =
|
|
145
|
+
### 2b. 域图(16 域,逐域计数之和 = 805)
|
|
146
146
|
|
|
147
147
|
| # | 域 | 名数 | 承重导出 | 用途 | 实现锚 |
|
|
148
148
|
|---|---|---|---|---|---|
|
|
149
149
|
| 1 | **适配内核(下行主链)** | 33 | `adapt` · `createWireToCcAdapter` · `runStream` · `eventToSdkMessage` · `terminalToSdkResult` · `turnUsageToModelUsage` · `isRunStreamActive` · `ADAPTER_DIVERGENCES` | 引擎 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` |
|
|
150
150
|
| 2 | **seam 公共契约** | 2(其余为 type-only) | `CHROME_ARMS` · `deriveTranscriptId` | 公共词汇 + **id 确定性不变量**(同一条流重放 ⇒ 同一串 id)。`CHROME_ARMS` = 端「我要消费哪些 chrome 臂」的对照清单 | `src/seam.ts` |
|
|
151
|
-
| 3 | **HITL 决断卡链**(§4/§5 主战场) |
|
|
151
|
+
| 3 | **HITL 决断卡链**(§4/§5 主战场) | 136 | `makeHitlCanUseTool` · `HitlBridge` · `findPendingForTask` · `HitlSafetyError` · `bridgeAskUserQuestionGates` · `surfaceToolApprovalFrameAndRespond` / `surfaceFsApprovalAndDecide` · `readToolApprovalRespondAck` · `installApprovalCardPort(For)` · `installHitlHostSurface(For)` · `armPlanReviewApproval` · `reopenPlanReviewCard` · `decidePlanReview` · `startApprovalsFeed` · `pendingRowIsOwnedByThisSession` · `approvalCallKey`/`liveFrameCallKey`/`planReviewQuestionId` · `registerArmedGateFor`/`wasGateArmedFor`/`clearArmedGateFor` · `waitForGateArmed(For)`/`onGateArmed(For)`/`gateArmedWaitMs`(#244 F1 呈现回执事件源) · `planReviewArmedKey(For)`/`notePlanReviewAnswered(For)`/`notePlanReviewAnsweredIfDecisive(For)`(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}` 仍可赋值)· `DecideTransportRetryExhaustedError`(Inkglow-1085 P0a:decide 出站瞬断重试耗尽的 typed 判别 —— HitlBridge 内建单次退避重试,耗尽走重呈臂不判死 turn;端一般只消费行为,不需要 instanceof) | 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 崩溃收敛读面) |
|
|
152
152
|
| 4 | **子代 wire + 面板侧信道台账** | 84 | `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` | 驱动与观测委派子代;经 module 级台账喂活体 agent/task 面板。全部**能力位 gate**(§5b) | `src/subagent/*.ts`、`src/subagentContentStore.ts`、`src/engineAgentPanelStore.ts`、`src/engineInlineTaskStats.ts`、`src/engineToolLabelStore.ts`、`src/liveQuestionStore.ts` |
|
|
153
153
|
| 5 | **fleet 投影** | 46 | `createFleetLedger` · `projectTasks` · `projectWorkflows` · `projectFleetAgentRows` · `readEngineActiveBgTasks` · `FLEET_TASK_VIEW_KEYS` · `escapeDisplayControlChars`(不可见字符可见化,行标签/描述消毒的共享底座)· `wireCycleSeq` / `wireRetiredBy`(0.38.0 提货补投的 #261 §2 两位:代际号 = SendMessage 复活即 +1,**缺席 ≠ 第一代**;`retiredBy` 在场 = 这条终态是对账腿从 durable run 行投影出来的、**不是**发布方亲报 —— 幽灵行与正常收尾唯一的 wire 判据。两位都只在场才落键) | 老 `fleetClient` 那一刀的成品:**帧体归库、连接归端** —— 端持 SSE 连接,库做行投影 + 保留台账 | `src/fleet/fleetProjection.ts`、`src/fleet/fleetLedger.ts`、`src/fleetAgentPanelProjection.ts`、`src/fleetTaskDesc.ts` |
|
|
154
154
|
| 6 | **请求装配(上行唯一构造口)** | 8 | `buildTaskRequest` · `REQUEST_FIELD_MATRIX` · `unregisteredRequestKeys` · `applyLiveRequestDefaults` · `taskNotificationToPrintFrame` | 两条车道(`interactive`/`print`)出站请求的**唯一**构造器;`unregisteredRequestKeys` 是可执行门 —— 端偷带一个未登记键上 wire 就红 | `src/request/taskRequest.ts`、`src/request/printNotification.ts` |
|
|
@@ -161,7 +161,7 @@ SDK 核对「本包 import 的每个值级符号仍然导出」「`TaskStats.cos
|
|
|
161
161
|
| 13 | **座位 IPC 契约** | 33 | `LOCAL_SESSIONS_SPEC` · `SEAT_METHOD_NAMES` · `SEAT_EVENT_TYPES` · `isLocalSessionEvent` · `isToolPermissionRequest` · `toolPermissionRequestId` · `SEAT_VALIDATOR_KEY_COVERAGE` | 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 桌面壳里的符号只会零命中,而零命中在这里**既不证真也不证伪**。复核这些断言**不得**拿本仓语料当反证 |
|
|
162
162
|
| 14 | **宿主端口与会话槽** | 26 | `installHost` · `installHostFor` · `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` |
|
|
163
163
|
| 15 | **控制面与传输** | 82 | `ControlRouter`(+ `ControlSafetyError`)· `makeEngineWireClient` + `resolveWireAuth` · `installEngineWireTarget` · `diagnoseSseIdleTear` / `isSseIdleError` · `attemptActiveRunSelfHeal` + `activeRunBusySignal` + `activeRunSelfHealRow` / `activeRunBusyHeadlessRow` · `kickEngineCapsProbe` / `engineCapTrue` / `invalidateEngineCaps(baseUrl, probe?)`(#307 S25:引擎温切后的 caps 生产失效口 —— kick 自带幂等闸,同 baseUrl 重启后不显式失效就永远读到旧引擎那一版能力位;调用方 = 壳的 respawn/restartEngine。🔴 **推荐两参形**:第二参给替代探测则「推进代际 + 注册新探测」在同一同步块内完成,失效与下一次 kick 之间那个「等待者读到未判」的窗按构造不存在;单参形保留给「只丢缓存、这一刻没有替代探测」的调用方,那种情形下读到未判是诚实结局) · `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 错误分型判定半场,人话文案与渲染归端) | 上行通道的**监管**半场(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` |
|
|
164
|
-
| 16 | **引擎词汇表与包自检** |
|
|
164
|
+
| 16 | **引擎词汇表与包自检** | 51 | `CONFIG_REFUSAL_CODES` / `isConfigRefusalCode` · `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) | 三端分臂共用的**去字面化** `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` 一位)、`src/classifierVerdictWire.ts`、`src/compensations.ts`、`src/clientSlice.ts` |
|
|
165
165
|
|
|
166
166
|
🔴 **`engineErrorCodes` 的开集纪律**(该文件头注逐字):这些 `ReadonlySet` / 前缀谓词一律是**识别表**,
|
|
167
167
|
回答的是「我认不认得这个码」,**绝不是**「合法码只有这些」。消费点 `switch` **必须留 `default`**,
|
|
@@ -1519,6 +1519,8 @@ CHANGELOG 0.29.0「已知局限」段与相应 JSDoc 都有成文。**别在读
|
|
|
1519
1519
|
|
|
1520
1520
|
| **P-42** | low @cli @web @desktop | 🆕 **Esc halt 只上收了判定,发射面仍在各端**(0.47.0 件③,刻意的分工不是半成品):`planInteractiveHalt` 给判据与升级码闭集,`POST /v1/runs/:id/interrupt` 的**发射**(以及 `?session=` 供给、超时窗、台账、留痕)仍归端。cli 侧那条「裸 fetch 直拨 interrupt」的网络面豁免,**退役条件就是端接上这个口子**(壳换装不在 0.47.0 批内) | `src/interactiveHalt.ts`;§10 | 按 §10b 的分支表接:判定用本包,发射用端自己的传输腿;🔴 halt 必须排在撕 SSE **之前**(§10c 第 1 条) |
|
|
1521
1521
|
|
|
1522
|
+
| **P-43** | med(治理面)@cli @web @desktop | 🆕 **`hooksForWire()` 只守住了本地执行器四条治理腿里的三条**(0.52.0 L-67④ 补了第三条,第四条**在册未修**):cli 仓那份本地执行器(`utils/hooks/hooksConfigSnapshot.ts` 的 `getHooksFromAllowedSources`,**cli 仓坐标不是本仓坐标**)的第四条腿 = `disableAllHooks` 出现在**非** managed 来源(user/project/local)时按 CC 语义降级成「只跑 managed hooks」。本包今天**只读** `policySettings.disableAllHooks` ⇒ 该形在引擎腿上**不成立**(用户把自己的 hooks 关了,引擎照投照跑)。**为什么不做单边近似**:cli 那条腿读的是**合并后**的标量(四源按 policy→user→project→local 后写覆盖前写),而本包 `SettingsPort` 只有 per-source 读口 —— 拿「任一来源为 true」去近似会在「user 写 `true`、local 写 `false`」这一形上**判反**(cli 那边是**不**限制)。忠实复刻要给 `SettingsPort` 加一个合并读口 = **公面改动**(端要跟车实现),属另一批 | `src/hooksWireCaps.ts`(头注「在册缺口」段);§15b/§15d | 端**不要**假定「用户 settings 里的 `disableAllHooks` 会挡住引擎腿的 hooks」——今天只有 **managed(policySettings)** 那一份挡得住。要它落地按 [C162] 令④ 回 C 板提(正位解在包侧:`SettingsPort` 补合并读口 + 本函数补第四条腿) |
|
|
1523
|
+
|
|
1522
1524
|
### 7e. 缺口的共同形状(值得单独说)
|
|
1523
1525
|
|
|
1524
1526
|
**P-1 / P-2 / P-3 / P-4 / P-5 / P-6 / P-7 是同一类**:上游(server / SDK)已经把材料铸到 wire 上了,
|
|
@@ -2264,3 +2266,183 @@ else {
|
|
|
2264
2266
|
**实现锚**:`src/selfOrchestrationDenial.ts`(码常量单源在 `src/engineErrorCodes.ts`;
|
|
2265
2267
|
两条 stamp 腿仍在 `src/selfOrchestrationWireCaps.ts` / `src/ultracodeWireCaps.ts`)。
|
|
2266
2268
|
**常驻门**:`scripts/run-self-orchestration-denial-test.mjs`。
|
|
2269
|
+
|
|
2270
|
+
## §14 🆕 park 再附着的 hop 预算 = 连续非进展轮(0.51.0;L-80)
|
|
2271
|
+
|
|
2272
|
+
### 14a. 语义(端不用改也要知道)
|
|
2273
|
+
|
|
2274
|
+
`bridgeAskUserQuestionGates` 对每一次 park 都会 decide/呈卡后**再附着** `runs.events`。修前每次 park 吃一格预算
|
|
2275
|
+
(24 格),模型在一个 turn 里问 25 次就撞 `gate hop limit (24) exceeded`——与真因无关。现在预算只数**连续非进展轮**:
|
|
2276
|
+
一轮再附着之后那段流里有没有 host 推进帧(`text_delta` / `reasoning_delta` / 非孙代 `tool_start`)。有 ⇒ 清零;
|
|
2277
|
+
没有 ⇒ +1;超过 `MAX_GATE_HOPS`(=2)⇒ 收场。「决了但引擎原样 park 回来」(坐标失配、`resume.tool_unavailable`
|
|
2278
|
+
这类 reopen 再 park)因此天然判非进展;「模型重试同一失败调用、每次真被门」每轮都有推进帧 ⇒ 不限次(CC 同款)。
|
|
2279
|
+
|
|
2280
|
+
### 14b. 端怎么接(两件,additive)
|
|
2281
|
+
|
|
2282
|
+
1. **`deps.onParkReattach?: (e: ParkReattachNotice) => void`** —— 每一轮非进展 reattach 调一次
|
|
2283
|
+
`{ attempt, max, reason }`。渲成瞬态状态行(cli:Spinner 行「re-attaching to the parked run (attempt n/m: <reason>)」),
|
|
2284
|
+
同 reason 覆盖不叠行,turn 结束清。缺席 = 只留 debug(修前形)。**不要**据它做任何处置。
|
|
2285
|
+
2. **`ReopenCardVerdict.decidedWithoutCard`** —— 端的 `reopenAskPark` 若链**没呈卡但已成功决断**(sync-allow /
|
|
2286
|
+
规则直决),返 `{ reopened: false, decidedWithoutCard: true }`。库**不**据此直接重发:它只证明「决断受理」,
|
|
2287
|
+
库先用 `runs.get` 有界等 claim 释放(与 cancel 释放窗同源,10s):释放 ⇒ `SelfHealOutcome{kind:'ask-decided-without-card', released:true}`,
|
|
2288
|
+
`selfHealSubmissionDisposition` = `resending`;没释放但 run 在跑 ⇒ 走既有 running 臂(三选卡或「等它跑完」);
|
|
2289
|
+
仍 parked / 读不出 / 端没给 `runs.get` ⇒ `ask-decided-release-unknown`(不重发、不谎报失败:「should be resuming … wait a moment and send it again」)。**决断成功之后绝不再落 `ask-reopen-failed`**。
|
|
2290
|
+
`ask-decided-release-unknown` 的 `selfHealSubmissionDisposition` = `not-delivered`(闭集**不加值**):用户消息按文案
|
|
2291
|
+
手动重发;系统注入件走既有 not-delivered 处置(端:归因上屏 + 问一次待决队列,不回灌不盲发)。库**不**承诺
|
|
2292
|
+
「稍后自动投递」—— 没有释放驱动的重投机制之前,承诺就是谎报(对抗复审 r4)。端的自动重发若按 kind 等值判
|
|
2293
|
+
(cli `running-cancelled` 那条),需同批把这个 kind 列进去,否则文案说「re-sending」而消息没发 = 谎报。
|
|
2294
|
+
裸 `{reopened:false}` 一字不变。
|
|
2295
|
+
|
|
2296
|
+
### 14c. 端必读的四条
|
|
2297
|
+
|
|
2298
|
+
- 终帧两码:`hitl_unanswered`(这一轮没决断落地:读空 / 传输败 / 无卡)文案带真因与出路(「… decide it on the card
|
|
2299
|
+
when it is shown again, or cancel the run」);**`hitl_stalled`**(新)= 这一轮 decide 已成功但引擎连续 N 次把同一只 call
|
|
2300
|
+
原样 park 回来 —— 文案说「decision was accepted … sema did not observe the run move on」,**不**说 could not be answered /
|
|
2301
|
+
still parked。两码都不再含 `gate hop limit`;端若曾 grep 这句做判别,改锚 `errorCode`。
|
|
2302
|
+
- 触顶时若上一轮**没**呈过卡,库会现读队列再呈一次收场卡(走同一个 `ApprovalCardPort`);上一轮呈过就**不**重复问。
|
|
2303
|
+
- 已解决臂同因限次仍是 1(第二次同因即收场);`retryExhausted`(decide 出站瞬断耗尽)臂同因连续 2 次即收场,
|
|
2304
|
+
两臂都经 `onParkReattach` 告知。
|
|
2305
|
+
- 进展判决分两半:帧半场(resolve 前,只复位同因账;有推进帧时**不在解析前触顶**)+ 身份半场(resolve 后,权威:
|
|
2306
|
+
这一轮真解析到的 pending 行;同一只 call 原样回来哪怕夹文本帧也不算进展;没解析到行的轮次一票否决(例外:上一轮在**新 call** 上真决断落地过 —— 那时的「首读空」是取件失败不是空转,推进帧照算进展;
|
|
2307
|
+
同一只 call 原样回来再决一次不算);帧上身份陈旧/缺席都不参与,也不回填)。提交后超上限 ⇒ 立即收场(该轮已呈过卡,不再呈)。tool-less park
|
|
2308
|
+
无身份只看帧,另有 `MAX_TOTAL_PARKS=64` 硬兜底 —— **只数解析不出身份的 park**(每轮都解析到新 call 的门不吃这格,CC 同款问 N 次答 N 次;命中终帧「N parks … resolved to no identifiable approval」)。
|
|
2309
|
+
- `MAX_GATE_HOPS` / `MAX_TOTAL_PARKS` / `nextHopBudget` / `HopBudget` / `HopRound` / `ParkReattachNotice` /
|
|
2310
|
+
在公面上;`nextHopBudget` 是纯函数,
|
|
2311
|
+
端可用它在自己的诊断面复算。
|
|
2312
|
+
|
|
2313
|
+
### 14d. 射程边界
|
|
2314
|
+
|
|
2315
|
+
引擎侧 reopen 类 re-park(`/decide` 200 `{retriable:true}` + 账本 `suspended`,server [6217])本库只判「非进展」并把
|
|
2316
|
+
最后一轮的 errorCode 带进终帧;为什么该副本工具不可达是引擎的事。plan_review 腿无「无卡直决」形(规则不决 plan),
|
|
2317
|
+
`planReviewArm` 不加此臂。
|
|
2318
|
+
|
|
2319
|
+
---
|
|
2320
|
+
|
|
2321
|
+
## §15 🆕 分类器拒绝行的现场 + hooks 的第三道 managed 治理门(0.52.0;L-69⑨ / L-67④)
|
|
2322
|
+
|
|
2323
|
+
### 15a. 件A:`surfaceClassifierDeny` 的 additive 第三参(端怎么接)
|
|
2324
|
+
|
|
2325
|
+
**修前**:引擎侧 auto-mode 分类器 block 掉一次工具调用时,`frameRouter` 的 `classifier-deny` 臂只把
|
|
2326
|
+
`toolName` 与裁决 verdict 交给宿主 ⇒ 端的「最近被拒」面板三行同名(三条被拒的 `Bash` 长一个样),
|
|
2327
|
+
重试也只能落到「整个 Bash 工具」这个粒度。根因在台账:`gateLedger` 此前**只在 gated `tool_start`**
|
|
2328
|
+
留 args,而分类器拒绝的工具通常**没被 gate**(引擎侧分类器直接 block,一张 `tool_approval` 帧都不出)。
|
|
2329
|
+
|
|
2330
|
+
**修后**(全部 additive):
|
|
2331
|
+
|
|
2332
|
+
```ts
|
|
2333
|
+
export interface ClassifierDenyContext {
|
|
2334
|
+
/** 这一只被拒调用的 wire `toolCallId`(retry 粒度的锚;帧上取,恒在场)。 */
|
|
2335
|
+
toolCallId: string
|
|
2336
|
+
/** 这一只调用的 `tool_start` 入参快照;**UNTRUSTED**,缺席 = 台账里没有。 */
|
|
2337
|
+
args?: unknown
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
interface HitlHostSurface {
|
|
2341
|
+
surfaceClassifierDeny(toolName: string, verdict: ClassifierDenyVerdict, ctx?: ClassifierDenyContext): void
|
|
2342
|
+
}
|
|
2343
|
+
```
|
|
2344
|
+
|
|
2345
|
+
端侧接法(两步):
|
|
2346
|
+
|
|
2347
|
+
```ts
|
|
2348
|
+
import { installHitlHostSurface, classifierDenyDisplay } from '@sema-agent/client-core'
|
|
2349
|
+
|
|
2350
|
+
installHitlHostSurface({
|
|
2351
|
+
showNotice, clearNoticeIfCurrent,
|
|
2352
|
+
surfaceClassifierDeny(toolName, verdict, ctx) {
|
|
2353
|
+
// ① 行文案:判定走库(三端同形),**展示消毒走端**。
|
|
2354
|
+
const display = classifierDenyDisplay(toolName, ctx?.args)
|
|
2355
|
+
recentDenials.push({
|
|
2356
|
+
tool: toolName,
|
|
2357
|
+
// 🔴 端的消毒单源(cli: cleanUntrustedForDisplay);库交出来的是**原文**。
|
|
2358
|
+
display: cleanUntrustedForDisplay(display),
|
|
2359
|
+
// ② retry 粒度:身份锚是 toolCallId,规则怎么铸由端定(见 §15d)。
|
|
2360
|
+
callId: ctx?.toolCallId,
|
|
2361
|
+
reason: verdict.reason,
|
|
2362
|
+
})
|
|
2363
|
+
},
|
|
2364
|
+
})
|
|
2365
|
+
```
|
|
2366
|
+
|
|
2367
|
+
`classifierDenyDisplay(toolName, args)` 的判据(纯函数、零 IO):
|
|
2368
|
+
|
|
2369
|
+
| 工具 | 读的入参键 | 说明 |
|
|
2370
|
+
|---|---|---|
|
|
2371
|
+
| `Bash` | `command` | |
|
|
2372
|
+
| `Read` / `Write` / `Edit` / `MultiEdit` | `file_path` | |
|
|
2373
|
+
| `NotebookEdit` | **`notebook_path`** | 🔴 **不是** `file_path` —— 那是这只工具的入参真形 |
|
|
2374
|
+
| 其余(开集) | —— | 回落工具名 |
|
|
2375
|
+
|
|
2376
|
+
- 取到的值必须是**非空串**(trim 后非空):非串 / 缺席 / 空串 / 纯空白一律回落工具名;
|
|
2377
|
+
- 工具名自身为空 ⇒ `'tool'`;
|
|
2378
|
+
- 工具名归一按「去空白/下划线/连字符 + 小写」(与 `toolNameIsFsWrite` 同姿势),`multi_edit` / `BASH` 都认;
|
|
2379
|
+
- 结果长度上界 `CLASSIFIER_DENY_DISPLAY_MAX`(= 200,导出常量,**别手抄那个数字**),超出截到上界、末位换 `…`。
|
|
2380
|
+
|
|
2381
|
+
### 15b. 件B:`hooksForWire()` 的第三道 managed 治理门(端不用改,但要知道)
|
|
2382
|
+
|
|
2383
|
+
`hooksForWire()` 此前过了两道 managed 治理门(`disableAllHooks` / `allowManagedHooksOnly`),**漏了**
|
|
2384
|
+
`strictPluginOnlyCustomization`。后果不是「少读一层配置」——管理侧把 hooks 面锁成 plugin-only 之后,
|
|
2385
|
+
端的**本地执行器**不再跑 user/project/local 的 hooks,而**引擎腿照投照跑**:同一条禁令只在一半的执行面上
|
|
2386
|
+
成立,而这一半恰好是工具真正执行的那一半。
|
|
2387
|
+
|
|
2388
|
+
修后判据(与 CC / cli 本地执行器 `isRestrictedToPluginOnly('hooks')` 逐条同形):
|
|
2389
|
+
|
|
2390
|
+
| `policySettings.strictPluginOnlyCustomization` | 结论 |
|
|
2391
|
+
|---|---|
|
|
2392
|
+
| `true` | **锁**(该值锁全部四个可定制面,hooks 在内) |
|
|
2393
|
+
| 数组且含 `"hooks"` | **锁** |
|
|
2394
|
+
| 数组不含 `"hooks"`(如 `["agents"]`) | 不锁(锁的是别的面) |
|
|
2395
|
+
| 缺席 / `false` / 串 / 对象 / 数字 / `[]` | **当未设**(不锁) |
|
|
2396
|
+
|
|
2397
|
+
「锁」的处置与 `allowManagedHooksOnly` **逐字相同**:`sources = ['policySettings']`,`/goal` 的用户态
|
|
2398
|
+
Stop overlay 一并不投,`hostLog('debug')` 留一行痕。四道门的**顺序**:信任门(最广)→ `disableAllHooks`
|
|
2399
|
+
(恒赢,连 policy 自己的也不投)→ 本门 / `allowManagedHooksOnly`(两者同场时结论同一个,无先后)。
|
|
2400
|
+
|
|
2401
|
+
🔴 **坏值形不 fail-closed 整条腿**:相邻两道门对 `SettingsPort` **抛出**选 fail-closed(治理策略读不出来 =
|
|
2402
|
+
未知态 ⇒ 当作有限制);本门守的是「读到了、但值是个坏形」—— 值在手里,方向由字段属主(cli `SettingsSchema`
|
|
2403
|
+
对该字段的 `.catch(undefined)`,原文口径是 *degrade to unlocked-for-this-field*)定。两件事别混。
|
|
2404
|
+
|
|
2405
|
+
### 15c. 端必读(三条)
|
|
2406
|
+
|
|
2407
|
+
1. **老宿主零行为差**(件A):`ctx` 是**可选**第三参。desktop / web 现有的两参
|
|
2408
|
+
`surfaceClassifierDeny(toolName, verdict)` 实现**不需要跟车** —— JS 里多传一个实参不影响两参函数,
|
|
2409
|
+
TS 里「参数少的函数可赋给参数多的签名」是语言规则。反过来**不成立**:端一旦读了 `ctx`,就必须按可选处理。
|
|
2410
|
+
2. **`ctx.args` 是 UNTRUSTED,库原样交出**:不渲、不截、不消毒。展示消毒(控制符 / 双向符 / 换行可见化)
|
|
2411
|
+
是**端的单源**(cli `cleanUntrustedForDisplay`)—— 库里消一遍、端再消一遍,两份字符集必然漂。
|
|
2412
|
+
🔴 **`CLASSIFIER_DENY_DISPLAY_MAX` 量的是「交出去的原文长度」,不是端渲出来那一行的最终宽度**:
|
|
2413
|
+
端的消毒会**变长**(200 个 ESC 在库里长度是 200,逐个转成 `\u001B` 之后是 1200)⇒ **端消毒之后
|
|
2414
|
+
必须再按自己的行宽兜一次底**,别把这个常量读成「拿到手就一定不超过 200 个显示格」。
|
|
2415
|
+
库那一侧保证的是两件、只有两件:原文不无限长;截断**不制造**畸形(边界跨 emoji 代理对时少切一个码元,
|
|
2416
|
+
绝不把一个代理对切成半只)。🔴 **输入里本来就有的**孤代理项(`JSON.parse('"\ud800"')` 完全合法 ⇒
|
|
2417
|
+
这种入参真实存在)**原样透出** —— 修好它属展示消毒,单源就是本包导出的 `escapeDisplayControlChars`
|
|
2418
|
+
(`collapseLabel` 的底座),其头注逐字点名这一族。端只要照第 2 条走自己的消毒,这一格就已经守住了。
|
|
2419
|
+
3. **`ctx.args` 会缺席,那是诚实缺席不是 bug**:台账对每张 `tool_start` 留快照,但那张表**按条目数有界**
|
|
2420
|
+
(`START_ARGS_MAX_ENTRIES = 256`,超容量丢最早)且 `tool_end` 收口即释放;durable re-attach 只消费
|
|
2421
|
+
`runs.events` 的一段,被拒 call 的 `tool_start` 完全可能落在本次连接之外。缺席时 `ctx` **只带
|
|
2422
|
+
`toolCallId`、`args` 键不铸** —— 端按「只有工具名」降级渲,**绝不**据此编一个空 args 出来。
|
|
2423
|
+
🔴 **「有界」是条目数,不是字节数**(成文的取舍):表里存的是 `ev.args` 的**引用**不是拷贝,而同一份
|
|
2424
|
+
入参在这一拍照常投影进转录面、本来就活着 ⇒ 表对驻留字节的增量是「一个指针 × 条目数」。单条载荷
|
|
2425
|
+
**没有**字节预算(一次 `Write` 的 `content` 有多大就跟着引用多大一份)——按字节记账要先定义降级形
|
|
2426
|
+
(截断 = 交出一份假入参,不许),属独立一件,在册未做。
|
|
2427
|
+
durable 重放会把 `tool_start` 再送一遍,那是**被淘汰项拿回快照**的机会(库把记账排在渲染去重闸之前),
|
|
2428
|
+
所以端不必自己缓存 args 去补这一格。
|
|
2429
|
+
|
|
2430
|
+
### 15d. 射程边界(别把本节读成比它更强)
|
|
2431
|
+
|
|
2432
|
+
- **retry 粒度不在包内**:库交出的是身份(`ctx.toolCallId`)与行文案判定(`classifierDenyDisplay`)。
|
|
2433
|
+
「重试这一只调用」具体怎么做 —— 铸一条 `Bash(git status:*)` 形的规则?按 callId 重放?只在面板上提示?——
|
|
2434
|
+
是**端侧规则面**的铸法,各端的规则存储与卡面都不同,库不替它们决定,也不提供「按 callId 重试」的动词。
|
|
2435
|
+
- **本包不改模型面**:`ctx` 只走宿主呈现/记账通道;喂回模型的那一份仍由引擎的 wire 承载,一个字节不碰。
|
|
2436
|
+
- **件B 只补第三道门**:cli 本地执行器还有**第四条**腿 —— `disableAllHooks` 出现在**非** managed 来源时
|
|
2437
|
+
降级成「只跑 managed hooks」。本包今天只读 `policySettings.disableAllHooks` ⇒ 该形在引擎腿上**不成立**,
|
|
2438
|
+
这是**在册缺口**(登记在 `src/hooksWireCaps.ts` 头注 + §7d)。不做单边近似的理由:cli 那条腿读的是
|
|
2439
|
+
**合并后**的标量(四源后写覆盖前写),而本包 `SettingsPort` 只有 per-source 读口,拿「任一来源为 true」
|
|
2440
|
+
去近似会在「user 写 true、local 写 false」这一形上判反(cli 那边是**不**限制)。忠实复刻需要给
|
|
2441
|
+
`SettingsPort` 加一个合并读口 = **公面改动**,属另一批。
|
|
2442
|
+
|
|
2443
|
+
**cli / web / desktop 认领**:cli 侧接点(Recent Denials 行 display + retry 粒度)在其下一批(表态制);
|
|
2444
|
+
web / desktop 无需动作(老宿主零行为差),件B 对三端都是治理面收紧、零签名改动。
|
|
2445
|
+
**实现锚**:`src/hitl/gateLedger.ts`(有界在飞表三动词)、`src/hitl/frameRouter.ts`(deny 臂 + 释放时序)、
|
|
2446
|
+
`src/hitl/hitlHostSurface.ts`(`ClassifierDenyContext`)、`src/classifierVerdictWire.ts`
|
|
2447
|
+
(`classifierDenyDisplay` / `CLASSIFIER_DENY_DISPLAY_MAX`)、`src/hooksWireCaps.ts`(第三道门)。
|
|
2448
|
+
**常驻门**:`scripts/run-client-core-pure-test.mjs`(B6 段 L-67④ 16 条 / B7 段 L-69⑨ 31 条)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
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",
|