little-king-41579
02/13/2026, 6:11 PMtall-airline-16756
02/13/2026, 6:12 PMtall-airline-16756
02/13/2026, 6:12 PMparticipant_joined, user_state_changed, or similar turn-taking events).
1. Switch the agent into a passive/listening mode:
◦ Disable audio output: call the session/output API to turn off agent audio (for example, session.output.set_audio_enabled(False)), or stop calling session.say() / TTS generation routines.
◦ Keep STT active on all subscribed tracks so transcription continues.
1. Buffer transcriptions:
◦ Append each user_input_transcribed (or equivalent) event to a transcript buffer along with participant identity and timestamps.
1. Generate summary with the LLM:
◦ When you want the summary (on demand, periodically, or at call end), pass the buffered transcript to the LLM with a summarization prompt and store/emit the result.
Why this works
• The agent remains in the room and subscribed to audio tracks, so STT continues for every participant.
• Disabling audio output or avoiding TTS prevents the agent from interrupting or speaking over the live participants.
• The LLM can produce summaries from the buffered transcripts independent of whether the agent speaks.
Quick clarifying questions
1. Are you using Python or Node.js for your agent code?
2. Do you want the agent to stop speaking immediately when any second participant joins, or only when that participant is actively speaking/taking the turn?
3. Do you want summaries in real time (e.g., every N seconds/minutes) or only at the end of the call?
If you tell me your language (Python/Node) and which summary timing you prefer, I’ll provide a short example snippet showing:
• listening for the participant join/turn event,
• disabling audio output while keeping STT active,
• collecting transcripts and invoking the LLM to summarize.
Would you like a Python example or a Node.js example next?
Sources: livekit/livekit_composite | DeepWiki | Agents Framework | livekit/livekit_composite | DeepWiki | Text and transcriptions | LiveKit Documentation | Building multi-agent architectures with LiveKit agents | LiveKit | Agent Builder | LiveKit Documentationlittle-king-41579
02/13/2026, 6:14 PMtall-airline-16756
02/13/2026, 6:15 PMuser_state_changed or similar event.
• When a non-agent participant becomes the active speaker, disable the agent’s audio output so it won’t generate TTS, but keep STT/transcription active.
• Buffer all transcriptions (with participant identity and timestamps).
• On session end (or when the room empties), send the buffered transcript to the LLM to generate a final summary.
Key behaviors to implement
• Disable speech output: use session.output.set_audio_enabled(False) (or the equivalent in your session object) when another participant takes the turn.
• Keep transcription: do not disable text output; continue handling user_input_transcribed (or conversation_item_added) events.
• End-of-call summary: trigger LLM summary in the shutdown hook or when the room becomes empty.
Minimal Python example (Adapt to your project structure and the exact LiveKit SDK objects you use.)
import asyncio
from typing import List
from livekit.agents import JobContext, AgentSession
from livekit import rtc
async def entrypoint(ctx: JobContext):
# Create agent session with your STT/LLM/TTS plugins
session = AgentSession(
room=ctx.room,
# stt=..., llm=..., tts=..., vad=...
)
transcript_buffer: List[str] = []
agent_identity = ctx.room.local_participant.identity # agent's identity
# Collect every transcription (keeps transcribing both participants)
@session.on("user_input_transcribed")
def on_transcribed(event):
# event.participant_identity, event.transcript (adjust according to actual event shape)
transcript_buffer.append(f"{event.participant_identity}: {event.transcript}")
# Track speaking/turn-taking and mute agent audio when a non-agent participant speaks
@session.on("user_state_changed")
def on_user_state_changed(event):
# event.participant_identity and event.new_state (e.g., "speaking" or "silent")
if event.participant_identity != agent_identity and event.new_state == "speaking":
# Another participant is taking the turn — stop agent TTS output
session.output.set_audio_enabled(False)
elif event.participant_identity != agent_identity and event.new_state == "silent":
# Optionally re-enable agent output when they finish
# Only re-enable if you want agent to speak again when the remote stops
session.output.set_audio_enabled(True)
# Optionally detect participant join to prepare for turns
@ctx.room.on("participant_joined")
def on_participant_joined(participant: rtc.RemoteParticipant):
# You may want to log or track participants here
print(f"Participant joined: {participant.identity}")
# Start the session (this will run until closed)
await session.start()
# Wait until session ends (depends on how your app ends sessions)
await session.wait_closed()
# On session close — generate final summary
if transcript_buffer:
summary_prompt = "Summarize the following conversation concisely:\n\n" + "\n".join(transcript_buffer)
# Call your LLM plugin to generate summary; adjust to plugin API
llm_response = await session.llm.chat.create(messages=[{"role":"user","content": summary_prompt}], max_tokens=250)
summary = llm_response.choices[0].message.content
print("Call summary:\n", summary)
# Save/send summary as needed
Practical notes and tips
• Use VAD and user_state_changed events for reliable turn detection instead of only participant joins. That lets you mute the agent only when the other participant is actively speaking.
• If you want the agent to remain able to speak again after the other stops, re-enable audio output when their state returns to idle/silent.
• Buffer format: include participant identity and timestamps for clearer summaries and context.
• Trigger summary when the session ends or when the room becomes empty (e.g., detect participant_left and check participant count).
• If you don’t want the agent to ever speak once a second participant appears, you can permanently keep audio_enabled false until you explicitly decide to re-enable it.
Would you like:
• A fully fleshed-out runnable sample tailored to a specific STT/LLM/TTS plugin (e.g., Deepgram + OpenAI + your TTS), or
• A version that keeps the agent muted only while the other participant is actively speaking (so the agent can speak again between turns)?
Tell me which option and I’ll produce the code snippet specific to your plugins.
Sources: Pipeline nodes and hooks | LiveKit Documentation | Turns overview | LiveKit Documentation | How to implement call greeting retries in voice agents | LiveKit | Building multi-agent architectures with LiveKit agents | LiveKit | How to build an agent with speech-to-text input and text-only output | Live...