how do I get agent voice transcription for gemini ...
# ask-ai
r
how do I get agent voice transcription for gemini realtime model?
Copy code
llm=google.realtime.RealtimeModel(
    model="gemini-2.5-flash-native-audio-preview-12-2025",
    voice="Aoede",
    temperature=0.8,
t
Thanks for reaching out, Gaurav. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
You're using the Gemini realtime model — here’s how to get agent voice transcriptions and verify they arrive in your app. 1) Enable transcription output on the AgentSession start
Copy code
from livekit.agents import AgentSession
from livekit.plugins import google, room_io

session = AgentSession(
    llm=google.realtime.RealtimeModel(
        model="gemini-2.5-flash-native-audio-preview-12-2025",
        voice="Aoede",
        temperature=0.8,
    ),
)

await session.start(
    agent=my_agent,
    room=ctx.room,
    room_options=room_io.RoomOptions(
        text_output=True
    ),
)
2) Subscribe to the transcription data stream on the frontend • Listen for data messages and filter
topic === 'lk.transcription'
. Example (web):
Copy code
room.on('dataReceived', (payload, participant, kind) => {
  const data = JSON.parse(payload.toString());
  if (data.topic === 'lk.transcription') {
    console.log('Transcription:', data);
  }
});
3) Sync vs immediate delivery • By default transcriptions are synchronized with audio. To get them delivered ASAP (not synced), set:
Copy code
room_options=room_io.RoomOptions(
  text_output=room_io.TextOutputOptions(sync_transcription=False)
)
4) Notes about Gemini realtime behavior • Gemini Live handles audio I/O and produces both user and agent transcriptions natively — no separate STT plugin is required. • If you need interim (early) STT results before Gemini begins inference, add a separate STT plugin (Gemini delays transcripts until inference starts). If you’re not seeing transcripts, tell me: • Are you seeing any
lk.transcription
messages in the client logs? • Did you change
room_options
or use custom AgentSession settings? • Which LiveKit client (web, iOS, Android) and SDK version are you using? Sources: Gemini Live API plugin | LiveKit docs | Text and transcriptions | LiveKit docs | Realtime model plugins | LiveKit Docs
r
@dataclass class TextOutputOptions: sync_transcription: NotGivenOr[bool] = NOT_GIVEN """False to disable transcription synchronization with audio output. Otherwise, transcription is emitted as quickly as available.""" transcription_speed_factor: float = 1.0 """Speed factor of transcription synchronization with audio output. Only effective if
sync_transcription
is True.""" explain with example
t
You're asking how `TextOutputOptions`'s
sync_transcription
and
transcription_speed_factor
work. Here’s a concise explanation and examples. What each field does •
sync_transcription
(bool): ◦ True (default behavior): transcriptions are timed to match audio playback so captions appear in sync with the spoken words. ◦ False: transcriptions are emitted as soon as they are available (earlier than synced captions). •
transcription_speed_factor
(float): ◦ Only used when
sync_transcription
is True. ◦ Multiplies the rate at which transcription is synchronized to audio. ◦ Values >1.0 make transcription catch up faster (appear slightly earlier relative to audio), values <1.0 delay transcription relative to audio. Examples 1) Synchronous, default speed (captions follow audio normally)
Copy code
from livekit.plugins import room_io

room_options = room_io.RoomOptions(
    text_output=room_io.TextOutputOptions(
        sync_transcription=True,              # sync with audio
        transcription_speed_factor=1.0        # normal sync speed
    )
)
Behavior: Captions appear aligned with speech timing. 2) Synchronous, faster transcription (captions appear a bit earlier while still aligned)
Copy code
room_options = room_io.RoomOptions(
    text_output=room_io.TextOutputOptions(
        sync_transcription=True,
        transcription_speed_factor=1.3        # speed up caption delivery
    )
)
Behavior: Captions are still synchronized but delivered slightly sooner to reduce perceived lag. 3) As-fast-as-possible (no sync) — get transcripts immediately
Copy code
room_options = room_io.RoomOptions(
    text_output=room_io.TextOutputOptions(
        sync_transcription=False               # emit transcripts ASAP
        # transcription_speed_factor ignored
    )
)
Behavior: Transcripts arrive as soon as available (may precede or not align with audio playback). When to use each • Use
sync_transcription=True
for captioning/subtitles where alignment with audio is important. Adjust
transcription_speed_factor
to tune perceived lag. • Use
sync_transcription=False
for real-time text processing, analytics, or when you prefer earliest possible transcripts over precise lip-sync. Want a recommendation for your app (captions vs. realtime analysis)? Tell me your use case and client platform.
r
2025-12-17 010313,798 - __mp_main__ - INFO - 🤖 Agent state: speaking → listening 010313.798 INFO __mp_main__ 🤖 Agent state: speaking → listening {"pid": 5962, "job_id": "AJ_94JeoHHsyhgj", "room_id": "RM_X8MjttBSZm8q"} 2025-12-17 010313,798 - __mp_main__ - INFO - 💬 assistant: Providing a Response I've determined this message is a standard greeting. It's unrelated to OneAssist services, so the
oneassist_chat
tool isn't needed. I'll craft a friendly, polite response with an Indian accent to address the user appropriately. I am good, thank you! How can I assist you today? INFO __mp_main__ 💬 assistant: Providing a Response I've determined this message is a standard greeting. It's unrelated to OneAssist services, so the
oneassist_chat
tool isn't needed. I'll craft a friendly, polite response with an Indian accent to address the user appropriately. I am good, thank you! How can I assist you today? {"pid": 5962, "job_id": "AJ_94JeoHHsyhgj", "room_id": "RM_X8MjttBSZm8q"} 2025-12-17 010313,798 - __mp_main__ - DEBUG - Skipping thought message: Providing a Response I've determined this mes... DEBUG __mp_main__ Skipping thought message: Providing a Response I've determined this mes... {"pid": 5962, "job_id": "AJ_94JeoHHsyhgj", "room_id": "RM_X8MjttBSZm8q"} this is what I have printed in my logs. is there any way i can get exact transcription of the agent output? for example, i am using session handler as well as room handler
t
You're already close — to capture the exact text the agent actually spoke (not internal "thought"/debug messages), use one of these, in order of recommendation: 1) conversation_item_added event (recommended — final, clean text)
Copy code
from livekit.agents import ConversationItemAddedEvent

@session.on("conversation_item_added")
def on_conversation_item(event: ConversationItemAddedEvent):
    if event.item.role == "assistant":
        print("Exact agent transcription:", event.item.text_content)
2) Listen for
lk.transcription
text stream (real-time, from room)
Copy code
# agent-side example handler for a Room text reader
async def on_text_stream(reader, participant_identity):
    message = await reader.read_all()
    is_final = reader.info.attributes.get("lk.transcription_final") == "true"
    is_agent = reader.info.attributes.get("lk.transcribed_track_id") is not None
    if is_final and is_agent:
        print("Final agent transcription:", message)
3) Override
transcription_node
(capture raw output passed to TTS)
Copy code
async def transcription_node(self, text: AsyncIterable[str], model_settings):
    async for chunk in text:
        print("Transcription chunk:", chunk)
        yield chunk
4) Session report after the session (batch final transcripts)
Copy code
report = ctx.make_session_report()
for item in report.conversation:
    if item["role"] == "assistant":
        print("Agent said:", item["text"])
Why your logs show thought/debug lines • Those log entries are LLM/internal reasoning or debug prints, not the committed assistant response. Only
conversation_item_added
,
lk.transcription
final entries,
transcription_node
output, or session reports contain the exact spoken text. If you want, tell me: • Do you want real-time capture (use method 2 or 3) or post-session transcripts (method 1 or 4)? • Are you using the session handler, room handler, or both in your current code so I can give an inline example? Sources: Pipeline nodes and hooks | LiveKit docs | Observability data hooks | LiveKit docs | Events and error handling | LiveKit docs