diff --git a/src/google/adk/agents/llm_agent.py b/src/google/adk/agents/llm_agent.py index 2eeb82f90c2..3785be27856 100644 --- a/src/google/adk/agents/llm_agent.py +++ b/src/google/adk/agents/llm_agent.py @@ -391,7 +391,9 @@ class LlmAgent(BaseAgent, abc.ABC): """The additional content generation configurations. NOTE: not all fields are usable, e.g. tools must be configured via `tools`, - thinking_config can be configured here or via the `planner`. If both are set, the planner's configuration takes precedence. + candidate_count must be 1 or unset, and thinking_config can be configured + here or via the `planner`. If both are set, the planner's configuration + takes precedence. For example: use this config to adjust model temperature, configure safety settings, etc. @@ -1252,6 +1254,16 @@ def validate_generate_content_config( ' or its client, not via' ' LlmAgent.generate_content_config.http_options.base_url.' ) + if ( + generate_content_config.candidate_count is not None + and generate_content_config.candidate_count > 1 + ): + raise ValueError( + 'candidate_count must be 1 or unset. LlmResponse keeps one' + ' candidate, so extra values are requested then discarded. Pass' + ' generate_content_config=types.GenerateContentConfig() without' + ' candidate_count, or set candidate_count=1.' + ) return generate_content_config @override diff --git a/tests/unittests/agents/test_llm_agent_error_messages.py b/tests/unittests/agents/test_llm_agent_error_messages.py index ae23d219829..8d2a9aec9d7 100644 --- a/tests/unittests/agents/test_llm_agent_error_messages.py +++ b/tests/unittests/agents/test_llm_agent_error_messages.py @@ -147,6 +147,15 @@ def test_response_schema_error_includes_move_guidance(self): with pytest.raises(ValueError, match=r'Move your schema'): LlmAgent.validate_generate_content_config(config) + def test_candidate_count_error_names_generate_content_config(self): + """candidate_count > 1 should name generate_content_config in the error.""" + config = types.GenerateContentConfig(candidate_count=2) + with pytest.raises( + ValueError, match=r'generate_content_config' + ) as exc_info: + LlmAgent.validate_generate_content_config(config) + assert 'candidate_count=1' in str(exc_info.value) + class TestGenerateContentKwargErrors: """Tests for misplaced GenerateContentConfig kwargs on LlmAgent.""" diff --git a/tests/unittests/agents/test_llm_agent_fields.py b/tests/unittests/agents/test_llm_agent_fields.py index 77beb5d8608..53ce69d5fa2 100644 --- a/tests/unittests/agents/test_llm_agent_fields.py +++ b/tests/unittests/agents/test_llm_agent_fields.py @@ -449,6 +449,24 @@ def test_validate_generate_content_config_http_options_base_url_throw(): ) +def test_validate_generate_content_config_candidate_count_throw(): + """candidate_count greater than 1 is rejected at LlmAgent construction.""" + with pytest.raises(ValueError, match=r'candidate_count must be 1 or unset'): + LlmAgent( + name='test_agent', + generate_content_config=types.GenerateContentConfig(candidate_count=2), + ) + + +def test_validate_generate_content_config_candidate_count_one_allowed(): + """candidate_count=1 remains settable on generate_content_config.""" + agent = LlmAgent( + name='test_agent', + generate_content_config=types.GenerateContentConfig(candidate_count=1), + ) + assert agent.generate_content_config.candidate_count == 1 + + def test_validate_generate_content_config_http_options_allowed(): """Tests that request-time http options remain settable in config.""" extra_body = {'tool_config': {'function_calling_config': {'mode': 'AUTO'}}}