@@ -40,6 +40,7 @@ pub struct OpenAICompatibleProvider<T: OpenAIProviderConfig> {
4040 pub reasoning_effort : Option < String > ,
4141 pub json_schema : Option < StructuredOutputFormat > ,
4242 pub voice : Option < String > ,
43+ pub extra_body : serde_json:: Map < String , serde_json:: Value > ,
4344 pub parallel_tool_calls : bool ,
4445 pub embedding_encoding_format : Option < String > ,
4546 pub embedding_dimensions : Option < u32 > ,
@@ -135,6 +136,8 @@ pub struct OpenAIChatRequest<'a> {
135136 pub stream_options : Option < OpenAIStreamOptions > ,
136137 #[ serde( skip_serializing_if = "Option::is_none" ) ]
137138 pub parallel_tool_calls : Option < bool > ,
139+ #[ serde( flatten) ]
140+ pub extra_body : serde_json:: Map < String , serde_json:: Value > ,
138141}
139142
140143/// Generic OpenAI-compatible chat response
@@ -306,6 +309,7 @@ impl<T: OpenAIProviderConfig> OpenAICompatibleProvider<T> {
306309 reasoning_effort : Option < String > ,
307310 json_schema : Option < StructuredOutputFormat > ,
308311 voice : Option < String > ,
312+ extra_body : Option < serde_json:: Value > ,
309313 parallel_tool_calls : Option < bool > ,
310314 normalize_response : Option < bool > ,
311315 embedding_encoding_format : Option < String > ,
@@ -315,6 +319,10 @@ impl<T: OpenAIProviderConfig> OpenAICompatibleProvider<T> {
315319 if let Some ( sec) = timeout_seconds {
316320 builder = builder. timeout ( std:: time:: Duration :: from_secs ( sec) ) ;
317321 }
322+ let extra_body = match extra_body {
323+ Some ( serde_json:: Value :: Object ( map) ) => map,
324+ _ => serde_json:: Map :: new ( ) , // Should we panic here?
325+ } ;
318326 Self {
319327 api_key : api_key. into ( ) ,
320328 base_url : Url :: parse ( & base_url. unwrap_or_else ( || T :: DEFAULT_BASE_URL . to_owned ( ) ) )
@@ -331,6 +339,7 @@ impl<T: OpenAIProviderConfig> OpenAICompatibleProvider<T> {
331339 reasoning_effort,
332340 json_schema,
333341 voice,
342+ extra_body,
334343 parallel_tool_calls : parallel_tool_calls. unwrap_or ( false ) ,
335344 normalize_response : normalize_response. unwrap_or ( true ) ,
336345 embedding_encoding_format,
@@ -432,6 +441,7 @@ impl<T: OpenAIProviderConfig> ChatProvider for OpenAICompatibleProvider<T> {
432441 response_format,
433442 stream_options : None ,
434443 parallel_tool_calls,
444+ extra_body : self . extra_body . clone ( ) ,
435445 } ;
436446 let url = self
437447 . base_url
@@ -547,6 +557,7 @@ impl<T: OpenAIProviderConfig> ChatProvider for OpenAICompatibleProvider<T> {
547557 } else {
548558 None
549559 } ,
560+ extra_body : self . extra_body . clone ( ) ,
550561 } ;
551562 let url = self
552563 . base_url
0 commit comments