From c6c9f051a27e4a13f4b56c38894331be626ae67f Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Mon, 6 Jul 2026 20:33:21 -0700 Subject: [PATCH] core: route Responses API through system proxy --- codex-rs/Cargo.lock | 1 + codex-rs/core/Cargo.toml | 1 + codex-rs/core/src/client.rs | 32 +++++++++- codex-rs/core/src/client_tests.rs | 5 ++ codex-rs/core/src/config/config_tests.rs | 4 ++ codex-rs/core/src/config/mod.rs | 12 ++++ codex-rs/core/src/session/session.rs | 1 + codex-rs/core/src/session/tests.rs | 5 ++ codex-rs/core/tests/responses_headers.rs | 3 + codex-rs/core/tests/suite/client.rs | 2 + .../core/tests/suite/client_websockets.rs | 1 + codex-rs/http-client/src/lib.rs | 4 +- codex-rs/http-client/src/outbound_proxy.rs | 62 +++++++++++++++---- .../http-client/src/outbound_proxy_tests.rs | 3 +- codex-rs/login/src/auth/default_client.rs | 56 ++++++++++++----- codex-rs/login/src/outbound_proxy.rs | 11 ++-- codex-rs/memories/write/src/runtime.rs | 1 + 17 files changed, 166 insertions(+), 38 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 9d89f8eb1f58..0d4d3c33bfc7 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -2647,6 +2647,7 @@ dependencies = [ "codex-git-utils", "codex-home", "codex-hooks", + "codex-http-client", "codex-image-generation-extension", "codex-install-context", "codex-login", diff --git a/codex-rs/core/Cargo.toml b/codex-rs/core/Cargo.toml index 4435a2eb630c..c617684f7896 100644 --- a/codex-rs/core/Cargo.toml +++ b/codex-rs/core/Cargo.toml @@ -49,6 +49,7 @@ codex-shell-command = { workspace = true } codex-execpolicy = { workspace = true } codex-git-utils = { workspace = true } codex-hooks = { workspace = true } +codex-http-client = { workspace = true } codex-install-context = { workspace = true } codex-network-proxy = { workspace = true } codex-otel = { workspace = true } diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index 43a758b0e851..d5918d520954 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -62,10 +62,13 @@ use codex_api::auth_header_telemetry; use codex_api::build_session_headers; use codex_api::create_text_param_for_request; use codex_api::response_create_client_metadata; +use codex_http_client::ClientRouteClass; +use codex_http_client::HttpClientFactory; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_login::RefreshTokenError; use codex_login::UnauthorizedRecovery; +use codex_login::default_client::build_default_reqwest_client_for_route; use codex_login::default_client::build_reqwest_client; use codex_otel::SessionTelemetry; use codex_otel::current_span_w3c_trace_context; @@ -248,6 +251,7 @@ pub struct ModelClient { state: Arc, agent_identity_policy: AgentIdentityAuthPolicy, prompt_cache_key_override: Option, + http_client_factory: HttpClientFactory, } /// A turn-scoped streaming session created from a [`ModelClient`]. @@ -396,7 +400,9 @@ impl ModelClient { /// Creates a new session-scoped `ModelClient`. /// /// All arguments are expected to be stable for the lifetime of a Codex session. Per-turn values - /// are passed to [`ModelClientSession::stream`] (and other turn-scoped methods) explicitly. + /// are passed to [`ModelClientSession::stream`] (and other turn-scoped methods) explicitly. The + /// HTTP client factory must come from the effective session configuration so every transport + /// observes the resolved outbound proxy policy. pub fn new( auth_manager: Option>, agent_identity_policy: AgentIdentityAuthPolicy, @@ -410,6 +416,7 @@ impl ModelClient { beta_features_header: Option, item_ids_enabled: bool, attestation_provider: Option>, + http_client_factory: HttpClientFactory, ) -> Self { let model_provider = create_model_provider(provider_info, auth_manager); let codex_api_key_env_enabled = model_provider @@ -439,6 +446,7 @@ impl ModelClient { }), agent_identity_policy, prompt_cache_key_override: None, + http_client_factory, } } @@ -532,7 +540,8 @@ impl ModelClient { return Ok(Vec::new()); } let client_setup = self.current_client_setup().await?; - let transport = ReqwestTransport::new(build_reqwest_client()); + let transport = + self.build_responses_transport(&client_setup.api_provider, RESPONSES_COMPACT_ENDPOINT)?; let request_telemetry = Self::build_request_telemetry( session_telemetry, AuthRequestTelemetryContext::new( @@ -938,6 +947,21 @@ impl ModelClient { }) } + fn build_responses_transport( + &self, + api_provider: &ApiProvider, + endpoint: &str, + ) -> Result { + let request_url = api_provider.url_for_path(endpoint); + let client = build_default_reqwest_client_for_route( + &self.http_client_factory, + &request_url, + ClientRouteClass::Api, + ) + .map_err(std::io::Error::from)?; + Ok(ReqwestTransport::new(client)) + } + pub(crate) async fn prewarm_auth(&self) -> Result<()> { self.current_client_setup().await.map(|_| ()) } @@ -1372,7 +1396,9 @@ impl ModelClientSession { let mut pending_retry = PendingUnauthorizedRetry::default(); loop { let client_setup = self.client.current_client_setup().await?; - let transport = ReqwestTransport::new(build_reqwest_client()); + let transport = self + .client + .build_responses_transport(&client_setup.api_provider, RESPONSES_ENDPOINT)?; let request_auth_context = AuthRequestTelemetryContext::new( client_setup.auth.as_ref().map(CodexAuth::auth_mode), client_setup.api_auth.as_ref(), diff --git a/codex-rs/core/src/client_tests.rs b/codex-rs/core/src/client_tests.rs index 82c464625d5d..b23b239eb0c3 100644 --- a/codex-rs/core/src/client_tests.rs +++ b/codex-rs/core/src/client_tests.rs @@ -19,6 +19,8 @@ use codex_api::AgentIdentityTelemetry; use codex_api::ApiError; use codex_api::ResponseEvent; use codex_api::TransportError; +use codex_http_client::HttpClientFactory; +use codex_http_client::OutboundProxyPolicy; use codex_login::AuthCredentialsStoreMode; use codex_login::AuthKeyringBackendKind; use codex_login::AuthManager; @@ -104,6 +106,7 @@ fn test_model_client_with_thread_id( /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault), ) } @@ -148,6 +151,7 @@ async fn compact_uses_bearer_after_agent_identity_session_fallback() -> anyhow:: /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault), ); let prompt = Prompt { input: vec![ResponseItem::Message { @@ -824,6 +828,7 @@ fn model_client_with_counting_attestation( Some(Arc::new(CountingAttestationProvider { calls: attestation_calls.clone(), })), + HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault), ); (model_client, attestation_calls) } diff --git a/codex-rs/core/src/config/config_tests.rs b/codex-rs/core/src/config/config_tests.rs index 6156b9b9eae1..40ebc64a0b77 100644 --- a/codex-rs/core/src/config/config_tests.rs +++ b/codex-rs/core/src/config/config_tests.rs @@ -1590,6 +1590,10 @@ respect_system_proxy = true .await?; assert!(config.respect_system_proxy); + assert_eq!( + config.http_client_factory().outbound_proxy_policy(), + codex_http_client::OutboundProxyPolicy::RespectSystemProxy + ); Ok(()) } diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 54fbb97f696e..8c0a165564db 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -70,6 +70,8 @@ use codex_features::MultiAgentV2ConfigToml; use codex_features::NetworkProxyConfigToml; use codex_features::TokenBudgetConfigToml; use codex_git_utils::resolve_root_git_project_for_trust; +use codex_http_client::HttpClientFactory; +use codex_http_client::OutboundProxyPolicy; use codex_install_context::InstallContext; use codex_login::AuthManagerConfig; use codex_login::AuthRouteConfig; @@ -1481,6 +1483,16 @@ impl Config { .then(AuthRouteConfig::respect_system_proxy) } + /// Creates the HTTP client factory resolved from the effective feature configuration. + pub fn http_client_factory(&self) -> HttpClientFactory { + let outbound_proxy_policy = if self.respect_system_proxy { + OutboundProxyPolicy::RespectSystemProxy + } else { + OutboundProxyPolicy::ReqwestDefault + }; + HttpClientFactory::new(outbound_proxy_policy) + } + /// Build the plugin-manager input from the effective config. pub fn plugins_config_input(&self) -> PluginsConfigInput { PluginsConfigInput::new( diff --git a/codex-rs/core/src/session/session.rs b/codex-rs/core/src/session/session.rs index 2261eaa495fe..d11673b973d4 100644 --- a/codex-rs/core/src/session/session.rs +++ b/codex-rs/core/src/session/session.rs @@ -1112,6 +1112,7 @@ impl Session { Self::build_model_client_beta_features_header(config.as_ref()), /*item_ids_enabled*/ config.features.enabled(Feature::ItemIds), attestation_provider, + config.http_client_factory(), ) .with_prompt_cache_key_override( crate::guardian::prompt_cache_key_override_for_review_session( diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 6cc223cd7d8e..c5cd78672aab 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -33,6 +33,8 @@ use codex_core_skills::HostSkillsSnapshot; use core_test_support::test_codex::local_selections; use codex_features::Feature; +use codex_http_client::HttpClientFactory; +use codex_http_client::OutboundProxyPolicy; use codex_login::CodexAuth; use codex_login::auth::AgentIdentityAuthPolicy; use codex_model_provider_info::ModelProviderInfo; @@ -491,6 +493,7 @@ fn test_model_client_session() -> crate::client::ModelClientSession { /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault), ) .new_session() } @@ -5461,6 +5464,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) { Session::build_model_client_beta_features_header(config.as_ref()), /*item_ids_enabled*/ config.features.enabled(Feature::ItemIds), /*attestation_provider*/ None, + config.http_client_factory(), ), code_mode_service: crate::tools::code_mode::CodeModeService::new(Arc::new( codex_code_mode::InProcessCodeModeSessionProvider, @@ -7587,6 +7591,7 @@ where Session::build_model_client_beta_features_header(config.as_ref()), /*item_ids_enabled*/ config.features.enabled(Feature::ItemIds), /*attestation_provider*/ None, + config.http_client_factory(), ), code_mode_service: crate::tools::code_mode::CodeModeService::new(Arc::new( codex_code_mode::InProcessCodeModeSessionProvider, diff --git a/codex-rs/core/tests/responses_headers.rs b/codex-rs/core/tests/responses_headers.rs index 5b7c2c65b830..bf01e27b28fd 100644 --- a/codex-rs/core/tests/responses_headers.rs +++ b/codex-rs/core/tests/responses_headers.rs @@ -132,6 +132,7 @@ async fn responses_stream_includes_subagent_header_on_review() { /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + config.http_client_factory(), ); let responses_metadata = test_turn_responses_metadata(&client, thread_id, &session_source); let mut client_session = client.new_session(); @@ -266,6 +267,7 @@ async fn responses_stream_includes_subagent_header_on_other() { /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + config.http_client_factory(), ); let responses_metadata = test_turn_responses_metadata(&client, thread_id, &session_source); let mut client_session = client.new_session(); @@ -386,6 +388,7 @@ async fn responses_respects_model_info_overrides_from_config() { /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + config.http_client_factory(), ); let responses_metadata = test_turn_responses_metadata(&client, thread_id, &session_source); let mut client_session = client.new_session(); diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index c87539f9406c..9f7e6405aa5b 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1335,6 +1335,7 @@ async fn send_provider_auth_request(server: &MockServer, auth: ModelProviderAuth /*beta_features_header*/ None, /*item_ids_enabled*/ config.features.enabled(Feature::ItemIds), /*attestation_provider*/ None, + config.http_client_factory(), ); let responses_metadata = test_turn_responses_metadata(&client, thread_id); let mut client_session = client.new_session(); @@ -2949,6 +2950,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() { /*beta_features_header*/ None, /*item_ids_enabled*/ false, /*attestation_provider*/ None, + config.http_client_factory(), ); let responses_metadata = test_turn_responses_metadata(&client, thread_id); let mut client_session = client.new_session(); diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index d5218cdcabce..737c8e298255 100755 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -2252,6 +2252,7 @@ async fn websocket_harness_with_provider_options( /*beta_features_header*/ None, /*item_ids_enabled*/ config.features.enabled(Feature::ItemIds), /*attestation_provider*/ None, + config.http_client_factory(), ); WebsocketTestHarness { diff --git a/codex-rs/http-client/src/lib.rs b/codex-rs/http-client/src/lib.rs index 5f90435452a2..07e579ecb33a 100644 --- a/codex-rs/http-client/src/lib.rs +++ b/codex-rs/http-client/src/lib.rs @@ -25,9 +25,9 @@ pub use crate::error::StreamError; pub use crate::error::TransportError; pub use crate::outbound_proxy::BuildRouteAwareHttpClientError; pub use crate::outbound_proxy::ClientRouteClass; -pub use crate::outbound_proxy::OutboundProxyConfig; +pub use crate::outbound_proxy::HttpClientFactory; +pub use crate::outbound_proxy::OutboundProxyPolicy; pub use crate::outbound_proxy::RouteFailureClass; -pub use crate::outbound_proxy::build_reqwest_client_for_route; pub use crate::request::EncodedJsonBody; pub use crate::request::PreparedRequestBody; pub use crate::request::Request; diff --git a/codex-rs/http-client/src/outbound_proxy.rs b/codex-rs/http-client/src/outbound_proxy.rs index e643698a8c3c..5506f3d40ba1 100644 --- a/codex-rs/http-client/src/outbound_proxy.rs +++ b/codex-rs/http-client/src/outbound_proxy.rs @@ -84,14 +84,54 @@ impl fmt::Display for RouteFailureClass { } } -/// Marker enabling fixed system/PAC/WPAD, environment, then direct routing. -/// Resolved endpoints and platform details remain internal to the client builder. +/// Resolved outbound proxy behavior for HTTP clients. +/// +/// Callers must choose a policy explicitly so omitting feature resolution cannot silently select +/// legacy behavior. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct OutboundProxyConfig; +pub enum OutboundProxyPolicy { + /// Preserve reqwest's built-in proxy behavior. + ReqwestDefault, + /// Resolve system/PAC/WPAD settings, then environment settings, then direct routing. + RespectSystemProxy, +} + +/// Builds route-specific HTTP clients using one resolved outbound proxy policy. +/// +/// Construct this once from the effective application configuration and carry it with the +/// session or component that owns outbound requests. Individual request paths should supply only +/// their destination and route class rather than resolving feature state themselves. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct HttpClientFactory { + outbound_proxy_policy: OutboundProxyPolicy, +} + +impl HttpClientFactory { + /// Creates a factory from the outbound proxy policy resolved by the application. + pub const fn new(outbound_proxy_policy: OutboundProxyPolicy) -> Self { + Self { + outbound_proxy_policy, + } + } + + /// Returns the outbound proxy policy used for clients built by this factory. + pub const fn outbound_proxy_policy(&self) -> OutboundProxyPolicy { + self.outbound_proxy_policy + } -impl OutboundProxyConfig { - pub const fn respect_system_proxy() -> Self { - Self + /// Builds a reqwest client for a concrete outbound route. + pub fn build_reqwest_client( + &self, + builder: reqwest::ClientBuilder, + request_url: &str, + route_class: ClientRouteClass, + ) -> Result { + build_reqwest_client_for_route( + builder, + request_url, + route_class, + self.outbound_proxy_policy, + ) } } @@ -120,18 +160,18 @@ impl From for io::Error { /// a route is selected are returned without trying another route. Ordered PAC candidates are /// currently collapsed to one route on both Windows and macOS; later proxy or `DIRECT` candidates /// are not retried after a connection failure. -pub fn build_reqwest_client_for_route( +fn build_reqwest_client_for_route( builder: reqwest::ClientBuilder, request_url: &str, route_class: ClientRouteClass, - config: Option<&OutboundProxyConfig>, + outbound_proxy_policy: OutboundProxyPolicy, ) -> Result { let builder = configure_proxy_for_route( &ProcessEnv, builder, request_url, route_class, - config, + outbound_proxy_policy, resolve_system_proxy, )?; build_reqwest_client_with_custom_ca(builder).map_err(Into::into) @@ -142,10 +182,10 @@ fn configure_proxy_for_route( builder: reqwest::ClientBuilder, request_url: &str, route_class: ClientRouteClass, - config: Option<&OutboundProxyConfig>, + outbound_proxy_policy: OutboundProxyPolicy, resolve_system_proxy: impl FnOnce(&str, &RequestOrigin) -> SystemProxyDecision, ) -> Result { - if config.is_none() { + if matches!(outbound_proxy_policy, OutboundProxyPolicy::ReqwestDefault) { return Ok(builder); } let origin = RequestOrigin::parse(request_url); diff --git a/codex-rs/http-client/src/outbound_proxy_tests.rs b/codex-rs/http-client/src/outbound_proxy_tests.rs index 60a1d563967e..734d5483ec8c 100644 --- a/codex-rs/http-client/src/outbound_proxy_tests.rs +++ b/codex-rs/http-client/src/outbound_proxy_tests.rs @@ -79,13 +79,12 @@ async fn enabled_environment_proxy_routes_request_through_proxy() { values: HashMap::from([("HTTP_PROXY".to_string(), format!("http://{proxy_addr}"))]), }; let request_url = "http://enabled-proxy.test/proxy-check"; - let config = OutboundProxyConfig::respect_system_proxy(); let builder = configure_proxy_for_route( &env, reqwest::Client::builder().timeout(Duration::from_secs(2)), request_url, ClientRouteClass::Auth, - Some(&config), + OutboundProxyPolicy::RespectSystemProxy, |_, _| SystemProxyDecision::Unavailable { failure: RouteFailureClass::ProxyResolutionUnavailable, }, diff --git a/codex-rs/login/src/auth/default_client.rs b/codex-rs/login/src/auth/default_client.rs index 1146a89d961f..089e78340b65 100644 --- a/codex-rs/login/src/auth/default_client.rs +++ b/codex-rs/login/src/auth/default_client.rs @@ -8,8 +8,9 @@ use codex_http_client::BuildCustomCaTransportError; use codex_http_client::BuildRouteAwareHttpClientError; use codex_http_client::ClientRouteClass; use codex_http_client::HttpClient; +use codex_http_client::HttpClientFactory; +use codex_http_client::OutboundProxyPolicy; pub use codex_http_client::RequestBuilder as CodexRequestBuilder; -use codex_http_client::build_reqwest_client_for_route; use codex_http_client::build_reqwest_client_with_custom_ca; use codex_http_client::with_chatgpt_cloudflare_cookie_store; use codex_terminal_detection::user_agent; @@ -235,6 +236,35 @@ pub fn try_build_reqwest_client() -> Result Result { + if matches!( + http_client_factory.outbound_proxy_policy(), + OutboundProxyPolicy::ReqwestDefault + ) { + return Ok(build_reqwest_client()); + } + if is_sandboxed() { + // Preserve the sandbox's existing no-proxy policy; sandboxed command egress is routed + // separately through network-proxy. + return Ok(build_reqwest_client()); + } + + http_client_factory.build_reqwest_client( + default_reqwest_client_builder(), + request_url, + route_class, + ) +} + fn default_reqwest_client_builder() -> reqwest::ClientBuilder { let mut builder = reqwest::Client::builder().default_headers(default_headers()); if is_sandboxed() { @@ -248,11 +278,10 @@ pub(crate) fn build_raw_auth_reqwest_client( endpoint: &str, auth_route_config: Option<&AuthRouteConfig>, ) -> Result { - build_reqwest_client_for_route( + auth_http_client_factory(auth_route_config).build_reqwest_client( reqwest::Client::builder(), endpoint, ClientRouteClass::Auth, - auth_route_config.map(AuthRouteConfig::route_config), ) } @@ -261,20 +290,10 @@ pub(crate) fn build_default_auth_reqwest_client( endpoint: &str, auth_route_config: Option<&AuthRouteConfig>, ) -> Result { - let Some(route_config) = auth_route_config.map(AuthRouteConfig::route_config) else { - return Ok(build_reqwest_client()); - }; - - if is_sandboxed() { - // Preserve the sandbox's existing no-proxy policy; sandboxed command egress is routed - // separately through network-proxy. - return Ok(build_reqwest_client()); - } - build_reqwest_client_for_route( - default_reqwest_client_builder(), + build_default_reqwest_client_for_route( + &auth_http_client_factory(auth_route_config), endpoint, ClientRouteClass::Auth, - Some(route_config), ) } @@ -286,6 +305,13 @@ pub(crate) fn create_default_auth_client( build_default_auth_reqwest_client(endpoint, auth_route_config).map(HttpClient::new) } +fn auth_http_client_factory(auth_route_config: Option<&AuthRouteConfig>) -> HttpClientFactory { + auth_route_config.map_or_else( + || HttpClientFactory::new(OutboundProxyPolicy::ReqwestDefault), + |config| config.http_client_factory().clone(), + ) +} + pub fn default_headers() -> HeaderMap { let mut headers = HeaderMap::new(); headers.insert("originator", originator().header_value); diff --git a/codex-rs/login/src/outbound_proxy.rs b/codex-rs/login/src/outbound_proxy.rs index 66441e363743..79fcf76de192 100644 --- a/codex-rs/login/src/outbound_proxy.rs +++ b/codex-rs/login/src/outbound_proxy.rs @@ -1,4 +1,5 @@ -use codex_http_client::OutboundProxyConfig; +use codex_http_client::HttpClientFactory; +use codex_http_client::OutboundProxyPolicy; /// Auth-layer adapter around client-owned proxy policy. /// @@ -6,17 +7,17 @@ use codex_http_client::OutboundProxyConfig; /// client layer. #[derive(Debug, Clone, PartialEq, Eq)] pub struct AuthRouteConfig { - route_config: OutboundProxyConfig, + http_client_factory: HttpClientFactory, } impl AuthRouteConfig { pub fn respect_system_proxy() -> Self { Self { - route_config: OutboundProxyConfig::respect_system_proxy(), + http_client_factory: HttpClientFactory::new(OutboundProxyPolicy::RespectSystemProxy), } } - pub(crate) fn route_config(&self) -> &OutboundProxyConfig { - &self.route_config + pub(crate) fn http_client_factory(&self) -> &HttpClientFactory { + &self.http_client_factory } } diff --git a/codex-rs/memories/write/src/runtime.rs b/codex-rs/memories/write/src/runtime.rs index 6c7ad3978fbf..c2dc60243e70 100644 --- a/codex-rs/memories/write/src/runtime.rs +++ b/codex-rs/memories/write/src/runtime.rs @@ -262,6 +262,7 @@ impl MemoryStartupContext { /*beta_features_header*/ None, config.features.enabled(Feature::ItemIds), /*attestation_provider*/ None, + config.http_client_factory(), ); let mut client_session = model_client.new_session();