Files
shiyue 69b6db0f5b 修复完整会话历史与长气泡交互并更新 CentOS 7 发布包
提交当前工作区全部源码、回归脚本、任务记录及重新构建的 Bun baseline 发布包。发布单文件 MCP 初始化及前端资源一致性验证通过。
2026-10-10 23:40:16 +08:00

62 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 运行中气泡续接独立审查
## 审查结论
服务端续接、完整运行态保存、取消门禁及前端折叠/复制通过。本次发现 3 项 P2 均已修复并通过原函数回归;当前没有未解决的 P1/P2,审查通过。
审查服务端基线为 `/tmp/ccweb-streaming-retry-server-before.js`,仅核对本任务新增差异;未把上一任务完整历史归档改动重复归入本任务。
## 发现及处理
| 级别 | 问题与触发条件 | 位置 | 当前状态 |
| --- | --- | --- | --- |
| P2 | A 的 `turn/start` 已发出但原生 ID 未知时取消,旧 entry 曾被释放;此时开始同线程 B,A 的 `turn/started` 先于 A RPC 回包到达,会按 thread 匹配到 B,旧通知能够写入或结束 B。 | `server.js` 的 `findCodexAppEntryByRuntime`、`startCodexAppTurn`、`handleCodexAppAbortSession` | 已修。未知 ID 取消保留门禁,通知/RPC 确认身份后只中断精确旧回合;RPC 超时仍保留门禁,app-server 明确退出后提交旧正文并释放。 |
| P2 | 重连可显示完整 105/130 条工具,但完成或历史读取仍经 40 条工具上限,变成 40 条记录加省略标记;`done` 重建气泡会再次缩短工具列表、输入及结果。 | `server.js:5796` 的 `sanitizeMessageForTransport`;`public/app.js:9237` 的完成气泡重建 | 已修。完成/历史单消息读取保留完整 `toolCalls`,实时 `tool_start`/`tool_end` 预览上限保留。 |
| P2 | 单条回复超过折叠阈值且包含多个自然段时,默认 `.assistant-single-collapsed` 以 420px 高度裁剪正文。点击“定位”仍直接选择末文本段并滚动,没有展开,目标段落继续被 `overflow:hidden` 隐藏。 | `public/app.js:2468` 的 `scrollAssistantBubbleToLastSection`;`public/style.css` 的 `.assistant-single-collapsed .assistant-reply-content` | 已修。定位前点击已有展开控件,同步展开状态后再计算末段坐标;原函数测试验证展开先于定位,多原生段气泡保持原收起状态。 |
## 失败证据与修复验证
取消竞态先用真实路由/退休函数 VM 验证:退休 `turnId:null` 的取消 entry 后,建立同线程 `turnId:null` 的 B,路由旧 A 通知得到 `{ retired: 0, routedToNewEntry: true }`。
新增真实开轮/路由/通知回归在修复前失败于“旧 A 身份未知时必须阻止同线程 B 开始”,实际 `beforeIdentity.ok=true`。工具完整读取断言在修复前失败于 130 条工具不能按预览上限替代完整列表。两项修复后均转绿。
取消回归执行真实 `startCodexAppTurn`、`handleMessage`、`findCodexAppEntryByRuntime`、`findCodexAppRouteByRuntime`、`adoptCodexAppUnroutedTurn`、`handleCodexAppNotification`、`handleCodexAppAbortSession`、`handleCodexAppServerExit` 和完成保存函数;仅模型 RPC、时钟及无关配置/生命周期回调由隔离夹具替代。覆盖:
- A 通知先于 A RPC 返回,未知身份时禁止 B 开轮;身份确认后中断 A,再开始 B;A 的迟到完成不能结束 B,B 的正文只归档一次且前后文完整。
- A RPC 超时后仍保留未知身份门禁;晚到 ID 通知触发精确 A 中断,随后 B 正常完成。
- A 取消且 ID 未知时 app-server 明确退出,先保存 A 既有完整前文,再释放 B 门禁;B 完整完成。
## 最终执行结果
所有单元/专项命令使用 60 秒上限,存储测试使用 `/dev/shm` 隔离临时目录。此前普通 `/tmp` 存储专项达到 60 秒上限;改用 `/dev/shm` 后完整专项约 12 秒通过,无需放宽超时。
| 命令 | 结果 | 退出码 |
| --- | --- | --- |
| `TMPDIR=/dev/shm timeout 60 node scripts/codexapp-retry-history-unit.js` | 21/21,含真实 mock 协议三轮续接 | 0 |
| `TMPDIR=/dev/shm timeout 60 node scripts/history-runtime-unit.js` | 13/13,完整 130 条工具及 24006 字输入、48006 字结果读回;实时预览仍有界 | 0 |
| `timeout 60 node scripts/assistant-bubble-controls-unit.js` | 最终 8/8,末原生段、多自然段/代码、Markdown 空白语义、围栏及未完整分界不误复制,单条长回复定位先展开 | 0 |
| `timeout 60 node scripts/streaming-retry-frontend-unit.js` | 5/5,多次续接、刷新/重连/切换、完成与保存失败气泡 | 0 |
| 两个所改测试文件 `node --check`、限定文件 `git diff --check` | 通过 | 0 |
## 验证版本
| 文件 | SHA-256 |
| --- | --- |
| `scripts/codexapp-retry-history-unit.js` | `8ff35d8e3722fec5fd2ba8fac5ffac94b69e711f5bcddf2150bc10c865e73b54` |
| `scripts/history-runtime-unit.js` | `0e1e549f2ece5337eb7808f235b6cadc4ec9192c7cf9561a77b71eca66c35ae4` |
| `server.js` | `c964060ad121bf16edd44caf94226455cf8a434bb8b14b9f5c434a3215d6b404` |
| `lib/codex-app-runtime.js` | `6fe66921ed8998ed1b1478eb804c0ad965ff40fff7a18dd8086e3de42b67c122` |
| `public/app.js` | `433b4e68a9e91440eada679199a86ca7a84cf28b0f979eb3f46044be99fe757e` |
| `scripts/assistant-bubble-controls-unit.js` | `f60bb8c1c393503c461885fd2ee7ef7636dacd2a94c3654ddcac470dc449ca63` |
## 验证边界
- 本代理只修改上述两个测试文件及本报告,不修改实现、真实会话、原生 rollout、生产服务或其他任务 CSV。
- 本代理没有执行全量回归或真实浏览器验收;主代理执行全量回归。前端代理已完成正式浏览器验收,退出码 0,证据在 `/dev/shm/ccweb-streaming-retry-browser-G8wkN6`,本代理只读核对报告与实现。
- 原函数/隔离 mock 回归证明修复实现,不证明生产已部署或目标会话旧前文已补回 UI。
- 完整正文用于复制;折叠仅控制 DOM 可见性。原生段复制包含该段原始 Markdown、多自然段及代码,不含工具、分隔时间或按钮。
## 工具调用简报
本地使用 FastCtx 读取任务契约、当前源码及基线差异,执行隔离回归;codebase-memory 起初索引 ready 且成功定位函数,之后 snippet 返回索引不可用,降级到精确本地源码读取。没有对外发送会话内容。