chore: Disable SetModelResponseTool workaround for Vertex AI Gemini 2+ models

Gemini models now [support Function calling being used together with structured output on Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#structured-output-bp).

Co-authored-by: Xuan Yang <xygoogle@google.com>
PiperOrigin-RevId: 827709903
This commit is contained in:
Xuan Yang
2025-11-03 17:12:01 -08:00
committed by Copybara-Service
parent 8b6ee576d5
commit 6a94af24bf
6 changed files with 170 additions and 12 deletions
@@ -14,6 +14,8 @@
"""Tests for basic LLM request processor."""
from unittest import mock
from google.adk.agents.invocation_context import InvocationContext
from google.adk.agents.llm_agent import LlmAgent
from google.adk.agents.run_config import RunConfig
@@ -80,7 +82,7 @@ class TestBasicLlmRequestProcessor:
assert llm_request.config.response_mime_type == 'application/json'
@pytest.mark.asyncio
async def test_skips_output_schema_when_tools_present(self):
async def test_skips_output_schema_when_tools_present(self, mocker):
"""Test that processor skips output_schema when agent has tools."""
agent = LlmAgent(
name='test_agent',
@@ -93,6 +95,11 @@ class TestBasicLlmRequestProcessor:
llm_request = LlmRequest()
processor = _BasicLlmRequestProcessor()
can_use_output_schema_with_tools = mocker.patch(
'google.adk.flows.llm_flows.basic.can_use_output_schema_with_tools',
mock.MagicMock(return_value=False),
)
# Process the request
events = []
async for event in processor.run_async(invocation_context, llm_request):
@@ -102,6 +109,40 @@ class TestBasicLlmRequestProcessor:
assert llm_request.config.response_schema is None
assert llm_request.config.response_mime_type != 'application/json'
# Should have checked if output schema can be used with tools
can_use_output_schema_with_tools.assert_called_once_with(agent.model)
@pytest.mark.asyncio
async def test_sets_output_schema_when_tools_present(self, mocker):
"""Test that processor skips output_schema when agent has tools."""
agent = LlmAgent(
name='test_agent',
model='gemini-2.5-flash',
output_schema=OutputSchema,
tools=[FunctionTool(func=dummy_tool)], # Has tools
)
invocation_context = await _create_invocation_context(agent)
llm_request = LlmRequest()
processor = _BasicLlmRequestProcessor()
can_use_output_schema_with_tools = mocker.patch(
'google.adk.flows.llm_flows.basic.can_use_output_schema_with_tools',
mock.MagicMock(return_value=True),
)
# Process the request
events = []
async for event in processor.run_async(invocation_context, llm_request):
events.append(event)
# Should have set response_schema since output schema can be used with tools
assert llm_request.config.response_schema == OutputSchema
assert llm_request.config.response_mime_type == 'application/json'
# Should have checked if output schema can be used with tools
can_use_output_schema_with_tools.assert_called_once_with(agent.model)
@pytest.mark.asyncio
async def test_no_output_schema_no_tools(self):
"""Test that processor works normally when agent has no output_schema or tools."""
@@ -14,14 +14,13 @@
"""Tests for output schema processor functionality."""
import json
from unittest import mock
from google.adk.agents.invocation_context import InvocationContext
from google.adk.agents.llm_agent import LlmAgent
from google.adk.agents.run_config import RunConfig
from google.adk.flows.llm_flows.single_flow import SingleFlow
from google.adk.models.llm_request import LlmRequest
from google.adk.models.llm_response import LlmResponse
from google.adk.sessions.in_memory_session_service import InMemorySessionService
from google.adk.tools.function_tool import FunctionTool
from pydantic import BaseModel
@@ -145,7 +144,16 @@ async def test_basic_processor_sets_output_schema_without_tools():
@pytest.mark.asyncio
async def test_output_schema_request_processor():
@pytest.mark.parametrize(
'output_schema_with_tools_allowed',
[
False,
True,
],
)
async def test_output_schema_request_processor(
output_schema_with_tools_allowed, mocker
):
"""Test that output schema processor adds set_model_response tool."""
from google.adk.flows.llm_flows._output_schema_processor import _OutputSchemaRequestProcessor
@@ -161,16 +169,29 @@ async def test_output_schema_request_processor():
llm_request = LlmRequest()
processor = _OutputSchemaRequestProcessor()
can_use_output_schema_with_tools = mocker.patch(
'google.adk.flows.llm_flows._output_schema_processor.can_use_output_schema_with_tools',
mock.MagicMock(return_value=output_schema_with_tools_allowed),
)
# Process the request
events = []
async for event in processor.run_async(invocation_context, llm_request):
events.append(event)
# Should have added set_model_response tool
assert 'set_model_response' in llm_request.tools_dict
if not output_schema_with_tools_allowed:
# Should have added set_model_response tool if output schema with tools is
# allowed
assert 'set_model_response' in llm_request.tools_dict
# Should have added instruction about using set_model_response
assert 'set_model_response' in llm_request.config.system_instruction
else:
# Should skip modifying LlmRequest
assert not llm_request.tools_dict
assert not llm_request.config.system_instruction
# Should have added instruction about using set_model_response
assert 'set_model_response' in llm_request.config.system_instruction
# Should have checked if output schema can be used with tools
can_use_output_schema_with_tools.assert_called_once_with(agent.model)
@pytest.mark.asyncio