316cd2704981ec2432f73ac015bb180f3e31e708
后端新契约切片给 `tool_execution.end` 的 `data` 补了一个**可选** `resultSummary` (与回看面 `toolCalls[].resultSummary` 同一份预算:已脱敏、已截断 ≤500 字符)。 它的语义是「拿到就带、没拿到就缺席」——失败 / 取消 / 超时 / 未落图时**整个键缺席**, 且契约明说**别把缺席读成「没有输出」**。在那之前工具卡只能显示工具名与状态。 改了什么: - wire:`WsEvent.ToolExecutionEnd` 新增 `resultSummary: String? = null`;共用的 `ToolExecutionData` 跟着加这个字段(只由 `.end` 读,`.start` / `.update` 的领域事件 仍然没有它)。缺键 ⇒ `null`,空串 ⇒ `""`,都在解码层照原样保留、不编结论。 - 领域:`ToolCallState` 新增 `resultSummary`;`applyToolExecution` 多一个同参数 (非空白时顶替、缺席 / 空白时保留原值——三帧里只有 `.end` 带它,一次落不到不该抹掉旧的); VM 的 `onToolExecution` 与 `ToolExecutionEnd` 分支透传。 - 判据:新增纯函数 `toolResultTextOf(tool)`:摘要非空白 ⇒ 用它;否则回落 `output` (今天唯一的来源,口径不变);两者都没有 ⇒ `null`。 - UI:`ToolCard` 折叠区里「结果」那一块(参数之后)改由 `toolResultTextOf` 决定要不要画。 `null` 时**连标签与它上方那道 Spacer 都不画** ⇒ 摘要缺席时这一屏与后端补这个键之前 逐字节相同。空串同理(服务端承诺不发空串,但真发了也绝不渲染出一个空的结果区块)。 摘要只展示:不再截断第二次、不解析、不当 markdown;正文沿用与参数同一个 `FoldCardBody` (`SelectionContainer` + 不设 `maxLines`),长文本整段可见,没有新增任何滚动 / 限高 modifier。 为什么这么做:一句话的判据、纯函数、单测可钉;渲染层只做「画 / 不画」这一个决定, 于是「老服务端(键恒缺席)」与「新服务端(键在场)」共用同一套 UI,不用等部署。 测试:新增 14 条(`WsEventToolExecutionTest` +5、`ToolExecutionCorrelationTest` +9), 覆盖 ①键在场 ⇒ 解出该值(含 500 字符原样透传)②键缺席 ⇒ `null` 且不报错 ③空串 ⇒ 解出 `""` 且判据按「不画」处理 ④`toolResultTextOf` 在缺席 / 空串 / 有值三档下的输出 (含摘要优先于 `output`、结果落卡、缺席不抹旧值、落不到卡时不影响任何卡)。 `assembleDebug` 通过;全量单测 114 suites / 1388 tests / 0 failures / 0 errors(基线 1374)。
Releases
5
Alpha_v0.1.0_4
Latest