Skip to content

fix(codex): parse the new rollout schema (item_completed) from Codex ≥ ~0.149 - #170

Open
DaeYounLee wants to merge 1 commit into
graykode:mainfrom
DaeYounLee:fix/codex-item-completed-schema
Open

fix(codex): parse the new rollout schema (item_completed) from Codex ≥ ~0.149#170
DaeYounLee wants to merge 1 commit into
graykode:mainfrom
DaeYounLee:fix/codex-item-completed-schema

Conversation

@DaeYounLee

Copy link
Copy Markdown

Problem

Recent Codex CLI versions (observed on v0.149) changed the rollout session format. Sessions recorded by these versions show up in abtop with:

  • empty chat, no tool timeline, no turn count
  • status stuck on Waiting even while the model is actively working
  • initial_prompt never populated, so the session summary stays

Root cause

The codex collector matches the old event vocabulary (event_msguser_message / agent_message / task_complete, response_itemfunction_call). New rollouts no longer emit any of those — everything arrives as event_msg with payload.type == "item_completed", wrapping a typed item:

{"type":"event_msg","payload":{"type":"item_completed","item":{
  "type":"AgentMessage","content":[{"type":"Text","text":""}],"phase":"final_answer"},
  "started_at_ms":1787291153283,"completed_at_ms":1787291154027}}

{"type":"event_msg","payload":{"type":"item_completed","item":{
  "type":"CommandExecution","command":["/bin/zsh","-lc","sed -n '1,240p' README.md"],
  "parsed_cmd":[{"type":"read","cmd":"sed -n '1,240p' README.md","path":"/work/README.md"}],
  "started_at_ms":1787291167583,"completed_at_ms":1787291168442}}

{"type":"event_msg","payload":{"type":"item_completed","item":{
  "type":"FileChange","changes":{"/work/report.md":{"type":"add"}}}}}

(Synthetic samples; field shapes match real rollouts. Note the inconsistent casing — "Text" on AgentMessage content vs "text" on UserMessage.)

Changes

One new arm in the event_msg match plus a handle_item_completed() helper:

item type handled as
UserMessage chat (User role), initial_prompt, marks model generating
AgentMessage chat (Assistant role), turn count, clears generating state
CommandExecution tool call — name from parsed_cmd[0].type (read/write/…), real duration from started_at_ms/completed_at_ms; file accesses from parsed_cmd[].path
FileChange file accesses (add → Write, else Edit) plus an edit tool-call entry
Extension tool call named by kind (e.g. web.search) with its query

Two small state fixes for the new schema: task_started now marks the model as generating (there is no user_message event anymore to do it), and turn_aborted clears it.

Side effect worth calling out: codex sessions gain file_accesses — the old schema never carried file information, so AgentSession.file_accesses was always empty for codex. FileChange and parsed_cmd now populate it, capped at MAX_FILE_ACCESSES like the claude collector.

Existing text hygiene is reused: chat goes through clean_chat_text, tool args through sanitize_tool_arg, MAX_CHAT_MESSAGES still applies.

Relation to #160 / #161

Complementary, not overlapping: #161 targets the previous generation (Codex 0.144.x — custom_tool_call in response_item, intermediate agent_message events), while this PR targets the item_completed vocabulary that replaced it. One coordination note: 0.149 rollouts still write custom_tool_call alongside item_completed.CommandExecution for the same call — this PR reads only the latter, so nothing double-counts today, but if both PRs land it would be worth deduplicating by call_id in a follow-up.

Backward compatibility

The old-schema arms are untouched and the two vocabularies never coexist in one file, so rollouts from older Codex versions parse exactly as before. All existing tests pass unchanged.

Testing

  • 4 new unit tests: chat from both content casings + turn counting, trailing-UserMessage generating state, CommandExecution tool call with real duration + file access from parsed_cmd, FileChange → Write/Edit accesses
  • cargo test — 204 passed, 0 failed; cargo clippy --all-targets -- -D warnings clean
  • Verified against live Codex 0.149 sessions: a session that previously showed 0 chat / 0 tools / 0 files and a stuck Waiting status now reports 21 chat messages, 18 tool calls, 13 file accesses, 11 turns, correct status

…≥ ~0.149

Recent Codex CLI versions replaced the user_message / agent_message /
function_call vocabulary with item_completed wrappers, leaving sessions
with empty chat, no tool timeline, no turn count and a status stuck on
Waiting. Handle the new item types — UserMessage/AgentMessage for chat,
CommandExecution (with real durations) and Extension for the tool
timeline, FileChange for file accesses, which the old schema never
carried at all — and adjust generating-state transitions via
task_started/turn_aborted. Old-schema parsing is untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant