salmon-belgium-62133
12/15/2025, 10:41 AMtall-airline-16756
12/15/2025, 10:42 AMtall-airline-16756
12/15/2025, 10:42 AMagent.update_chat_ctx() (or otherwise injects the data into the session) so the agent updates its context from inside its own runtime.
• Alternatively, expose an HTTP endpoint in your agent service that your webhook calls; when that endpoint receives new data it directly calls agent.update_chat_ctx().
Quick clarifying questions so I can give precise code/examples:
1. What language is your agent service written in (Python or Node.js)?
2. Is this for a voice agent or text-only?
3. Where would you prefer storing updates (database, Redis, or a message queue)? Sources: server-sdk-js | livekit/livekit_composite | DeepWiki | Agents Framework | livekit/livekit_composite | DeepWiki | External data and RAG | LiveKit Docs | Announcing Agent Builder: A Pathway to Code | Agents v0.x migration guide - Python | LiveKit docssalmon-belgium-62133
12/15/2025, 10:44 AMtall-airline-16756
12/15/2025, 10:45 AMAgent instance to trigger a transfer within the agent logic.
• Warm transfer / move participant: Use the LiveKit server APIs (e.g., move_participant) to move a participant between rooms after a consultation/transfer workflow.
• External orchestration + agent listener: Use webhooks/SSE to notify your service, store the intent in a DB or queue, and have the agent process poll or receive that event and then call connect(), session.shutdown(), or agent-level APIs to leave/join.
Quick questions so I can give a concrete example:
1. Is your agent service in Python or Node.js?
2. Is this for voice (call transfer) or text/chat?
3. Do you want an immediate move (hard transfer) or a warm/consultation transfer? Sources: Webhooks | LiveKit docs | Agents and handoffs | LiveKit docs | Agent-assisted warm transfer | LiveKit docs | Job lifecycle | LiveKit docssalmon-belgium-62133
12/15/2025, 10:47 AMAgent instance to trigger a transfer within the agent logic.tall-airline-16756
12/15/2025, 10:47 AMAgent instance (agent A hands off to agent B), below is a concise Python text/chat example you can adapt.
Notes:
• This example shows an agent tool that triggers a transfer by returning a new Agent instance; the framework will use that to perform the handoff.
• Minimal surrounding setup is included (agent classes, tool registration, session start). Replace SDK-specific imports and session/room wiring with your app’s actual initialization.
# Example: Python agent-initiated handoff (text/chat)
# Replace imports with your agent framework/LiveKit agent SDK modules.
from typing import Tuple
# --- Agent definitions ---
class BaseAgent:
async def on_message(self, session, message):
"""Handle incoming message and optionally call tools."""
raise NotImplementedError()
class SupportAgent(BaseAgent):
async def on_message(self, session, message):
# Support agent handles the message normally
await session.send_reply("SupportAgent: I can help with that.")
return None # No transfer
class SalesAgent(BaseAgent):
async def on_message(self, session, message):
# If the message needs support, initiate a handoff via tool
if "support" in message.lower():
# Call a tool that triggers transfer
return await self.transfer_to_support_tool(session, message)
await session.send_reply("SalesAgent: Tell me more about your needs.")
return None
# Tool that returns a new Agent instance to trigger a transfer
async def transfer_to_support_tool(self, session, message) -> Tuple[BaseAgent, str]:
# Optional: log or save context before transfer
await session.send_reply("SalesAgent: I'm transferring you to Support.")
# Create the new agent instance (SupportAgent)
new_agent = SupportAgent()
# Return the agent instance and an optional reason note
return new_agent, "handoff_to_support"
# --- Agent session handling (framework shim) ---
# The framework code below demonstrates how it could accept a returned Agent
# and perform the handoff: shut down current agent in room and start new agent.
class AgentSession:
def __init__(self, room, agent: BaseAgent):
self.room = room
self.agent = agent
self.running = True
async def start(self):
# Start listening to messages (simplified)
while self.running:
message = await self._wait_for_incoming_message()
result = await self.agent.on_message(self, message)
# If the agent returned a new agent instance, perform the handoff
if isinstance(result, tuple) and isinstance(result[0], BaseAgent):
new_agent, reason = result
await self._perform_handoff(new_agent, reason)
# After handoff performed, stop this session loop
break
async def send_reply(self, text: str):
# Send a reply into the room (replace with actual send)
print(f"[{self.room}] reply: {text}")
async def _wait_for_incoming_message(self) -> str:
# Replace with real message receive; here simulated input for demo
# In real usage this yields messages from participants in the LiveKit room
import asyncio
await asyncio.sleep(0.1)
return "I need support" # demo message that triggers transfer
async def _perform_handoff(self, new_agent: BaseAgent, reason: str):
# 1) Optionally persist context/state to DB or share via your service
print(f"Handoff reason: {reason}, moving from {self.agent.__class__.__name__} to {new_agent.__class__.__name__}")
# 2) Current agent leaves / session.shutdown() (framework-specific)
await self._shutdown_current_agent()
# 3) Start a new agent session in the same room (or another room as needed)
new_session = AgentSession(self.room, new_agent)
# Depending on your framework, you may need to spawn new_session.start() in background
await new_session.start()
async def _shutdown_current_agent(self):
# Perform any cleanup (unpublish tracks, close connections)
print(f"Shutting down agent: {self.agent.__class__.__name__}")
self.running = False
# --- Run demo ---
import asyncio
async def demo():
room = "room-123"
initial_agent = SalesAgent()
session = AgentSession(room, initial_agent)
await session.start()
asyncio.run(demo())
How this maps to a real system
• The framework’s agent session would call connect() / session.shutdown() and manage LiveKit participant lifecycle. Replace _shutdown_current_agent and session start logic with SDK calls that disconnect the agent participant and have the new agent connect.
• Preserve and pass any necessary chat context (store in DB or attach to the new agent session) before starting the new agent so the conversation continues smoothly.
If you want, I can:
• Convert this to Node.js, or
• Show the same flow with explicit LiveKit SDK calls for disconnecting a participant and connecting another (tell me whether you use Python or Node.js).