Skip to content

Conversation

@AlexeyChernenkoPlato
Copy link
Contributor

Description

Fixes an issue in base_llm_flow.py where, in Bidi-streaming (live) mode, the multi-agent structure causes duplicated responses after tool calling.

Problem

In Bidi-streaming (live) mode, when utilizing a multi-agent structure, the leaf-level sub-agent and its parent agent both process the same function call response, leading to duplicate replies. This duplication occurs because the parent agent's live connection remains open while initiating a new connection with the child agent.

Root Cause

The issue originated from the placement of agent transfer logic in the _postprocess_live method at lines 547-557. When a transfer_to_agent function call was made:

  1. The function response was processed in _postprocess_live
  2. A recursive call to agent_to_run.run_live was initiated
  3. This prevented the closure of the parent agent's connection at line 175 of the run_live method, as that code path was never reached
  4. Both the parent and child agents remained active, causing both to process subsequent function responses

Solution

This PR addresses the issue by ensuring the parent agent's live connection is closed before initiating a new one with the child agent. Changes made:

Connection Management: Moved the agent transfer logic from _postprocess_live method to the run_live method, specifically:

  • Removed agent transfer handling from lines 547-557 in _postprocess_live
  • Added agent transfer handling after connection closure at lines 176-184 in run_live

Code Refactoring: The agent transfer now occurs in the proper sequence:

  1. Parent agent processes the transfer_to_agent function response
  2. Parent agent's live connection is properly closed (line 175)
  3. New connection with child agent is initiated (line 182)
  4. Child agent handles subsequent function calls without duplication

Improved Flow Control: This ensures that each agent processes function call responses without duplication, maintaining proper connection lifecycle management in multi-agent structures.

Testing

To verify this fix works correctly:

  1. Multi-Agent Structure Test: Set up a multi-agent structure with a parent agent that transfers to a child agent via transfer_to_agent function call
  2. Bidi-Streaming Mode: Enable Bidi-streaming (live) mode in the configuration
  3. Function Call Verification: Trigger a function call that results in agent transfer
  4. Response Monitoring: Verify that only one response is generated (not duplicated)
  5. Connection Management: Confirm that parent agent's connection is properly closed before child agent starts

Expected Behavior:

  • Single function response per call
  • Clean agent handoffs without connection leaks
  • Proper connection lifecycle management

Backward Compatibility

This change is fully backward compatible:

  • No changes to public APIs or method signatures
  • Existing single-agent flows remain unaffected
  • Non-live (regular async) flows continue to work as before
  • Only affects the internal flow control in live multi-agent scenarios

@google-cla
Copy link

google-cla bot commented Aug 18, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added bot triaged live [Component] This issue is related to live, voice and video chat labels Aug 18, 2025
@adk-bot adk-bot requested a review from hangfei August 18, 2025 11:05
@adk-bot
Copy link
Collaborator

adk-bot commented Aug 18, 2025

Response from ADK Triaging Agent

Hello @AlexeyChernenkoPlato, thank you for creating this PR!

Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). You can find more information at https://cla.developers.google.com/about.

Also, for bug fixes, could you please associate a GitHub issue with this PR? If there is no existing issue, could you please create one?

This information will help reviewers to review your PR more efficiently. Thanks!

@hangfei
Copy link
Collaborator

hangfei commented Nov 14, 2025

This is a nice PR. I will review and merge.

@hangfei
Copy link
Collaborator

hangfei commented Nov 14, 2025

Do you have any minimal code to reproduce the original issue?

@AlexeyChernenkoPlato
Copy link
Contributor Author

AlexeyChernenkoPlato commented Nov 17, 2025

Do you have any minimal code to reproduce the original issue?

Hey @hangfei,

Yes, I have a demo app.
Here are the steps to reproduce the issue using the demo app:

  1. Pull and set up the repo.
  2. Run the agent.
  3. Navigate to the http://127.0.0.1:8000/ page.
  4. Press Start Audio.
  5. Let the agent finish the greeting part.
  6. Say: "I want to book a new appointment".
  7. The agent will take you to a sub-agent.
  8. The sub-agent will ask you: "What date are you available for an appointment?", say any future date.
  9. Here is the place where the issue happens.
  10. The agent will get back to you with a duplicated response:
image

copybara-service bot pushed a commit that referenced this pull request Nov 22, 2025
Merge #2588

## Description
Fixes an issue in `base_llm_flow.py` where, in Bidi-streaming (live) mode, the multi-agent structure causes duplicated responses after tool calling.

## Problem
In Bidi-streaming (live) mode, when utilizing a multi-agent structure, the leaf-level sub-agent and its parent agent both process the same function call response, leading to duplicate replies. This duplication occurs because the parent agent's live connection remains open while initiating a new connection with the child agent.

## Root Cause
The issue originated from the placement of agent transfer logic in the `_postprocess_live` method at lines 547-557. When a `transfer_to_agent` function call was made:

1. The function response was processed in `_postprocess_live`
2. A recursive call to `agent_to_run.run_live` was initiated
3. This prevented the closure of the parent agent's connection at line 175 of the `run_live` method, as that code path was never reached
4. Both the parent and child agents remained active, causing both to process subsequent function responses

## Solution
This PR addresses the issue by ensuring the parent agent's live connection is closed before initiating a new one with the child agent. Changes made:

**Connection Management**: Moved the agent transfer logic from `_postprocess_live` method to the `run_live` method, specifically:
- Removed agent transfer handling from lines 547-557 in `_postprocess_live`
- Added agent transfer handling after connection closure at lines 176-184 in `run_live`

**Code Refactoring**: The agent transfer now occurs in the proper sequence:
1. Parent agent processes the `transfer_to_agent` function response
2. Parent agent's live connection is properly closed (line 175)
3. New connection with child agent is initiated (line 182)
4. Child agent handles subsequent function calls without duplication

**Improved Flow Control**: This ensures that each agent processes function call responses without duplication, maintaining proper connection lifecycle management in multi-agent structures.

## Testing
To verify this fix works correctly:

1. **Multi-Agent Structure Test**: Set up a multi-agent structure with a parent agent that transfers to a child agent via `transfer_to_agent` function call
2. **Bidi-Streaming Mode**: Enable Bidi-streaming (live) mode in the configuration
3. **Function Call Verification**: Trigger a function call that results in agent transfer
4. **Response Monitoring**: Verify that only one response is generated (not duplicated)
5. **Connection Management**: Confirm that parent agent's connection is properly closed before child agent starts

**Expected Behavior**:
- Single function response per call
- Clean agent handoffs without connection leaks
- Proper connection lifecycle management

## Backward Compatibility
This change is **fully backward compatible**:
- No changes to public APIs or method signatures
- Existing single-agent flows remain unaffected
- Non-live (regular async) flows continue to work as before
- Only affects the internal flow control in live multi-agent scenarios

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=#2588 from AlexeyChernenkoPlato:fix/double-function-response-processing-issue 3339260
PiperOrigin-RevId: 835619170
@adk-bot
Copy link
Collaborator

adk-bot commented Nov 22, 2025

Thank you @AlexeyChernenkoPlato for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit cf21ca3.

Closing this PR as the changes are now in the main branch.

@adk-bot adk-bot closed this Nov 22, 2025
sarojrout pushed a commit to sarojrout/adk-python that referenced this pull request Nov 27, 2025
Merge google#2588

## Description
Fixes an issue in `base_llm_flow.py` where, in Bidi-streaming (live) mode, the multi-agent structure causes duplicated responses after tool calling.

## Problem
In Bidi-streaming (live) mode, when utilizing a multi-agent structure, the leaf-level sub-agent and its parent agent both process the same function call response, leading to duplicate replies. This duplication occurs because the parent agent's live connection remains open while initiating a new connection with the child agent.

## Root Cause
The issue originated from the placement of agent transfer logic in the `_postprocess_live` method at lines 547-557. When a `transfer_to_agent` function call was made:

1. The function response was processed in `_postprocess_live`
2. A recursive call to `agent_to_run.run_live` was initiated
3. This prevented the closure of the parent agent's connection at line 175 of the `run_live` method, as that code path was never reached
4. Both the parent and child agents remained active, causing both to process subsequent function responses

## Solution
This PR addresses the issue by ensuring the parent agent's live connection is closed before initiating a new one with the child agent. Changes made:

**Connection Management**: Moved the agent transfer logic from `_postprocess_live` method to the `run_live` method, specifically:
- Removed agent transfer handling from lines 547-557 in `_postprocess_live`
- Added agent transfer handling after connection closure at lines 176-184 in `run_live`

**Code Refactoring**: The agent transfer now occurs in the proper sequence:
1. Parent agent processes the `transfer_to_agent` function response
2. Parent agent's live connection is properly closed (line 175)
3. New connection with child agent is initiated (line 182)
4. Child agent handles subsequent function calls without duplication

**Improved Flow Control**: This ensures that each agent processes function call responses without duplication, maintaining proper connection lifecycle management in multi-agent structures.

## Testing
To verify this fix works correctly:

1. **Multi-Agent Structure Test**: Set up a multi-agent structure with a parent agent that transfers to a child agent via `transfer_to_agent` function call
2. **Bidi-Streaming Mode**: Enable Bidi-streaming (live) mode in the configuration
3. **Function Call Verification**: Trigger a function call that results in agent transfer
4. **Response Monitoring**: Verify that only one response is generated (not duplicated)
5. **Connection Management**: Confirm that parent agent's connection is properly closed before child agent starts

**Expected Behavior**:
- Single function response per call
- Clean agent handoffs without connection leaks
- Proper connection lifecycle management

## Backward Compatibility
This change is **fully backward compatible**:
- No changes to public APIs or method signatures
- Existing single-agent flows remain unaffected
- Non-live (regular async) flows continue to work as before
- Only affects the internal flow control in live multi-agent scenarios

Co-authored-by: Hangfei Lin <hangfei@google.com>
COPYBARA_INTEGRATE_REVIEW=google#2588 from AlexeyChernenkoPlato:fix/double-function-response-processing-issue 3339260
PiperOrigin-RevId: 835619170
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

live [Component] This issue is related to live, voice and video chat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants