@@ -98,7 +98,12 @@ impl OpenAiProvider {
9898 user_prompt : & str ,
9999 request : ProviderRequest ,
100100 ) -> CoreResult < String > {
101- let base = self . responses_base_payload ( system_prompt, user_prompt, Some ( request. temperature ) ) ;
101+ let temperature = if self . is_gpt5 ( ) {
102+ None
103+ } else {
104+ Some ( request. temperature )
105+ } ;
106+ let base = self . responses_base_payload ( system_prompt, user_prompt, temperature) ;
102107
103108 match self
104109 . complete_responses_with_fallbacks ( & base, request. max_output_tokens )
@@ -123,11 +128,16 @@ impl OpenAiProvider {
123128 user_prompt : & str ,
124129 request : ProviderRequest ,
125130 ) -> CoreResult < String > {
131+ let temperature = if self . is_gpt5 ( ) {
132+ None
133+ } else {
134+ Some ( request. temperature )
135+ } ;
126136 let body = self . chat_payload (
127137 system_prompt,
128138 user_prompt,
129139 request. max_output_tokens ,
130- Some ( request . temperature ) ,
140+ temperature,
131141 ) ;
132142
133143 let http_request = self
@@ -182,6 +192,16 @@ impl OpenAiProvider {
182192 } ) ;
183193
184194 if let Some ( obj) = payload. as_object_mut ( ) {
195+ if self . is_gpt5 ( ) {
196+ obj. insert (
197+ "reasoning" . to_string ( ) ,
198+ serde_json:: json!( { "effort" : "none" } ) ,
199+ ) ;
200+ obj. insert (
201+ "text" . to_string ( ) ,
202+ serde_json:: json!( { "format" : { "type" : "text" } } ) ,
203+ ) ;
204+ }
185205 if let Some ( value) = temperature {
186206 obj. insert ( "temperature" . to_string ( ) , serde_json:: json!( value) ) ;
187207 }
@@ -236,6 +256,10 @@ impl OpenAiProvider {
236256 }
237257 }
238258
259+ fn is_gpt5 ( & self ) -> bool {
260+ self . model . trim ( ) . to_lowercase ( ) . starts_with ( "gpt-5" )
261+ }
262+
239263 async fn complete_responses_with_param (
240264 & self ,
241265 base : & Value ,
@@ -396,6 +420,41 @@ mod tests {
396420 assert ! ( payload. get( "temperature" ) . is_none( ) ) ;
397421 }
398422
423+ #[ test]
424+ fn responses_payload_sets_reasoning_none_for_gpt5 ( ) {
425+ let provider = OpenAiProvider :: new (
426+ "gpt-5-nano-2025-08-07" . to_string ( ) ,
427+ "https://api.openai.com/v1" . to_string ( ) ,
428+ OpenAiMode :: Responses ,
429+ 5 ,
430+ Some ( "test-key" . to_string ( ) ) ,
431+ )
432+ . expect ( "provider" ) ;
433+
434+ let payload = provider. responses_base_payload ( "system" , "user" , None ) ;
435+ let effort = payload
436+ . get ( "reasoning" )
437+ . and_then ( |value| value. get ( "effort" ) )
438+ . and_then ( |value| value. as_str ( ) ) ;
439+ assert_eq ! ( effort, Some ( "none" ) ) ;
440+ assert ! ( payload. get( "text" ) . is_some( ) ) ;
441+ }
442+
443+ #[ test]
444+ fn responses_payload_skips_reasoning_for_non_gpt5 ( ) {
445+ let provider = OpenAiProvider :: new (
446+ "gpt-4o-mini" . to_string ( ) ,
447+ "https://api.openai.com/v1" . to_string ( ) ,
448+ OpenAiMode :: Responses ,
449+ 5 ,
450+ Some ( "test-key" . to_string ( ) ) ,
451+ )
452+ . expect ( "provider" ) ;
453+
454+ let payload = provider. responses_base_payload ( "system" , "user" , None ) ;
455+ assert ! ( payload. get( "reasoning" ) . is_none( ) ) ;
456+ }
457+
399458 #[ test]
400459 fn chat_payload_omits_temperature_when_none ( ) {
401460 let provider = OpenAiProvider :: new (
0 commit comments