can i control when model is realtime and I want to...
# ask-ai
n
can i control when model is realtime and I want to generate only reply if transcription contains some words ? or like even subscribe method that is called before generating reply like in the non realtime model case on_user_turn_completed method is called
t
Thanks for reaching out, Darshak. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I can help with that. Yes. You can prevent automatic replies from a realtime model and only generate a reply when the transcription contains certain words. Instead of
on_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):
Copy code
@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 | DeepWiki
n
suppose i know when user start speaking (usnig user_state_changed) i know for this turn i just only want to transcribe not reply then how can i do it like want to skip llm response generation in realtime model case ? is there any functionality so that i can skip it or prevent it
t
You're already on the right track. You can skip LLM response generation for a specific turn in realtime by simply not calling the generation API when that turn begins — use the speech/state events as a gate. How to do it: 1. Detect turn start (e.g.,
user_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:
Copy code
# 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?
n
@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 i do not want to override this method because there is no point to override this method
t
Thanks — I hear you: you want to skip LLM reply generation for some turns in realtime without overriding the existing
user_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
Copy code
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
Copy code
# 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