背景
当前项目已经能读取 Codex 本机会话 JSONL,并在浏览器里提供会话列表、阅读/精简/Terminal/Audit/Trace/Raw 视图、按需 Raw event 和外部查询 API。现有解析逻辑主要围绕当前样本中的 session_meta、turn_context、event_msg、response_item 等事件形态展开,并已经对工具调用、子代理、加密 reasoning 摘要状态和大 payload 截断做了处理。
参考 agent-sessions/docs/session-storage-format.md 可以看到,Codex CLI 会话文件本质上是 UTF-8 JSONL 事件流,但不同客户端和版本可能出现字段漂移:事件类型可能来自 type 或 role,消息 ID 可能叫 id / message_id,时间字段可能有多种命名和 epoch 精度,内容可能是字符串、content parts、delta chunk,工具调用和输出字段也可能落在 function.name、arguments、input、stdout、stderr、result、output 等不同位置。图片还可能以 data URI、HTTP(S) URL 或文件引用出现,reasoning 可能只包含 encrypted_content。
如果这些差异继续散落在摘要、turn 聚合、工具识别、Audit、查询 API 和前端渲染中,后续兼容新版 Codex 日志、其他客户端日志或大体积图像事件时会变得脆弱,也难以对外承诺稳定的数据模型。
目标
建设一层明确的“Codex JSONL 事件规范化与兼容契约”,把原始 JSONL 行转换为项目内部稳定事件模型,使 UI、Audit、Trace、Markdown 导出和外部查询 API 尽量面向稳定字段工作,同时完整保留原始事件以便诊断和回溯。
需要建设的能力
1. 规范化事件模型
服务端需要为每条可解析 JSONL 行生成稳定的内部事件字段,至少覆盖事件种类、角色、文本、工具名、工具输入、工具输出、消息 ID、父消息 ID、时间、附件/图片摘要、加密 reasoning 状态和原始事件引用。
规范化模型应保留未知字段和原始 JSON,不要求丢弃现有 payload 结构;目标是让上层视图逐步减少对不同原始字段名的直接判断。
2. 字段漂移兼容
解析层需要吸收常见字段漂移:
- 事件 kind 优先从
type 识别,缺失时可从 role 或嵌套 payload 推断。
- 时间可识别常见时间字段和 ISO 字符串、秒/毫秒/微秒 epoch。
- 文本可从字符串字段、
content parts、text、message、value 等形态提取。
- 工具调用可识别
tool、name、function.name,参数可识别 arguments、input,输出可识别 stdout、stderr、result、output。
function_call / function_result 等兼容类型应映射到稳定工具调用语义。
3. 流式 delta 与工具输出合并
同一 message_id 或等价标识下的 streamed/delta 事件应能在展示层形成连续可读内容。工具调用和工具输出也应尽量按调用 ID 或稳定 fallback 合并,避免同一动作在阅读、Terminal、Audit 中被拆成难以理解的碎片。
4. 图片与附件安全摘要
解析层需要识别 content parts、事件 payload 或附件字段中的图片信息,并产出安全的摘要模型:
- data URI 图片默认懒加载,暴露媒体类型和大小估计,不把大 base64 直接塞进列表、搜索索引或轻量详情。
- HTTP(S) URL、文件 ID 或本地路径默认展示为引用/占位,不自动远程拉取。
- UI 和外部 API 能区分 inline 图片、远程 URL、文件引用和不可识别附件。
5. 加密 reasoning 的边界
encrypted_content 必须作为敏感不透明字段处理:
- 默认不进入全文搜索索引。
- 轻量视图只标记存在、大小和来源事件,不尝试解密或伪造摘要。
- Raw event 仍可按需查看完整原始 JSON,文档说明其敏感性和保留策略。
6. 原始行与错误行保留
JSONL 读取和查询需要能区分“可解析事件”和“不可解析/空行/异常行”的处理结果。对于可解析事件,应能追溯原始 JSON;对于解析失败行,应保留行号、错误类别和安全摘要,方便 Raw 视图提示数据质量问题,而不是静默丢失。
非目标
- 不在本 issue 中重写全部 UI 视图或改变页面信息架构。
- 不要求一次性支持所有历史或第三方日志格式;首版覆盖 Codex CLI 会话文档中列出的常见形态即可。
- 不自动下载远程图片、不解密 reasoning、不把敏感 blob 写入日志或搜索索引。
- 不改变现有
/api/sessions/* 和 /api/query/* 的兼容语义;必要的新字段应以增量方式加入。
- 不要求外部消费者直接依赖本机 JSONL 绝对路径。
验收标准
- 项目中有清晰的规范化事件模型或文档,说明稳定字段、原始事件保留策略和未知字段处理方式。
- 列表、会话详情、Audit/Trace/Raw 或外部查询中的关键路径至少有一层开始使用规范化字段,而不是直接重复判断所有原始字段形态。
- 单元测试覆盖:字段漂移的文本提取、时间识别、工具调用/输出识别、
function_call 兼容映射、message/delta 合并、图片引用摘要、encrypted_content 不进搜索文本。
- 大体积 data URI 不会进入轻量会话列表、默认搜索索引或默认详情 DOM;Raw event 仍可按需查看完整 payload。
- JSONL 中出现无法解析的行时,读取过程不会整体失败,并能在 Raw/诊断模型中暴露行号和错误摘要。
- 现有
npm test 通过,并补充与本能力对应的回归测试。
- README 或专门文档同步说明 Codex 会话 JSONL 的兼容边界、图片处理策略、加密 reasoning 处理策略和原始事件保留策略。
可拆分建设顺序
- 先定义规范化
SessionEvent 契约和纯函数解析入口,并用固定样例测试覆盖字段漂移、时间、文本、工具和 reasoning。
- 将事件摘要、turn 聚合或外部事件查询中的一个关键路径改为消费规范化字段,保持旧 API 兼容。
- 增加图片/附件摘要模型和轻量视图保护,避免 data URI 对列表、搜索和 DOM 造成压力。
- 增加 delta/同消息合并能力,并让阅读或 Terminal/Audit 至少一个视图体现合并结果。
- 补齐 Raw 诊断对解析失败行和原始 JSON 的说明,更新 README/相关文档。
价值
完成后,本项目会从“能读取当前样本”提升为“有明确兼容契约的 Codex 会话解析器”。这能降低新版 Codex 日志字段变化带来的维护成本,让 UI、Audit、Markdown 导出和外部查询 API 共享同一套稳定语义,也能更安全地处理图片、加密 reasoning 和异常 JSONL 行。
背景
当前项目已经能读取 Codex 本机会话 JSONL,并在浏览器里提供会话列表、阅读/精简/Terminal/Audit/Trace/Raw 视图、按需 Raw event 和外部查询 API。现有解析逻辑主要围绕当前样本中的
session_meta、turn_context、event_msg、response_item等事件形态展开,并已经对工具调用、子代理、加密 reasoning 摘要状态和大 payload 截断做了处理。参考
agent-sessions/docs/session-storage-format.md可以看到,Codex CLI 会话文件本质上是 UTF-8 JSONL 事件流,但不同客户端和版本可能出现字段漂移:事件类型可能来自type或role,消息 ID 可能叫id/message_id,时间字段可能有多种命名和 epoch 精度,内容可能是字符串、content parts、delta chunk,工具调用和输出字段也可能落在function.name、arguments、input、stdout、stderr、result、output等不同位置。图片还可能以 data URI、HTTP(S) URL 或文件引用出现,reasoning 可能只包含encrypted_content。如果这些差异继续散落在摘要、turn 聚合、工具识别、Audit、查询 API 和前端渲染中,后续兼容新版 Codex 日志、其他客户端日志或大体积图像事件时会变得脆弱,也难以对外承诺稳定的数据模型。
目标
建设一层明确的“Codex JSONL 事件规范化与兼容契约”,把原始 JSONL 行转换为项目内部稳定事件模型,使 UI、Audit、Trace、Markdown 导出和外部查询 API 尽量面向稳定字段工作,同时完整保留原始事件以便诊断和回溯。
需要建设的能力
1. 规范化事件模型
服务端需要为每条可解析 JSONL 行生成稳定的内部事件字段,至少覆盖事件种类、角色、文本、工具名、工具输入、工具输出、消息 ID、父消息 ID、时间、附件/图片摘要、加密 reasoning 状态和原始事件引用。
规范化模型应保留未知字段和原始 JSON,不要求丢弃现有
payload结构;目标是让上层视图逐步减少对不同原始字段名的直接判断。2. 字段漂移兼容
解析层需要吸收常见字段漂移:
type识别,缺失时可从role或嵌套 payload 推断。contentparts、text、message、value等形态提取。tool、name、function.name,参数可识别arguments、input,输出可识别stdout、stderr、result、output。function_call/function_result等兼容类型应映射到稳定工具调用语义。3. 流式 delta 与工具输出合并
同一
message_id或等价标识下的 streamed/delta 事件应能在展示层形成连续可读内容。工具调用和工具输出也应尽量按调用 ID 或稳定 fallback 合并,避免同一动作在阅读、Terminal、Audit 中被拆成难以理解的碎片。4. 图片与附件安全摘要
解析层需要识别 content parts、事件 payload 或附件字段中的图片信息,并产出安全的摘要模型:
5. 加密 reasoning 的边界
encrypted_content必须作为敏感不透明字段处理:6. 原始行与错误行保留
JSONL 读取和查询需要能区分“可解析事件”和“不可解析/空行/异常行”的处理结果。对于可解析事件,应能追溯原始 JSON;对于解析失败行,应保留行号、错误类别和安全摘要,方便 Raw 视图提示数据质量问题,而不是静默丢失。
非目标
/api/sessions/*和/api/query/*的兼容语义;必要的新字段应以增量方式加入。验收标准
function_call兼容映射、message/delta 合并、图片引用摘要、encrypted_content不进搜索文本。npm test通过,并补充与本能力对应的回归测试。可拆分建设顺序
SessionEvent契约和纯函数解析入口,并用固定样例测试覆盖字段漂移、时间、文本、工具和 reasoning。价值
完成后,本项目会从“能读取当前样本”提升为“有明确兼容契约的 Codex 会话解析器”。这能降低新版 Codex 日志字段变化带来的维护成本,让 UI、Audit、Markdown 导出和外部查询 API 共享同一套稳定语义,也能更安全地处理图片、加密 reasoning 和异常 JSONL 行。