@sema-agent/client-core 0.54.0 → 0.55.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 +82 -0
- package/README.md +1 -1
- package/dist/adapt/arms.js +9 -1
- package/dist/adapter/downstream/eventToSdkMessage.js +12 -0
- package/dist/hitl/editedRuleTextPrecheck.d.ts +25 -0
- package/dist/retryStatus.d.ts +112 -16
- package/dist/retryStatus.js +46 -2
- package/dist/toolResult.js +8 -0
- package/docs/INTEGRATION-CLIENTS.md +107 -9
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -49,6 +49,88 @@
|
|
|
49
49
|
> 挡住 ⇒ 本批把它机械化——④a0 对 `pending` 行**要求段头已是日期形**(`(未发布)` 直接红),阶段一
|
|
50
50
|
> commit 漏转在发布前就红,不再靠人记。
|
|
51
51
|
|
|
52
|
+
## 0.55.0(2026-09-05)
|
|
53
|
+
|
|
54
|
+
### `waiting_first_token` —— 等第一个 token 是一种**状态**,不是一次错误(core 7.3.0 / #530;cli B-003 / L-108①)
|
|
55
|
+
|
|
56
|
+
用户报案(sema-bug4「模型调用失败对用户不可见」)的两个面,同一个根因:
|
|
57
|
+
|
|
58
|
+
| 引擎 | 用户看到 |
|
|
59
|
+
|---|---|
|
|
60
|
+
| 7.57.0(内嵌 core 7.2.0) | **什么都没有** —— 相不存在,壳无从渲 |
|
|
61
|
+
| 7.58.0(内嵌 core 7.3.1) | 一条**错误色**的 `API error` 行 —— 方向反了:一次尝试都没失败过 |
|
|
62
|
+
|
|
63
|
+
core 7.3.0 在 `BrainStatusPhase` 上加了第七相 `waiting_first_token`:首 token 看门狗已武装
|
|
64
|
+
(`firstTokenTimeoutMs > 30_000`)而第一个字还没到,等满 30s 起每 30s 发一帧,携 `elapsedMs` /
|
|
65
|
+
`timeoutMs`(`core/dist/brain/stream-engine.js` 的 `emitWaitFrame` 铸点)。本包 0.54.0 及以前
|
|
66
|
+
`mapBrainStatusToRetry` 的 `switch` 只认六相 ⇒ **第七相落 `default:` 被投成 `{kind:'error'}`**,
|
|
67
|
+
壳照 `kind` 渲成重试行。病形 = 「上游闭集加员落 default 臂 ⇒ 新状态被渲成最像的旧状态」,
|
|
68
|
+
与 #3004 修的 `recovered`(重试**成功**被渲成 `API error`)逐字同族。
|
|
69
|
+
|
|
70
|
+
- **新 `kind: 'waiting'` 臂**(`src/retryStatus.ts`):携 `elapsedMs` / `timeoutMs`,不打 `terminal`
|
|
71
|
+
位(首 token 到了 core 补 `recovered`,彻底失败补 `gave_up` —— 等待本身从来不是终态)。
|
|
72
|
+
`deadline` 恒 = 映射时刻的 `nowMs`(本相不带 `retryIn*`)⇒ 渲染面按「剩余量 ≤ 0」自然不渲倒计时。
|
|
73
|
+
- 🔴 **老宿主分两形(不许含混说「零差异」)**:`waiting` 臂刻意是 `error` 臂的**结构超集** ——
|
|
74
|
+
**结构形**消费者(`if (kind==='stalled') … else …`)逐字节零差异;而**穷尽形**消费者
|
|
75
|
+
(`switch (kind)` + `default: assertNever`)**加员即破**(重新编译报「waiting 不可赋给 never」,
|
|
76
|
+
已编译老产物在 default 臂**抛**)—— 破的是判别值本身,补结构位救不了。⇒ 对这一类消费方
|
|
77
|
+
0.55.0 是 **BREAKING**,三端必须审一遍自己的 `RetryStatus` switch。两形的事实分别钉在
|
|
78
|
+
`run-client-core-pure-test.mjs` G6-e ①②③。结构形的细节:还没跟车的端
|
|
79
|
+
(desktop / web-client)其 `if (kind==='stalled') … else …` 的 else 臂照旧读到 `error` /
|
|
80
|
+
`deadline` / `terminal`,渲出与 0.54.0 **逐字节相同**的那一行。少了 `error` 这一位,
|
|
81
|
+
`status.error.rateLimits` 就是一次 TypeError —— 渲染路径裸抛 = 整屏崩,把「一行渲错」升级成
|
|
82
|
+
「一屏全没」。判据不是一句承诺,是门:`run-client-core-pure-test.mjs` G6-d 与
|
|
83
|
+
`run-additive-key-passthrough-test.mjs` G5d 拿**本函数自己的 `default:` 臂**当活对照
|
|
84
|
+
(一个未知相走的正是加员前第七相走的那条臂),两边逐位相等才绿。
|
|
85
|
+
- **两位跟车过两层白名单**:`BrainStatus` 加 `elapsedMs` / `timeoutMs`(九键 → **十一键**)。
|
|
86
|
+
🔴 族扫落点是**两处**,不是派工单点名的那一处:`adapter/downstream/eventToSdkMessage.ts`
|
|
87
|
+
的 `case 'status'`(wire → 内部臂)与 `adapt/arms.ts` 的 `retryStatusArm`(内部臂 → chrome 事件)。
|
|
88
|
+
漏任一层,新相到壳只剩空壳:kind 对了、秒数永远缺席。两位缺席一律**键不 stamp**,绝不折 0。
|
|
89
|
+
- **相位运行期镜像**六相 → **七相**;devDep `@sema-agent/core` `^7.1.0` → `~7.3.0`
|
|
90
|
+
(对账物不抬,`engine-vocab` G2-b 对新相**没有判别力** —— 这正是该门头注记过五次的恒绿病根)。
|
|
91
|
+
|
|
92
|
+
### 抬对账物同批捞出的三件存量(族扫,不是点名件)
|
|
93
|
+
|
|
94
|
+
抬 devDep core 到 7.3.1 后 `engine-vocab` 门当场翻红三处,逐条如实修:
|
|
95
|
+
|
|
96
|
+
1. **`CC_DETAIL_TYPES` 漏 `list-agents`**(42 / core 43)—— ListAgents 的结构化卡
|
|
97
|
+
(`core/dist/agents/list-agents-tool.js` 铸点)。漏词的实际后果是那一类卡**永远退回正则解
|
|
98
|
+
模型面文本**,而任何一层都不会响。与 5.20 / 5.43 两次逐字同族。
|
|
99
|
+
2. **`EditedRuleTextPrecheck` ok 臂漏 `warnings`**(core 7.3.0 / design/382 §3.3-5 的**宽度提示**)。
|
|
100
|
+
这条腿是端口注入(值原样穿过),所以漏的不是运行期的值,是**消费端的类型面可见性** ——
|
|
101
|
+
端读不到就不会渲,「宽度在点头之前被说出来」就只剩引擎那半边。同批转出
|
|
102
|
+
`EditedRuleBreadthWarning`(`code` 按本包一贯纪律取**开集串**,不镜像 core 的闭集枚举)。
|
|
103
|
+
3. **门自身的抽取口径病**:`extractStringUnion` 的 `([^;]+);` 在**第一个分号**处截断,而 core 7.3.0
|
|
104
|
+
的 `BrainStatusPhase` 成员之间夹着一段**正文带分号**的 JSDoc ⇒ 第七相被静默漏抽,门报出
|
|
105
|
+
「core 6 相 / 本包 7 相;多:waiting_first_token」这种**方向反了的**红 —— 一个抽取口径的病
|
|
106
|
+
足以把跟车做对的人判成做错。修 = 先剥注释再匹配(同族的 `extractInterfaceKeys` 早就这么做),
|
|
107
|
+
并补两条自证腿(带分号 JSDoc 夹层 / 剥注释后不把注释里的串当成员)。
|
|
108
|
+
|
|
109
|
+
### 已知局限(本版新增)
|
|
110
|
+
|
|
111
|
+
- 壳半场的文案是 sema 超集:CC 2.1.250 语料**无同形提示行**(`cli250.js` 里 `first token` /
|
|
112
|
+
`firstToken` / `first_token` 的全部命中都是账号首 token 日期与流式计时**遥测**,无渲染面;
|
|
113
|
+
同族里唯一的用户可见行是 `Waiting for API response`,那是 `reconnecting` 相的既有行)。
|
|
114
|
+
⇒ 措辞按 [6386] / L-79② 既定形,登记 divergence。
|
|
115
|
+
- 未跟车的**结构形**端(desktop / web-client)在 7.58.0 引擎上仍会渲 0.54.0 那一行。这是加员的
|
|
116
|
+
**设计选择**而不是遗漏:零崩渲、零行为漂移,跟车与否由各端自己排期。**穷尽形**端不在此列 ——
|
|
117
|
+
见上一条,那是 BREAKING,必须加 case。
|
|
118
|
+
- 🔴 **本版发出去也还不能让用户看见这一行**(异源对抗复审 [high] 如实记):cli 侧 deps 仍是
|
|
119
|
+
`@sema-agent/client-core ^0.53.0` / `@sema-agent/core ^7.2.0`,ENGINE_PIN 仍是 server 7.57.0
|
|
120
|
+
(内嵌 core 7.2.0,**没有**这个相)。⇒ 端到端可见需要三件同批:0.55.0 发布 → cli deps 抬到
|
|
121
|
+
^0.55.0(含 lockfile)→ ENGINE_PIN 抬到 ≥7.58.0,并在**那一对真版本**上重跑 live 腿、
|
|
122
|
+
摘掉它在 `skip-baseline.json` 里的必 SKIP 登记。
|
|
123
|
+
|
|
124
|
+
- **发包前异源扫描四修(2026-09-05,三域 opus 扫描 + opus 反证,17 条 7 实证)**:①[medium] **waiting 相的覆盖层拆除生命周期无门**——
|
|
125
|
+
把 `retryStatusArm` 尾行 `noteRetryOverlay()` 对 waiting 摘掉,pure 3455 + additive 81 照样全绿 ⇒ 补 R1w 三判据(waiting 后首个主 lane
|
|
126
|
+
内容帧即 `status:null`、先于 `response_metrics start`、子流帧不清);②[low] `elapsedMs`/`timeoutMs` 负数/NaN 直穿 ⇒ `saneMs` 只认有限非负
|
|
127
|
+
数(缺席不渲 0);③[medium] cli 侧 waiting 相曾走 RetryStatusRow 的 all-or-nothing 槽,整块顶掉动画 glyph 与每秒计时,30s 一帧之间屏上零变化
|
|
128
|
+
(像卡死)⇒ 壳改为只替换 byline、glyph 照常动(cli 半场);④文档/门勘误:`retryStatus.ts` 键集注释 9→11 键、server 7.54.0→7.58.0;typeshape
|
|
129
|
+
棘轮 b4 21→20 的推导理由改按实测(此前只有一处内联);engine-vocab `CORE_FLOOR` 7.1→7.3 与对账物同步;INTEGRATION-CLIENTS §0a 已发版本的
|
|
130
|
+
「未发」告示按「发出即退场」约定退场。**老宿主三形**(§18c 更正):结构形(读 `kind` 走 default)零差异;穷尽形(`switch`+`assertNever`)
|
|
131
|
+
BREAKING;**不读 kind 的宿主**(web-client 现状)在 waiting 相上仍渲既有错误行「Request failed · retrying」——不是回归(0.54.0 同形),
|
|
132
|
+
但接 §18b 才有真进度行。
|
|
133
|
+
|
|
52
134
|
## 0.54.0(2026-09-05)
|
|
53
135
|
|
|
54
136
|
### design/385 —— 三条引擎注入车道的类型化投影(`src/peerFrames.ts`;cli L-61② / L-87 5a①5a②)
|
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.
|
|
38
|
+
**Version:** 0.55.0
|
|
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/arms.js
CHANGED
|
@@ -765,7 +765,7 @@ const retryStatusArm = function* (m, { ctx, flags }) {
|
|
|
765
765
|
// #47 矩阵 #5:子代 lane 帧绝不骑主 spinner(无判别守卫的无条件 store 写=默认可疑)。
|
|
766
766
|
if (typeof m.parentToolCallId === 'string')
|
|
767
767
|
return;
|
|
768
|
-
// 🔴
|
|
768
|
+
// 🔴 十一键全转(0.55.0;首建 #3004 跟修批 2026-08-08):此前这里只挑 phase/detail/retryInSec 三键,attempt /
|
|
769
769
|
// maxRetries / retryInMs 被剥在本层 —— 而 server 两腿的 brainStatusEventData 是全发的,
|
|
770
770
|
// `RetryStatus` 上也早就留好了 attempt/maxRetries 两位。键集真源 =
|
|
771
771
|
// `BRAIN_STATUS_PAYLOAD_KEYS`(engine-vocab G2-c 对实装 core 对账)。
|
|
@@ -789,6 +789,14 @@ const retryStatusArm = function* (m, { ctx, flags }) {
|
|
|
789
789
|
// 剥掉它 = 用户看得到「在重试」却看不到「谁失败了/该不该等」)。
|
|
790
790
|
...(typeof m.retryAtMs === 'number' ? { retryAtMs: m.retryAtMs } : {}),
|
|
791
791
|
...(typeof m.errorStatus === 'number' ? { errorStatus: m.errorStatus } : {}),
|
|
792
|
+
// ── 十一键(0.55.0;core 7.3.0 #530,server ≥7.58 `brainStatusEventData` 放行)──────────
|
|
793
|
+
// 🔴 **同一个病形的第五、第六例**,而且这一次剥掉的是**新相的全部内容**:
|
|
794
|
+
// `waiting_first_token` 帧上除了 phase 就只有这两位携带信息(它不带 retryIn*/attempt/
|
|
795
|
+
// errClass/errorStatus —— core 明说本相不宣告等待)。这层白名单不跟车,`mapBrainStatusToRetry`
|
|
796
|
+
// 的新 `waiting` 臂就只能收到一个空壳:kind 对了、秒数永远缺席,屏上那行渲不出「等了多久」。
|
|
797
|
+
// ⇒ 加相**必同批加键**;键集真源仍是实装 core 的 `BrainStatus` 整个键集(G2-c 逐键等值门)。
|
|
798
|
+
...(typeof m.elapsedMs === 'number' ? { elapsedMs: m.elapsedMs } : {}),
|
|
799
|
+
...(typeof m.timeoutMs === 'number' ? { timeoutMs: m.timeoutMs } : {}),
|
|
792
800
|
}, ctx.now());
|
|
793
801
|
// `status === null` = 引擎直报 `recovered`(重试成功)。这一拍是**清除腿之一** —— 但间接腿
|
|
794
802
|
// (TurnFlags 的「主 lane 内容帧到达即清」)可能已经清过了:已安装 core 在内容流跑完的 finally
|
|
@@ -344,6 +344,11 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
344
344
|
// 不等 SDK**,类型面缺席不等于 wire 上缺席。
|
|
345
345
|
// 📋 **退役条件**:sdk 把这两位补进 `status` 臂声明的那一批,把它们并进上面的类型面直读、
|
|
346
346
|
// 删掉本段的 `st2` 结构视图(与本批刚兑现的四键退役逐字同一条路)。
|
|
347
|
+
// 🔴 **0.55.0 又添两位,同一条退役路**(core 7.3.0 #530 / server ≥7.58 `brainStatusEventData`
|
|
348
|
+
// 放行):`elapsedMs`(第一个 token 已被等了多久)与 `timeoutMs`(这次等待的天花板)。
|
|
349
|
+
// 它们只在新相 `waiting_first_token` 上在场,而那一相**除了 phase 就只有这两位带信息** ——
|
|
350
|
+
// 本层剥掉 = 新相到了下游只剩一个空壳,屏上渲不出「等了多久」。sdk 的 `status` 臂同样尚未
|
|
351
|
+
// 声明这两位 ⇒ 与上面两位同款结构视图读,退役条件同(sdk 补声明的那一批一起并进类型面直读)。
|
|
347
352
|
const st2 = ev;
|
|
348
353
|
const num = (v) => typeof v === 'number' && Number.isFinite(v) ? v : undefined;
|
|
349
354
|
const attempt = num(ev.attempt);
|
|
@@ -351,6 +356,8 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
351
356
|
const retryInMs = num(ev.retryInMs);
|
|
352
357
|
const retryAtMs = num(st2.retryAtMs);
|
|
353
358
|
const errorStatus = num(st2.errorStatus);
|
|
359
|
+
const elapsedMs = num(st2.elapsedMs);
|
|
360
|
+
const timeoutMs = num(st2.timeoutMs);
|
|
354
361
|
// 非空串才透传(空串既不是桶也不是「不知道」,只会在下游被渲成一个空的原因)。
|
|
355
362
|
const errClass = typeof ev.errClass === 'string' && ev.errClass.length > 0 ? ev.errClass : undefined;
|
|
356
363
|
return projected(stamp(ctx, armBody({
|
|
@@ -370,6 +377,11 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
370
377
|
// **全链**(adapt 入口 → chrome 事件),所以漏任一层它都红。
|
|
371
378
|
...(retryAtMs !== undefined ? { retryAtMs } : {}),
|
|
372
379
|
...(errorStatus !== undefined ? { errorStatus } : {}),
|
|
380
|
+
// ── 0.55.0 跟车两位(core 7.3.0 #530 / server ≥7.58 放行)──────────────────────────
|
|
381
|
+
// 族扫同址:本条腿的**两层白名单**(本层 + `adapt/arms.ts` 的 `retryStatusArm`)本批同改,
|
|
382
|
+
// 与上面 0.48.0 那两位逐字同一个理由;漏任一层,新相 `waiting_first_token` 的秒数就到不了壳。
|
|
383
|
+
...(elapsedMs !== undefined ? { elapsedMs } : {}),
|
|
384
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
373
385
|
// 🔴 §E2 lane 身份必须透传(2026-08-08 对抗复审二轮复审命中的**跨 lane 状态破坏**)。
|
|
374
386
|
// `status` 臂本来就是 `& EventIdentity`(SDK events.d.ts),server 两腿共用的
|
|
375
387
|
// `brainStatusEventData` 也经 `identityFields` 发 eventId/parentToolCallId —— 而本层此前
|
|
@@ -57,10 +57,35 @@
|
|
|
57
57
|
* 🔴 `code` 是**开集串**:core 的 `RuleRejectCode` 词表属主是引擎,本包**刻意不镜像那张枚举**
|
|
58
58
|
* (镜像 = 引擎加员当天把一个合法值判没,#157 词表纪律的反面)。要分支就按串比,未知值原样呈现。
|
|
59
59
|
*/
|
|
60
|
+
/**
|
|
61
|
+
* core 7.3.0(design/382 §3.3-5)—— 关于一条**已被接受**的规则的**宽度提示**。
|
|
62
|
+
* 🔴 **提示不是拒绝**:拒绝集一字未动,这一位说的是「这条规则比这张卡宽,持有人该知道」
|
|
63
|
+
* (`Bash(adb:*)` admits every argument form of `adb`)。渲不渲、怎么渲是端的事;引擎保证的是
|
|
64
|
+
* 另一半 —— 走 edit 臂确认时命中码会写进记录(`edited.warnings`),「宽度在点头之前被说出来过」
|
|
65
|
+
* 因此是可审计的事实。
|
|
66
|
+
* 🔴 `code` 在本包是**开集串**,与本文件 `code?: string` 那一位同一条纪律:core 的
|
|
67
|
+
* `EditedRuleBreadthWarning['code']` 今天是 `'broad_prefix' | 'compound_prefix'` 两员,
|
|
68
|
+
* 镜像那张枚举 = 引擎加员当天把一个合法值判没(#157 词表纪律的反面)。
|
|
69
|
+
*/
|
|
70
|
+
export interface EditedRuleBreadthWarning {
|
|
71
|
+
/** 开集串(见类型注)。未知码原样呈现,绝不因为不认得就丢掉这条提示。 */
|
|
72
|
+
readonly code: string;
|
|
73
|
+
/** 基线措辞(端可改写,**绝不可反转**;与 §3.5 的 reason 基线同契约)。 */
|
|
74
|
+
readonly message: string;
|
|
75
|
+
}
|
|
60
76
|
export type EditedRuleTextPrecheck = {
|
|
61
77
|
ok: true;
|
|
62
78
|
/** 真正会落库的那一形(可能与输入字节不同 —— 拼写归一)。内联反馈显示**这一形**。 */
|
|
63
79
|
canonicalRule: string;
|
|
80
|
+
/**
|
|
81
|
+
* core 7.3.0 跟车一位(B-003 批抬 devDep core ^7.1.0 → ~7.3.0 时由 engine-vocab G4 形对账
|
|
82
|
+
* 抓出:「ok 臂键集恰 {ok, canonicalRule}」当场翻红,core 真返回三键)。**ADDITIVE,缺席 =
|
|
83
|
+
* 没什么可说的**(不是「没有提示 = 规则很窄」的反推位)。
|
|
84
|
+
* 🔴 本包只做**类型面转出**:这条腿是端口注入(值从 core 原样穿过,本层零加工),所以镜像
|
|
85
|
+
* 漏这一位不会剥掉运行期的值,漏掉的是**消费端的类型面可见性** —— 端读不到就不会渲,
|
|
86
|
+
* 「宽度在点头之前被说出来」这件事就只剩引擎那半边。
|
|
87
|
+
*/
|
|
88
|
+
warnings?: readonly EditedRuleBreadthWarning[];
|
|
64
89
|
} | {
|
|
65
90
|
ok: false;
|
|
66
91
|
/** 验证器自己拒时在场;coverage 闸拒时缺席(开集串,见类型注)。 */
|
package/dist/retryStatus.d.ts
CHANGED
|
@@ -9,8 +9,12 @@
|
|
|
9
9
|
* recovered → null → 覆盖层摘掉(重试**成功**,不是错误 —— 见下)
|
|
10
10
|
* gave_up → error+terminal → '✻ <detail>'(重试用尽的终态;与 recovered 反向。**打 terminal 位**,
|
|
11
11
|
* 渲染面据此不得再接「· Retrying in Ns」——已经没有下一次了)
|
|
12
|
+
* waiting_first_token → waiting → '✻ Waiting for the model's first token · Ns [/ Ns]'(core 7.3.0 /
|
|
13
|
+
* #530;0.55.0 接。**非错误、非重连**:模型已连上,正在生成前的静默。
|
|
14
|
+
* 携 elapsedMs/timeoutMs;本臂是 error 臂的结构超集 —— 老宿主的
|
|
15
|
+
* else 臂照旧渲 0.54.0 那一行,零行为差异零崩渲,见该臂顶注)
|
|
12
16
|
* 绝不捏造 attempt 计数——只用引擎真给的 phase / detail / retryInSec / retryInMs / attempt /
|
|
13
|
-
* maxRetries / errClass / retryAtMs / errorStatus(core 7.0.x
|
|
17
|
+
* maxRetries / errClass / retryAtMs / errorStatus(core 7.0.x 起**九键**、7.3.0 起 +`elapsedMs`/`timeoutMs` 成**十一键**;0.48.0 补齐后两位,
|
|
14
18
|
* 族扫账见 {@link BRAIN_STATUS_PAYLOAD_KEYS} 末段)。
|
|
15
19
|
*
|
|
16
20
|
* 🔴 员数与字段补全(2026-08-08,#3004 跟修批)。此前本文件只列 4 相 + 3 字段,而引擎侧
|
|
@@ -40,6 +44,10 @@ export type RetryStatus =
|
|
|
40
44
|
retryAtMs?: number;
|
|
41
45
|
/** 见 {@link BrainStatusPayload.errorStatus}(引擎给了才在场;缺席禁渲成 0/未知码)。 */
|
|
42
46
|
errorStatus?: number;
|
|
47
|
+
/** 见 {@link BrainStatusPayload.elapsedMs}(引擎给了才在场;本层零重算)。 */
|
|
48
|
+
elapsedMs?: number;
|
|
49
|
+
/** 见 {@link BrainStatusPayload.timeoutMs}(引擎给了才在场;缺席禁渲成 0)。 */
|
|
50
|
+
timeoutMs?: number;
|
|
43
51
|
} | {
|
|
44
52
|
kind: 'error';
|
|
45
53
|
deadline: number;
|
|
@@ -64,24 +72,92 @@ export type RetryStatus =
|
|
|
64
72
|
* 渲染措辞是壳半场(本包不渲染),本位只保证那个事实到得了壳。
|
|
65
73
|
*/
|
|
66
74
|
terminal?: true;
|
|
67
|
-
error:
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
error: RetryStatusErrorPayload;
|
|
76
|
+
/** 见 {@link BrainStatusPayload.elapsedMs}(引擎给了才在场;本层零重算)。 */
|
|
77
|
+
elapsedMs?: number;
|
|
78
|
+
/** 见 {@link BrainStatusPayload.timeoutMs}(引擎给了才在场;缺席禁渲成 0)。 */
|
|
79
|
+
timeoutMs?: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* **等第一个 token**(core 7.3.0 / #530 的 `waiting_first_token` 相,0.55.0 接):请求已经发出、
|
|
83
|
+
* 模型已经连上,只是**还没吐出第一个字**。它既不是错误,也不是重连 —— 没有任何一次尝试失败过,
|
|
84
|
+
* 引擎也不是在**宣告**一次等待,而是在**观测**一次等待(core 顶注逐字:"no wait is being
|
|
85
|
+
* announced, a wait is being OBSERVED")。
|
|
86
|
+
*
|
|
87
|
+
* 🔴 **为什么必须单开一个 kind**(病形:上游闭集加员落 default 臂 ⇒ 新状态被渲成**最像的旧状态**):
|
|
88
|
+
* 0.54.0 及以前本相落 `mapBrainStatusToRetry` 的 `default:` 臂 ⇒ 投成 `{kind:'error'}`,壳把
|
|
89
|
+
* 「在等第一个字」渲成一条**错误色**的 `API error` 行(无 eta、无 attempt)。方向相反的谎报,
|
|
90
|
+
* 与 #3004 修的 `recovered`(重试**成功**被渲成 `API error`)逐字同族。用户报案形正是这一条。
|
|
91
|
+
*
|
|
92
|
+
* 🔴 **本臂刻意是 `error` 臂的结构超集 —— 这是加员的兼容形,不是冗余**:一个还不认得
|
|
93
|
+
* `'waiting'` 的宿主(desktop / web-client 尚未跟车)其 `if (kind==='stalled') … else …` 的
|
|
94
|
+
* else 臂会照旧读到 `error` / `deadline` / `terminal`,渲出与 **0.54.0 逐字节相同**的那一行。
|
|
95
|
+
* 少了 `error` 这一位,老宿主的 `status.error.rateLimits` 就是一次 TypeError —— 渲染路径裸抛
|
|
96
|
+
* = 整屏崩([render-path-must-not-throw]),把「一行渲错」升级成「一屏全没」。
|
|
97
|
+
* 判据写进门:`run-client-core-pure-test.mjs` G6-d「老宿主归约视图对本相的输出 ≡ 0.54.0 对
|
|
98
|
+
* 同一 payload 的输出」。认得本 kind 的宿主拿 {@link elapsedMs} / {@link timeoutMs} 渲真话。
|
|
99
|
+
*/
|
|
100
|
+
| {
|
|
101
|
+
kind: 'waiting';
|
|
102
|
+
/**
|
|
103
|
+
* 🔴 **兼容位,不是一个真等待的截止点**:core 明说本相**绝不带** `retryInMs`/`retryAtMs`
|
|
104
|
+
* (它不宣告等待),故本位恒 = 映射时刻的 `nowMs` ⇒ 渲染面按「剩余量 ≤ 0」自然不渲倒计时。
|
|
105
|
+
* 它在场只为让**老宿主**的 else 臂算得出数而不是 NaN;**认得本 kind 的宿主不得拿它渲倒计时**
|
|
106
|
+
* ——「距下次重试」在本相根本没有所指。要渲进度,读 {@link elapsedMs} / {@link timeoutMs}。
|
|
107
|
+
*/
|
|
108
|
+
deadline: number;
|
|
109
|
+
attempt?: number;
|
|
110
|
+
maxRetries?: number;
|
|
111
|
+
/** 见 {@link BrainStatusPayload.errClass}(core 不变式:本相恒缺席;本层不写特判,给了就透)。 */
|
|
112
|
+
errClass?: BrainRetryErrClass | (string & {});
|
|
113
|
+
/** 见 {@link BrainStatusPayload.retryAtMs}(core 不变式:本相恒缺席;本层不写特判,给了就透)。 */
|
|
114
|
+
retryAtMs?: number;
|
|
115
|
+
/** 见 {@link BrainStatusPayload.errorStatus}(core 不变式:本相恒缺席;本层不写特判,给了就透)。 */
|
|
116
|
+
errorStatus?: number;
|
|
117
|
+
/** 已经等了多久(ms)。见 {@link BrainStatusPayload.elapsedMs};缺席 = 引擎没给,禁渲 0。 */
|
|
118
|
+
elapsedMs?: number;
|
|
119
|
+
/** 这次等待的天花板(ms)。见 {@link BrainStatusPayload.timeoutMs};缺席 = 不渲「/ Ns」。 */
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
/**
|
|
122
|
+
* 🔴 **恒缺席**(`?: never`):等第一个 token **不是**终态 —— 引擎还在等,首 token 到了会补
|
|
123
|
+
* `recovered`、彻底失败会补 `gave_up`。这一位写在型上只为让**老宿主**那句 `status.terminal`
|
|
124
|
+
* 在加员后仍然编译得过(union 各员都得有这个键才允许直接读),值上永不 stamp。
|
|
125
|
+
*/
|
|
126
|
+
terminal?: never;
|
|
127
|
+
/**
|
|
128
|
+
* 🔴 **兼容位**:`formatted` 恒为空串 —— 与 0.54.0 的 `default:` 臂逐字节相同(那一臂也是
|
|
129
|
+
* `{ formatted: '' }`)。本相**没有错误**,所以这里也不许编一句错误文案出来;它存在的唯一
|
|
130
|
+
* 理由是老宿主的 else 臂要读得到这个对象(见上文 G6-d)。新宿主**不得**读本位当错误证据 ——
|
|
131
|
+
* 判「有没有错」的量是 `kind`,不是这个恒空的壳([anchor-on-the-deciding-quantity])。
|
|
132
|
+
*/
|
|
133
|
+
error: RetryStatusErrorPayload;
|
|
78
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* `error` 载荷的**具名形**。
|
|
137
|
+
* 🔴 具名不是风格偏好,是 typeshape 门 B4 的硬要求:导出签名里的**内联匿名形(≥3 成员)**受棘轮
|
|
138
|
+
* 管(只降不升)—— 0.55.0 的 `waiting` 臂复用同一个形,再内联抄一份就是把同一个结构写第三遍、
|
|
139
|
+
* 并把棘轮顶高一格。具名后结构与此前**逐字节相同**(TS 结构化类型 ⇒ 对消费端零差异,不是收窄),
|
|
140
|
+
* 而且这一形从此只有**一处**定义 —— 三个臂再也不可能各自漂。
|
|
141
|
+
* 🔴 **刻意不导出**:它是 `RetryStatus` 的内部构件,公面契约仍是 `RetryStatus` 本身
|
|
142
|
+
* (公面导出表是登记制,加一个名字要走那张表;这一位没有独立的消费理由)。
|
|
143
|
+
*/
|
|
144
|
+
interface RetryStatusErrorPayload {
|
|
145
|
+
formatted: string;
|
|
146
|
+
isNetworkDown?: boolean;
|
|
147
|
+
connection?: {
|
|
148
|
+
isSSLError?: boolean;
|
|
149
|
+
};
|
|
150
|
+
rateLimits?: {
|
|
151
|
+
resetsAt?: number;
|
|
152
|
+
rateLimitType?: string;
|
|
153
|
+
} | null;
|
|
154
|
+
}
|
|
79
155
|
/**
|
|
80
156
|
* core `BrainStatusPhase` 的**运行期值拷贝**(engine-vocab 门 G2-b 拿它对实装 core 对账)。
|
|
81
157
|
* 引擎侧是闭集,**读时按开集处理** —— 一个部署可以在自己的通道上冒出别的相,认得的分支照走,
|
|
82
158
|
* 认不得的落 `default:` 兜底(见 {@link mapBrainStatusToRetry} 末臂)。
|
|
83
159
|
*/
|
|
84
|
-
export declare const BRAIN_STATUS_PHASES: readonly ["rate_limited", "retrying", "reconnecting", "circuit_open", "recovered", "gave_up"];
|
|
160
|
+
export declare const BRAIN_STATUS_PHASES: readonly ["rate_limited", "retrying", "reconnecting", "circuit_open", "recovered", "gave_up", "waiting_first_token"];
|
|
85
161
|
export type BrainStatusPhase = (typeof BRAIN_STATUS_PHASES)[number];
|
|
86
162
|
/**
|
|
87
163
|
* core `BrainRetryErrClass`(5.43.0)的**类型面镜像** —— 一次重试等待的**原因分桶**,
|
|
@@ -99,8 +175,8 @@ export type BrainStatusPhase = (typeof BRAIN_STATUS_PHASES)[number];
|
|
|
99
175
|
* 判据锚在「真正决定结果的量」上:决定结果的是有没有分支,不是有没有一张表。
|
|
100
176
|
*/
|
|
101
177
|
export type BrainRetryErrClass = 'connect_refused' | 'transport' | 'rate_limit' | 'server' | 'http' | 'output_cap';
|
|
102
|
-
/** wire 上 `status` 臂的载荷(= core `BrainStatus`;server 两腿白名单原样转发这 **
|
|
103
|
-
* 真源 = server 7.
|
|
178
|
+
/** wire 上 `status` 臂的载荷(= core `BrainStatus`;server 两腿白名单原样转发这 **11** 键(7.3.0 起含 `elapsedMs`/`timeoutMs`)——
|
|
179
|
+
* 真源 = server 7.58.0 `dist/trace/project.js` 的 `brainStatusEventData`,逐条条件拷贝)。 */
|
|
104
180
|
export interface BrainStatusPayload {
|
|
105
181
|
/** 闭集 + `(string & {})`:未知相仍可携带(开集读),不必先改类型再解析。 */
|
|
106
182
|
phase: BrainStatusPhase | (string & {});
|
|
@@ -162,13 +238,32 @@ export interface BrainStatusPayload {
|
|
|
162
238
|
* 分工:本包只负责让这个事实到得了壳(投影/透传保真),措辞与是否上屏是壳半场。
|
|
163
239
|
*/
|
|
164
240
|
errClass?: BrainRetryErrClass | (string & {});
|
|
241
|
+
/**
|
|
242
|
+
* core 7.3.0(#530;server ≥7.58 `brainStatusEventData` 真发;ADDITIVE,0.55.0 补)——
|
|
243
|
+
* 在一帧 `waiting_first_token` 上:**第一个 token 已经被等了多久**(ms,发帧那一刻,发帧进程
|
|
244
|
+
* 自己的钟;跨进程跳是近似值)。core 顶注:`Absent on every other phase`。
|
|
245
|
+
*
|
|
246
|
+
* 🔴 缺席禁折 0:「不知道等了多久」与「等了 0 毫秒」是两件事,后者会让屏上那行秒数恒 0
|
|
247
|
+
* ([honest-absence-not-fabricated-zero])。
|
|
248
|
+
*/
|
|
249
|
+
elapsedMs?: number;
|
|
250
|
+
/**
|
|
251
|
+
* core 7.3.0(#530;server ≥7.58 `brainStatusEventData` 真发;ADDITIVE,0.55.0 补)——
|
|
252
|
+
* 在一帧 `waiting_first_token` 上:**已武装的首 token 看门狗**(ms)= 这次等待的天花板,
|
|
253
|
+
* 消费方据它渲「45s of 120s」。core 顶注:`Absent on every other phase`。
|
|
254
|
+
*
|
|
255
|
+
* 🔴 与 `retryInMs` 不是同一个量,**绝不可互换**:那一位是「还要等多久才重试」(引擎在宣告一次
|
|
256
|
+
* 等待),本位是「这次等待最多容忍多久」(引擎在观测一次等待)。把本位当倒计时渲,渲出来的是
|
|
257
|
+
* 一个从不递减的数。
|
|
258
|
+
*/
|
|
259
|
+
timeoutMs?: number;
|
|
165
260
|
}
|
|
166
261
|
/**
|
|
167
262
|
* 上面那个 interface 的**运行期键镜像**(照 `TOOL_APPROVAL_FRAME_KEYS_MIRROR` 先例):
|
|
168
263
|
* engine-vocab 门 G2-c 拿它与 core `BrainStatus` 的键集逐元素比 ⇒ 引擎 additive 增键当天红。
|
|
169
264
|
* 下面两个类型钉保证镜像与 interface 之间不可能漂移(少键/多键都是编译错)。
|
|
170
265
|
*/
|
|
171
|
-
export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus"];
|
|
266
|
+
export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "retryInSec", "retryInMs", "attempt", "maxRetries", "errClass", "retryAtMs", "errorStatus", "elapsedMs", "timeoutMs"];
|
|
172
267
|
/**
|
|
173
268
|
* BrainStatus 载荷 → spinner 行状态。
|
|
174
269
|
*
|
|
@@ -176,3 +271,4 @@ export declare const BRAIN_STATUS_PAYLOAD_KEYS: readonly ["phase", "detail", "re
|
|
|
176
271
|
* 已经成功,行就该摘掉。此前本函数返回型钉死非空,于是 `recovered` 只能被塞进 error 臂。
|
|
177
272
|
*/
|
|
178
273
|
export declare function mapBrainStatusToRetry(p: BrainStatusPayload, nowMs: number): RetryStatus | null;
|
|
274
|
+
export {};
|
package/dist/retryStatus.js
CHANGED
|
@@ -9,8 +9,12 @@
|
|
|
9
9
|
* recovered → null → 覆盖层摘掉(重试**成功**,不是错误 —— 见下)
|
|
10
10
|
* gave_up → error+terminal → '✻ <detail>'(重试用尽的终态;与 recovered 反向。**打 terminal 位**,
|
|
11
11
|
* 渲染面据此不得再接「· Retrying in Ns」——已经没有下一次了)
|
|
12
|
+
* waiting_first_token → waiting → '✻ Waiting for the model's first token · Ns [/ Ns]'(core 7.3.0 /
|
|
13
|
+
* #530;0.55.0 接。**非错误、非重连**:模型已连上,正在生成前的静默。
|
|
14
|
+
* 携 elapsedMs/timeoutMs;本臂是 error 臂的结构超集 —— 老宿主的
|
|
15
|
+
* else 臂照旧渲 0.54.0 那一行,零行为差异零崩渲,见该臂顶注)
|
|
12
16
|
* 绝不捏造 attempt 计数——只用引擎真给的 phase / detail / retryInSec / retryInMs / attempt /
|
|
13
|
-
* maxRetries / errClass / retryAtMs / errorStatus(core 7.0.x
|
|
17
|
+
* maxRetries / errClass / retryAtMs / errorStatus(core 7.0.x 起**九键**、7.3.0 起 +`elapsedMs`/`timeoutMs` 成**十一键**;0.48.0 补齐后两位,
|
|
14
18
|
* 族扫账见 {@link BRAIN_STATUS_PAYLOAD_KEYS} 末段)。
|
|
15
19
|
*
|
|
16
20
|
* 🔴 员数与字段补全(2026-08-08,#3004 跟修批)。此前本文件只列 4 相 + 3 字段,而引擎侧
|
|
@@ -35,6 +39,11 @@ export const BRAIN_STATUS_PHASES = [
|
|
|
35
39
|
'circuit_open',
|
|
36
40
|
'recovered',
|
|
37
41
|
'gave_up',
|
|
42
|
+
// core 7.3.0 跟车一相(#530;0.55.0)——「等第一个 token」。加员的**理由**与 recovered 那一相
|
|
43
|
+
// 逐字同族:少一相 ⇒ 它落 `mapBrainStatusToRetry` 的 default 臂被渲成错误行。engine-vocab G2-b
|
|
44
|
+
// 对**实装 core** 逐词对账(本批 devDep ^7.1.0 → ^7.4.0 后那道门先红后绿,红文逐字:
|
|
45
|
+
// 「漏:waiting_first_token」)。
|
|
46
|
+
'waiting_first_token',
|
|
38
47
|
];
|
|
39
48
|
/**
|
|
40
49
|
* 上面那个 interface 的**运行期键镜像**(照 `TOOL_APPROVAL_FRAME_KEYS_MIRROR` 先例):
|
|
@@ -59,6 +68,11 @@ export const BRAIN_STATUS_PAYLOAD_KEYS = [
|
|
|
59
68
|
// engine-vocab G2-c 的等值门本批**先红后绿**,红文逐字:「漏:retryAtMs,errorStatus」。
|
|
60
69
|
'retryAtMs',
|
|
61
70
|
'errorStatus',
|
|
71
|
+
// ── core 7.3.0 跟车**两键**(0.55.0;#530)────────────────────────────────────────────────
|
|
72
|
+
// 与 4) 的相位加员同一批上游变更:core 在 `BrainStatus` 上加了 elapsedMs/timeoutMs 两位,
|
|
73
|
+
// server 7.58.0 的 `brainStatusEventData` 白名单同批放行。镜像不跟 ⇒ G2-c 等值门红。
|
|
74
|
+
'elapsedMs',
|
|
75
|
+
'timeoutMs',
|
|
62
76
|
];
|
|
63
77
|
const _brainStatusKeyPin = [true, true];
|
|
64
78
|
void _brainStatusKeyPin;
|
|
@@ -97,7 +111,24 @@ export function mapBrainStatusToRetry(p, nowMs) {
|
|
|
97
111
|
*/
|
|
98
112
|
const producerTiming = typeof p.retryAtMs === 'number' ? { retryAtMs: p.retryAtMs } : {};
|
|
99
113
|
const failureStatus = typeof p.errorStatus === 'number' ? { errorStatus: p.errorStatus } : {};
|
|
100
|
-
|
|
114
|
+
/**
|
|
115
|
+
* core 7.3.0 跟车两位(0.55.0),**原样透传、零重算**,并且**与其它键一样进 `extra`**
|
|
116
|
+
* (= 每个臂都透,不按相位写特判)。理由与上面 `producerTiming`/`failureStatus` 那段逐字同源:
|
|
117
|
+
* core 的不变式说这两位只在 `waiting_first_token` 上在场 —— 但**由 core 说,不由本层复述**。
|
|
118
|
+
* 本层若写「只有 waiting 臂才透 elapsedMs」,上游哪天把它铺到别的相,本层就成了单方面剥键
|
|
119
|
+
* (`task_progress.model` / `retryAtMs` 两次同形存量的病根)。判据锚在真正决定渲染的量
|
|
120
|
+
* (`kind`),不锚一个恰好同时成立的第二事实([anchor-on-the-deciding-quantity])。
|
|
121
|
+
*/
|
|
122
|
+
// 两个进度位是引擎快照(ms):负数 / NaN / Infinity 不是「等了负久」,一律当缺席(0.55.0 发包扫描 [low] 采;
|
|
123
|
+
// 同一包的 eventToSdkMessage 腿对数值位同样只认有限非负数,两条腿同律)。
|
|
124
|
+
const saneMs = (v) => typeof v === 'number' && Number.isFinite(v) && v >= 0 ? v : undefined;
|
|
125
|
+
const elapsedMs = saneMs(p.elapsedMs);
|
|
126
|
+
const timeoutMs = saneMs(p.timeoutMs);
|
|
127
|
+
const waitProgress = {
|
|
128
|
+
...(elapsedMs !== undefined ? { elapsedMs } : {}),
|
|
129
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
130
|
+
};
|
|
131
|
+
const extra = { ...counts, ...cause, ...producerTiming, ...failureStatus, ...waitProgress };
|
|
101
132
|
switch (p.phase) {
|
|
102
133
|
// 🔴 引擎直报「恢复」:摘行。绝不落 error 臂 —— 那是把成功渲成失败。
|
|
103
134
|
case 'recovered':
|
|
@@ -119,6 +150,19 @@ export function mapBrainStatusToRetry(p, nowMs) {
|
|
|
119
150
|
// 靠 attempt===maxRetries 去推是错的(供给方根本不发那两位)。
|
|
120
151
|
case 'gave_up':
|
|
121
152
|
return { kind: 'error', deadline, terminal: true, ...extra, error: { formatted: p.detail ?? '' } };
|
|
153
|
+
/**
|
|
154
|
+
* 🔴 core 7.3.0 / #530 加的第七相 —— 等第一个 token。**必须在 default 臂之前落自己的 kind**:
|
|
155
|
+
* 这一相走到 `default:` 就是本 bug 的根因(B-003 / L-108①)——「模型正在生成前的静默」被投成
|
|
156
|
+
* `{kind:'error'}`,壳照 `kind` 渲成错误色的 `API error` 行,用户看到的是「在重试」,而事实是
|
|
157
|
+
* 「在等第一个字」。这不是措辞问题:方向是反的(没有任何一次尝试失败过)。
|
|
158
|
+
*
|
|
159
|
+
* `error: { formatted: '' }` 与 `deadline` 是**兼容位**(见 `RetryStatus` 的 `waiting` 臂顶注):
|
|
160
|
+
* 老宿主的 else 臂据它们渲出与 0.54.0 **逐字节相同**的那一行 ⇒ 加员对未跟车的端零行为差异、
|
|
161
|
+
* 零崩渲。`terminal` 永不 stamp —— 首 token 到了 core 补 `recovered`(壳摘行),彻底失败补
|
|
162
|
+
* `gave_up`(壳翻终态错误行),等待本身从来不是终态。
|
|
163
|
+
*/
|
|
164
|
+
case 'waiting_first_token':
|
|
165
|
+
return { kind: 'waiting', deadline, ...extra, error: { formatted: '' } };
|
|
122
166
|
case 'retrying':
|
|
123
167
|
default:
|
|
124
168
|
return { kind: 'error', deadline, ...extra, error: { formatted: '' } };
|
package/dist/toolResult.js
CHANGED
|
@@ -117,6 +117,14 @@ export const STRUCTURED_DETAIL_TYPES = new Set([
|
|
|
117
117
|
// 病根仍是对账物代际差:门锚本仓 devDep core,devDep 停 5.20.0 时该词还没铸 ⇒ 门恒绿。
|
|
118
118
|
// 修 = devDep 升 ^5.43.0(门当场翻红显出漂移)+ 补词,与 A-004.5 那批同一条路。
|
|
119
119
|
'read_path_denied',
|
|
120
|
+
// ── core 7.3.0 跟车一词(B-003 批,2026-09-05;engine-vocab ⑤ 段对 7.3.1 实装物直证)──────────
|
|
121
|
+
// 🔴 **不是本批点名的件,是抬对账物时族扫捞出来的存量漏词**([same-shape-residue-constitution]):
|
|
122
|
+
// 本批为了让 G2-b 对 `waiting_first_token` 有判别力,把 devDep core 从 ^7.1.0 抬到 ~7.3.0;
|
|
123
|
+
// 门当场翻红,红文逐字:「core 7.3.1:43 项 / 本包 42 项;漏:list-agents」。
|
|
124
|
+
// `list-agents` = ListAgents 工具的结构化卡(core `dist/agents/list-agents-tool.js` 铸点,
|
|
125
|
+
// 并已登记在 `dist/core/runner/tool-output-projection.js:67` 的 `CC_DETAIL_TYPES` 里)。
|
|
126
|
+
// 病根与 5.20 / 5.43 两次逐字同族:词漏了不会响,只会让那一类卡**永远退回正则解模型面文本**。
|
|
127
|
+
'list-agents',
|
|
120
128
|
]);
|
|
121
129
|
// 🔴 同批**删三词**(core 5.10.0 BREAKING「幽灵卡」清仓):`multiedit` / `memory-saved` /
|
|
122
130
|
// `memory-recall` —— 全树零铸点(MultiEdit/批量重放铸的是 `type:"edit"` 带 `edits[]`;core
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
| 项 | 值 | 真源 |
|
|
21
21
|
|---|---|---|
|
|
22
|
-
| 本包 | `@sema-agent/client-core` **0.
|
|
22
|
+
| 本包 | `@sema-agent/client-core` **0.55.0**(工作树**未发**;npm 最新 = **0.54.0**。B-003 `waiting_first_token` 那一批进 `CHANGELOG.md` 的 `## 0.55.0(2026-09-05)` 段,冻结账已按两阶段协议插 `pending` 行) | `package.json` `version` |
|
|
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
|
-
| 公开导出面 | **815** 个运行期符号(+ 41 个测试钩;= 工作树当下的值
|
|
26
|
+
| 公开导出面 | **815** 个运行期符号(+ 41 个测试钩;= 工作树当下的值 = 已发 `0.54.0`(design/385 十件 additive 含 `AUTHORITY_ENVELOPE_TAGS`);`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
|
|
|
@@ -31,13 +31,11 @@
|
|
|
31
31
|
(`readSessionMemoryStatus` / `classifyMemoryStatusFailure` / `readCaptureOptOut` / `readLastCapture`)
|
|
32
32
|
在旧版上按名 import 会**在 ESM 实例化当场炸**(具名导出不存在)—— 提货前先抬依赖。
|
|
33
33
|
装 ≤`0.48.0` 的端同理:`0.49.0` 的 `projectCrashConverged`(L-38,§12)在旧版上不存在。
|
|
34
|
-
|
|
35
|
-
`
|
|
36
|
-
`
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
在此之前按名 import 会在 ESM 实例化当场炸 —— 提货前先抬依赖。
|
|
40
|
-
(L-38 的 `projectCrashConverged` 已随 `0.49.0` 发出,不再是未发件。)
|
|
34
|
+
装 ≤`0.49.0` 的端同理:`0.50.0` 的 S-81 五件(`classifySelfOrchestrationRefusal` / `stripSelfOrchestrationIntent` /
|
|
35
|
+
`projectWorkflowsGate` / `SELF_ORCHESTRATION_RETRY_WITHOUT` / `CAPABILITY_SELF_ORCHESTRATION_REQUIRED`
|
|
36
|
+
+ **四个** type-only 形 `SelfOrchestrationRefusal` / `SelfOrchestrationDenialReason` / `WorkflowsGateProjection` / `WorkflowsGateUnknownDenial`,§13)、
|
|
37
|
+
装 ≤`0.53.0` 的端同理:`0.54.0` 的 design/385 十件(§17)—— 在旧版上按名 import 会在 ESM 实例化当场炸,提货前先抬依赖。
|
|
38
|
+
(「未发」告示按「发出即退场」约定退场:本档只列**已发版本**的下限,不再预告工作树里的未发件。)
|
|
41
39
|
🔴 **0.48.0 还抬了 peer 地板**(`@sema-agent/sdk >=7.4.0`),这是本版**唯一**的非 additive 面:
|
|
42
40
|
端装 <7.4.0 的 SDK 会看到 peer 警告(运行期不因此变化)。同一条对 0.47.0 那 **3 个 additive 导出**
|
|
43
41
|
成立(`planInteractiveHalt` / `RUN_LEVEL_STOP_ERROR_CODES` / `readDecideCurrentPending`)。同一条对 0.38.0 那 11 个
|
|
@@ -2694,3 +2692,103 @@ module 台账一个都没动(它们判的是「哪个 task 的哪个状态」,
|
|
|
2694
2692
|
**实现锚**:`src/peerFrames.ts`(`classifyPeerNotification` / `renderPeerFrameTranscriptText` /
|
|
2695
2693
|
`parsePeerFrameText` / `peerFrameDisplayName` / 三张闭集表)、`src/adapt/arms.ts` 的通知臂。
|
|
2696
2694
|
**常驻门**:`scripts/run-peer-frame-projection-test.mjs`(71 checks,含适配器级的两条台账回归)。
|
|
2695
|
+
|
|
2696
|
+
## §18 🆕 `waiting_first_token` —— 等第一个 token 的相(0.55.0;core 7.3.0 #530 / server ≥7.58;cli B-003 / L-108①)
|
|
2697
|
+
|
|
2698
|
+
### 18a. 修的是哪一形
|
|
2699
|
+
|
|
2700
|
+
`BrainStatusPhase` 是**闭集**,而消费端对它有 `switch`。core 7.3.0 加了第七相
|
|
2701
|
+
`waiting_first_token`(首 token 看门狗已武装、第一个字还没到;等满 `WAITING_FIRST_TOKEN_AFTER_MS`
|
|
2702
|
+
= 30s 起每 30s 一帧,携 `elapsedMs` / `timeoutMs`;铸点 `core/dist/brain/stream-engine.js`
|
|
2703
|
+
的 `emitWaitFrame`)。0.54.0 及以前本包不认得它 ⇒ 落 `mapBrainStatusToRetry` 的 `default:` 臂
|
|
2704
|
+
被投成 `{kind:'error'}`。用户端两个面:
|
|
2705
|
+
|
|
2706
|
+
| 引擎 | 用户看到 | 事实 |
|
|
2707
|
+
|---|---|---|
|
|
2708
|
+
| 7.57.0(core 7.2.0) | 什么都没有 | 相不存在 |
|
|
2709
|
+
| 7.58.0(core 7.3.1) | 一条**错误色**的 `API error` 行 | 模型已连上,正在生成前的静默;**一次尝试都没失败过** |
|
|
2710
|
+
|
|
2711
|
+
病形 = 「上游闭集加员落 default 臂 ⇒ 新状态被渲成**最像的旧状态**」,与 #3004 修的 `recovered`
|
|
2712
|
+
(重试**成功**被渲成 `API error`)逐字同族。
|
|
2713
|
+
|
|
2714
|
+
### 18b. 端该怎么用
|
|
2715
|
+
|
|
2716
|
+
```ts
|
|
2717
|
+
import { mapBrainStatusToRetry, type RetryStatus } from '@sema-agent/client-core'
|
|
2718
|
+
|
|
2719
|
+
const st = mapBrainStatusToRetry(brainStatusPayload, Date.now())
|
|
2720
|
+
if (st === null) return null // recovered:摘掉覆盖层
|
|
2721
|
+
if (st.kind === 'waiting') { // 🆕 0.55.0
|
|
2722
|
+
// 非错误色。elapsedMs 缺席 ⇒ 不渲秒数(绝不折 0);timeoutMs 缺席 ⇒ 不渲「/ Ns」。
|
|
2723
|
+
return renderWaitingRow({ elapsedMs: st.elapsedMs, timeoutMs: st.timeoutMs })
|
|
2724
|
+
}
|
|
2725
|
+
if (st.kind === 'stalled') return renderStalledRow(st) // reconnecting:网络面
|
|
2726
|
+
return renderErrorRow(st) // 其余:重试/限流/熔断/放弃
|
|
2727
|
+
```
|
|
2728
|
+
|
|
2729
|
+
三条**必须**照做的纪律:
|
|
2730
|
+
|
|
2731
|
+
1. **不得拿 `deadline` 渲倒计时**。本相不带 `retryIn*`(core:它不宣告等待,它**观测**等待),
|
|
2732
|
+
`deadline` 恒 = 映射时刻的 `nowMs`,是**兼容位**(见 18c),不是一个真的截止点。
|
|
2733
|
+
2. **不得拿 `timeoutMs` 当倒计时源**。它是这次等待的**天花板**(渲「45s of 120s」的分母),
|
|
2734
|
+
拿它当「还要等多久」会渲出一个从不递减的数。
|
|
2735
|
+
3. **缺席禁折 0**。两位都可能缺席(旧 server 不发 / 未来相位铺开),缺席 = 不知道,不渲。
|
|
2736
|
+
|
|
2737
|
+
### 18c. 🔴 老宿主:**结构形免动,穷尽形必须加一条 case**
|
|
2738
|
+
|
|
2739
|
+
`waiting` 臂刻意是 `error` 臂的**结构超集**:它带 `deadline` / `attempt` / `maxRetries` /
|
|
2740
|
+
`errClass` / `retryAtMs` / `errorStatus` / `error{formatted:''}`,`terminal` 恒缺席。于是一个还没加
|
|
2741
|
+
`kind === 'waiting'` 分支的端,其 `if (kind==='stalled') … else …` 的 else 臂读到的一切与 0.54.0
|
|
2742
|
+
**逐位相同**,渲出的行也逐字节相同。
|
|
2743
|
+
|
|
2744
|
+
**为什么不用「更干净」的瘦臂**:少了 `error` 这一位,结构形老宿主的 `status.error.rateLimits` 就是
|
|
2745
|
+
一次 TypeError —— 渲染路径裸抛 = 整屏崩,把「一行渲错」升级成「一屏全没」。加员制造崩渲是不可接受
|
|
2746
|
+
的代价;让未跟车的端**保持原样**才是加员的诚实形。
|
|
2747
|
+
|
|
2748
|
+
🔴 **但结构超集救不了穷尽形消费者,这一条必须说清楚,不许含混成「无需动作」**(异源对抗复审
|
|
2749
|
+
[medium] 采纳):`switch (status.kind) { case 'stalled': …; case 'error': …; default: assertNever(status) }`
|
|
2750
|
+
这一形破的是**判别值**本身,不是形状 —— 补多少结构位都没用。后果两面:重新编译时报
|
|
2751
|
+
「`waiting` 不可赋给 `never`」(编译错,响亮,好);**已经编译好**的老产物拿到新 kind 会在
|
|
2752
|
+
default 臂**抛**(运行期,安静得多)。⇒ 对这一类消费方,0.55.0 是 **BREAKING**,发布帖必须点名。
|
|
2753
|
+
两形的事实各自钉在门里:`run-client-core-pure-test.mjs` G6-e ①(结构形零差异)/ ②(穷尽形真抛)
|
|
2754
|
+
/ ③(反空转:加员**前**同一个穷尽形消费者**不抛** ⇒ ② 的抛精确归因于多了一个判别值)。
|
|
2755
|
+
|
|
2756
|
+
🔴 **第三形:不读 `kind` 的宿主**(0.55.0 发包扫描 [medium] 采,按实际消费者取来的分类):web-client 现状是把
|
|
2757
|
+
`retryStatus` 非空一律渲成既有错误行「Request failed · retrying (n/m)」,根本不看 `kind`。它在 waiting 相上
|
|
2758
|
+
渲的仍是那一行 —— 与 0.54.0 **逐字节相同**,所以不是回归;但用户面拿不到进度行,要接 §18b(读 `kind==='waiting'`
|
|
2759
|
+
渲 headline + `elapsedMs`/`timeoutMs`)才有真话。三形对照:结构形零差异 / 穷尽形 BREAKING / 不读 kind 形=旧行不变。
|
|
2760
|
+
|
|
2761
|
+
判据不是一句承诺,是两道门(拿**本函数自己的 `default:` 臂**当活对照 —— 一个未知相走的正是加员前
|
|
2762
|
+
第七相走的那条臂 —— 两边在老宿主读得到的键上逐位相等才绿):
|
|
2763
|
+
`scripts/run-client-core-pure-test.mjs` G6-d(单元)/ `scripts/run-additive-key-passthrough-test.mjs`
|
|
2764
|
+
G5d(全链两段)。
|
|
2765
|
+
|
|
2766
|
+
### 18d. `BrainStatus` 九键 → 十一键
|
|
2767
|
+
|
|
2768
|
+
新增 `elapsedMs`(已经等了多久,ms)与 `timeoutMs`(这次等待的天花板,ms)。两位**进 `extra` 统一
|
|
2769
|
+
透传**,不按相位写特判 —— core 的不变式(「只在本相在场」)由 core 说,本层复述一遍就等于上游哪天
|
|
2770
|
+
把它铺到别的相时本层单方面剥键(`task_progress.model` / `retryAtMs` 两次存量的病根)。
|
|
2771
|
+
|
|
2772
|
+
🔴 **族扫落点两处**:`adapter/downstream/eventToSdkMessage.ts` 的 `case 'status'`(wire → 内部臂)
|
|
2773
|
+
与 `adapt/arms.ts` 的 `retryStatusArm`(内部臂 → chrome 事件)。漏任一层,新相到端只剩空壳
|
|
2774
|
+
(kind 对了、秒数永远缺席)。
|
|
2775
|
+
|
|
2776
|
+
### 18e. 端的措辞(sema 超集,非 CC parity)
|
|
2777
|
+
|
|
2778
|
+
CC 2.1.250 语料**无同形提示行** —— `first token` / `firstToken` / `first_token` 的全部命中都是
|
|
2779
|
+
账号首 token 日期与流式计时**遥测**,无渲染面;同族里唯一的用户可见行是 `Waiting for API response`,
|
|
2780
|
+
而那是 `reconnecting` 相的既有行(「在等应答」≠「已连上、在等第一个字」)。⇒ 措辞按 [6386] / L-79②
|
|
2781
|
+
既定形 `Waiting for the model's first token · Ns [/ Ns]`,各端登记 divergence。
|
|
2782
|
+
|
|
2783
|
+
**cli / web / desktop 认领**:cli 侧渲染臂在本批同车。web / desktop 按 18c **分两形**:
|
|
2784
|
+
消费形是**结构形**(`if (kind==='stalled') … else …`)⇒ 免动,逐字节零差异;
|
|
2785
|
+
消费形是**穷尽形**(`switch (kind)` + `default: assertNever`)⇒ **必须加一条 `waiting` case**,
|
|
2786
|
+
否则重新编译报「waiting 不可赋给 never」、已编译的老产物在 default 臂**抛**。
|
|
2787
|
+
跟车的正形都是加一条 `kind === 'waiting'` 臂,渲成**非错误色**的进度行。
|
|
2788
|
+
|
|
2789
|
+
**实现锚**:`src/retryStatus.ts`(`RetryStatus` 的 `waiting` 臂 / `BRAIN_STATUS_PHASES` 七相 /
|
|
2790
|
+
`BRAIN_STATUS_PAYLOAD_KEYS` 十一键 / `mapBrainStatusToRetry` 的 `case 'waiting_first_token'`)、
|
|
2791
|
+
`src/adapt/arms.ts`、`src/adapter/downstream/eventToSdkMessage.ts`。
|
|
2792
|
+
**常驻门**:`scripts/run-client-core-pure-test.mjs` G6 组(相位→kind 全矩阵 / 缺席位不捏造 /
|
|
2793
|
+
老宿主零差异)、`scripts/run-additive-key-passthrough-test.mjs` G5 组(全链两段)、
|
|
2794
|
+
`scripts/run-engine-vocab-floor-test.mjs` G2-b/G2-c(对**实装 core** 逐词逐键等值)。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/client-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.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",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@sema-agent/agent-types": "^0.2.0",
|
|
38
|
-
"@sema-agent/core": "
|
|
38
|
+
"@sema-agent/core": "~7.3.0",
|
|
39
39
|
"@sema-agent/sdk": "^7.4.0",
|
|
40
40
|
"esbuild": "^0.27.4",
|
|
41
41
|
"typescript": "^6.0.2"
|