From 7ebd8c27ba4fd3eb532842c0b135c761fe5cfab3 Mon Sep 17 00:00:00 2001 From: doug <110487462+doughayden@users.noreply.github.com> Date: Thu, 7 May 2026 19:46:57 -0400 Subject: [PATCH] fix(flows): terminate invocation at tool-level EUC - Set end_invocation after auth event in postprocess - Mirrors _resolve_toolset_auth's interrupt signal - Tests assert single LLM call when auth requested - events[-3] -> events[-2] in resume tests (tail trimmed) --- src/google/adk/flows/llm_flows/base_llm_flow.py | 3 +++ .../flows/llm_flows/test_functions_request_euc.py | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/google/adk/flows/llm_flows/base_llm_flow.py b/src/google/adk/flows/llm_flows/base_llm_flow.py index 31f998a588..9b6eda7dbb 100644 --- a/src/google/adk/flows/llm_flows/base_llm_flow.py +++ b/src/google/adk/flows/llm_flows/base_llm_flow.py @@ -1123,6 +1123,9 @@ async def _postprocess_handle_function_calls_async( if auth_event: yield auth_event + # Interrupt invocation (mirrors _resolve_toolset_auth behavior) + invocation_context.end_invocation = True + tool_confirmation_event = functions.generate_request_confirmation_event( invocation_context, function_call_event, function_response_event ) diff --git a/tests/unittests/flows/llm_flows/test_functions_request_euc.py b/tests/unittests/flows/llm_flows/test_functions_request_euc.py index f1e1d1f610..5ef81c8748 100644 --- a/tests/unittests/flows/llm_flows/test_functions_request_euc.py +++ b/tests/unittests/flows/llm_flows/test_functions_request_euc.py @@ -152,6 +152,8 @@ def call_external_api2(tool_context: ToolContext) -> Optional[int]: == auth_configs[idx].raw_auth_credential ) + assert len(mock_model.requests) == 1 + def test_function_get_auth_response(): id_1 = 'id_1' @@ -309,7 +311,7 @@ def call_external_api2(tool_context: ToolContext) -> int: ) runner = testing_utils.InMemoryRunner(agent) runner.run('test') - request_euc_function_call_event = runner.session.events[-3] + request_euc_function_call_event = runner.session.events[-2] function_response1 = types.FunctionResponse( name=request_euc_function_call_event.content.parts[0].function_call.name, response=auth_response1.model_dump(), @@ -505,7 +507,7 @@ def call_external_api2(tool_context: ToolContext) -> int: ) runner = testing_utils.InMemoryRunner(agent) runner.run('test') - request_euc_function_call_event = runner.session.events[-3] + request_euc_function_call_event = runner.session.events[-2] function_response1 = types.FunctionResponse( name=request_euc_function_call_event.content.parts[0].function_call.name, response=auth_response1.model_dump(), @@ -531,7 +533,7 @@ def call_external_api2(tool_context: ToolContext) -> int: ) assert function_invoked == 3 - assert len(mock_model.requests) == 3 + assert len(mock_model.requests) == 2 request = mock_model.requests[-1] content = request.contents[-1] parts = content.parts @@ -550,7 +552,7 @@ def call_external_api2(tool_context: ToolContext) -> int: ), ) assert function_invoked == 4 - assert len(mock_model.requests) == 4 + assert len(mock_model.requests) == 3 request = mock_model.requests[-1] content = request.contents[-1] parts = content.parts