@sema-agent/client-core 0.70.0 → 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 +25 -0
- package/README.md +1 -1
- package/dist/adapt/textStream.js +40 -0
- package/dist/agentsWireCaps.d.ts +6 -0
- package/dist/agentsWireCaps.js +14 -8
- package/dist/mcpPanel.d.ts +5 -0
- package/docs/INTEGRATION-CLIENTS.md +64 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,31 @@
|
|
|
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
|
+
|
|
64
|
+
## 0.70.1(2026-09-16)
|
|
65
|
+
|
|
66
|
+
> 主题:**CC-17 推理/文本面安全修复** —— `handOffOnly` 形(段跨包侧边界 ∧ 已提交前缀自身过期)同步两本补差账 + 清未提交尾段。接入面 §40。
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- 🔴 **CC-17 `handOffOnly` 形不再漏账**(接入方两形回执,整链实测复现)。段跨过包侧边界(工具卡 / 消息划界)且已提交前缀自身也过期时,`replaceAnswerSegment` 旧码只发三键信号就返回,两本补差账一行不动:
|
|
71
|
+
- **形一(卡后有增量)**:`answerSegment` 里那截**原始未脱敏**尾段照常被 `takeAnswerSegment` 提交上屏落盘 —— 它属于一个已作废的段,宿主换的是**另一条**消息,没人会来清它。
|
|
72
|
+
- **形二(卡后零增量)**:`lastCommittedAnswerText` 回退到上一条消息的原始正文,`result` 臂第④臂据此把尾段当「屏上缺的后缀」再吐一遍(终帧未脱敏时连字节都残留)。
|
|
73
|
+
修后:前缀落在哪本账就把哪本的 `livePrefix` 换成 `content`(`endsWith` 守卫,与非跨界形逐字同律),`answer` 同步,并清掉本段还没交出去的那一截(含它押在活体缓冲里的部分;上一段的 `carry` 原样留)。**仍然一个字节都不新交**,不铸任何消息。
|
|
74
|
+
🔴 **收窄(实测逼出)**:两本账是**按消息**记的,而 `livePrefix` 可能跨**多条**消息(多个工具卡 ⇒ 段身份覆盖多行)。那一形下宿主自己也换不了(归属歧义,端按「证明不了就不动手」整发放弃),包若照样清账清尾段,补差基线会回退到中间那条,`result` 反而从第⑤臂(只报分岔)掉进第④臂(补吐一整段)。⇒ 账对不上就退回既有行为:只发信号、一个字节不动;多行那一形的正解是把整段归属交全(`text_segment_end.committedUuids[]`,排下一版),不是包单方面清。
|
|
75
|
+
`run-text-segment-authority-test` Y 段九格 + D14b 按更强判据改口(旧格钉的「与 0.68.0 基线逐字相同」正是这个病);232 → 247;变异三发(去收窄 / 不清尾段 / 不同步账)各红。
|
|
76
|
+
|
|
52
77
|
## 0.70.0(2026-09-16)
|
|
53
78
|
|
|
54
79
|
> 主题:**CC-04 技能帽退役改预算式**(server 7.78.1 + core 7.19.0 同窗:`SKILL_CAPS` 三键退役、零条数丢弃、清单裁切整只归引擎 + `readSkillsListingTruncated` 读器)+ 通告码 +3 + CC-15 形 (a) 透传 `committedUuids: []`。接入面 §39。
|
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.
|
|
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
|
package/dist/adapt/textStream.js
CHANGED
|
@@ -367,6 +367,46 @@ export function createTextStream(ctx, idOf) {
|
|
|
367
367
|
*/
|
|
368
368
|
const handOffOnly = committedPrefixDiverged && previousSegmentCommitted.length > 0;
|
|
369
369
|
if (handOffOnly) {
|
|
370
|
+
// ── CC-17(0.70.1,cli 接入回执两形;整链实测复现)────────────────────────────────────
|
|
371
|
+
// 🔴 「只发信号」曾被写成「两本账一行都不动」,那是**漏账**不是克制:权威全文这一刻已经
|
|
372
|
+
// 交给宿主去换了,包却还按「屏上只有那截原始前缀」继续算,于是
|
|
373
|
+
// 形一(卡后有增量):`answerSegment` 里那截**原始未脱敏**尾段照常被 `takeAnswerSegment`
|
|
374
|
+
// 提交上屏落盘 —— 它属于一个已经作废的段,宿主换的是**另一条**消息,没人会来清它;
|
|
375
|
+
// 形二(卡后零增量):`lastCommittedAnswerText` 回退到上一条消息的原始正文,`result` 臂
|
|
376
|
+
// 的第④臂据此把尾段当「屏上缺的后缀」再吐一遍(终帧未脱敏时连字节都残留)。
|
|
377
|
+
// ⇒ 同步两本补差账(前缀落在哪本就换哪本,`endsWith` 守卫不匹配就不动,与非跨界形逐字同律)
|
|
378
|
+
// + 清掉本段还没交出去的那一截。**仍然一个字节都不新交**(不铸任何消息):那些字节在别的
|
|
379
|
+
// 消息里,宿主按三键换;本分支改的只是「包自己以为屏上有什么」。
|
|
380
|
+
// 🔴 旧注释(异源复审轮五 finding②)说「清未提交尾段会让 `lastCommittedAnswerText` 回退 ⇒
|
|
381
|
+
// 第④臂补吐一整段」—— 那个后果的**前提正是账没同步**;上面一行同步之后前提消失。这句话
|
|
382
|
+
// 不是推理,是判据:`run-text-segment-authority-test.mjs` 的 Y4 就跑那条时序。
|
|
383
|
+
// 🔴 **只在「宿主确定会把某一整条换成 `content`」时才认账**(收窄,实测逼出):这两本账是
|
|
384
|
+
// **按消息**记的,而 `livePrefix` 可能跨了**多条**消息(两个工具卡 ⇒ 段身份覆盖多行)。
|
|
385
|
+
// 那一形下宿主自己也换不了(段身份对上多行 = 归属歧义,端按「证明不了就不动手」整发放弃),
|
|
386
|
+
// 包若照样清账清尾段,`lastCommittedAnswerText` 会回退到中间那条,`result` 臂反而从第⑤臂
|
|
387
|
+
// (只报分岔)掉进第④臂(补吐一整段)—— 那正是轮五 finding② 抓到的**新增重复转录路径**,
|
|
388
|
+
// 实测确认过(D35/D36 两格钉的就是它)。⇒ 对不上就退回 0.68.0 行为:只发信号,一个字节不动。
|
|
389
|
+
// 多行跨界那一形的正解是把整段归属交全(`committedUuids[]`,CC-16),不是包单方面清。
|
|
390
|
+
const syncedBook = committedText.length > 0 && committedText.endsWith(livePrefix) ? 'current'
|
|
391
|
+
: previousCommittedText.endsWith(livePrefix) ? 'previous'
|
|
392
|
+
: null;
|
|
393
|
+
if (syncedBook === 'current') {
|
|
394
|
+
committedText = committedText.slice(0, committedText.length - livePrefix.length) + content;
|
|
395
|
+
}
|
|
396
|
+
else if (syncedBook === 'previous') {
|
|
397
|
+
previousCommittedText =
|
|
398
|
+
previousCommittedText.slice(0, previousCommittedText.length - livePrefix.length) + content;
|
|
399
|
+
}
|
|
400
|
+
if (syncedBook !== null && answer.endsWith(liveSegment)) {
|
|
401
|
+
answer = answer.slice(0, answer.length - liveSegment.length) + content;
|
|
402
|
+
}
|
|
403
|
+
if (syncedBook !== null) {
|
|
404
|
+
// 活体面:本段还押着没吐的那一截也作废(`textPending` 是段缓冲的后缀,前面那截 `carry`
|
|
405
|
+
// 属于上一段,与本次替换无关 ⇒ 原样留)。
|
|
406
|
+
const staleTailLen = Math.min(textPending.length, prevSegment.length);
|
|
407
|
+
textPending = textPending.slice(0, textPending.length - staleTailLen);
|
|
408
|
+
answerSegment = '';
|
|
409
|
+
}
|
|
370
410
|
segmentCommitted = '';
|
|
371
411
|
previousSegmentCommitted = '';
|
|
372
412
|
idleFlushUsedInSegment = false;
|
package/dist/agentsWireCaps.d.ts
CHANGED
|
@@ -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;
|
package/dist/agentsWireCaps.js
CHANGED
|
@@ -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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
|
|
135
|
-
|
|
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
|
|
144
|
+
item.skills = joined;
|
|
139
145
|
}
|
|
140
146
|
if (typeof def.background === 'boolean')
|
|
141
147
|
item.background = def.background;
|
package/dist/mcpPanel.d.ts
CHANGED
|
@@ -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.
|
|
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` |
|
|
@@ -7736,6 +7736,8 @@ import { AgentClient, isApprovalRequestFrameV1, type AgentEvent } from '@sema-ag
|
|
|
7736
7736
|
|
|
7737
7737
|
**语义一句话**:一个身份覆盖「上一次段收口 → 本次段收口」之间过境的**全部** committed assistant 文本行。流开场一个初值;idle-flush 提交的半段与终态提交的同段**共享**一个身份(归属正要这个);`text_segment_end` 帧带的是轮换**前**的那个(与它盖过的行同值);臂处理完之后轮换;思考→回答边界**不**轮换;子流(带 `parentToolCallId`)的段边界不轮换。
|
|
7738
7738
|
|
|
7739
|
+
🔧 **0.70.0 订正(cli 1.0.116 归层清账真机实撞,一句打回)**:与 `text_segment_end.segmentId` 同值的**只有段边界之前**提交的行(idle-flush 半段、或收口前已提交的整段)。**常态段**(`text_end` 先到、定稿行在边界**之后**才提交)的定稿行按包语义属于**下一**窗口 —— 它提交时正文已经是权威文本(缓冲在臂里换过),端**不用也不该**拿它对账;拿它去认「这一段交出去的那一行」会锚错行。上面「idle-flush 提交的半段与终态提交的同段共享一个身份」只对**两者都在边界前提交**那一形成立。
|
|
7740
|
+
|
|
7739
7741
|
**形**:派生自窗口首帧锚 + 窗口序号(`idOf(anchor, 'segment<n>')`)⇒ **同流重放同身份**(与行 `uuid` 同一条确定性纪律);锚缺席那一形(durable 整条消息先于任何增量到达)退到 `ctx.uuid()` 并**缓存一次**。
|
|
7740
7742
|
|
|
7741
7743
|
**铸点唯一** = `adapt()` 的出口(`TextStream.stampSegmentIdentity`):durable 整条消息(`assistant` 臂)与流式分段(M1 提交口)两条腿都从那里过。🔴 **只盖尾块是 `text` 的 assistant 行**:思考块、只带 `tool_use` 的行、chrome 事件一个字节不动;就地盖不复制(台账/宿主持有的引用仍是同一条)。
|
|
@@ -7770,6 +7772,10 @@ const line = mcpPanelLastLegDetail(view, { reachable }) // 一行措辞唯一
|
|
|
7770
7772
|
| `servers[]` 行 | `name` + `status` 必需(`status` **按开集读**);`serverInfo` / `toolNames` / `error` 逐键挑,形坏只丢该键 | 坏行只丢自己;`[]` = 一台都没配(正面事实) |
|
|
7771
7773
|
| `degraded` | `true`(never false)= materialize 超时/失败,`servers` 空但**不是**「没有 MCP」 | 正常 materialize |
|
|
7772
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
|
+
|
|
7773
7779
|
| `lastLegMcpUnreadable` | `true`(never false)= server 送了 `lastLegMcp` 但本视图读不出(`runId`/`at` 非非空串、`mcp` 读不出一行、值是 null) | 缺席 = 没这回事 |
|
|
7774
7780
|
|
|
7775
7781
|
🔴 **两面合法可不同**(契约 G.7 ④;server 判据 LL-2):`servers[].name` 与 `lastLegMcp.mcp[].name` 是两张表(部署缺省场景 vs 按请求注入的名册),视图上**没有**任何「一致/不一致」位,五句措辞没有一句提到 `servers`。端渲并排两块,不对账。
|
|
@@ -7926,7 +7932,7 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
7926
7932
|
|
|
7927
7933
|
| 件 | 一句话 | 端要做什么 |
|
|
7928
7934
|
|---|---|---|
|
|
7929
|
-
| S-1 🔴 **已知边界** |
|
|
7935
|
+
| S-1 🔴 **已知边界**(0.70.0 改口:test [7335] B-125 实证 cli **两条车道**都经 `runStream`,「交互车道 `adapt()` 不经去重不受影响」是包视角的车道假设)| **凡经 `runStream` 的消费端(cli 交互 + `-p` 皆是;只有直喂 `adapt()` 的自建管线不在内)在 server <7.78.1 上收不到 `reasoning_end`**:server 7.77.0 给它的 SSE `id:` 复用该段首枚 `reasoning_delta` 的 id,`runStream` 的 durable seq 去重把它当重放丢;0.69.1 起**丢了必留痕**(`ctx.onDroppedFrame({ type:'reasoning_end', why:'duplicate_seq' })`)。**交互车道 `adapt()` 不经这只去重**,`thinking_segment_end` 照到 | 装 `onDroppedFrame` 的端把 `duplicate_seq` 当运维面留痕渲(不是用户面);`-p` 端在 server <7.78.1 上**如实披露**「推理面权威段不到」,不许壳侧绕过去重(去重律是契约) |
|
|
7930
7936
|
| S-2 🔴 **安全面** | **段末帧子流断闸改按身份三键**(CC-10):`text_end` / `reasoning_end` 内部臂新带 `sourceTaskId?` / `bgAgentId?`(与 `parentToolCallId` 同律原样透传),两臂任一在场即断;只带 `sourceTaskId` 的子代段末帧不再被当 leader 投上来 | 自建管线的端(print 车道 / 座位层)断子流按**三键**判,别只看 `parentToolCallId` |
|
|
7931
7937
|
| S-3 🔴 **安全面** | **跨工具卡的推理段归属交全**(CC-11):`thinking_segment_end` 新带 `committedUuids[]`(段内全部已提交思考行,按序;`committedUuid` = 末条兼容位);`committedPrefixLen` = 全部之和;新增 (b1) 形(前缀对得上 ⇒ 只换还押着的后段) | **宿主义务改口**:`committedPrefixDiverged` ⇒ `committedUuids` 首行就地换成 `content`,其余行**删除或清空其推理正文**(宿主按自身转录结构选;不再只换 `committedUuid` 那一条);缺席 ⇒ 行照旧 |
|
|
7932
7938
|
| S-4 | **park 两新键进 `WorkflowRunState`**(CC-12):`parks?` / `resumeAdmissionIncomplete?`(additive,由两读器铸) | 渲 resume 候选 / park 行的端改读视图上这两位;cli 的「到货锚」可翻 consumed |
|
|
@@ -8015,4 +8021,59 @@ installCoreValuePorts({ resolveAutonomousLoopPrompt, loosenReasons, combinePolic
|
|
|
8015
8021
|
2. **清单裁切只从 `skills.listing_truncated` 读**:`readSkillsListingTruncated(notice)` 给八格事实 + `laneClamped?`;运维面据此分「调 `skillListingBudgetFraction` 有用(部署比例)」与「调了也没用(车道 clamp)」;别自己数条数。
|
|
8016
8022
|
3. **CC-15 读法改口**:`thinking_segment_end.committedUuids` 在场即以它为准(`[]` = 本段零已提交行),整键缺席才是「包说不出」;为形 (a) 自建的过境行计数臂删。
|
|
8017
8023
|
|
|
8018
|
-
|
|
8024
|
+
**到期复核(0.70.0 发后当拍记)**:① core 7.20.0 预告([7334] ③a)删 `skills.listing_truncated.detail.requestedBudgetBytes`(8 KiB 天花板退役后请求预算即实际预算)⇒ `readSkillsListingTruncated` 该键可选、`laneClamped` 只在它在场时派生,到货零改即缺席;随 7.20.0 提货批把 `laneClamped` 派生位整只删。② §37y ③ 「交互车道 `adapt()` 不经去重不受影响」是包视角的车道假设:cli 交互车道实际也经 `runStream`(durable-seq 去重在那里),server 7.77.0 的 `reasoning_end` id 复用在交互车道**同样**把权威段当重放丢(test [7335] B-125 实证);包侧去重律不变、零改,根因修在 server 7.78.1(唯一 id)。**已知边界改口**:凡经 `runStream` 的车道(cli 两车道皆是)在 server <7.78.1 上都收不到 `reasoning_end`。
|
|
8025
|
+
|
|
8026
|
+
**包侧缺口:** ① `readRootCandidate` 候 sdk 出键;② CC-08 三段(`tool_progress` / `tool_disclosure` / `wiring_manifest`)顺延 0.71;③ `laneClamped` 派生位随 core 7.20.0 删;④ 其余同 §38 包侧缺口。
|
|
8027
|
+
|
|
8028
|
+
## §40 🆕 0.70.1 安全修复(CC-17:`handOffOnly` 形同步两本补差账 + 清未提交尾段)
|
|
8029
|
+
|
|
8030
|
+
### 40a. 本节速览
|
|
8031
|
+
|
|
8032
|
+
| 件 | 一句话 | 端要做什么 |
|
|
8033
|
+
|---|---|---|
|
|
8034
|
+
| S-1 🔴 **安全面** | **`handOffOnly` 形不再漏账**:段跨包侧边界(工具卡 / 消息划界)∧ 已提交前缀自身过期时,旧码只发三键信号、两本补差账一行不动 ⇒ 形一 卡后**原始未脱敏**尾段照常上屏落盘;形二 `result` 臂第④臂把它当「屏上缺的后缀」补吐一遍。修后账同步 + 清未交尾段,仍一个字节不新交 | **零动作**(端义务不变:按三键把那一行换成 `content`)。为这两形自建的壳侧补偿可退役;「归属证明不了就不动手」的闸留着当反钉 |
|
|
8035
|
+
| S-2 | **收窄:账对不上就不动**(`livePrefix` 跨多条消息 ⇒ 宿主自己也换不了)| 多行跨界那一形**照旧**是既有行为(原始行在场);它的正解是整段归属交全(`committedUuids[]`,排下一版),端在那之前对多行段保持「整发放弃」是对的 |
|
|
8036
|
+
|
|
8037
|
+
### 40z. 逐键处置表(0.70.1)
|
|
8038
|
+
|
|
8039
|
+
| # | 键 / 面 | 处置 | 坐标 / 理由 |
|
|
8040
|
+
|---|---|---|---|
|
|
8041
|
+
| 1 | `handOffOnly` 分支的两本补差账(`committedText` / `previousCommittedText`) | **consumed(修复)** | `src/adapt/textStream.ts` 的 `#replaceAnswerSegment`;`endsWith` 守卫按前缀落在哪本换哪本 |
|
|
8042
|
+
| 2 | 本段未提交尾段(`answerSegment` + 其 `textPending` 那截) | **consumed(修复)** | 账同步成功才清;`carry`(上一段的)原样留 |
|
|
8043
|
+
| 3 | 多行跨界形(`livePrefix` 跨多条消息) | **declined(退回既有行为)** | 清了会把补差基线搞回退 ⇒ `result` 从第⑤臂掉进第④臂补吐;正解是 `committedUuids[]`(下一版) |
|
|
8044
|
+
| 4 | 三键信号(`diverged` / `committedPrefixLen` / `committedPrefixDiverged`) | **不变** | 本批只改「包自己以为屏上有什么」,信号面逐字未动 |
|
|
8045
|
+
|
|
8046
|
+
### 40y. 🔴 三端升级必读(固定段式,[C295];本批**两条**)
|
|
8047
|
+
|
|
8048
|
+
1. 🔴 **端义务不变**,但包不再交那截未脱敏尾段:为这两形自建的壳侧补偿(记住原始尾段再比对、或整发放弃后手工清)**可退役**;通用的「归属证明不了就不动手」闸留着。
|
|
8049
|
+
2. **多行跨界段仍按老规矩**:一个 `segmentId` 对上多行时端照旧整发放弃(包这一版不单方面清);整段归属交全在下一版(`text_segment_end.committedUuids[]`)。
|
|
8050
|
+
|
|
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.
|
|
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",
|