@@ -2037,6 +2037,7 @@ class Google(Llm, GenAIMixin):
20372037 })
20382038
20392039 select_models = param .List (default = [
2040+ "gemini-3.5-flash" ,
20402041 "gemini-3-flash-preview" ,
20412042 "gemini-3-pro-preview" ,
20422043 "gemini-2.5-pro" ,
@@ -2089,12 +2090,16 @@ def _get_content(cls, response: Any) -> str | BaseModel:
20892090 return str (response )
20902091
20912092 @classmethod
2092- def _messages_to_contents (cls , messages : list [Message ]) -> tuple [list [dict [str , Any ]], str | None ]:
2093+ def _messages_to_contents (
2094+ cls , messages : list [Message ]
2095+ ) -> tuple [list [dict [str , Any ]], str | None , list [dict [str , Any ]]]:
20932096 """
20942097 Transform messages into contents format expected by Google GenAI API.
20952098
20962099 Extracts system messages and returns them separately since Google
2097- requires them via the system_instruction parameter.
2100+ requires them via the system_instruction parameter. Also returns a
2101+ role-normalized (assistant → model) flat messages list for use with
2102+ instructor's Gemini provider, which rejects role="assistant".
20982103
20992104 Parameters
21002105 ----------
@@ -2103,21 +2108,29 @@ def _messages_to_contents(cls, messages: list[Message]) -> tuple[list[dict[str,
21032108
21042109 Returns
21052110 -------
2106- tuple[list[dict[str, Any]], str | None]
2107- Tuple of (contents list, system_instruction)
2111+ tuple[list[dict[str, Any]], str | None, list[dict[str, Any]] ]
2112+ Tuple of (contents list, system_instruction, instructor_messages )
21082113 """
2114+ # Normalize roles up front: Gemini (and instructor's Gemini converter)
2115+ # use "model" instead of "assistant".
2116+ normalized = [
2117+ {** m , "role" : "model" } if m .get ("role" ) == "assistant" else m
2118+ for m in messages
2119+ ]
2120+
21092121 contents = []
21102122 system_instruction = None
2123+ instructor_messages = []
21112124
2112- for message in messages :
2125+ for message in normalized :
21132126 role = message ["role" ]
21142127 content = message ["content" ]
21152128 if role == "system" :
21162129 system_instruction = content
21172130 continue
21182131
2119- # Assistant message containing tool calls → model with function_call parts
2120- if role == "assistant " and message .get ("tool_calls" ):
2132+ # Model message containing tool calls → function_call parts
2133+ if role == "model " and message .get ("tool_calls" ):
21212134 parts = []
21222135 for tc in message ["tool_calls" ]:
21232136 name , args , _ = cls ._parse_tool_call (tc )
@@ -2158,8 +2171,9 @@ def _messages_to_contents(cls, messages: list[Message]) -> tuple[list[dict[str,
21582171 "role" : role ,
21592172 "parts" : [{"text" : content }]
21602173 })
2174+ instructor_messages .append ({"role" : role , "content" : content })
21612175
2162- return contents , system_instruction
2176+ return contents , system_instruction , instructor_messages
21632177
21642178 async def get_client (self , model_spec : str | dict , response_model : BaseModel | None = None , ** kwargs ):
21652179 model_kwargs = self ._get_model_kwargs (model_spec )
@@ -2241,7 +2255,7 @@ def _translate_tool_specs(cls, tool_specs: list) -> Any:
22412255 description = func .get ("description" , "" ),
22422256 parameters = parameters ,
22432257 ))
2244- return Tool (function_declarations = declarations ) if declarations else None
2258+ return [ Tool (function_declarations = declarations )] if declarations else None
22452259
22462260 @classmethod
22472261 def _get_delta (cls , chunk : Any ) -> str :
@@ -2280,7 +2294,7 @@ async def run_client(self, model_spec: str | dict, messages: list[Message], **kw
22802294
22812295 tools = self ._translate_tool_specs (kwargs .pop ("tools" , []))
22822296 client = await self .get_client (model_spec , ** kwargs )
2283- contents , system_instruction = self ._messages_to_contents (messages )
2297+ contents , system_instruction , instructor_messages = self ._messages_to_contents (messages )
22842298 config = GenerateContentConfig (
22852299 http_options = http_options ,
22862300 temperature = self .temperature ,
@@ -2290,7 +2304,7 @@ async def run_client(self, model_spec: str | dict, messages: list[Message], **kw
22902304 )
22912305
22922306 if response_model :
2293- result = await client (messages = messages , config = config , ** kwargs )
2307+ result = await client (messages = instructor_messages , config = config , ** kwargs )
22942308 return result
22952309
22962310 kwargs .pop ("stream" , None )
0 commit comments