diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index 5acb3d6da..3631f3afb 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -4,9 +4,9 @@ //! configuration and state needed to talk to a provider (auth, provider selection, conversation id, //! and feature-gated request behavior). //! -//! Per-turn settings (model selection, reasoning controls, telemetry context, web search -//! eligibility, and turn metadata) are passed explicitly to streaming and unary methods so that the -//! turn lifetime is visible at the call site. +//! Per-turn settings (model selection, reasoning controls, telemetry context, and turn metadata) +//! are passed explicitly to streaming and unary methods so that the turn lifetime is visible at the +//! call site. //! //! A [`ModelClientSession`] is created per turn and is used to stream one or more Responses API //! requests during that turn. It caches a Responses WebSocket connection (opened lazily) and @@ -82,7 +82,6 @@ use crate::model_provider_info::ModelProviderInfo; use crate::model_provider_info::WireApi; use crate::tools::spec::create_tools_json_for_responses_api; -pub const WEB_SEARCH_ELIGIBLE_HEADER: &str = "x-oai-web-search-eligible"; pub const X_CODEX_TURN_STATE_HEADER: &str = "x-codex-turn-state"; pub const X_CODEX_TURN_METADATA_HEADER: &str = "x-codex-turn-metadata"; pub const X_RESPONSESAPI_INCLUDE_TIMING_METRICS_HEADER: &str = @@ -115,9 +114,8 @@ struct ModelClientState { /// WebSocket fallback is session-scoped: once a turn activates the HTTP fallback, subsequent turns /// will also use HTTP for the remainder of the session. /// -/// Turn-scoped settings (model selection, reasoning controls, telemetry context, web search -/// eligibility, and turn metadata) are passed explicitly to the relevant methods to keep turn -/// lifetime visible at the call site. +/// Turn-scoped settings (model selection, reasoning controls, telemetry context, and turn metadata) +/// are passed explicitly to the relevant methods to keep turn lifetime visible at the call site. /// /// This type is cheap to clone. #[derive(Debug, Clone)] @@ -349,7 +347,6 @@ impl ModelClientSession { model_info: &ModelInfo, effort: Option, summary: ReasoningSummaryConfig, - web_search_eligible: bool, turn_metadata_header: Option<&str>, compression: Compression, ) -> ApiResponsesOptions { @@ -404,7 +401,6 @@ impl ModelClientSession { session_source: Some(self.client.state.session_source.clone()), extra_headers: build_responses_headers( self.client.state.beta_features_header.as_deref(), - web_search_eligible, Some(&self.turn_state), turn_metadata_header.as_ref(), ), @@ -529,7 +525,6 @@ impl ModelClientSession { otel_manager: &OtelManager, effort: Option, summary: ReasoningSummaryConfig, - web_search_eligible: bool, turn_metadata_header: Option<&str>, ) -> Result { if let Some(path) = &*CODEX_RS_SSE_FIXTURE { @@ -571,7 +566,6 @@ impl ModelClientSession { model_info, effort, summary, - web_search_eligible, turn_metadata_header, compression, ); @@ -604,7 +598,6 @@ impl ModelClientSession { otel_manager: &OtelManager, effort: Option, summary: ReasoningSummaryConfig, - web_search_eligible: bool, turn_metadata_header: Option<&str>, ) -> Result { let auth_manager = self.client.state.auth_manager.clone(); @@ -631,7 +624,6 @@ impl ModelClientSession { model_info, effort, summary, - web_search_eligible, turn_metadata_header, compression, ); @@ -687,9 +679,9 @@ impl ModelClientSession { /// Streams a single model request within the current turn. /// /// The caller is responsible for passing per-turn settings explicitly (model selection, - /// reasoning settings, telemetry context, web search eligibility, and turn metadata). This - /// method will prefer the Responses WebSocket transport when enabled and healthy, and will - /// fall back to the HTTP Responses API transport otherwise. + /// reasoning settings, telemetry context, and turn metadata). This method will prefer the + /// Responses WebSocket transport when enabled and healthy, and will fall back to the HTTP + /// Responses API transport otherwise. pub async fn stream( &mut self, prompt: &Prompt, @@ -697,7 +689,6 @@ impl ModelClientSession { otel_manager: &OtelManager, effort: Option, summary: ReasoningSummaryConfig, - web_search_eligible: bool, turn_metadata_header: Option<&str>, ) -> Result { let wire_api = self.client.state.provider.wire_api; @@ -713,7 +704,6 @@ impl ModelClientSession { otel_manager, effort, summary, - web_search_eligible, turn_metadata_header, ) .await @@ -724,7 +714,6 @@ impl ModelClientSession { otel_manager, effort, summary, - web_search_eligible, turn_metadata_header, ) .await @@ -772,12 +761,10 @@ fn build_api_prompt(prompt: &Prompt, instructions: String, tools_json: Vec, - web_search_eligible: bool, turn_state: Option<&Arc>>, turn_metadata_header: Option<&HeaderValue>, ) -> ApiHeaderMap { @@ -788,10 +775,6 @@ fn build_responses_headers( { headers.insert("x-codex-beta-features", header_value); } - headers.insert( - WEB_SEARCH_ELIGIBLE_HEADER, - HeaderValue::from_static(if web_search_eligible { "true" } else { "false" }), - ); if let Some(turn_state) = turn_state && let Some(state) = turn_state.get() && let Ok(header_value) = HeaderValue::from_str(state) diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 77d6d6a73..b4c211883 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -4525,10 +4525,6 @@ async fn try_run_sampling_request( ); sess.persist_rollout_items(&[rollout_item]).await; - let web_search_eligible = !matches!( - turn_context.config.web_search_mode, - Some(WebSearchMode::Disabled) - ); let mut stream = client_session .stream( prompt, @@ -4536,7 +4532,6 @@ async fn try_run_sampling_request( &turn_context.otel_manager, turn_context.reasoning_effort, turn_context.reasoning_summary, - web_search_eligible, turn_metadata_header, ) .instrument(trace_span!("stream_request")) diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index 91b95759c..ab9a9f15d 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -20,7 +20,6 @@ use crate::truncate::TruncationPolicy; use crate::truncate::approx_token_count; use crate::truncate::truncate_text; use crate::util::backoff; -use codex_protocol::config_types::WebSearchMode; use codex_protocol::items::ContextCompactionItem; use codex_protocol::items::TurnItem; use codex_protocol::models::ContentItem; @@ -352,10 +351,6 @@ async fn drain_to_completed( turn_metadata_header: Option<&str>, prompt: &Prompt, ) -> CodexResult<()> { - let web_search_eligible = !matches!( - turn_context.config.web_search_mode, - Some(WebSearchMode::Disabled) - ); let mut stream = client_session .stream( prompt, @@ -363,7 +358,6 @@ async fn drain_to_completed( &turn_context.otel_manager, turn_context.reasoning_effort, turn_context.reasoning_summary, - web_search_eligible, turn_metadata_header, ) .await?; diff --git a/codex-rs/core/src/lib.rs b/codex-rs/core/src/lib.rs index ed7fc6e3e..ff54bdc80 100644 --- a/codex-rs/core/src/lib.rs +++ b/codex-rs/core/src/lib.rs @@ -130,7 +130,6 @@ mod user_shell_command; pub mod util; pub use apply_patch::CODEX_APPLY_PATCH_ARG1; -pub use client::WEB_SEARCH_ELIGIBLE_HEADER; pub use client::X_CODEX_TURN_METADATA_HEADER; pub use command_safety::is_dangerous_command; pub use command_safety::is_safe_command; diff --git a/codex-rs/core/tests/responses_headers.rs b/codex-rs/core/tests/responses_headers.rs index 04cfdc037..83f1d1042 100644 --- a/codex-rs/core/tests/responses_headers.rs +++ b/codex-rs/core/tests/responses_headers.rs @@ -9,14 +9,12 @@ use codex_core::ModelProviderInfo; use codex_core::Prompt; use codex_core::ResponseEvent; use codex_core::ResponseItem; -use codex_core::WEB_SEARCH_ELIGIBLE_HEADER; use codex_core::WireApi; use codex_core::models_manager::manager::ModelsManager; use codex_otel::OtelManager; use codex_otel::TelemetryAuthMode; use codex_protocol::ThreadId; use codex_protocol::config_types::ReasoningSummary; -use codex_protocol::config_types::WebSearchMode; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::SubAgentSource; use core_test_support::load_default_config_for_test; @@ -87,7 +85,6 @@ async fn responses_stream_includes_subagent_header_on_review() { session_source.clone(), ); - let web_search_eligible = !matches!(config.web_search_mode, Some(WebSearchMode::Disabled)); let client = ModelClient::new( None, conversation_id, @@ -113,15 +110,7 @@ async fn responses_stream_includes_subagent_header_on_review() { }]; let mut stream = client_session - .stream( - &prompt, - &model_info, - &otel_manager, - effort, - summary, - web_search_eligible, - None, - ) + .stream(&prompt, &model_info, &otel_manager, effort, summary, None) .await .expect("stream failed"); while let Some(event) = stream.next().await { @@ -198,7 +187,6 @@ async fn responses_stream_includes_subagent_header_on_other() { session_source.clone(), ); - let web_search_eligible = !matches!(config.web_search_mode, Some(WebSearchMode::Disabled)); let client = ModelClient::new( None, conversation_id, @@ -224,15 +212,7 @@ async fn responses_stream_includes_subagent_header_on_other() { }]; let mut stream = client_session - .stream( - &prompt, - &model_info, - &otel_manager, - effort, - summary, - web_search_eligible, - None, - ) + .stream(&prompt, &model_info, &otel_manager, effort, summary, None) .await .expect("stream failed"); while let Some(event) = stream.next().await { @@ -248,66 +228,6 @@ async fn responses_stream_includes_subagent_header_on_other() { ); } -#[tokio::test] -async fn responses_stream_includes_web_search_eligible_header_true_by_default() { - core_test_support::skip_if_no_network!(); - - let server = responses::start_mock_server().await; - let response_body = responses::sse(vec![ - responses::ev_response_created("resp-1"), - responses::ev_completed("resp-1"), - ]); - - let request_recorder = responses::mount_sse_once_match( - &server, - header(WEB_SEARCH_ELIGIBLE_HEADER, "true"), - response_body, - ) - .await; - - let test = test_codex().build(&server).await.expect("build test codex"); - test.submit_turn("hello").await.expect("submit test prompt"); - - let request = request_recorder.single_request(); - assert_eq!( - request.header(WEB_SEARCH_ELIGIBLE_HEADER).as_deref(), - Some("true") - ); -} - -#[tokio::test] -async fn responses_stream_includes_web_search_eligible_header_false_when_disabled() { - core_test_support::skip_if_no_network!(); - - let server = responses::start_mock_server().await; - let response_body = responses::sse(vec![ - responses::ev_response_created("resp-1"), - responses::ev_completed("resp-1"), - ]); - - let request_recorder = responses::mount_sse_once_match( - &server, - header(WEB_SEARCH_ELIGIBLE_HEADER, "false"), - response_body, - ) - .await; - - let test = test_codex() - .with_config(|config| { - config.web_search_mode = Some(WebSearchMode::Disabled); - }) - .build(&server) - .await - .expect("build test codex"); - test.submit_turn("hello").await.expect("submit test prompt"); - - let request = request_recorder.single_request(); - assert_eq!( - request.header(WEB_SEARCH_ELIGIBLE_HEADER).as_deref(), - Some("false") - ); -} - #[tokio::test] async fn responses_respects_model_info_overrides_from_config() { core_test_support::skip_if_no_network!(); @@ -368,7 +288,6 @@ async fn responses_respects_model_info_overrides_from_config() { session_source.clone(), ); - let web_search_eligible = !matches!(config.web_search_mode, Some(WebSearchMode::Disabled)); let client = ModelClient::new( None, conversation_id, @@ -394,15 +313,7 @@ async fn responses_respects_model_info_overrides_from_config() { }]; let mut stream = client_session - .stream( - &prompt, - &model_info, - &otel_manager, - effort, - summary, - web_search_eligible, - None, - ) + .stream(&prompt, &model_info, &otel_manager, effort, summary, None) .await .expect("stream failed"); while let Some(event) = stream.next().await { diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 7debde217..fafa8b086 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1340,15 +1340,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() { }); let mut stream = client_session - .stream( - &prompt, - &model_info, - &otel_manager, - effort, - summary, - true, - None, - ) + .stream(&prompt, &model_info, &otel_manager, effort, summary, None) .await .expect("responses stream to start"); diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index f78b7b1a3..e58a512f9 100644 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -47,7 +47,6 @@ struct WebsocketTestHarness { model_info: ModelInfo, effort: Option, summary: ReasoningSummary, - web_search_eligible: bool, otel_manager: OtelManager, } @@ -198,7 +197,6 @@ async fn responses_websocket_emits_reasoning_included_event() { &harness.otel_manager, harness.effort, harness.summary, - harness.web_search_eligible, None, ) .await @@ -269,7 +267,6 @@ async fn responses_websocket_emits_rate_limit_events() { &harness.otel_manager, harness.effort, harness.summary, - harness.web_search_eligible, None, ) .await @@ -455,7 +452,6 @@ async fn websocket_harness_with_runtime_metrics( .with_metrics(metrics); let effort = None; let summary = ReasoningSummary::Auto; - let web_search_eligible = true; let client = ModelClient::new( None, conversation_id, @@ -474,7 +470,6 @@ async fn websocket_harness_with_runtime_metrics( model_info, effort, summary, - web_search_eligible, otel_manager, } } @@ -491,7 +486,6 @@ async fn stream_until_complete( &harness.otel_manager, harness.effort, harness.summary, - harness.web_search_eligible, None, ) .await