From 792478ef87080eb7175dd4e54ed56030c512d47b Mon Sep 17 00:00:00 2001 From: Charles Cunningham Date: Fri, 6 Mar 2026 00:08:31 -0800 Subject: [PATCH] codex: keep response metadata out of app-server schema Mark response metadata as internal-only for schema export and strip it from app-server notifications while keeping rollout persistence intact. Co-authored-by: Codex --- .../schema/json/EventMsg.json | 60 ------------------- .../codex_app_server_protocol.schemas.json | 30 ---------- .../codex_app_server_protocol.v2.schemas.json | 30 ---------- .../schema/typescript/EventMsg.ts | 3 +- .../typescript/ResponseMetadataEvent.ts | 5 -- .../schema/typescript/index.ts | 1 - .../app-server/src/codex_message_processor.rs | 26 ++++++-- codex-rs/protocol/src/protocol.rs | 2 + 8 files changed, 24 insertions(+), 133 deletions(-) delete mode 100644 codex-rs/app-server-protocol/schema/typescript/ResponseMetadataEvent.ts diff --git a/codex-rs/app-server-protocol/schema/json/EventMsg.json b/codex-rs/app-server-protocol/schema/json/EventMsg.json index 02398dc8e9..26f15b8fe1 100644 --- a/codex-rs/app-server-protocol/schema/json/EventMsg.json +++ b/codex-rs/app-server-protocol/schema/json/EventMsg.json @@ -2680,36 +2680,6 @@ "title": "ExitedReviewModeEventMsg", "type": "object" }, - { - "properties": { - "request_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "response_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "type": { - "enum": [ - "response_metadata" - ], - "title": "ResponseMetadataEventMsgType", - "type": "string" - } - }, - "required": [ - "type" - ], - "title": "ResponseMetadataEventMsg", - "type": "object" - }, { "properties": { "item": { @@ -8503,36 +8473,6 @@ "title": "ExitedReviewModeEventMsg", "type": "object" }, - { - "properties": { - "request_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "response_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "type": { - "enum": [ - "response_metadata" - ], - "title": "ResponseMetadataEventMsgType", - "type": "string" - } - }, - "required": [ - "type" - ], - "title": "ResponseMetadataEventMsg", - "type": "object" - }, { "properties": { "item": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 9436462acd..e9c7921890 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -3911,36 +3911,6 @@ "title": "ExitedReviewModeEventMsg", "type": "object" }, - { - "properties": { - "request_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "response_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "type": { - "enum": [ - "response_metadata" - ], - "title": "ResponseMetadataEventMsgType", - "type": "string" - } - }, - "required": [ - "type" - ], - "title": "ResponseMetadataEventMsg", - "type": "object" - }, { "properties": { "item": { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 650b5ab921..2aac99cb3a 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -5448,36 +5448,6 @@ "title": "ExitedReviewModeEventMsg", "type": "object" }, - { - "properties": { - "request_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "response_id": { - "default": null, - "type": [ - "string", - "null" - ] - }, - "type": { - "enum": [ - "response_metadata" - ], - "title": "ResponseMetadataEventMsgType", - "type": "string" - } - }, - "required": [ - "type" - ], - "title": "ResponseMetadataEventMsg", - "type": "object" - }, { "properties": { "item": { diff --git a/codex-rs/app-server-protocol/schema/typescript/EventMsg.ts b/codex-rs/app-server-protocol/schema/typescript/EventMsg.ts index 3c263972bb..658a97ef14 100644 --- a/codex-rs/app-server-protocol/schema/typescript/EventMsg.ts +++ b/codex-rs/app-server-protocol/schema/typescript/EventMsg.ts @@ -57,7 +57,6 @@ import type { ReasoningContentDeltaEvent } from "./ReasoningContentDeltaEvent"; import type { ReasoningRawContentDeltaEvent } from "./ReasoningRawContentDeltaEvent"; import type { RemoteSkillDownloadedEvent } from "./RemoteSkillDownloadedEvent"; import type { RequestUserInputEvent } from "./RequestUserInputEvent"; -import type { ResponseMetadataEvent } from "./ResponseMetadataEvent"; import type { ReviewRequest } from "./ReviewRequest"; import type { SessionConfiguredEvent } from "./SessionConfiguredEvent"; import type { StreamErrorEvent } from "./StreamErrorEvent"; @@ -82,4 +81,4 @@ import type { WebSearchEndEvent } from "./WebSearchEndEvent"; * Response event from the agent * NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen. */ -export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "image_generation_begin" } & ImageGenerationBeginEvent | { "type": "image_generation_end" } & ImageGenerationEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "dynamic_tool_call_response" } & DynamicToolCallResponseEvent | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "response_metadata" } & ResponseMetadataEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent; +export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "image_generation_begin" } & ImageGenerationBeginEvent | { "type": "image_generation_end" } & ImageGenerationEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "dynamic_tool_call_response" } & DynamicToolCallResponseEvent | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent; diff --git a/codex-rs/app-server-protocol/schema/typescript/ResponseMetadataEvent.ts b/codex-rs/app-server-protocol/schema/typescript/ResponseMetadataEvent.ts deleted file mode 100644 index b6768f220c..0000000000 --- a/codex-rs/app-server-protocol/schema/typescript/ResponseMetadataEvent.ts +++ /dev/null @@ -1,5 +0,0 @@ -// GENERATED CODE! DO NOT MODIFY BY HAND! - -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export type ResponseMetadataEvent = { request_id: string | null, response_id: string | null, }; diff --git a/codex-rs/app-server-protocol/schema/typescript/index.ts b/codex-rs/app-server-protocol/schema/typescript/index.ts index bebb8eee78..21272ecf2d 100644 --- a/codex-rs/app-server-protocol/schema/typescript/index.ts +++ b/codex-rs/app-server-protocol/schema/typescript/index.ts @@ -160,7 +160,6 @@ export type { RequestUserInputQuestionOption } from "./RequestUserInputQuestionO export type { Resource } from "./Resource"; export type { ResourceTemplate } from "./ResourceTemplate"; export type { ResponseItem } from "./ResponseItem"; -export type { ResponseMetadataEvent } from "./ResponseMetadataEvent"; export type { ReviewCodeLocation } from "./ReviewCodeLocation"; export type { ReviewDecision } from "./ReviewDecision"; export type { ReviewFinding } from "./ReviewFinding"; diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index 44a74a0675..474db14f96 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -5837,22 +5837,36 @@ impl CodexMessageProcessor { break; } }; + let mut public_event = event.clone(); + match &mut public_event.msg { + EventMsg::ResponseMetadata(_) => continue, + EventMsg::SessionConfigured(session_configured) => { + if let Some(initial_messages) = + session_configured.initial_messages.as_mut() + { + initial_messages.retain(|msg| { + !matches!(msg, EventMsg::ResponseMetadata(_)) + }); + } + } + _ => {} + } // For now, we send a notification for every event, // JSON-serializing the `Event` as-is, but these should // be migrated to be variants of `ServerNotification` // instead. - let event_formatted = match &event.msg { + let event_formatted = match &public_event.msg { EventMsg::TurnStarted(_) => "task_started", EventMsg::TurnComplete(_) => "task_complete", - _ => &event.msg.to_string(), + _ => &public_event.msg.to_string(), }; let request_event_name = format!("codex/event/{event_formatted}"); tracing::trace!( conversation_id = %conversation_id, "app-server event: {request_event_name}" ); - let mut params = match serde_json::to_value(event.clone()) { + let mut params = match serde_json::to_value(public_event.clone()) { Ok(serde_json::Value::Object(map)) => map, Ok(_) => { error!("event did not serialize to an object"); @@ -5869,13 +5883,15 @@ impl CodexMessageProcessor { ); let raw_events_enabled = { let mut thread_state = thread_state.lock().await; - thread_state.track_current_turn_event(&event.msg); + thread_state.track_current_turn_event(&public_event.msg); thread_state.experimental_raw_events }; let subscribed_connection_ids = thread_state_manager .subscribed_connection_ids(conversation_id) .await; - if let EventMsg::RawResponseItem(_) = &event.msg && !raw_events_enabled { + if let EventMsg::RawResponseItem(_) = &public_event.msg + && !raw_events_enabled + { continue; } diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index c857c820b1..bdaa69affe 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -1176,6 +1176,8 @@ pub enum EventMsg { /// Exited review mode with an optional final result to apply. ExitedReviewMode(ExitedReviewModeEvent), + #[schemars(skip)] + #[ts(skip)] ResponseMetadata(ResponseMetadataEvent), RawResponseItem(RawResponseItemEvent),