colossal-xylophone-68609
04/09/2026, 3:48 AMtall-airline-16756
04/09/2026, 3:49 AMtall-airline-16756
04/09/2026, 3:49 AMgenerate_reply and then using a tool call to transfer to another agent:
The new agent’s full on_enter method will run. When a tool-based handoff returns a new agent, the framework finishes the current agent’s pending output, sets the returned agent as active, and automatically invokes that agent’s on_enter so it can initialize and (for example) send its greeting or state setup.
Would you like an example sequence of calls or a short code snippet showing this flow?
Sources: Pipeline nodes and hooks | LiveKit Documentation | Agents and handoffs | LiveKit Documentation | How to Use the Supervisor Pattern for Multi-Agent Voice AI Systems | LiveKi..., with interactive elementscolossal-xylophone-68609
04/09/2026, 3:51 AMtall-airline-16756
04/09/2026, 3:51 AMon_enter completes fully before the handoff. The framework finishes any pending work/output from the current agent, then sets the returned agent as active and invokes the new agent’s on_enter.
Would you like a short example of the exact call/order flow?
, with interactive elementscolossal-xylophone-68609
04/09/2026, 3:51 AMtall-airline-16756
04/09/2026, 3:51 AMgenerate_reply then a tool call returns another agent.
Execution flow (ordered):
1. Current agent's on_enter runs to completion.
2. If on_enter calls generate_reply, that output is produced (and any pending speech/output completes).
3. The tool call executes; if it returns a new agent, the framework accepts the handoff.
4. The framework sets the returned agent as active.
5. The new agent's on_enter is invoked (runs fully), allowing it to initialize and emit its own greeting/state.
Simple pseudocode example:
class AgentA:
def on_enter(self, session):
session.generate_reply("Hi from A") # runs and completes
tool_result = session.call_tool("handoff_to_b") # returns AgentB instance
# after tool returns, framework performs handoff
class AgentB:
def on_enter(self, session):
session.generate_reply("Hello from B") # runs after AgentA finished
Behavior notes:
• AgentA’s on_enter finishes and its output is completed before AgentB’s on_enter starts.
• The handoff occurs after the tool call returns the new agent; the framework then triggers the new agent’s on_enter.
Want this shown with exact function names from your codebase or a more detailed timeline (timestamps/events)?
, with interactive elementscolossal-xylophone-68609
04/09/2026, 3:53 AMtall-airline-16756
04/09/2026, 3:53 AMgenerate_reply will run if it executes before the handoff; it will not run if the handoff happens first. Here’s why, with two concrete scenarios.
Scenario A — code after generate_reply runs (handoff happens later)
1. on_enter starts.
2. session.generate_reply("...") runs and completes — output/speech is produced.
3. Additional code in the same on_enter continues to run (e.g., state updates, logging, analytics).
4. Later the agent calls the handoff tool (e.g., session.call_tool("handoff_to_b")), which returns AgentB.
5. Framework finishes current agent’s pending output, sets AgentB active, then invokes AgentB.on_enter.
Why: the handoff only transfers control when the handoff tool is called and returns. Any synchronous statements placed before that tool call run as part of the current agent’s on_enter and complete before the handoff begins.
Scenario B — code after generate_reply does NOT run (handoff happens immediately)
1. on_enter starts.
2. session.generate_reply("...") runs.
3. Immediately the agent calls the handoff tool (synchronously) and the tool returns AgentB.
4. Framework performs the handoff: completes pending output, sets AgentB active, invokes AgentB.on_enter.
5. Any code in AgentA after the tool call is not executed because control has been transferred.
Why: the tool call triggers the transfer. Once the framework accepts and switches active agent, execution context moves to the new agent; remaining AgentA on_enter code after the handoff is not run.
Practical note: if you need post-reply work to always run before handoff, place it before the handoff tool call (or perform it inside the tool so it completes before returning the new agent).
Would you like a short code example showing both placements?
, with interactive elementscolossal-xylophone-68609
04/09/2026, 3:57 AMtall-airline-16756
04/09/2026, 3:57 AMon_enter does not continue after the tool returns a new agent.
Why, with a scenario:
• AgentA starts on_enter.
• AgentA calls await session.generate_reply("…") — reply completes.
• AgentA then calls a handoff tool (e.g., await session.call_tool("handoff")) that returns AgentB.
• When the tool returns AgentB, the framework immediately begins the handoff: it runs AgentA’s on_exit (if present), stops executing any further lines in AgentA’s on_enter, sets AgentB as active, and invokes AgentB.on_enter.
• AgentB’s on_enter runs next; there is no overlap and no concurrent execution of the remaining AgentA on_enter lines.
Why no race:
• The framework treats the tool return that yields an agent as an atomic control transfer, and it serializes agent activation so only one agent owns the session at a time.
• If you need cleanup that always runs before transfer, put it in on_exit or run it before calling the handoff tool.
If you want, I can show a concise async code example for both the safe pattern (do work before handoff or in on_exit) and the pattern that stops after handoff.
Sources: Agents and handoffs | LiveKit Documentation | Pipeline nodes and hooks | LiveKit Documentation, with interactive elements