@@ -68,7 +68,7 @@ use crate::error::RetryLimitReachedError;
6868use crate :: error:: UnexpectedResponseError ;
6969use crate :: error:: UsageLimitReachedError ;
7070use crate :: flags:: CODEX_RS_SSE_FIXTURE ;
71- use crate :: model_family:: { find_family_for_model, ModelFamily } ;
71+ use crate :: model_family:: { derive_default_model_family , find_family_for_model, ModelFamily } ;
7272use crate :: model_provider_info:: ModelProviderInfo ;
7373use crate :: model_provider_info:: WireApi ;
7474use crate :: openai_tools:: create_tools_json_for_responses_api;
@@ -372,6 +372,46 @@ impl ModelClient {
372372 }
373373 }
374374
375+ /// Resolve the model family used to build a request.
376+ ///
377+ /// The newer codex-rs path passes resolved `ModelInfo` into the request
378+ /// builder. This older code-rs path still reconstructs families from the
379+ /// slug, so keep that reconstruction provider-aware at the final boundary.
380+ pub ( crate ) fn normalize_model_family_for_provider (
381+ & self ,
382+ mut family : ModelFamily ,
383+ ) -> ModelFamily {
384+ if !self . uses_first_party_openai_model_metadata ( ) {
385+ family. use_responses_lite = false ;
386+ family. prefer_websockets = false ;
387+ }
388+ family
389+ }
390+
391+ fn uses_first_party_openai_model_metadata ( & self ) -> bool {
392+ // Provider-owned ModelInfo is the codex-rs source of truth. This
393+ // compatibility check identifies the one built-in first-party path;
394+ // proxy/custom endpoints must not inherit embedded OpenAI capabilities.
395+ self . config . model_provider_id == "openai"
396+ && self . provider . is_public_openai_responses_endpoint ( )
397+ }
398+
399+ fn model_family_for_request ( & self , prompt : & Prompt , model : & str ) -> ModelFamily {
400+ let family = prompt
401+ . model_family_override
402+ . clone ( )
403+ . unwrap_or_else ( || {
404+ if self . uses_first_party_openai_model_metadata ( ) {
405+ find_family_for_model ( model)
406+ . unwrap_or_else ( || self . config . model_family . clone ( ) )
407+ } else {
408+ derive_default_model_family ( model)
409+ }
410+ } ) ;
411+
412+ self . normalize_model_family_for_provider ( family)
413+ }
414+
375415 /// Get the reasoning effort configuration
376416 pub fn get_reasoning_effort ( & self ) -> ReasoningEffortConfig {
377417 self . effort
@@ -778,11 +818,7 @@ impl ModelClient {
778818 . as_deref ( )
779819 . unwrap_or ( self . config . model . as_str ( ) ) ;
780820 let effective_effort = clamp_reasoning_effort_for_model ( request_model, self . effort ) ;
781- let request_family = prompt
782- . model_family_override
783- . clone ( )
784- . or_else ( || find_family_for_model ( request_model) )
785- . unwrap_or_else ( || self . config . model_family . clone ( ) ) ;
821+ let request_family = self . model_family_for_request ( prompt, request_model) ;
786822 let store = should_store_responses ( prompt, & self . provider , & request_family) ;
787823
788824 let full_instructions = prompt. get_full_instructions ( & request_family) ;
@@ -1265,11 +1301,7 @@ impl ModelClient {
12651301 . as_deref ( )
12661302 . unwrap_or ( self . config . model . as_str ( ) ) ;
12671303 let effective_effort = clamp_reasoning_effort_for_model ( request_model, self . effort ) ;
1268- let request_family = prompt
1269- . model_family_override
1270- . clone ( )
1271- . or_else ( || find_family_for_model ( request_model) )
1272- . unwrap_or_else ( || self . config . model_family . clone ( ) ) ;
1304+ let request_family = self . model_family_for_request ( prompt, request_model) ;
12731305 let store = should_store_responses ( prompt, & self . provider , & request_family) ;
12741306
12751307 let full_instructions = prompt. get_full_instructions ( & request_family) ;
@@ -2059,11 +2091,7 @@ impl ModelClient {
20592091 . model_override
20602092 . as_deref ( )
20612093 . unwrap_or ( self . config . model . as_str ( ) ) ;
2062- let family = prompt
2063- . model_family_override
2064- . clone ( )
2065- . or_else ( || find_family_for_model ( model_slug) )
2066- . unwrap_or_else ( || self . config . model_family . clone ( ) ) ;
2094+ let family = self . model_family_for_request ( prompt, model_slug) ;
20672095 let session_id = prompt. session_id_override . unwrap_or ( self . session_id ) ;
20682096 let session_id_str = session_id. to_string ( ) ;
20692097 let instructions = prompt. get_full_instructions ( & family) . into_owned ( ) ;
0 commit comments