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:
pakrym-oai
2025-09-30 17:21:37 -07:00
committed by GitHub
parent 01e6503672
commit 7fc3edf8a7
5 changed files with 27 additions and 114 deletions

View File

@@ -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 {