From 677532f97bf1ead8740e71fb74e4686585ba89e7 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Thu, 18 Dec 2025 18:25:07 -0800 Subject: [PATCH] progress --- codex-rs/core/src/client.rs | 12 ++++++++++-- codex-rs/core/src/codex.rs | 8 ++++++++ codex-rs/core/src/openai_models/models_manager.rs | 4 ++++ codex-rs/core/tests/chat_completions_payload.rs | 1 + codex-rs/core/tests/chat_completions_sse.rs | 1 + codex-rs/core/tests/responses_headers.rs | 3 +++ codex-rs/core/tests/suite/client.rs | 1 + 7 files changed, 28 insertions(+), 2 deletions(-) diff --git a/codex-rs/core/src/client.rs b/codex-rs/core/src/client.rs index aaf3b0ea35..53212f72ff 100644 --- a/codex-rs/core/src/client.rs +++ b/codex-rs/core/src/client.rs @@ -58,6 +58,7 @@ pub struct ModelClient { config: Arc, auth_manager: Option>, model_family: ModelFamily, + models_etag: Option, otel_manager: OtelManager, provider: ModelProviderInfo, conversation_id: ConversationId, @@ -72,6 +73,7 @@ impl ModelClient { config: Arc, auth_manager: Option>, model_family: ModelFamily, + models_etag: Option, otel_manager: OtelManager, provider: ModelProviderInfo, effort: Option, @@ -83,6 +85,7 @@ impl ModelClient { config, auth_manager, model_family, + models_etag, otel_manager, provider, conversation_id, @@ -262,7 +265,7 @@ impl ModelClient { store_override: None, conversation_id: Some(conversation_id.clone()), session_source: Some(session_source.clone()), - extra_headers: beta_feature_headers(&self.config), + extra_headers: beta_feature_headers(&self.config, self.models_etag.clone()), }; let stream_result = client @@ -398,7 +401,7 @@ fn build_api_prompt(prompt: &Prompt, instructions: String, tools_json: Vec ApiHeaderMap { +fn beta_feature_headers(config: &Config, models_etag: Option) -> ApiHeaderMap { let enabled = FEATURES .iter() .filter_map(|spec| { @@ -416,6 +419,11 @@ fn beta_feature_headers(config: &Config) -> ApiHeaderMap { { headers.insert("x-codex-beta-features", header_value); } + if let Some(etag) = models_etag + && let Ok(header_value) = HeaderValue::from_str(&etag) + { + headers.insert("X-If-Models-Match", header_value); + } headers } diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index f0d2056587..649bac18c4 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -492,6 +492,7 @@ impl Session { session_configuration: &SessionConfiguration, per_turn_config: Config, model_family: ModelFamily, + models_etag: Option, conversation_id: ConversationId, sub_id: String, ) -> TurnContext { @@ -505,6 +506,7 @@ impl Session { per_turn_config.clone(), auth_manager, model_family.clone(), + models_etag, otel_manager, provider, session_configuration.model_reasoning_effort, @@ -919,6 +921,7 @@ impl Session { .models_manager .construct_model_family(session_configuration.model.as_str(), &per_turn_config) .await; + let models_etag = self.services.models_manager.get_models_etag().await; let mut turn_context: TurnContext = Self::make_turn_context( Some(Arc::clone(&self.services.auth_manager)), &self.services.otel_manager, @@ -926,6 +929,7 @@ impl Session { &session_configuration, per_turn_config, model_family, + models_etag, self.conversation_id, sub_id, ); @@ -2105,6 +2109,7 @@ async fn spawn_review_thread( .models_manager .construct_model_family(&model, &config) .await; + let models_etag = sess.services.models_manager.get_models_etag().await; // For reviews, disable web_search and view_image regardless of global settings. let mut review_features = sess.features.clone(); review_features @@ -2137,6 +2142,7 @@ async fn spawn_review_thread( per_turn_config.clone(), auth_manager, model_family.clone(), + models_etag, otel_manager, provider, per_turn_config.model_reasoning_effort, @@ -3163,6 +3169,7 @@ mod tests { &session_configuration, per_turn_config, model_family, + None, conversation_id, "turn_id".to_string(), ); @@ -3249,6 +3256,7 @@ mod tests { &session_configuration, per_turn_config, model_family, + None, conversation_id, "turn_id".to_string(), )); diff --git a/codex-rs/core/src/openai_models/models_manager.rs b/codex-rs/core/src/openai_models/models_manager.rs index d6ca13e76b..fa8ea4b12d 100644 --- a/codex-rs/core/src/openai_models/models_manager.rs +++ b/codex-rs/core/src/openai_models/models_manager.rs @@ -131,6 +131,10 @@ impl ModelsManager { .with_config_overrides(config) } + pub async fn get_models_etag(&self) -> Option { + self.etag.read().await.clone() + } + pub async fn get_model(&self, model: &Option, config: &Config) -> String { if let Some(model) = model.as_ref() { return model.to_string(); diff --git a/codex-rs/core/tests/chat_completions_payload.rs b/codex-rs/core/tests/chat_completions_payload.rs index 5867935470..b0086ef518 100644 --- a/codex-rs/core/tests/chat_completions_payload.rs +++ b/codex-rs/core/tests/chat_completions_payload.rs @@ -92,6 +92,7 @@ async fn run_request(input: Vec) -> Value { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort, diff --git a/codex-rs/core/tests/chat_completions_sse.rs b/codex-rs/core/tests/chat_completions_sse.rs index f58b039220..74f7730504 100644 --- a/codex-rs/core/tests/chat_completions_sse.rs +++ b/codex-rs/core/tests/chat_completions_sse.rs @@ -93,6 +93,7 @@ async fn run_stream_with_bytes(sse_body: &[u8]) -> Vec { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort, diff --git a/codex-rs/core/tests/responses_headers.rs b/codex-rs/core/tests/responses_headers.rs index 5c32685cc9..f005ec5be9 100644 --- a/codex-rs/core/tests/responses_headers.rs +++ b/codex-rs/core/tests/responses_headers.rs @@ -86,6 +86,7 @@ async fn responses_stream_includes_subagent_header_on_review() { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort, @@ -181,6 +182,7 @@ async fn responses_stream_includes_subagent_header_on_other() { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort, @@ -275,6 +277,7 @@ async fn responses_respects_model_family_overrides_from_config() { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort, diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index bda232433d..65b1a7f4c8 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1146,6 +1146,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() { Arc::clone(&config), None, model_family, + None, otel_manager, provider, effort,