@@ -168,7 +168,26 @@ def _convert_messages(self, messages: List[Dict[str, Any]]) -> tuple[Optional[st
168168 if role == "system" :
169169 system_instruction = content
170170 elif role == "assistant" :
171- contents .append ({"role" : "model" , "parts" : [{"text" : content }]})
171+ # Handle assistant messages with or without tool calls
172+ parts = []
173+ if content :
174+ parts .append ({"text" : content })
175+ # Convert tool_calls to Google's function_call format
176+ tool_calls = msg .get ("tool_calls" , [])
177+ if tool_calls :
178+ import json
179+
180+ for tc in tool_calls :
181+ if tc .get ("type" ) == "function" :
182+ func = tc .get ("function" , {})
183+ args_str = func .get ("arguments" , "{}" )
184+ try :
185+ args = json .loads (args_str ) if isinstance (args_str , str ) else args_str
186+ except json .JSONDecodeError :
187+ args = {}
188+ parts .append ({"function_call" : {"name" : func .get ("name" , "" ), "args" : args }})
189+ if parts :
190+ contents .append ({"role" : "model" , "parts" : parts })
172191 elif role == "tool" :
173192 # Tool response in Google format
174193 tool_call_id = msg .get ("tool_call_id" , "" )
@@ -237,7 +256,7 @@ def _parse_response(self, response: Any) -> ChatResponse:
237256 tool_calls = None
238257 if hasattr (response , "candidates" ) and response .candidates :
239258 candidate = response .candidates [0 ]
240- if hasattr (candidate , "content" ) and candidate .content :
259+ if hasattr (candidate , "content" ) and candidate .content and candidate . content . parts :
241260 for part in candidate .content .parts :
242261 if hasattr (part , "function_call" ) and part .function_call :
243262 if tool_calls is None :
0 commit comments