@sema-agent/client-core 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
23
23
 
24
24
  ## Scope
25
25
 
26
- **Version:** 0.16.0
26
+ **Version:** 0.16.1
27
27
 
28
28
  - **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
29
29
  B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
@@ -14,6 +14,27 @@ function rejectMessageForRender() {
14
14
  /** core 对被 gate/连坐 abort 的 call 铸的 tool_end 载体(逐字;desktop session-host 真引擎实测
15
15
  * 同款)——HOLD 谓词锚它做**精确等值**,普通工具错的输出是各自错误文案,永不进 HOLD。 */
16
16
  export const ENGINE_ABORT_TOOL_RESULT = 'Operation aborted';
17
+ /**
18
+ * tool_end.output 的文本归一(P0 案B,2026-08-03,server 6.0.0 wire 实测):sync leg 的毒化帧
19
+ * `output` 不再是裸 string,而是 content-block 数组 `[{"type":"text","text":"Operation aborted"}]`
20
+ * (8790 裸引擎 POST /v1/tasks/stream 逐帧记录字节形)。abort 标记的**等值锚**必须先归一再比,
21
+ * 否则 6.0.0 下 hold-poison 臂全盲:毒化帧当场上屏 + generic-close 记 ended ⇒ decide 后重放的
22
+ * 真收口帧被 isEnded 早退去重 —— 「按 Yes 屏幕永远停在 Error: Operation aborted」整案复发。
23
+ * 只归一**判定**,帧本身一个字节不改;等值语义不放宽([2084]①-b 收窄仍然成立,负控见 gate ⑩)。
24
+ */
25
+ function toolEndOutputText(output) {
26
+ if (typeof output === 'string')
27
+ return output;
28
+ if (!Array.isArray(output))
29
+ return undefined;
30
+ const parts = [];
31
+ for (const b of output) {
32
+ const bb = b;
33
+ if (bb?.type === 'text' && typeof bb.text === 'string')
34
+ parts.push(bb.text);
35
+ }
36
+ return parts.length > 0 ? parts.join('') : undefined;
37
+ }
17
38
  // ── gate 词汇(两把刀共享)──────────────────────────────────────────────────────────────────────
18
39
  /** 工具名是不是 AskUserQuestion(空白/下划线/连字符与大小写都不敏感)。
19
40
  * **宽口**:帧上的 `toolName` 位是 UNTRUSTED 的任意值,判据自己吃 `unknown`,本模块内部用。 */
@@ -81,7 +102,7 @@ function isGatedToolName(name) {
81
102
  function isGatedToolEnd(ev) {
82
103
  if (isGatedToolName(ev.toolName))
83
104
  return true;
84
- return ev.output === ENGINE_ABORT_TOOL_RESULT;
105
+ return toolEndOutputText(ev.output) === ENGINE_ABORT_TOOL_RESULT;
85
106
  }
86
107
  /** done 帧的 AskUserQuestion park 形状(结构性读;别的终态一律 false)。 */
87
108
  function isAskGatePark(result) {
@@ -200,7 +221,8 @@ const TOOL_END_ARMS = [
200
221
  run(ev, callId, led) {
201
222
  if (ev.isError !== true || !isGatedToolEnd(ev))
202
223
  return undefined;
203
- if (ev.output !== ENGINE_ABORT_TOOL_RESULT)
224
+ // 6.0.0 wire:output 可为 content-block 数组形(见 toolEndOutputText 头注)—— 归一后仍做精确等值。
225
+ if (toolEndOutputText(ev.output) !== ENGINE_ABORT_TOOL_RESULT)
204
226
  return undefined;
205
227
  led.hold(callId, ev); // park 毒化帧,先 HOLD(gate 定性前不渲 Error 卡)
206
228
  return { kind: 'skip' };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/client-core",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
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. Blackboard [1832] design axioms; [1651]/[1652]/[1653] signed seam design. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
5
5
  "license": "MIT",
6
6
  "type": "module",