diff --git a/codex-rs/app-server/tests/suite/v2/web_search.rs b/codex-rs/app-server/tests/suite/v2/web_search.rs index ef8d56270..0d2d99532 100644 --- a/codex-rs/app-server/tests/suite/v2/web_search.rs +++ b/codex-rs/app-server/tests/suite/v2/web_search.rs @@ -140,6 +140,7 @@ async fn standalone_web_search_round_trips_encrypted_output() -> Result<()> { ); let search_body = search_request_body(&server).await?; + assert_eq!(search_body["model"], json!("mock-model")); assert_eq!( search_body["commands"], json!({ diff --git a/codex-rs/codex-api/src/endpoint/search.rs b/codex-rs/codex-api/src/endpoint/search.rs index 2940f872d..d01fbfb78 100644 --- a/codex-rs/codex-api/src/endpoint/search.rs +++ b/codex-rs/codex-api/src/endpoint/search.rs @@ -145,7 +145,7 @@ mod tests { .search( &SearchRequest { id: "search-session".to_string(), - model: Some("gpt-test".to_string()), + model: "gpt-test".to_string(), reasoning: None, input: Some(SearchInput::Items(vec![ResponseItem::Message { id: None, diff --git a/codex-rs/codex-api/src/search.rs b/codex-rs/codex-api/src/search.rs index 8328415f8..061b3ac8c 100644 --- a/codex-rs/codex-api/src/search.rs +++ b/codex-rs/codex-api/src/search.rs @@ -7,8 +7,7 @@ use serde::Serialize; #[derive(Debug, Clone, Serialize, PartialEq)] pub struct SearchRequest { pub id: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub model: Option, + pub model: String, #[serde(skip_serializing_if = "Option::is_none")] pub reasoning: Option, #[serde(skip_serializing_if = "Option::is_none")] diff --git a/codex-rs/core/src/tools/handlers/extension_tools.rs b/codex-rs/core/src/tools/handlers/extension_tools.rs index 8a8854c14..95b272bbf 100644 --- a/codex-rs/core/src/tools/handlers/extension_tools.rs +++ b/codex-rs/core/src/tools/handlers/extension_tools.rs @@ -147,6 +147,7 @@ async fn to_extension_call(invocation: &ToolInvocation) -> ExtensionToolCall { turn_id: invocation.turn.sub_id.clone(), call_id: invocation.call_id.clone(), tool_name: invocation.tool_name.clone(), + model: invocation.turn.model_info.slug.clone(), truncation_policy: invocation.turn.truncation_policy, conversation_history, turn_item_emitter: Arc::new(CoreTurnItemEmitter { @@ -307,6 +308,7 @@ mod tests { let weak_session = Arc::downgrade(&session); let weak_turn = Arc::downgrade(&turn); let turn_id = turn.sub_id.clone(); + let model = turn.model_info.slug.clone(); let truncation_policy = turn.truncation_policy; let history_item = ResponseItem::Message { id: None, @@ -350,6 +352,7 @@ mod tests { captured_call.tool_name, codex_tools::ToolName::plain("extension_echo") ); + assert_eq!(captured_call.model, model); assert_eq!(captured_call.truncation_policy, truncation_policy); assert_eq!( captured_call.conversation_history.items(), diff --git a/codex-rs/ext/goal/tests/goal_extension_backend.rs b/codex-rs/ext/goal/tests/goal_extension_backend.rs index 92f4313fc..f325c5f90 100644 --- a/codex-rs/ext/goal/tests/goal_extension_backend.rs +++ b/codex-rs/ext/goal/tests/goal_extension_backend.rs @@ -1129,6 +1129,7 @@ fn tool_call(tool_name: &str, call_id: &str, arguments: serde_json::Value) -> To turn_id: "turn-1".to_string(), call_id: call_id.to_string(), tool_name: codex_extension_api::ToolName::plain(tool_name), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), diff --git a/codex-rs/ext/memories/src/tests.rs b/codex-rs/ext/memories/src/tests.rs index f2d79c850..ce03d7496 100644 --- a/codex-rs/ext/memories/src/tests.rs +++ b/codex-rs/ext/memories/src/tests.rs @@ -211,6 +211,7 @@ async fn add_ad_hoc_note_tool_creates_note_file() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::ADD_AD_HOC_NOTE_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), @@ -253,6 +254,7 @@ async fn add_ad_hoc_note_tool_rejects_paths_as_filenames() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::ADD_AD_HOC_NOTE_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), @@ -296,6 +298,7 @@ async fn read_tool_reads_memory_file() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::READ_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), @@ -342,6 +345,7 @@ async fn search_tool_accepts_multiple_queries() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), @@ -414,6 +418,7 @@ async fn search_tool_accepts_windowed_all_match_mode() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), @@ -466,6 +471,7 @@ async fn search_tool_rejects_legacy_single_query() { turn_id: "turn-1".to_string(), call_id: "call-1".to_string(), tool_name: memory_tool_name(crate::SEARCH_TOOL_NAME), + model: "gpt-test".to_string(), truncation_policy: TruncationPolicy::Bytes(1024), conversation_history: codex_extension_api::ConversationHistory::default(), turn_item_emitter: Arc::new(NoopTurnItemEmitter), diff --git a/codex-rs/ext/web-search/src/tool.rs b/codex-rs/ext/web-search/src/tool.rs index 2cf25b007..35b855c5c 100644 --- a/codex-rs/ext/web-search/src/tool.rs +++ b/codex-rs/ext/web-search/src/tool.rs @@ -90,7 +90,7 @@ impl ToolExecutor for WebSearchTool { ); let request = SearchRequest { id: self.session_id.clone(), - model: None, + model: call.model.clone(), reasoning: None, input: recent_input(call.conversation_history.items()), commands: Some(commands), diff --git a/codex-rs/tools/src/tool_call.rs b/codex-rs/tools/src/tool_call.rs index 9bbe00a6c..e2434ccbe 100644 --- a/codex-rs/tools/src/tool_call.rs +++ b/codex-rs/tools/src/tool_call.rs @@ -87,6 +87,7 @@ pub struct ToolCall { pub turn_id: String, pub call_id: String, pub tool_name: ToolName, + pub model: String, pub truncation_policy: TruncationPolicy, pub conversation_history: ConversationHistory, pub turn_item_emitter: Arc, @@ -99,6 +100,7 @@ impl std::fmt::Debug for ToolCall { .field("turn_id", &self.turn_id) .field("call_id", &self.call_id) .field("tool_name", &self.tool_name) + .field("model", &self.model) .field("truncation_policy", &self.truncation_policy) .field("conversation_history", &self.conversation_history) .field("turn_item_emitter", &"")