修复完整会话历史与长气泡交互并更新 CentOS 7 发布包

提交当前工作区全部源码、回归脚本、任务记录及重新构建的 Bun baseline 发布包。发布单文件 MCP 初始化及前端资源一致性验证通过。
This commit is contained in:
shiyue
2026-10-10 23:40:16 +08:00
parent 747771a048
commit 69b6db0f5b
71 changed files with 9536 additions and 503 deletions

View File

@@ -0,0 +1,32 @@
# 调研记录
## 用户现象
- Codex App 的 ccweb 表单答案在点击发送时,上一轮实际上已经结束,但 UI 仍按运行中消息走插入。
- 失败卡片显示“插入失败”;点击“重试”仍被当成原 turn 插入,无法把答案作为新一轮发送。
## 代码证据
- `handleCcwebPromptUserResponse` 将答案交给 `handleMessage`;若 `activeCodexAppTurns` 仍有条目,`handleMessage` 无条件转入 `handleCodexAppSteerMessage`。
- `handleCodexAppSteerMessage` 已能处理 app-server 返回 `no active turn to steer` 的部分竞态,但 `waitForSteerReady` 超时会直接失败。
- 前端 `retryCodexAppSteerMessage` 在 `!isGenerating || !currentSessionRunning` 时直接报“当前对话已结束,无法在原 turn 中重试插入”,正好阻断用户要求的新 turn 降级。
- 失败项保留 `clientMessageId`,服务端普通 `handleMessage` 可用该 ID 避免重复持久化;前端需要把临时卡片提升为普通用户消息并启动生成态。
## 设计决策
- 运行中的 turn 继续使用 steer;只有本地运行态已结束或 steer 明确确认旧 turn 不存在时,才转普通 `handleMessage` 新开 turn。
- 新 turn 重试沿用原 `clientMessageId`、正文和附件,避免重复消息;转为普通消息后移除失败操作区并提交消息序号。
- 不把 expectedTurnId 不匹配、网络错误或附件失效等真实失败泛化成新 turn。
## 基线验证
- `node scripts/failed-insert-card-unit.js` 当前通过,但现有断言明确要求 turn 结束后禁止重试,正是需要改掉的旧行为。
- `node scripts/regression.js --target codexapp-stale-running` 当前通过,覆盖了 `no active turn to steer` 的旧 turn 替换;尚未覆盖 `waitForSteerReady` 超时和前端失败卡片转普通新 turn。
- `node --check server.js && node --check public/app.js` 当前通过。
## 实现与回归发现
- 本机 app-server 二进制包含带 expectedTurnId 的无活动 turn 文案,原先只匹配 `no active turn to steer` 的恢复条件不足。
- `turn/completed` 可以先于 steer 错误到达;恢复需要允许本地 entry 已清除,并把旧轮助手消息放回新用户消息之前。
- 已补充普通文字、完成先到、表单答案的端到端回归;截至本阶段均通过。
- 前端仍需等待明确发送成功回执后提交临时消息,并通过稳定消息 ID 合并普通 `session_message`,才能同时避免永久 pending 和重复气泡。

View File

@@ -0,0 +1,14 @@
# 进度记录
## 2026-10-10
- 已确认 codebase-memory 项目 `home-cc-web` 索引可用。
- 已定位前端 `retryCodexAppSteerMessage` 的结束会话拦截,以及后端 `handleCodexAppSteerMessage` 的 ready 超时失败分支。
- 工作区包含其他未提交的会话历史改动,本任务将只修改插入/重试相关代码和回归测试。
- 基线定向回归和语法检查均通过;现有前端单测中的“turn 已结束时不能重试”断言与用户需求相反,下一步先改为新 turn 重试回归。
- 已修复无活动 turn 文案识别、完成先到后的旧输出顺序和自动续发,增加对应 mock、表单答案与竞态回归。
- 最新定向回归:`timeout 60s node scripts/regression.js --target codexapp-stale-running` 通过。
- 正在完善前端重试回执、普通消息合并及失败后的再次重试;此前乐观提交不应作为最终成功依据。
- 已完成 `waitForSteerReady` 的 replaced/timeout 分支、entry 已清理时的直接重分发、完成先到竞态的历史重排,以及前端重试按新 turn 发送与 sent 回执提交。
- 已复核关键差异:`reorderStaleCodexAppTurnMessages` 的 messageIndex 推送、`completeCodexAppSteerMessage` 的索引提交、`updateCodexAppSteerMessage` 返回值调用方,均符合预期。
- 部署状态:重启前检查到除当前对话外仍有 2 个 running 会话(`826deaa0`、`2f1134fe`),按 AGENTS.md 暂缓重启,等其结束后再执行 `pm2 restart ccweb --update-env`。

View File

@@ -0,0 +1,40 @@
# 会话结束后插入转新对话计划
## 目标
当 Codex App 的上一轮已经结束、但页面或服务端仍把本轮视为可插入时,表单答案和普通跟进消息都应自动按新一轮对话处理;失败卡片点击“重试”也应真正发送,不能继续被“仅允许插入原 turn”拦截。
## 阶段
1. [completed] 复现并定位会话结束后的发送与失败重试链路
2. [completed] 补充结束会话后重试自动新开对话的回归用例
3. [completed] 修复前端失败项重试与后端旧轮结束竞态
4. [completed] 运行定向测试、语法检查和完整回归
5. [completed] 复核差异并清理临时跟踪文件
## 验收标准
- 会话结束后点击失败卡片的“重试”会启动普通新 turn,答案只进入一次历史。
- 发送时本地运行态落后于 app-server 时,不再把用户答案永久留在“插入失败”。
- 仍在运行的 turn 继续走 `turn/steer`,expectedTurnId 不匹配等真实错误不被错误降级。
- 普通文本和带附件的表单答案均有回归覆盖,且定向测试、语法检查和完整回归通过。
## 约束
- 保留工作区中其他会话历史改动,不覆盖现有任务目录或 CSV。
- 代码定位优先使用 `codebase-memory-mcp`;FastCtx 只用于读取、编辑和验证本地文件。
- 不重启服务,除非重启前确认除当前会话外没有其他 `running` 会话。
- 新增注释和文档使用简体中文。
## 错误记录
| 错误 | 尝试 | 处理 |
|---|---:|---|
| 表单回归读取到旧轮 done,导致提前检查新输出 | 1 | 等待携带新答案助手消息的 done 后再验收历史 |
## 收尾记录
- 完整回归 `npm run regression` exit 0;定向回归与三个单测脚本、语法检查全部通过。
- 独立后端审查新增 `scripts/codexapp-steer-recovery-unit.js`(5 项通过),覆盖 ready 等待期间旧轮结束、completion 先到、保存失败与错误分类。
- 部署:重启前检查到除当前对话外仍有 running 会话(`826deaa0`、`2f1134fe`),按约束暂缓重启;待其结束后执行 `pm2 restart ccweb --update-env` 生效。
- 临时跟踪文件:本任务 CSV 已按 todo-list-csv 流程清理。