1+ import warnings
12from typing import Any , Dict , List , Optional
23
34from pydantic import BaseModel , ConfigDict , Field
@@ -22,9 +23,7 @@ class OpenAIRealtimeOptions(BaseModel):
2223 messages : Optional [List [Dict [str , Any ]]] = Field (default = None , description = "Conversation messages" )
2324 params : Optional [Dict [str , Any ]] = Field (default = None , description = "Additional parameters" )
2425 turn_detection : Optional [MllmTurnDetectionConfig ] = Field (default = None , description = "MLLM turn detection configuration" )
25- predefined_tools : Optional [List [str ]] = Field (default = None , description = "Predefined tools" )
2626 failure_message : Optional [str ] = Field (default = None , description = "Message played on failure" )
27- max_history : Optional [int ] = Field (default = None , description = "Maximum conversation history length" )
2827
2928class OpenAIRealtime (BaseMLLM ):
3029 def __init__ (self , ** kwargs : Any ):
@@ -53,18 +52,97 @@ def to_config(self) -> Dict[str, Any]:
5352 config ["output_modalities" ] = self .options .output_modalities
5453 if self .options .messages is not None :
5554 config ["messages" ] = self .options .messages
56- if self .options .predefined_tools is not None :
57- config ["predefined_tools" ] = self .options .predefined_tools
5855 if self .options .failure_message is not None :
5956 config ["failure_message" ] = self .options .failure_message
60- if self .options .max_history is not None :
61- config ["max_history" ] = self .options .max_history
6257 if self .options .turn_detection is not None :
6358 config ["turn_detection" ] = self .options .turn_detection
6459
6560 return config
6661
6762
63+ # xAI MLLM: use XaiGrok (product name, mllm.vendor "xai"). Do not use XaiRealtime—that name
64+ # is deprecated and reserved naming for future XaiSTT / XaiTTS cascading vendors.
65+
66+
67+ class XaiGrokOptions (BaseModel ):
68+ model_config = ConfigDict (extra = "forbid" )
69+
70+ api_key : str = Field (..., description = "xAI API key" )
71+ url : str = Field (default = "wss://api.x.ai/v1/realtime" , description = "xAI Realtime WebSocket URL" )
72+ voice : Optional [str ] = Field (default = None , description = "Voice identifier (e.g., eve or rex)" )
73+ language : Optional [str ] = Field (default = None , description = "Language code (e.g., en)" )
74+ sample_rate : Optional [int ] = Field (default = None , description = "Audio sample rate in Hz" )
75+ greeting_message : Optional [str ] = Field (default = None , description = "Agent greeting message" )
76+ input_modalities : Optional [List [str ]] = Field (default = None , description = "Input modalities" )
77+ output_modalities : Optional [List [str ]] = Field (default = None , description = "Output modalities" )
78+ messages : Optional [List [Dict [str , Any ]]] = Field (default = None , description = "Conversation messages" )
79+ params : Optional [Dict [str , Any ]] = Field (default = None , description = "Additional xAI parameters" )
80+ turn_detection : Optional [MllmTurnDetectionConfig ] = Field (default = None , description = "MLLM turn detection configuration" )
81+ failure_message : Optional [str ] = Field (default = None , description = "Message played on failure" )
82+
83+
84+ class XaiGrok (BaseMLLM ):
85+ """xAI Grok MLLM vendor (`mllm.vendor`: ``xai``)."""
86+
87+ def __init__ (self , ** kwargs : Any ):
88+ self .options = XaiGrokOptions (** kwargs )
89+
90+ def to_config (self ) -> Dict [str , Any ]:
91+ params : Dict [str , Any ] = dict (self .options .params or {})
92+ if self .options .voice is not None :
93+ params ["voice" ] = self .options .voice
94+ if self .options .language is not None :
95+ params ["language" ] = self .options .language
96+ if self .options .sample_rate is not None :
97+ params ["sample_rate" ] = self .options .sample_rate
98+
99+ config : Dict [str , Any ] = {
100+ "vendor" : "xai" ,
101+ "api_key" : self .options .api_key ,
102+ "url" : self .options .url ,
103+ "params" : params ,
104+ }
105+
106+ if self .options .greeting_message is not None :
107+ config ["greeting_message" ] = self .options .greeting_message
108+ if self .options .input_modalities is not None :
109+ config ["input_modalities" ] = self .options .input_modalities
110+ if self .options .output_modalities is not None :
111+ config ["output_modalities" ] = self .options .output_modalities
112+ if self .options .messages is not None :
113+ config ["messages" ] = self .options .messages
114+ if self .options .failure_message is not None :
115+ config ["failure_message" ] = self .options .failure_message
116+ if self .options .turn_detection is not None :
117+ config ["turn_detection" ] = self .options .turn_detection
118+
119+ return config
120+
121+
122+ class XaiRealtimeOptions (XaiGrokOptions ):
123+ """Deprecated: use :class:`XaiGrokOptions` instead."""
124+
125+ def __init__ (self , ** data : Any ):
126+ warnings .warn (
127+ "XaiRealtimeOptions is deprecated; use XaiGrokOptions instead." ,
128+ DeprecationWarning ,
129+ stacklevel = 2 ,
130+ )
131+ super ().__init__ (** data )
132+
133+
134+ class XaiRealtime (XaiGrok ):
135+ """Deprecated: use :class:`XaiGrok` instead."""
136+
137+ def __init__ (self , ** kwargs : Any ):
138+ warnings .warn (
139+ "XaiRealtime is deprecated; use XaiGrok instead." ,
140+ DeprecationWarning ,
141+ stacklevel = 2 ,
142+ )
143+ super ().__init__ (** kwargs )
144+
145+
68146class VertexAIOptions (BaseModel ):
69147 model_config = ConfigDict (extra = "forbid" )
70148
@@ -81,28 +159,24 @@ class VertexAIOptions(BaseModel):
81159 messages : Optional [List [Dict [str , Any ]]] = Field (default = None , description = "Conversation messages" )
82160 additional_params : Optional [Dict [str , Any ]] = Field (default = None , description = "Additional parameters" )
83161 turn_detection : Optional [MllmTurnDetectionConfig ] = Field (default = None , description = "MLLM turn detection configuration" )
84- predefined_tools : Optional [List [str ]] = Field (default = None , description = "Predefined tools" )
85162 failure_message : Optional [str ] = Field (default = None , description = "Message played on failure" )
86- max_history : Optional [int ] = Field (default = None , description = "Maximum conversation history length" )
87163
88164class VertexAI (BaseMLLM ):
89165 def __init__ (self , ** kwargs : Any ):
90166 self .options = VertexAIOptions (** kwargs )
91167
92168 def to_config (self ) -> Dict [str , Any ]:
93- params : Dict [ str , Any ] = {
94- "model" : self . options . model ,
95- "project_id" : self .options .project_id ,
96- "location" : self .options .location ,
97- "adc_credentials_string" : self .options .adc_credentials_string ,
98- }
99-
169+ # additional_params spread first so that explicit fields always win,
170+ # matching the TypeScript SDK.
171+ params : Dict [ str , Any ] = dict ( self .options .additional_params or {})
172+ params [ "model" ] = self .options .model
173+ params [ "project_id" ] = self .options .project_id
174+ params [ "location" ] = self . options . location
175+ params [ "adc_credentials_string" ] = self . options . adc_credentials_string
100176 if self .options .instructions is not None :
101177 params ["instructions" ] = self .options .instructions
102178 if self .options .voice is not None :
103179 params ["voice" ] = self .options .voice
104- if self .options .additional_params is not None :
105- params .update (self .options .additional_params )
106180
107181 config : Dict [str , Any ] = {
108182 "vendor" : "vertexai" ,
@@ -119,12 +193,8 @@ def to_config(self) -> Dict[str, Any]:
119193 config ["output_modalities" ] = self .options .output_modalities
120194 if self .options .messages is not None :
121195 config ["messages" ] = self .options .messages
122- if self .options .predefined_tools is not None :
123- config ["predefined_tools" ] = self .options .predefined_tools
124196 if self .options .failure_message is not None :
125197 config ["failure_message" ] = self .options .failure_message
126- if self .options .max_history is not None :
127- config ["max_history" ] = self .options .max_history
128198 if self .options .turn_detection is not None :
129199 config ["turn_detection" ] = self .options .turn_detection
130200
@@ -145,9 +215,7 @@ class GeminiLiveOptions(BaseModel):
145215 messages : Optional [List [Dict [str , Any ]]] = Field (default = None , description = "Conversation messages" )
146216 additional_params : Optional [Dict [str , Any ]] = Field (default = None , description = "Additional parameters" )
147217 turn_detection : Optional [MllmTurnDetectionConfig ] = Field (default = None , description = "MLLM turn detection configuration" )
148- predefined_tools : Optional [List [str ]] = Field (default = None , description = "Predefined tools" )
149218 failure_message : Optional [str ] = Field (default = None , description = "Message played on failure" )
150- max_history : Optional [int ] = Field (default = None , description = "Maximum conversation history length" )
151219
152220class GeminiLive (BaseMLLM ):
153221 def __init__ (self , ** kwargs : Any ):
@@ -179,12 +247,8 @@ def to_config(self) -> Dict[str, Any]:
179247 config ["output_modalities" ] = self .options .output_modalities
180248 if self .options .messages is not None :
181249 config ["messages" ] = self .options .messages
182- if self .options .predefined_tools is not None :
183- config ["predefined_tools" ] = self .options .predefined_tools
184250 if self .options .failure_message is not None :
185251 config ["failure_message" ] = self .options .failure_message
186- if self .options .max_history is not None :
187- config ["max_history" ] = self .options .max_history
188252 if self .options .turn_detection is not None :
189253 config ["turn_detection" ] = self .options .turn_detection
190254
0 commit comments