aloof-scooter-47164
05/14/2026, 12:19 AMtall-airline-16756
05/14/2026, 12:19 AMtall-airline-16756
05/14/2026, 12:20 AMstt parameter when creating the AgentSession (string descriptor like "deepgram/nova-3:multi" or a provider-specific class such as inference.STT(model="deepgram/flux-general")).
• Override the agent’s stt_node method to implement a fully custom STT node.
Supported providers include Deepgram, Cartesia, ElevenLabs, AssemblyAI, xAI, Sarvam, etc. Provider plugins require installing the plugin and configuring API keys (for example, DEEPGRAM_API_KEY, ELEVEN_API_KEY) in your environment.
If you want, tell me which provider/model you’d like to use and whether you prefer the AgentSession parameter approach or a custom stt_node, and I’ll give a short code example.
Sources: Build Your First AI Voice Agent in Python: Complete Tutorial | LiveKit | ElevenLabs STT | LiveKit Documentation | Cartesia STT | LiveKit Documentation | AssemblyAI STT | LiveKit Documentation | Sarvam STT plugin guide | LiveKit Documentation, with interactive elementsaloof-scooter-47164
05/14/2026, 1:06 AMtall-airline-16756
05/14/2026, 1:06 AMstt parameter on your AgentSession (string or provider class) to the Soniox model identifier, or implement a custom stt_node.
• Install/configure any Soniox plugin and set your Soniox API key in your environment (e.g., in .env).
If you want, tell me whether you'd like a brief code example for AgentSession vs. a custom stt_node, and I’ll provide it.
, with interactive elementsaloof-scooter-47164
05/14/2026, 1:09 AMtall-airline-16756
05/14/2026, 1:09 AMgpt-realtime (specifying a different STT overrides the default).
1) Set your Soniox API key in your environment (example .env):
SONIOX_API_KEY=your_soniox_key_here
2) Install the Soniox plugin (if provided by LiveKit) or the Soniox client library per Soniox instructions.
3) Minimal AgentSession example (AgentSession stt set to Soniox):
from livekit import AgentSession, inference
# Option A: string descriptor (if Soniox model identifier is supported)
agent = AgentSession(
stt="soniox/your-model-id",
# other params...
)
# Option B: provider class if available
agent = AgentSession(
stt=inference.STT(model="soniox/your-model-id"),
# other params...
)
4) Optional: custom stt_node (only if you need advanced control)
class MyAgent(Agent):
async def stt_node(self, audio_chunk):
# call Soniox client directly using SONIOX_API_KEY
# return transcription text
...
What I did not change: you do not need to disable gpt-realtime. Setting stt to Soniox tells the agent to use that provider instead.
Do you want a full runnable example for your language (Python/Node), or help with the exact Soniox model identifier and plugin install commands?
, with interactive elementsaloof-scooter-47164
05/14/2026, 1:49 AMtall-airline-16756
05/14/2026, 1:49 AMconversation_item_added event. That event contains the committed message used in the conversation history and is the source of truth.
• The "user transcript" debug events you’re seeing are intermediate/partial transcripts and can change; don’t rely on them for final text.
• Filter for user messages and extract the text, e.g.:
@session.on("conversation_item_added")
def on_item_added(event):
if event.item.role != "user":
return
text = "".join(c for c in event.item.content if isinstance(c, str))
if not text.strip():
return
print("Final transcript:", text)
• You do not need to disable `gpt-realtime`; setting stt to Soniox will override the default.
Would you like a runnable Python example that shows Soniox setup + the event handler together?
Sources: Agent session | LiveKit Documentation | How to Build a Background Observer for Voice AI Guardrails | LiveKit | How to Build a Background Observer for Voice AI Guardrails | LiveKit | Text and transcriptions | LiveKit Documentation | Soniox STT plugin guide | LiveKit Documentation, with interactive elementsaloof-scooter-47164
05/14/2026, 1:53 AMtall-airline-16756
05/14/2026, 1:53 AMtext_content is a convenience property that already returns the concatenated text for an item. It was added to simplify code so you don’t need to manually join the content array.
• Both approaches produce the same final string; using text_content is just more readable and future‑proof.
• Make sure your SDK version includes text_content — if you’re on an older version, keep using the join approach until you upgrade.
• Example using text_content in the conversation_item_added handler:
@session.on("conversation_item_added")
def on_item_added(event):
if event.item.role != "user":
return
text = event.item.text_content or ""
if not text.strip():
return
print("Final transcript:", text)
Would you like me to show the full Soniox + handler example for your codebase (Python or Node)?
, with interactive elementsaloof-scooter-47164
05/14/2026, 1:56 AMtall-airline-16756
05/14/2026, 1:57 AMtext_content on conversation_item_added is the finalized, committed utterance after voice activity detection (VAD) / segmentation. In your example it shows the single committed user turn: "¿Y si pongo música?"
• The debug "user_transcript" is an incremental/streaming result from the STT node. It can include partial or previously received speech (or merged segments) while the engine is still listening, so it may contain extra words like "¿Cómo se escucha? ... By the way, y si pongo música?"
Why this happens:
• STT providers stream partial hypotheses as audio arrives. Those debug events surface those intermediate hypotheses.
• The agent waits for VAD or finalization before creating a conversation item; only then does conversation_item_added.text_content contain the final committed text.
What you can do:
• Use conversation_item_added.text_content as the source of truth for final transcripts.
• If you need earlier/near-real-time transcripts, listen to the STT debug/stream events but treat them as provisional.
• You can tune VAD/finalization behavior or the STT provider settings (if supported) to change when finalization occurs.
Do you want help:
• showing how to capture both streaming partials and final items in code, or
• adjusting VAD/finalization settings for Soniox?, with interactive elementsaloof-scooter-47164
05/14/2026, 1:58 AMtall-airline-16756
05/14/2026, 1:59 AMgpt-realtime).
1) Confirm your AgentSession stt setting
• Ensure your agent is created with Soniox, e.g.:
session = AgentSession(
stt=soniox.STT(params=soniox.STTOptions(model="stt-rt-v4")),
...
)
If stt is set to a Soniox plugin/class or Soniox model string, the agent will use Soniox.
2) Inspect STT debug events for provider/model info
• Debug events often include metadata like provider/model. Log the raw debug payload to see the field that names the provider (e.g., "provider": "soniox" or "model": "stt-rt-v4").
3) Add logging in a custom stt_node (definitive)
• If you need absolute proof, override stt_node to call Soniox directly (or wrap the plugin) and log provider/model with each transcript. Example:
class MyAgent(Agent):
async def stt_node(self, audio_chunk):
# if using plugin, the plugin call will be here
transcript, meta = await soniox_client.transcribe(audio_chunk)
print("STT provider=soniox model=stt-rt-v4", "partial=" in meta)
return transcript
• When you implement this, every transcript printed will include the provider/model you logged.
4) Correlate streaming debug -> final conversation item
• Streaming debug (user_transcript) are provisional and may show different content.
• The final committed text is in conversation_item_added. To confirm the final text came from Soniox, log both the debug event and the conversation item with timestamps or an utterance ID:
# on debug event
print("DEBUG stt event:", debug_event)
# on final item
print("FINAL conversation_item_added:", event.item.text_content, "source_meta:", event.item.meta)
Check that the debug events you logged earlier reference Soniox/model and that the final item was created after those Soniox debug events.
5) Quick checklist to rule out gpt-realtime
• stt in AgentSession is NOT gpt-realtime.
• Debug event payloads or plugin logs indicate `soniox`/model.
• Your custom stt_node or plugin wrapper logs show Soniox requests/responses.
If you want, tell me:
• whether you prefer a Python or Node example, and
• whether you already have Soniox plugin logs enabled — I’ll provide a short runnable snippet that logs provider/model with each partial and final transcript., with interactive elementsaloof-scooter-47164
05/14/2026, 2:06 AMtall-airline-16756
05/14/2026, 2:06 AMconversation_item_added won’t fire. That event is emitted only when the agent commits a user message (usually from the STT pipeline).
What you can do
• Re-enable STT (set stt to Soniox or another valid model) so the pipeline produces transcripts and conversation_item_added resumes.
• OR if you intentionally want STT off but still need conversation items, add them yourself via the session API (manually create/commit conversation items).
Examples
1) Re-enable Soniox STT (Python):
session = AgentSession(
stt=soniox.STT(params=soniox.STTOptions(model="stt-rt-v4")),
...
)
2) Manually add a conversation item if STT is disabled:
# pseudo-code: create a conversation item and add to session
item = ConversationItem(role="user", content=["Transcribed text here"])
await session.add_conversation_item(item)
# this will trigger conversation_item_added
If you want, tell me which option you prefer (re-enable Soniox or add items manually) and whether you want a full runnable example in Python or Node.
, with interactive elementsaloof-scooter-47164
05/14/2026, 2:07 AMtall-airline-16756
05/14/2026, 2:08 AMconversation_item_added stopped after disabling the realtime model transcription and how to ensure Soniox emits the final conversation items.
Summary of the problem you described
• You disabled the realtime model’s internal audio transcription but still expect Soniox STT to produce conversation_item_added. When the realtime model transcription is disabled, nothing will create conversation items unless Soniox’s STT output is properly wired to the session.
What to check (quick checklist)
• Confirm AgentSession stt is set to Soniox (not null).
• Ensure the realtime model has transcription disabled: input_audio_transcription=None (or equivalent).
• Verify Soniox plugin is initialized and receiving audio (API key present, plugin installed).
• Confirm Soniox’s final transcripts are being forwarded/committed to the session (so they create conversation items).
• Add logging on both the STT debug events and conversation_item_added with timestamps/IDs to correlate.
Minimal Python example (Soniox + disabled realtime transcription)
from livekit.plugins import soniox
from livekit import AgentSession, openai
session = AgentSession(
stt=soniox.STT(params=soniox.STTOptions(model="stt-rt-v4")),
llm=openai.realtime.RealtimeModel(input_audio_transcription=None),
# ...other config
)
@session.on("stt_debug") # if your SDK emits debug/partial events
def on_stt_debug(ev):
print("STT DEBUG:", ev) # inspect provider/model fields
@session.on("conversation_item_added")
def on_item_added(event):
if event.item.role != "user":
return
print("FINAL transcript:", event.item.text_content)
Troubleshooting steps if you still don’t see conversation_item_added
• Check Soniox logs: confirm it receives audio and returns final transcripts.
• Make sure the Soniox STT instance isn’t failing silently (exceptions, auth errors).
• Confirm the session actually wires Soniox transcripts into conversation commits (if you implemented a custom stt_node, ensure it calls the session API to add/commit items).
• Temporarily re-enable realtime model transcription to verify events return — if they do, the issue is in the Soniox-to-session integration.
If you want, tell me:
• whether you’re using the Soniox plugin or a custom stt_node, and
• whether you prefer a full runnable example for Python or Node — I’ll provide the exact code to log provider/model and force commits so you can confirm Soniox is the source. Sources: Realtime models overview | LiveKit Documentation | Soniox STT plugin guide | LiveKit Documentation | Speech-to-text (STT) models overview | LiveKit Documentation | Agent session | LiveKit Documentation | How to Build a Background Observer for Voice AI Guardrails | LiveKit, with interactive elements