docs(05): 锚点补记三十九 —— 后端回执二十五/二十六要点(.end 加 resultSummary 已批准、proactive 在 data 里、帧 id 同源、channel_persisted 可能带 proactive、markup 畸形确认是 bug 且已修但未部署)+ 我们去重口径复核没踩坑 + W59 工具卡结果区落地 + 真机验收边界(这批只有单测证据)
This commit is contained in:
1 parent
e0bdaa3537
commit
53c3c5c8ee
1 file changed
+37
@@ -2090,3 +2090,40 @@ infinity maximum height constraints, which is disallowed.
|
||||
- **模拟器已重启**(主人建议):`adb emu kill` → 冷启动 `-avd Pixel_10_Pro_XL -no-boot-anim -no-snapshot-load`,约 35 秒 `boot_completed=1`。重启**会丢 `adb reverse`**,已重设:`tcp:80 → 10942`(真后端)、`tcp:10942 → 10942`。
|
||||
- ⚠️ 重启前的旧模拟器上,**system_server 崩过至少三次**(`com.android.phone` 反复报 `DeadSystemException: The system died`,时间 `00:03` / `00:48` / `01:19`)——这也是长跑第 3 次 2 小时失败的原因(见上一节)。
|
||||
- HEAD = **`df7b504`** = `origin/android`;主仓唯一脏 = `devdocs/02`(后端在途 + 我的 markup 登记)。
|
||||
|
||||
## ★★ 锚点补记三十九 · 后端回执二十五/二十六 + W59 工具卡结果区(2026-10-07 上午)
|
||||
|
||||
### 1. 后端说了什么(两条回执,都在 `devdocs/02`)
|
||||
|
||||
**`回执二十五`**(四条 + 一问 + 告知):
|
||||
|
||||
1. **`.end` 加可选 `resultSummary` ⇒ 做**。「与回看面 `toolCalls[].resultSummary` 同一份预算」:截断 ≤500 字符、**走同一条脱敏路径**。**缺席语义**:只有结果**真的拿到了**才出现;失败/取消/超时/未落图 ⇒ **整键缺席**,**绝不用空串顶位**、也别把缺席读成「没有输出」。原话:**「你们现在就可以把工具卡定死」**(在场渲染结果区 / 缺席只显示工具名与状态,同一套 UI)。排期=新切片、下一个契约版本;`.update` 仍不补。
|
||||
2. **事实核对:我们对、他们注释错了** —— `proactive` 确实在帧的 `data` 里(不是帧壳顶层),他们已把 4 处注释 + 2 处测试注释改掉。
|
||||
3. **新登记的依赖 ⇒ 确认**:`proactive_message.data.id` 与 `message_persisted{proactive}.data.message.id` **同源**(都是主会话落库行的 id)⇒ 登记成**成对契约**;⚠️ `proactive_message.messageId` 是 **IM 侧号**,**不能拿去对齐落库行**。
|
||||
4. **`channel_persisted` 会不会带 `proactive`**:**结构上会**(帧型由会话 id 决定、`proactive` 是独立入参),但当前所有主动推送都落主会话 ⇒ 实际发的是 `message_persisted`。我们**两层都读**是正确做法,继续保持。
|
||||
5. 告知:主动帧的 `sessionId` **恒为主会话 `web`**(所以「切主会话」与他们的口径一致)。
|
||||
|
||||
**`回执二十六` + `·补`**(回我们的 markup 畸形登记):
|
||||
|
||||
- 问 1 ⇒ **是 bug,不是有意形状**(契约里 `<p>` 就是「一段」,没有嵌套语义)。
|
||||
- 问 2 ⇒ **认下,已修完推库 `8051906`**(`fix(turnreply): 产出侧不再产出未配对的段落标签`)。根因**两半且在同一个文件**:① `paragraph.go` 的段块正则**非贪婪** ⇒ 把 `<p><p>X</p>` 当成「已完整包裹」逐字保留,**连护栏都用同一个非贪婪正则**(护栏是盲的);② `normalizePiece` 对「未闭合的段首 `<p>`」**无条件再套一层** —— 他们用我们上报的那条串**逐字节复现**了。③ 顺带挖出幂等漏洞(落单 `</p>` 越跑越多)。
|
||||
- ⚠️ **未部署**:跑着的后端是旧产物 ⇒ **畸形仍会产出**,要我们**继续保留容错**(我们已保留)。历史畸形只 **1 行**,不做回填脚本。
|
||||
- 契约面会补一条**产出侧硬约束**(落库/对外文本不得出现未配对的段落标签)。
|
||||
- ⚠️ 一条**与归因有关的诚实说明**(他们给的):那条具体是 (a) 还是 (b) 产生的**无法判定**(两条路径产出的串逐字节相同、原始模型输出没副本)。
|
||||
|
||||
### 2. 我们的动作
|
||||
|
||||
**① 去重口径复核 ⇒ 没踩坑(无需改动)**。他们提醒「`messageId` 别拿去重」,我核了 `proactiveNotifyKey`:它**不是拼接**,而是 `firstOrNull { !isNullOrBlank() }`,顺序 `id → messageId → timestamp → 文本兜底`。⇒ 实时帧(`id` = 落库行 id)与落库帧(`message.id` = 同一行 id)算出**同一个键**,去重正确;`messageId` 只在 `id` 缺席时才可能被用到,而那档(落库失败)根本没有对应的落库帧。**这条已写进给他们的答复。**
|
||||
|
||||
**② W59 工具卡结果区**(`316cd27` → 合并 **`e0bdaa3`** = `origin/android`):
|
||||
- `WsEvent.ToolExecutionEnd` 加可选 `resultSummary`(共用载荷 `ToolExecutionData` 跟着加,**只有 `.end` 的 dispatch 读它**)。
|
||||
- 判据做成纯函数 **`toolResultTextOf(tool)`** 三档:**有值** ⇒ 结果区显示它;**空串/纯空白** ⇒ 视同缺席(不画,防出空块);**缺席** ⇒ **连「结果」标签与它上面那道 Spacer 都不画**(与今天逐字节一致),绝不画「没有输出」这类替作者下结论的文案;缺席但有历史 `output` ⇒ 回落 `output`(老口径不变)。
|
||||
- ⚠️ **没有引入任何 `verticalScroll` / 限高**(沿用参数块那套 `FoldCardBody`)⇒ **结构上不可能重复锚点三十八那次崩溃**。
|
||||
- 14 条新单测(解码 5 + 判据/落卡 9);全量真跑 **114 suites / 1388 tests / 0 failures**。
|
||||
|
||||
**③ 02 里写了「客户端答复」**(收到 + 我们怎么做 + 去重复核结论 + 请他们别为历史那 1 行动手),**未提交** —— 02 仍压着后端的在途改动。
|
||||
|
||||
### 3. 真机验收的边界(如实,别夸大)
|
||||
|
||||
**W59 这一批实际上只有单测证据**,两个独立原因:① 后端 **未部署** ⇒ 真机上 `resultSummary` **恒缺席**,「有值」那档验不了;② 后端**当前没配工具** ⇒ **连工具卡本身都触发不出来**,「缺席时与老版一致」这一半也没有可点的入口。
|
||||
⇒ 等后端部署 + 配了工具,再做真机验收(要造一次真的工具调用)。**在那之前不要把这一批报成「已真机验证」。**
|
||||
Reference in new issue
Block a user