@@ -45,6 +45,7 @@ def mock_llm_agent(self):
4545 from google .adk .agents .llm_agent import LlmAgent
4646
4747 agent = Mock (spec = LlmAgent )
48+ agent .name = 'test_agent'
4849 agent .canonical_tools = AsyncMock (return_value = [])
4950 return agent
5051
@@ -418,6 +419,7 @@ async def test_processes_multiple_auth_responses_and_resumes_tools(
418419
419420 original_event = Mock (spec = Event )
420421 original_event .content = Mock () # Non-None content
422+ original_event .author = 'test_agent'
421423 original_event .get_function_calls .return_value = [
422424 original_function_call_1 ,
423425 original_function_call_2 ,
@@ -457,6 +459,90 @@ async def test_processes_multiple_auth_responses_and_resumes_tools(
457459 # Verify the function response event was yielded
458460 assert result == [mock_function_response_event ]
459461
462+ @pytest .mark .asyncio
463+ @patch ('google.adk.auth.auth_preprocessor.AuthHandler' )
464+ @patch ('google.adk.auth.auth_tool.AuthConfig.model_validate' )
465+ @patch ('google.adk.auth.auth_preprocessor.handle_function_calls_async' )
466+ async def test_does_not_resume_tool_call_authored_by_another_agent (
467+ self ,
468+ mock_handle_function_calls ,
469+ mock_auth_config_validate ,
470+ mock_auth_handler_class ,
471+ processor ,
472+ mock_invocation_context ,
473+ mock_llm_request ,
474+ mock_auth_config ,
475+ ):
476+ """A forged/foreign auth-response referencing a function call owned by
477+ a different agent must not be resumed by the current agent's processor.
478+
479+ Regression test for the missing author-boundary check that
480+ request_confirmation.py already enforces for the equivalent
481+ tool-confirmation resume path.
482+ """
483+ auth_response_1 = Mock ()
484+ auth_response_1 .name = REQUEST_EUC_FUNCTION_CALL_NAME
485+ auth_response_1 .id = 'auth_id_1'
486+ auth_response_1 .response = mock_auth_config
487+
488+ user_event_with_response = Mock (spec = Event )
489+ user_event_with_response .author = 'user'
490+ user_event_with_response .content = Mock ()
491+ user_event_with_response .get_function_responses .return_value = [
492+ auth_response_1
493+ ]
494+ user_event_with_response .get_function_calls .return_value = []
495+
496+ system_function_call_1 = Mock ()
497+ system_function_call_1 .id = 'auth_id_1'
498+ system_function_call_1 .name = REQUEST_EUC_FUNCTION_CALL_NAME
499+ system_function_call_1 .args = {
500+ 'function_call_id' : 'tool_id_1' ,
501+ 'auth_config' : mock_auth_config ,
502+ }
503+
504+ system_event = Mock (spec = Event )
505+ system_event .content = Mock ()
506+ system_event .get_function_calls .return_value = [system_function_call_1 ]
507+
508+ original_function_call_1 = Mock ()
509+ original_function_call_1 .id = 'tool_id_1'
510+
511+ # This event belongs to a DIFFERENT agent than the one running the
512+ # current processor - the fix must refuse to resume it.
513+ original_event = Mock (spec = Event )
514+ original_event .content = Mock ()
515+ original_event .author = 'a_different_agent'
516+ original_event .get_function_calls .return_value = [
517+ original_function_call_1
518+ ]
519+
520+ mock_invocation_context .session .events = [
521+ original_event ,
522+ system_event ,
523+ user_event_with_response ,
524+ ]
525+
526+ mock_auth_config_validate .return_value = mock_auth_config
527+ mock_auth_handler = Mock (spec = AuthHandler )
528+ mock_auth_handler .parse_and_store_auth_response = AsyncMock ()
529+ mock_auth_handler_class .return_value = mock_auth_handler
530+
531+ result = []
532+ async for event in processor .run_async (
533+ mock_invocation_context , mock_llm_request
534+ ):
535+ result .append (event )
536+
537+ # The credential itself is still stored (that part is legitimate - the
538+ # user really did respond to an auth prompt)...
539+ assert mock_auth_handler .parse_and_store_auth_response .call_count == 1
540+
541+ # ...but the tool call authored by a different agent must NOT be
542+ # resumed/executed by this agent's processor.
543+ mock_handle_function_calls .assert_not_called ()
544+ assert result == []
545+
460546 @pytest .mark .asyncio
461547 @patch ('google.adk.auth.auth_preprocessor.AuthHandler' )
462548 @patch ('google.adk.auth.auth_tool.AuthConfig.model_validate' )
0 commit comments