From c0892c725c105458b5cac09e3b8eb982a389f169 Mon Sep 17 00:00:00 2001 From: Ieva Grublyte Date: Thu, 30 Oct 2025 06:05:51 -0700 Subject: [PATCH] chore: remove legacy validation that forbids co-exist of agent transfer and output_schema. Closes #3318 Remove validation for output_schema and agent transfer flags. The check that prevented `output_schema` from co-existing with agent transfer capabilities (`disallow_transfer_to_parent` or `disallow_transfer_to_peers` being False) has been removed. The agent will no longer automatically set these transfer flags to True when `output_schema` is present. Co-authored-by: Ieva Grublyte PiperOrigin-RevId: 825998224 --- src/google/adk/agents/llm_agent.py | 24 ----------- .../unittests/agents/test_llm_agent_fields.py | 40 ++++++------------- .../llm_flows/test_output_schema_processor.py | 18 +++++++++ 3 files changed, 31 insertions(+), 51 deletions(-) diff --git a/src/google/adk/agents/llm_agent.py b/src/google/adk/agents/llm_agent.py index 8e13ea89..c2d00783 100644 --- a/src/google/adk/agents/llm_agent.py +++ b/src/google/adk/agents/llm_agent.py @@ -744,32 +744,8 @@ class LlmAgent(BaseAgent): @model_validator(mode='after') def __model_validator_after(self) -> LlmAgent: - self.__check_output_schema() return self - def __check_output_schema(self): - if not self.output_schema: - return - - if ( - not self.disallow_transfer_to_parent - or not self.disallow_transfer_to_peers - ): - logger.warning( - 'Invalid config for agent %s: output_schema cannot co-exist with' - ' agent transfer configurations. Setting' - ' disallow_transfer_to_parent=True, disallow_transfer_to_peers=True', - self.name, - ) - self.disallow_transfer_to_parent = True - self.disallow_transfer_to_peers = True - - if self.sub_agents: - raise ValueError( - f'Invalid config for agent {self.name}: if output_schema is set,' - ' sub_agents must be empty to disable agent transfer.' - ) - @field_validator('generate_content_config', mode='after') @classmethod def validate_generate_content_config( diff --git a/tests/unittests/agents/test_llm_agent_fields.py b/tests/unittests/agents/test_llm_agent_fields.py index 5540e55b..c57254db 100644 --- a/tests/unittests/agents/test_llm_agent_fields.py +++ b/tests/unittests/agents/test_llm_agent_fields.py @@ -167,27 +167,7 @@ async def test_async_canonical_global_instruction(): assert bypass_state_injection -def test_output_schema_will_disable_transfer(caplog: pytest.LogCaptureFixture): - with caplog.at_level('WARNING'): - - class Schema(BaseModel): - pass - - agent = LlmAgent( - name='test_agent', - output_schema=Schema, - ) - - # Transfer is automatically disabled - assert agent.disallow_transfer_to_parent - assert agent.disallow_transfer_to_peers - assert ( - 'output_schema cannot co-exist with agent transfer configurations.' - in caplog.text - ) - - -def test_output_schema_with_sub_agents_will_throw(): +def test_output_schema_with_sub_agents_will_not_throw(): class Schema(BaseModel): pass @@ -195,12 +175,18 @@ def test_output_schema_with_sub_agents_will_throw(): name='sub_agent', ) - with pytest.raises(ValueError): - _ = LlmAgent( - name='test_agent', - output_schema=Schema, - sub_agents=[sub_agent], - ) + agent = LlmAgent( + name='test_agent', + output_schema=Schema, + sub_agents=[sub_agent], + ) + + # Transfer is not disabled + assert not agent.disallow_transfer_to_parent + assert not agent.disallow_transfer_to_peers + + assert agent.output_schema == Schema + assert agent.sub_agents == [sub_agent] def test_output_schema_with_tools_will_not_throw(): diff --git a/tests/unittests/flows/llm_flows/test_output_schema_processor.py b/tests/unittests/flows/llm_flows/test_output_schema_processor.py index a9dea8c9..4c43407c 100644 --- a/tests/unittests/flows/llm_flows/test_output_schema_processor.py +++ b/tests/unittests/flows/llm_flows/test_output_schema_processor.py @@ -72,6 +72,24 @@ async def test_output_schema_with_tools_validation_removed(): assert len(agent.tools) == 1 +@pytest.mark.asyncio +async def test_output_schema_with_sub_agents(): + """Test that LlmAgent now allows output_schema with sub_agents.""" + sub_agent = LlmAgent( + name='sub_agent', + model='gemini-1.5-flash', + ) + agent = LlmAgent( + name='test_agent', + model='gemini-1.5-flash', + output_schema=PersonSchema, + sub_agents=[sub_agent], + ) + + assert agent.output_schema == PersonSchema + assert len(agent.sub_agents) == 1 + + @pytest.mark.asyncio async def test_basic_processor_skips_output_schema_with_tools(): """Test that basic processor doesn't set output_schema when tools are present."""