narrow-chef-71655
01/02/2026, 6:02 AMtall-airline-16756
01/02/2026, 6:02 AMtall-airline-16756
01/02/2026, 6:02 AMon_user_turn_completed, use the realtime transcription events as pre-generation hooks (for example user_input_transcribed, plus user_started_speaking / user_stop_speaking) to inspect transcripts and decide whether to call the generation method.
Quick example (conceptual):
@session.on("user_input_transcribed")
def on_transcript(transcript):
if transcript.is_final and "trigger_word" in transcript.transcript.lower():
session.generate_reply()
# otherwise do nothing (skip generation)
If you want to stop generation mid-stream or interrupt an in-progress reply, LiveKit supports interruption controls so you can cancel or preempt generation when needed.
Would you like a concrete example in your SDK/language (Python, TypeScript, or another) or a pattern that includes interruption handling?
Sources: Interrupt User | LiveKit docs | Pi Zero Transcriber | LiveKit docs | examples/voice_agents | livekit/livekit_composite | DeepWikinarrow-chef-71655
01/02/2026, 6:46 AMtall-airline-16756
01/02/2026, 6:46 AMuser_state_changed or user_started_speaking) and mark the turn as "transcribe-only".
2. During user_input_transcribed (or final transcript event), check that flag. If the turn is marked "transcribe-only", do not call session.generate_reply() (or the equivalent generation method).
3. Clear the flag when the turn ends (user_stop_speaking / user_state_changed indicates end) so subsequent turns behave normally.
Conceptual example:
# per-user or per-turn state
turn_mode = "reply" # or "transcribe-only"
@session.on("user_state_changed")
def on_state_change(evt):
if evt.state == "started_speaking":
# decide mode for this turn
turn_mode = "transcribe-only" # or "reply"
@session.on("user_input_transcribed")
def on_transcript(transcript):
if transcript.is_final:
if turn_mode == "reply":
session.generate_reply()
else:
# skip generation, maybe store transcript or log it
pass
@session.on("user_stop_speaking")
def on_stop(evt):
turn_mode = "reply" # reset to default
Notes and tips:
• Use per-user turn state if multiple users speak concurrently.
• If your system can auto-generate replies, ensure you disable any automatic generation option so you only generate when you explicitly call it.
• To interrupt an in-progress generation, use the session’s interruption/cancel control (supported in realtime) if you later change the decision mid-generation.
Would you like a concrete snippet for Python or TypeScript with the exact LiveKit SDK calls you’re using?narrow-chef-71655
01/02/2026, 6:48 AMtall-airline-16756
01/02/2026, 6:48 AMuser_input_transcribed handler.
Short answer: there is no built‑in flag that suppresses generation at a lower level; the supported pattern is to gate calls to session.generate_reply() from the transcription event. If you don’t want to modify or override that handler directly, here are two clean alternatives you can use.
Options
• Encapsulate decision logic in a helper function the handler calls
◦ Keep the existing user_input_transcribed handler intact but have it call a small decision function like should_generate_reply(user_id, turn_id) that returns true/false.
◦ That moves policy out of the handler and avoids changing its signature or core behavior.
• Use per-turn/per-user state and middleware-style hooks
◦ On user_state_changed / user_started_speaking set a per-user turn_mode = "transcribe-only" flag.
◦ Let the existing handler check that flag (or call a shared middleware function) and skip calling session.generate_reply() when flagged.
◦ Reset the flag on user_stop_speaking.
Example patterns (conceptual)
1) Helper function approach
def should_generate_reply(user_id, transcript):
# central place to decide; can be swapped without touching handler
return transcript.is_final and not is_transcribe_only(user_id)
@session.on("user_input_transcribed")
def on_transcript(transcript):
if should_generate_reply(transcript.user_id, transcript):
session.generate_reply()
2) State/flag approach
# set elsewhere on user_state_changed
turn_mode_by_user[user_id] = "transcribe-only" # or "reply"
@session.on("user_input_transcribed")
def on_transcript(transcript):
if transcript.is_final and turn_mode_by_user.get(transcript.user_id) != "transcribe-only":
session.generate_reply()
Notes
• There is no alternative API that auto-blocks generation for a turn; the framework expects explicit calls to generate_reply() for controlled behavior.
• If you worry about concurrency or multiple users, keep the flags keyed by user/session or turn id.
• If you need, I can convert one of these patterns into a concrete snippet for your language (Python or TypeScript) that plugs directly into your existing handler without overriding it. Which language are you using? Sources: Repeater | LiveKit docs | Pipeline Translator Agent | LiveKit docs | Transcriber | LiveKit docs | Collect recording consent with tasks | LiveKit docs | Interrupt User | LiveKit docs