This page documents the event processing architecture in exec mode (codex exec), the headless, non-interactive variant of Codex CLI. Exec mode processes agent events via the EventProcessor trait, which has two implementations: EventProcessorWithHumanOutput for human-readable terminal output and EventProcessorWithJsonOutput for structured JSONL output suitable for automation.
For the overall exec mode architecture and CLI arguments, see Headless Execution Mode. For the interactive TUI event processing, see ChatWidget and Conversation Display.
The EventProcessor trait defines a common interface for consuming agent events and rendering them to the terminal. The trait abstraction allows exec mode to support multiple output formats without duplicating the core event loop logic.
Sources: codex-rs/exec/src/event_processor.rs1-46 codex-rs/exec/src/lib.rs316-323
| Method | Purpose | Return Value |
|---|---|---|
print_config_summary() | Emits session configuration summary and echoes initial user prompt | () |
process_event() | Handles a single Event from the agent | CodexStatus enum (Running/InitiateShutdown/Shutdown) |
print_final_output() | Optional post-processing after event loop completes | () |
The CodexStatus enum controls the event loop lifecycle:
Sources: codex-rs/exec/src/event_processor.rs7-11
The main event loop in run_main() instantiates the appropriate processor implementation based on the --json CLI flag, then drives the event loop until shutdown is signaled.
Sources: codex-rs/exec/src/lib.rs91-431 codex-rs/exec/src/lib.rs452-652
In exec mode, approval requests are automatically resolved based on configured policies. The loop detects ExecApprovalRequestEvent, ApplyPatchApprovalRequestEvent, and ElicitationRequestEvent, then submits the corresponding approval operations (ExecApproval, PatchApproval, ResolveElicitation) with a predetermined decision.
Sources: codex-rs/exec/src/lib.rs561-633
EventProcessorWithHumanOutput renders agent events to stderr with optional ANSI color codes for improved readability. It tracks execution state (patch applications, MCP calls) and formats output with semantic styling.
Sources: codex-rs/exec/src/event_processor_with_human_output.rs56-79
The process_event() implementation matches on EventMsg variants and emits formatted output. Key event types:
| Event Type | Output Behavior | Example |
|---|---|---|
AgentMessage | Prints message text to stderr, accumulates to final_message | Agent response content |
ExecCommandBegin | Prints command with $ prefix styled in cyan | $ ls -la |
ExecCommandEnd | Prints exit status, optionally truncates output to 20 lines | [exit: 0] (1.2s) |
PatchApplyBegin | Records start time, prints file path | Applying patch to src/main.rs |
PatchApplyEnd | Prints success/failure with duration | ✓ Applied patch (0.3s) |
TurnComplete | Writes final message to --last-message-file, prints token usage | [tokens: 1,234] |
Error | Prints error with red "ERROR:" prefix | ERROR: API request failed |
Warning | Prints warning with bold yellow prefix | warning: config deprecated |
Sources: codex-rs/exec/src/event_processor_with_human_output.rs141-529
Exec command output is capped at MAX_OUTPUT_LINES_FOR_EXEC_TOOL_CALL = 20 lines to prevent overwhelming the terminal. If output exceeds this threshold, a warning is printed:
[... 15 more lines omitted; set MAX_OUTPUT_LINES_FOR_EXEC_TOOL_CALL higher to see full transcript]
Sources: codex-rs/exec/src/event_processor_with_human_output.rs55 codex-rs/exec/src/event_processor_with_human_output.rs278-290
Styles are conditionally created based on the --color flag, which determines stdout_with_ansi and stderr_with_ansi booleans. When color is disabled, all Style fields default to Style::new() (no-op).
Sources: codex-rs/exec/src/event_processor_with_human_output.rs82-126 codex-rs/exec/src/lib.rs118-125
EventProcessorWithJsonOutput serializes each Event to a single-line JSON object and writes it to stdout. This format enables programmatic consumption by CI systems, automation scripts, or downstream analysis tools.
Each line is a JSON object containing:
Event structure (id, msg)Example output:
Sources: codex-rs/exec/src/event_processor_with_jsonl_output.rs (file not shown in context, but referenced in trait implementation)
In --json mode:
This separation ensures stdout contains only parseable JSON, critical for piping exec output to tools like jq.
Sources: codex-rs/exec/src/lib.rs4-5 codex-rs/exec/src/event_processor_with_jsonl_output.rs
Exec mode returns process exit codes to signal success, failure, or specific error conditions. The exit code is determined by the final CodexStatus and whether errors occurred during the session.
| Exit Code | Meaning | Trigger Condition |
|---|---|---|
0 | Success | Turn completed without errors, no ErrorEvent messages emitted |
1 | Error | Agent encountered an error, or config/policy violation occurred |
130 | Interrupted | User sent SIGINT (Ctrl+C) before turn completed |
Sources: codex-rs/exec/src/lib.rs643-652 (implied from event loop logic)
When --last-message-file PATH is specified, the final agent message is written to the specified file path. This enables automation scripts to extract the final response without parsing the full event stream.
Sources: codex-rs/exec/src/event_processor.rs28-45 codex-rs/exec/src/event_processor_with_human_output.rs75-77
Exec mode supports resuming previous sessions and running code reviews via specialized CLI commands that map to different InitialOperation types.
The codex exec resume [SESSION_ID] command reconstructs a session from a rollout file and continues execution:
Sources: codex-rs/exec/src/lib.rs433-450 codex-rs/exec/src/cli.rs (command definition)
The codex review command (or codex exec review) initiates a code review session with specialized prompts:
The operation is translated to Op::Review and submitted to the thread.
Sources: codex-rs/exec/src/lib.rs74-82 codex-rs/exec/src/cli.rs (ReviewArgs struct)
Event processors handle errors at multiple levels:
ErrorEvent messages are captured and printed immediately. The processor tracks whether any errors occurred to determine the final exit code.
Sources: codex-rs/exec/src/event_processor_with_human_output.rs180-183
StreamErrorEvent indicates a protocol-level failure (e.g., WebSocket disconnect, SSE parsing error). These are terminal and trigger immediate shutdown.
Sources: codex-rs/exec/src/event_processor_with_human_output.rs443-448
Configuration validation and exec policy errors are caught during initialization and result in early exit with code 1, emitting a human-readable error message to stderr.
Sources: codex-rs/exec/src/lib.rs274-283
| Entity | File | Purpose |
|---|---|---|
EventProcessor | event_processor.rs13-26 | Trait defining event consumption interface |
CodexStatus | event_processor.rs7-11 | Event loop state machine enum |
EventProcessorWithHumanOutput | event_processor_with_human_output.rs56-79 | Human-readable output implementation |
EventProcessorWithJsonOutput | event_processor_with_jsonl_output.rs | JSONL output implementation |
run_main() | lib.rs91-652 | Main entry point and event loop driver |
InitialOperation | lib.rs74-82 | Discriminator for UserTurn vs Review |
MAX_OUTPUT_LINES_FOR_EXEC_TOOL_CALL | event_processor_with_human_output.rs55 | Output truncation threshold |
Sources: codex-rs/exec/src/event_processor.rs1-46 codex-rs/exec/src/event_processor_with_human_output.rs1-529 codex-rs/exec/src/lib.rs1-652
Refresh this wiki