Remove legacy codex exec --json format (#4525)
`codex exec --json` now maps to the behavior of `codex exec
--experimental-json` with new event and item shapes.
Thread events:
- thread.started
- turn.started
- turn.completed
- turn.failed
- item.started
- item.updated
- item.completed
Item types:
- assistant_message
- reasoning
- command_execution
- file_change
- mcp_tool_call
- web_search
- todo_list
- error
Sample output:
<details>
`codex exec "list my assigned github issues" --json | jq`
```
{
"type": "thread.started",
"thread_id": "01999ce5-f229-7661-8570-53312bd47ea3"
}
{
"type": "turn.started"
}
{
"type": "item.completed",
"item": {
"id": "item_0",
"item_type": "reasoning",
"text": "**Planning to list assigned GitHub issues**"
}
}
{
"type": "item.started",
"item": {
"id": "item_1",
"item_type": "mcp_tool_call",
"server": "github",
"tool": "search_issues",
"status": "in_progress"
}
}
{
"type": "item.completed",
"item": {
"id": "item_1",
"item_type": "mcp_tool_call",
"server": "github",
"tool": "search_issues",
"status": "completed"
}
}
{
"type": "item.completed",
"item": {
"id": "item_2",
"item_type": "reasoning",
"text": "**Organizing final message structure**"
}
}
{
"type": "item.completed",
"item": {
"id": "item_3",
"item_type": "assistant_message",
"text": "**Assigned Issues**\n- openai/codex#3267 – “stream error: stream disconnected before completion…” (bug) – last update 2025-09-08\n- openai/codex#3257 – “You've hit your usage limit. Try again in 4 days 20 hours 9 minutes.” – last update 2025-09-23\n- openai/codex#3054 – “reqwest SSL panic (library has no ciphers)” (bug) – last update 2025-09-03\n- openai/codex#3051 – “thread 'main' panicked at linux-sandbox/src/linux_run_main.rs:53:5:” (bug) – last update 2025-09-10\n- openai/codex#3004 – “Auto-compact when approaching context limit” (enhancement) – last update 2025-09-26\n- openai/codex#2916 – “Feature request: Add OpenAI service tier support for cost optimization” – last update 2025-09-12\n- openai/codex#1581 – “stream error: stream disconnected before completion: stream closed before response.complete; retrying...” (bug) – last update 2025-09-17"
}
}
{
"type": "turn.completed",
"usage": {
"input_tokens": 34785,
"cached_input_tokens": 12544,
"output_tokens": 560
}
}
```
</details>
This commit is contained in:
@@ -13,6 +13,7 @@ use codex_core::protocol::PatchApplyBeginEvent;
|
||||
use codex_core::protocol::PatchApplyEndEvent;
|
||||
use codex_core::protocol::SessionConfiguredEvent;
|
||||
use codex_core::protocol::WebSearchEndEvent;
|
||||
use codex_exec::event_processor_with_jsonl_output::EventProcessorWithJsonOutput;
|
||||
use codex_exec::exec_events::AssistantMessageItem;
|
||||
use codex_exec::exec_events::CommandExecutionItem;
|
||||
use codex_exec::exec_events::CommandExecutionStatus;
|
||||
@@ -36,7 +37,6 @@ use codex_exec::exec_events::TurnFailedEvent;
|
||||
use codex_exec::exec_events::TurnStartedEvent;
|
||||
use codex_exec::exec_events::Usage;
|
||||
use codex_exec::exec_events::WebSearchItem;
|
||||
use codex_exec::experimental_event_processor_with_json_output::ExperimentalEventProcessorWithJsonOutput;
|
||||
use mcp_types::CallToolResult;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::path::PathBuf;
|
||||
@@ -51,7 +51,7 @@ fn event(id: &str, msg: EventMsg) -> Event {
|
||||
|
||||
#[test]
|
||||
fn session_configured_produces_thread_started_event() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let session_id = codex_protocol::mcp_protocol::ConversationId::from_string(
|
||||
"67e55044-10b1-426f-9247-bb680e5fe0c8",
|
||||
)
|
||||
@@ -80,7 +80,7 @@ fn session_configured_produces_thread_started_event() {
|
||||
|
||||
#[test]
|
||||
fn task_started_produces_turn_started_event() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let out = ep.collect_thread_events(&event(
|
||||
"t1",
|
||||
EventMsg::TaskStarted(codex_core::protocol::TaskStartedEvent {
|
||||
@@ -93,7 +93,7 @@ fn task_started_produces_turn_started_event() {
|
||||
|
||||
#[test]
|
||||
fn web_search_end_emits_item_completed() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let query = "rust async await".to_string();
|
||||
let out = ep.collect_thread_events(&event(
|
||||
"w1",
|
||||
@@ -120,7 +120,7 @@ fn plan_update_emits_todo_list_started_updated_and_completed() {
|
||||
use codex_core::plan_tool::StepStatus;
|
||||
use codex_core::plan_tool::UpdatePlanArgs;
|
||||
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// First plan update => item.started (todo_list)
|
||||
let first = event(
|
||||
@@ -237,7 +237,7 @@ fn plan_update_emits_todo_list_started_updated_and_completed() {
|
||||
|
||||
#[test]
|
||||
fn mcp_tool_call_begin_and_end_emit_item_events() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let invocation = McpInvocation {
|
||||
server: "server_a".to_string(),
|
||||
tool: "tool_x".to_string(),
|
||||
@@ -297,7 +297,7 @@ fn mcp_tool_call_begin_and_end_emit_item_events() {
|
||||
|
||||
#[test]
|
||||
fn mcp_tool_call_failure_sets_failed_status() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let invocation = McpInvocation {
|
||||
server: "server_b".to_string(),
|
||||
tool: "tool_y".to_string(),
|
||||
@@ -344,7 +344,7 @@ fn plan_update_after_complete_starts_new_todo_list_with_new_id() {
|
||||
use codex_core::plan_tool::StepStatus;
|
||||
use codex_core::plan_tool::UpdatePlanArgs;
|
||||
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// First turn: start + complete
|
||||
let start = event(
|
||||
@@ -389,7 +389,7 @@ fn plan_update_after_complete_starts_new_todo_list_with_new_id() {
|
||||
|
||||
#[test]
|
||||
fn agent_reasoning_produces_item_completed_reasoning() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let ev = event(
|
||||
"e1",
|
||||
EventMsg::AgentReasoning(AgentReasoningEvent {
|
||||
@@ -412,7 +412,7 @@ fn agent_reasoning_produces_item_completed_reasoning() {
|
||||
|
||||
#[test]
|
||||
fn agent_message_produces_item_completed_assistant_message() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let ev = event(
|
||||
"e1",
|
||||
EventMsg::AgentMessage(AgentMessageEvent {
|
||||
@@ -435,7 +435,7 @@ fn agent_message_produces_item_completed_assistant_message() {
|
||||
|
||||
#[test]
|
||||
fn error_event_produces_error() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let out = ep.collect_thread_events(&event(
|
||||
"e1",
|
||||
EventMsg::Error(codex_core::protocol::ErrorEvent {
|
||||
@@ -452,7 +452,7 @@ fn error_event_produces_error() {
|
||||
|
||||
#[test]
|
||||
fn stream_error_event_produces_error() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
let out = ep.collect_thread_events(&event(
|
||||
"e1",
|
||||
EventMsg::StreamError(codex_core::protocol::StreamErrorEvent {
|
||||
@@ -469,7 +469,7 @@ fn stream_error_event_produces_error() {
|
||||
|
||||
#[test]
|
||||
fn error_followed_by_task_complete_produces_turn_failed() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
let error_event = event(
|
||||
"e1",
|
||||
@@ -502,7 +502,7 @@ fn error_followed_by_task_complete_produces_turn_failed() {
|
||||
|
||||
#[test]
|
||||
fn exec_command_end_success_produces_completed_command_item() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// Begin -> no output
|
||||
let begin = event(
|
||||
@@ -562,7 +562,7 @@ fn exec_command_end_success_produces_completed_command_item() {
|
||||
|
||||
#[test]
|
||||
fn exec_command_end_failure_produces_failed_command_item() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// Begin -> no output
|
||||
let begin = event(
|
||||
@@ -621,7 +621,7 @@ fn exec_command_end_failure_produces_failed_command_item() {
|
||||
|
||||
#[test]
|
||||
fn exec_command_end_without_begin_is_ignored() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// End event arrives without a prior Begin; should produce no thread events.
|
||||
let end_only = event(
|
||||
@@ -642,7 +642,7 @@ fn exec_command_end_without_begin_is_ignored() {
|
||||
|
||||
#[test]
|
||||
fn patch_apply_success_produces_item_completed_patchapply() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// Prepare a patch with multiple kinds of changes
|
||||
let mut changes = std::collections::HashMap::new();
|
||||
@@ -724,7 +724,7 @@ fn patch_apply_success_produces_item_completed_patchapply() {
|
||||
|
||||
#[test]
|
||||
fn patch_apply_failure_produces_item_completed_patchapply_failed() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
let mut changes = std::collections::HashMap::new();
|
||||
changes.insert(
|
||||
@@ -778,7 +778,7 @@ fn patch_apply_failure_produces_item_completed_patchapply_failed() {
|
||||
|
||||
#[test]
|
||||
fn task_complete_produces_turn_completed_with_usage() {
|
||||
let mut ep = ExperimentalEventProcessorWithJsonOutput::new(None);
|
||||
let mut ep = EventProcessorWithJsonOutput::new(None);
|
||||
|
||||
// First, feed a TokenCount event with known totals.
|
||||
let usage = codex_core::protocol::TokenUsage {
|
||||
|
||||
Reference in New Issue
Block a user