@sema-agent/client-core 0.70.1 → 0.70.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -49,6 +49,18 @@
49
49
  > 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
50
50
  > commit 漏转在发布前就红,不再靠人记。
51
51
 
52
+ ## 0.70.2(2026-09-16)
53
+
54
+ > 主题:**CC-18 `agents[].skills` 两条孪生帽退役** —— 0.70.0 那批(`SKILL_CAPS` 三键)的**同形存量**,同轴的这两条当时漏扫。接入面 §41。
55
+
56
+ ### Fixed
57
+
58
+ - 🔴 **CC-18 `agents[].skills` 不再被条数帽与名字长度帽静默削掉**(接入方实撞)。`src/agentsWireCaps.ts` 两处:
59
+ - **条数帽**:`joined.slice(0, MAX_AGENT_SKILLS)` 在第 10 条处截 + 一行运维 warn ⇒ 声明 11 个以上技能的 agent **静默丢技能**,用户看到的只是「我声明的第 11 个技能没生效」。server 7.78.1 的 `agents[].skills` 臂已删 `v.length <= MAX_AGENT_SKILLS`(7.78.0 及以前仍有),改按字节预算渲染清单。
60
+ - **名字长度帽**:join 时要求 `spec.name.length <= MAX_AGENT_NAME_CHARS`,名字超 64 的技能被滤掉后落进 `missing`,再被措辞说成「not found in the loaded skill set」—— 它明明加载了,那句话是假的。server `skillOk` 里 name 只判非空。
61
+ 🔴 **射程止于这两条**:`MAX_AGENT_NAME_CHARS` 管的是 **agent 自己的名字**(server 仍逐字判非空且 ≤64,超了整请求 400),`MAX_AGENT_SKILL_CONTENT_CHARS`(1MB)server `skillOk` 至今仍判 —— 两条都**不退**,退了就是把响亮的 400 换成静默通过。
62
+ `MAX_AGENT_SKILLS` 常量本身**已退役但保留导出**(不再被任何投影读),只为本版不破型面,随下一个 minor 删。判据:pure 门 CC-18a–e 五格(含两条反向自证:真没加载的仍 warn 并剪、content 超 1MB 仍剪);变异三发(条数帽回来 / 名字滤回来 / content 帽也退)各红。
63
+
52
64
  ## 0.70.1(2026-09-16)
53
65
 
54
66
  > 主题:**CC-17 推理/文本面安全修复** —— `handOffOnly` 形(段跨包侧边界 ∧ 已提交前缀自身过期)同步两本补差账 + 清未提交尾段。接入面 §40。
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.70.1
38
+ **Version:** 0.70.2
39
39
 
40
40
  - **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
41
41
  B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
@@ -5,6 +5,12 @@ export declare const MAX_AGENT_TEXT_CHARS = 4096;
5
5
  export declare const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65536;
6
6
  export declare const MAX_AGENT_TOOLS = 64;
7
7
  export declare const MAX_AGENT_TOOL_NAME_CHARS = 128;
8
+ /**
9
+ * 🔴 **已退役(0.70.2,CC-18):本常量不再被任何投影读**,保留导出只为不破型面,随下一个 minor 删。
10
+ * server 7.78.1 的 `agents[].skills` 臂删掉了 `v.length <= MAX_AGENT_SKILLS`(7.78.0 及以前仍有),
11
+ * 引擎侧改按字节预算渲染技能清单;包侧再按 10 条截 = 在一道已不存在的门下面**静默丢技能**,
12
+ * 与顶层 `SKILL_CAPS.items`(0.70.0 退役)是同一个病形的同轴存量。
13
+ */
8
14
  export declare const MAX_AGENT_SKILLS = 10;
9
15
  export declare const MAX_AGENT_SKILL_CONTENT_CHARS = 1048576;
10
16
  export declare const MAX_AGENT_MAX_TURNS = 1000;
@@ -16,6 +16,12 @@ export const MAX_AGENT_TEXT_CHARS = 4_096;
16
16
  export const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65_536;
17
17
  export const MAX_AGENT_TOOLS = 64;
18
18
  export const MAX_AGENT_TOOL_NAME_CHARS = 128;
19
+ /**
20
+ * 🔴 **已退役(0.70.2,CC-18):本常量不再被任何投影读**,保留导出只为不破型面,随下一个 minor 删。
21
+ * server 7.78.1 的 `agents[].skills` 臂删掉了 `v.length <= MAX_AGENT_SKILLS`(7.78.0 及以前仍有),
22
+ * 引擎侧改按字节预算渲染技能清单;包侧再按 10 条截 = 在一道已不存在的门下面**静默丢技能**,
23
+ * 与顶层 `SKILL_CAPS.items`(0.70.0 退役)是同一个病形的同轴存量。
24
+ */
19
25
  export const MAX_AGENT_SKILLS = 10;
20
26
  export const MAX_AGENT_SKILL_CONTENT_CHARS = 1_048_576;
21
27
  export const MAX_AGENT_MAX_TURNS = 1_000;
@@ -118,10 +124,10 @@ export function projectAgentsForWire(defs, deps) {
118
124
  if (typeof skillName !== 'string' || skillName.length === 0)
119
125
  continue;
120
126
  const spec = byName.get(skillName.toLowerCase());
121
- if (spec &&
122
- spec.name.length <= MAX_AGENT_NAME_CHARS &&
123
- spec.content.length > 0 &&
124
- spec.content.length <= MAX_AGENT_SKILL_CONTENT_CHARS) {
127
+ // 🔴 CC-18(0.70.2):**不再按名字长度滤**(server `skillOk` 里 name 只判非空)。修前名字超 64 的
128
+ // 技能会落进下面的 `missing`,再被措辞说成「not found in the loaded skill set」—— 它明明加载了,
129
+ // 那句话是假的。`content` 两条判**保留**:server `skillOk` 至今逐字判非空且 ≤1MB(超了整请求 400)。
130
+ if (spec && spec.content.length > 0 && spec.content.length <= MAX_AGENT_SKILL_CONTENT_CHARS) {
125
131
  joined.push(spec);
126
132
  }
127
133
  else {
@@ -131,11 +137,11 @@ export function projectAgentsForWire(defs, deps) {
131
137
  if (missing.length > 0) {
132
138
  warnings.push(`agents wire: agent "${name}" skills not found in the loaded skill set (dropped): ${missing.join(', ')}`);
133
139
  }
134
- if (joined.length > MAX_AGENT_SKILLS) {
135
- warnings.push(`agents wire: agent "${name}" skills truncated to ${MAX_AGENT_SKILLS}`);
136
- }
140
+ // 🔴 CC-18(0.70.2):**零条数帽**,join 上几条发几条(server 7.78.1 的 skills 臂已无
141
+ // `v.length <= MAX_AGENT_SKILLS`)。修前在第 10 条处 `slice` + warn —— warn 落在运维日志里,
142
+ // 用户看到的只是「我声明的第 11 个技能没生效」,没有任何一层会响。
137
143
  if (joined.length > 0)
138
- item.skills = joined.slice(0, MAX_AGENT_SKILLS);
144
+ item.skills = joined;
139
145
  }
140
146
  if (typeof def.background === 'boolean')
141
147
  item.background = def.background;
@@ -13,6 +13,11 @@
13
13
  * · `lastLegMcp` **整键缺席** = server 的三形同形(新会话 / 最近腿的账本行在保留窗外 / 该腿没推
14
14
  * `wiring_manifest`)**或**引擎早于 7.77.0;本视图同样不铸该键。「为什么缺席」这一位答不出来,
15
15
  * 也不猜。
16
+ * 🔒 **定谳(0.70.1,三方闭环):这三形永远不会长出缺席原因伴生键**,本读器也不留位。理由 ①
17
+ * 后两形在上游是同一条代码路径(走完事件表就是没有那一帧),分不出是保留窗剪的还是压根没推,
18
+ * 启发式 = 把猜测穿成事实;② 该读面的属主门那一臂必须与其余缺席**同形**(非属主读别人的会话
19
+ * 时本键缺席、面板照常 200,反枚举),一旦带原因键,「不存在的会话答 no_leg、别人的会话不答」
20
+ * 就是一个**会话存在性 oracle** —— 可分辨性在这里让位给反枚举。⇒ 缺席只有一句话可说,不编第三句。
16
21
  * · `lastLegMcp` **在场但形坏**(`runId` / `at` 不是非空串、`mcp` 读不出一行)⇒ 视图不铸该键,
17
22
  * 改立 {@link McpPanelView.lastLegMcpUnreadable}(never false)。「引擎送了一份我读不懂的」与
18
23
  * 「引擎没送」对运维是两句话,不折成一个 `undefined`。
@@ -19,7 +19,7 @@
19
19
 
20
20
  | 项 | 值 | 真源 |
21
21
  |---|---|---|
22
- | 本包 | `@sema-agent/client-core` **0.70.1**(本批发布版 = patch,零型面变化:🔴 CC-17 `handOffOnly` 形(段跨包侧边界 ∧ 已提交前缀自身过期)同步两本补差账 + 清未提交尾段 —— 修前形一卡后原始未脱敏尾段照常上屏落盘、形二 `result` 臂把它当缺的后缀补吐;账对不上(前缀跨多条消息)则退回既有行为;§40 / 40y 两条)|
22
+ | 本包 | `@sema-agent/client-core` **0.70.2**(本批发布版 = patch,零型面变化:🔴 CC-18 `agents[].skills` 两条孪生帽退役 —— 条数帽(修前 11+ 技能的 agent 静默丢技能)与技能名字长度过滤(修前长名技能被误报「未加载」);射程止于这两条,agent 自己的名字帽与 skill content 帽上游仍判故不退;`MAX_AGENT_SKILLS` 常量退役但保留导出,随下一个 minor 删;§41 / 41y 两条)|
23
23
  | peer:wire 契约 | `@sema-agent/sdk` **>=8.4.0**(value-level,非 type-only;**0.60.0 抬版**,四条硬理由见 §24a 与 `scripts/run-sdk-floor-test.mjs` 的 `FLOOR` 注;上一次是 0.59.0 的 `>=8.3.0`)。🔴 支持窗同批收到 **engine ≥7.64.0**:sdk 8.4.0 与 7.63.0 及以前的 wire **不同窗** | `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` |
@@ -7772,6 +7772,10 @@ const line = mcpPanelLastLegDetail(view, { reachable }) // 一行措辞唯一
7772
7772
  | `servers[]` 行 | `name` + `status` 必需(`status` **按开集读**);`serverInfo` / `toolNames` / `error` 逐键挑,形坏只丢该键 | 坏行只丢自己;`[]` = 一台都没配(正面事实) |
7773
7773
  | `degraded` | `true`(never false)= materialize 超时/失败,`servers` 空但**不是**「没有 MCP」 | 正常 materialize |
7774
7774
  | `lastLegMcp` | `{ runId, at, mcp[] }`;`mcp[]` 与 `wiring_manifest` 第三段**同一只读器**(`projectMcpSection`,同形同缺席律) | server 三形同形(新会话 / 最近腿账本行在保留窗外 / 该腿没推 manifest)**或**引擎 <7.77.0 —— 视图不铸键,「为什么缺席」不猜 |
7775
+
7776
+ 🔒 **定谳(0.70.1;三方闭环):`lastLegMcp` 的三形同形**(新会话 / 最近腿账本行在保留窗外 / 该腿没推 manifest)**不是包侧缺口,永远不会长出缺席原因伴生键** —— 消费端可以照此设计,不必给原因键留位。两条硬理由:① 后两形在 server 是**同一条代码路径**(走完事件表就是没有那一帧),分不出「被保留窗剪掉」还是「压根没推」;能凑的启发式是把猜测穿成事实,与本包「不知道绝不渲成 0」同一条纪律。② 该读面的**属主门那一臂必须与其余缺席同形**(非属主读别人的会话时本键缺席、面板照常 200,反枚举);一旦有原因键,「不存在的会话答 `no_leg`、别人的会话不答」就是一个**会话存在性 oracle** ⇒ 可分辨性在这里必须让位给反枚举。
7777
+ ⇒ 端渲这一格只有两句话可说:`lastLegMcp` 在场就照它渲,整键缺席就一句「不报」(`mcpPanelLastLegDetail` 的五句之一),**不编第三句**。上游对照:server 契约 B.2c-bis 第 3 条 + `lastLegMcpFor` 头注同批钉住。「这条会话跑过腿没有」属 **runs 面**、不属本面板,上游愿在真实用户困惑出现后评估做成 runs 面读法,届时本包认领投影。
7778
+
7775
7779
  | `lastLegMcpUnreadable` | `true`(never false)= server 送了 `lastLegMcp` 但本视图读不出(`runId`/`at` 非非空串、`mcp` 读不出一行、值是 null) | 缺席 = 没这回事 |
7776
7780
 
7777
7781
  🔴 **两面合法可不同**(契约 G.7 ④;server 判据 LL-2):`servers[].name` 与 `lastLegMcp.mcp[].name` 是两张表(部署缺省场景 vs 按请求注入的名册),视图上**没有**任何「一致/不一致」位,五句措辞没有一句提到 `servers`。端渲并排两块,不对账。
@@ -8045,3 +8049,31 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
8045
8049
  2. **多行跨界段仍按老规矩**:一个 `segmentId` 对上多行时端照旧整发放弃(包这一版不单方面清);整段归属交全在下一版(`text_segment_end.committedUuids[]`)。
8046
8050
 
8047
8051
  **包侧缺口:** ① 多行跨界形候 `committedUuids[]`(下一版);② 其余同 §39 包侧缺口。
8052
+
8053
+ ## §41 🆕 0.70.2 安全修复(CC-18:`agents[].skills` 两条孪生帽退役)
8054
+
8055
+ ### 41a. 本节速览
8056
+
8057
+ | 件 | 一句话 | 端要做什么 |
8058
+ |---|---|---|
8059
+ | S-1 🔴 | **`agents[].skills` 零条数帽**:`projectAgentsForWire` 不再在第 10 条处截 —— 修前声明 11+ 技能的 agent **静默丢技能**(只有一行运维 warn) | 为这一条自建的壳侧规避(先自己截到 10、或把 agent 拆成多个)**可退役**;端不要复刻条数帽 |
8060
+ | S-2 🔴 | **不再按技能名字长度滤**:名字超 64 的技能修前被滤进 `missing`,措辞说成「not found in the loaded skill set」= 假事实 | 读 `missing` 那条 warning 的端:它现在只含**真没加载**的名字,可以照字面信 |
8061
+ | S-3 | **射程止于这两条**:`MAX_AGENT_NAME_CHARS`(agent 自己的名字 ≤64)与 `MAX_AGENT_SKILL_CONTENT_CHARS`(1MB)上游仍判,**不退** | 零动作;别顺手把这两条也退了 —— 退了就是把响亮的 400 换成静默通过 |
8062
+ | S-4 | `MAX_AGENT_SKILLS` 常量**已退役但保留导出**(不再被任何投影读) | 读它的端改不读;常量随下一个 minor 删(型面 BREAKING,单独一版) |
8063
+
8064
+ ### 41z. 逐键处置表(0.70.2)
8065
+
8066
+ | # | 键 / 面 | 处置 | 坐标 / 理由 |
8067
+ |---|---|---|---|
8068
+ | 1 | `agents[].skills` 条数帽 | **retired(行为)** | `src/agentsWireCaps.ts` 的 `#projectAgentsForWire`;server 7.78.1 `spec-fields.js` 的 `skills` 臂已删该判 |
8069
+ | 2 | `agents[].skills[].name` 长度过滤 | **retired(行为)** | 同上;server `skillOk` 里 name 只判非空 |
8070
+ | 3 | `MAX_AGENT_NAME_CHARS`(agent 自己的名字) | **不退** | server `spec-fields.js` 的 `name` 臂仍判非空且 ≤64 |
8071
+ | 4 | `MAX_AGENT_SKILL_CONTENT_CHARS`(1MB) | **不退** | server `skillOk` 仍判;超了整请求 400 |
8072
+ | 5 | `MAX_AGENT_SKILLS` 常量导出 | **deprecated(保留一版)** | 零读点;删它 = 型面 BREAKING,随下一个 minor |
8073
+
8074
+ ### 41y. 🔴 三端升级必读(固定段式,[C295];本批**两条**)
8075
+
8076
+ 1. 🔴 **别在端里复刻技能条数帽**:`agents[].skills` 上游已无条数帽,包侧也退了;为这一条自建的规避(自己先截到 10、把 agent 拆成多个)可退役。
8077
+ 2. **`missing` 那条 warning 现在可以照字面信**:它只含真没加载的技能名;修前名字超 64 的已加载技能也在里面。
8078
+
8079
+ **包侧缺口:** ① `MAX_AGENT_SKILLS` 常量删除随下一个 minor;② 其余同 §40。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/client-core",
3
- "version": "0.70.1",
3
+ "version": "0.70.2",
4
4
  "description": "Client-side session runtime shared by every sema human client (TUI / web / desktop): sema wire frames (AgentEvent) -> CC session vocabulary (SDKMessage) with dual-plane output (transcript/chrome), deterministic transcript ids, lane discipline as a type, and the notification/dedup ledgers. Every CC-skin shape is collected here so the wire itself stays neutral. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
5
5
  "license": "MIT",
6
6
  "type": "module",