bumpy-needle-9917
03/16/2026, 7:06 AMtall-airline-16756
03/16/2026, 7:06 AMtall-airline-16756
03/16/2026, 7:07 AMRoomInputOptions with a participant_filter that includes other agents (for example, participant_filter=lambda p: True to include all participants). This forwards agent audio into each agent’s input so one bot can process another bot’s speech.
• Once audio/transcript is available to an agent, use turn-detection, transcription, and LLM reasoning inside that agent to decide when to interrupt (for example, when an agent detects a factual error, higher-priority message, or an urgent cue).
• The actual interrupt action is implemented in agent logic (e.g., calling an interrupt API like session.interrupt() or stopping/overriding current output and starting a new response).
Typical architecture and patterns
• One room with multiple agent participants; each agent is started with input options that allow it to “listen” to the other agents.
• Each agent runs a small control loop:
a. Transcribe recent audio or use real-time speech events.
b. Apply contextual rules or an LLM to decide whether to interrupt (priority rules, content triggers, safety checks).
c. If interrupting, call the session-level interrupt/stop and begin the new utterance.
• Use priority levels or arbitration logic to avoid interrupt loops (for example: higher-priority agent always wins, or require a threshold confidence before interrupting).
Things to watch out for
• Interrupt storms: without clear arbitration, agents can repeatedly cut each other off. Implement priority, backoff, or rate limits.
• Latency and turn-detection accuracy: false positives/negatives in detecting when someone’s speaking can cause awkward cut-ins. Tune transcription/voice-activity thresholds.
• Conversation state: keep a shared short-term context or event log so agents reason about what was just said and whether an interrupt is still relevant.
• Safety and user experience: ensure interruptions improve the experience (corrections, urgent info) rather than degrade it.
If you’d like, I can:
• Show a short example of how to start two agents with participant_filter set so they hear each other.
• Sketch sample interrupt arbitration logic (priority + cooldown).
• Help design rules for when an agent should interrupt (e.g., urgency, correction, user-directed).
Which of those would help you next? If you want the example, tell me which language or SDK you’re using (Python, TypeScript, etc.).
Sources: examples/voice_agents | livekit/livekit_composite | DeepWiki | How to Enable Agent-to-Agent Speech Detection in LiveKitbumpy-needle-9917
03/16/2026, 7:28 AMtall-airline-16756
03/16/2026, 7:29 AMsession.start, RoomInputOptions, session.interrupt() semantics)? If yes, I’ll use those primitives. If not, tell me which SDK or platform you’re using.
Example (Python) — assumes LiveKit-style session/agent APIs and that session.interrupt() or session.stop() and mute/unmute controls are available. Adapt identifiers to your SDK.
1) High-level flow
• Start both agents in the same room with participant_filter that includes other agents so they hear each other.
• Generic agent starts responding to the user by default.
• Both agents transcribe incoming speech (including agent speech forwarded to inputs).
• Tech agent runs a lightweight classifier or keyword/LLM check on incoming user transcript; when it detects a tech-specific question it:
◦ Asserts priority, mutes generic agent, interrupts the generic agent’s session, then un-mutes itself and begins speaking.
◦ After finishing, it can unmute the generic agent and yield the floor.
2) Example code sketch
# Pseudocode / sketch using LiveKit-like APIs in Python.
# Replace API calls with exact SDK functions in your environment.
from time import sleep
from threading import Thread
from typing import Callable
# Helpers to represent SDK behavior
class AgentSession:
def __init__(self, name, session):
self.name = name
self.session = session # actual SDK session object
self.muted = False
async def start(self, room, input_options=None):
# start agent in room with input_options
await self.session.start(agent=self.name, room=room, input_options=input_options)
async def mute(self):
# mute this agent's published audio
await self.session.mute() # SDK call to mute publishing
self.muted = True
async def unmute(self):
await self.session.unmute()
self.muted = False
async def interrupt(self):
# signal to stop current output (if SDK provides)
await self.session.interrupt()
async def speak(self, text):
# start a TTS/agent response (SDK-specific)
await self.session.speak(text)
# subscribe to transcript events, agent's SDK will call on_transcript with (speaker, text)
def on_transcript(self, speaker, text):
pass
# User-defined simple classifier to detect tech-specific question
def is_tech_question(text: str) -> bool:
keywords = ["install", "error", "stack trace", "refactor", "deployment", "api", "endpoint", "server"]
text_lower = text.lower()
return any(k in text_lower for k in keywords)
# Or use an LLM classifier for higher accuracy (call your model here)
async def classify_text_with_llm(text: str) -> bool:
# call LLM to determine if tech-specific
# return True if tech-specific
pass
# Example orchestration
async def run_room(room):
# configure both agents to hear all participants (including other agents)
input_options = RoomInputOptions(participant_filter=lambda p: True)
generic = AgentSession("generic_help_agent", session=GenericSDKSession(...))
tech = AgentSession("tech_agent", session=TechSDKSession(...))
await generic.start(room, input_options=input_options)
await tech.start(room, input_options=input_options)
# Hook transcript event handlers (SDK-specific wiring)
# Assume SDK provides a way to subscribe to transcriptions with speaker id
async def on_transcript(speaker_id, text):
# If speaker is user, let generic normally respond (generic agent logic)
if is_user(speaker_id):
# Generic agent will start speaking by default. Tech agent should listen.
if is_tech_question(text):
# Tech agent should interrupt generic agent and take over.
# 1. Mute generic agent's output so it won't broadcast while interrupted.
await generic.mute()
# 2. Interrupt generic agent's ongoing response (if SDK supports)
await generic.interrupt()
# 3. Unmute tech agent (ensure it can speak)
await tech.unmute()
# 4. Tech agent responds
await tech.speak("I can help with that technical issue. Can you share the error message?")
# 5. After finishing, optionally mute tech and unmute generic
await tech.mute()
await generic.unmute()
else:
# Not a tech question — generic continues as usual
pass
# If speaker is an agent (generic speaking), tech agent may also listen and decide to interrupt
if is_agent(speaker_id) and speaker_id == generic.session.participant_id:
# Evaluate the generic agent's output content; if it missed a tech cue, tech can preemptively interrupt
if is_tech_question(text):
await generic.mute()
await generic.interrupt()
await tech.unmute()
await tech.speak("Hold on — that sounds like a technical issue; let me handle it.")
await tech.mute()
await generic.unmute()
# SDK: subscribe to transcript events
room.on("transcript", on_transcript)
# Utility predicates - depends on SDK participant object model
def is_user(participant_id) -> bool:
# determine if the speaker is a user (vs. an agent)
# implement according to how you label agent participants
return not participant_id.startswith("agent_")
def is_agent(participant_id) -> bool:
return participant_id.startswith("agent_")
3) Mute/unmute and interrupt details (practical notes)
• Always mute the agent being interrupted before calling interrupt/stop to avoid overlapping audio.
• Use session.interrupt() to stop the outgoing response if available; if not, call whatever SDK method cancels the current TTS/stream.
• Ensure the interrupting agent is unmuted before starting TTS. After it finishes, mute it and unmute the previous agent to restore flow.
• Add small delays (100–300 ms) between mute/unmute/interrupt to allow the room and audio pipeline to stabilize.
4) Arbitration to avoid flip-flopping
• Use a priority rule: tech agent has higher priority than generic agent for tech queries.
• Add cooldown: once an agent interrupts, block further interrupts for N seconds.
• Require confidence thresholds from your classifier/LLM before interrupting.
5) Can a bot interrupt the user mid-conversation?
• Yes, a bot can interrupt another agent in the room by muting and calling an interrupt/stop on their session and starting its own output.
• Interrupting a human user is possible in technical terms if:
◦ The user is publishing audio and the system uses VAD/transcription and server-side audio control to mute/unmute participants. However, muting a human participant without consent may be a poor UX and could require explicit client support or policy decisions.
• Best practices:
◦ Prefer interrupting agents rather than forcibly muting users.
◦ If you must interrupt a speaking user, use clear audible signals (chime) and keep interruptions brief.
◦ Consider asking users permission or using a visual cue before cutting audio.
If you want, I can:
• Provide a concrete, complete Python example using your exact LiveKit SDK bindings (give me the package names or a snippet of how you currently start agents).
• Add a sample LLM classifier snippet to reduce false positives.
• Draft a safe arbitration/cooldown module you can drop into your agent logic.
Which should I build next for you — a full SDK-aligned code sample or an LLM-based classifier + cooldown module?bumpy-needle-9917
03/16/2026, 7:38 AMtall-airline-16756
03/16/2026, 7:39 AMbumpy-needle-9917
03/16/2026, 7:46 AMbillowy-hairdresser-80384
03/16/2026, 10:29 AMbumpy-needle-9917
03/16/2026, 1:49 PMbillowy-hairdresser-80384
03/16/2026, 2:12 PMbumpy-needle-9917
03/16/2026, 2:43 PM