diff --git a/src/google/adk/integrations/oci/_oci_genai_llm.py b/src/google/adk/integrations/oci/_oci_genai_llm.py index 1e9b00b56f..3edf779a51 100644 --- a/src/google/adk/integrations/oci/_oci_genai_llm.py +++ b/src/google/adk/integrations/oci/_oci_genai_llm.py @@ -196,14 +196,25 @@ def _content_to_oci_message(content: types.Content) -> Any: role = _to_oci_role(content.role) - # Tool results map to ToolMessage (one per result) + # Tool results map to ToolMessage (one per result). Multiple parallel tool + # results are returned as a list of ToolMessages so none are dropped; + # mirror _content_to_message_param in lite_llm.py. if tool_results: - call_id, result_text = tool_results[0] - return oci_models.ToolMessage( - role=oci_models.ToolMessage.ROLE_TOOL, - tool_call_id=call_id, - content=[oci_models.TextContent(type="TEXT", text=result_text)], - ) + if len(tool_results) == 1: + call_id, result_text = tool_results[0] + return oci_models.ToolMessage( + role=oci_models.ToolMessage.ROLE_TOOL, + tool_call_id=call_id, + content=[oci_models.TextContent(type="TEXT", text=result_text)], + ) + return [ + oci_models.ToolMessage( + role=oci_models.ToolMessage.ROLE_TOOL, + tool_call_id=call_id, + content=[oci_models.TextContent(type="TEXT", text=result_text)], + ) + for call_id, result_text in tool_results + ] if role == "ASSISTANT": oci_content: list[Any] = [] @@ -451,7 +462,13 @@ def _build_chat_details( """Build OCI ChatDetails from an LlmRequest.""" import oci.generative_ai_inference.models as oci_models - messages = [_content_to_oci_message(c) for c in llm_request.contents or []] + messages: list[Any] = [] + for c in llm_request.contents or []: + msg = _content_to_oci_message(c) + if isinstance(msg, list): + messages.extend(msg) + else: + messages.append(msg) # Prepend SystemMessage when a system instruction is present if llm_request.config and llm_request.config.system_instruction: diff --git a/tests/unittests/integrations/oci/test_oci_genai_llm.py b/tests/unittests/integrations/oci/test_oci_genai_llm.py index b076f8a226..9aea3ca10a 100644 --- a/tests/unittests/integrations/oci/test_oci_genai_llm.py +++ b/tests/unittests/integrations/oci/test_oci_genai_llm.py @@ -227,6 +227,50 @@ def test_content_to_oci_message_function_response(): assert msg.content[0].text +def test_content_to_oci_message_multiple_function_responses(): + import oci.generative_ai_inference.models as oci_models + + part_a = Part.from_function_response( + name="get_weather", response={"temp": 22} + ) + part_a.function_response.id = "call_A" + part_b = Part.from_function_response( + name="get_price", response={"price": 150} + ) + part_b.function_response.id = "call_B" + content = Content(role="user", parts=[part_a, part_b]) + msg = _content_to_oci_message(content) + assert isinstance(msg, list) + assert len(msg) == 2 + assert all(isinstance(m, oci_models.ToolMessage) for m in msg) + assert msg[0].tool_call_id == "call_A" + assert msg[1].tool_call_id == "call_B" + assert msg[0].content[0].text + assert msg[1].content[0].text + + +def test_build_chat_details_flattens_multiple_tool_messages(oci_llm): + import oci.generative_ai_inference.models as oci_models + + part_a = Part.from_function_response( + name="get_weather", response={"temp": 22} + ) + part_a.function_response.id = "call_A" + part_b = Part.from_function_response( + name="get_price", response={"price": 150} + ) + part_b.function_response.id = "call_B" + request = LlmRequest( + model="google.gemini-2.5-flash", + contents=[Content(role="user", parts=[part_a, part_b])], + ) + chat_details = oci_llm._build_chat_details(request) + messages = chat_details.chat_request.messages + assert len(messages) == 2 + assert all(m.role == oci_models.ToolMessage.ROLE_TOOL for m in messages) + assert [m.tool_call_id for m in messages] == ["call_A", "call_B"] + + # --------------------------------------------------------------------------- # _oci_response_to_llm_response # ---------------------------------------------------------------------------