From 9ce0e89e4355b9b4b8604295206f6fc681929bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 4 Sep 2026 17:02:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=20DirectProject=20Codex=20?= =?UTF-8?q?=E5=8E=9F=E5=A7=8B=E5=8E=86=E5=8F=B2=E6=81=A2=E5=A4=8D=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 DirectProject 原始 Responses item 历史格式与异常收尾规则 明确 thread/inject_items 恢复流程及半成品处理边界 不涉及旧格式迁移、DirectHome 或审计账本 --- ...ectProject Codex原始历史与异常恢复-2026-09-04.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md diff --git a/docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md b/docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md new file mode 100644 index 000000000..58f0537b8 --- /dev/null +++ b/docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md @@ -0,0 +1,50 @@ +# DirectProject Codex 原始历史与异常恢复 + +更新时间:`2026-09-04` + +## 目标 + +DirectProject 只使用 `.agent/conversations/project.jsonl` 作为对话历史。历史保存 Codex Responses API 的完整 item,使聊天展示与新线程恢复使用同一份事实来源;两者只是不同读取动作。 + +本方案只适用于 DirectProject,不改变 DirectHome、Agent session 历史或 `runtime/direct-codex/turns` 审计账本。 + +## 文件格式 + +每行采用 Codex CLI rollout 的最小事件外壳,不保存 AGC 自有的顺序号或运行环境字段: + +```json +{"type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"你好"}]}} +``` + +`payload` 必须是未经改写的 Responses item。用户 message 在 `turn/start` 前追加;Codex 返回的 `rawResponseItem/completed.params.item` 原样追加。native 工具、MCP 工具、reasoning、调用参数和调用结果都保留完整内容,不截断、不摘要、不保存 delta/started 事件。 + +DirectProject 不迁移旧 `{role,content}` 行;实现按新格式工作。 + +## 正常回合 + +1. 将本轮用户文本构造成 Responses `message` item 并追加、flush。 +2. 启动 `ephemeral: true` 线程,并启用 `experimentalRawEvents: true`。 +3. 收到 `rawResponseItem/completed` 后立即追加其 `params.item` 并 flush。 +4. 正常 `turn/completed: completed` 不生成额外记录。 + +## 异常回合收尾 + +AGC 判定本轮不会再产生新事件时收尾:用户中断、turn failed、无响应/idle timeout、硬超时、transport closed、stdout EOF 或 app-server 卡死终止均属于异常终态;正常 completed 不收尾。 + +`item/agentMessage/delta` 带有 `itemId`。AGC 在内存中按 `itemId` 累计 assistant 文本,不实时写 delta。异常终态时,对仍有累计文本的 item 合成普通 Responses assistant `message` item: + +```json +{"type":"response_item","payload":{"type":"message","role":"assistant","id":"msg_1","content":[{"type":"output_text","text":"已累计文本"}]}} +``` + +合成 item 在返回错误、销毁连接或启动恢复线程前追加并 flush。没有文本 delta 的半截工具/MCP 调用不合成,等待完整 `rawResponseItem/completed`。 + +## 恢复 + +创建新的 ephemeral thread 后,读取 `project.jsonl` 中所有 `response_item.payload`,按文件行顺序一次调用 `thread/inject_items`,再执行新的 `turn/start`。Codex 负责上下文窗口管理;注入失败直接失败,AGC 不截断、摘要或改写历史。 + +聊天界面只从 message item 提取 user/assistant 内容;工具 item 不再拼成 `tool: ...` 假文本。 + +## 写入与损坏边界 + +写入使用 `write_all + flush`。读取时允许丢弃文件末尾一条不完整 JSON 行;中间坏行直接失败。不会对旧格式做迁移或兼容。