numerous-lighter-25835
05/07/2026, 9:40 AMtall-airline-16756
05/07/2026, 9:40 AMtall-airline-16756
05/07/2026, 9:40 AMnumerous-lighter-25835
05/07/2026, 9:41 AMtall-airline-16756
05/07/2026, 9:41 AMgoogle/gemini-1.5-flash.
Facts from the LiveKit model registry:
• google/gemini-1.5-flash is not a supported model ID in LiveKit.
• LiveKit resolves string model descriptors against its model registry; an unknown model ID causes the inference backend to return the 400 "Error getting model definition" error.
What you can do now
• Update the model reference to a supported Gemini model. For example:
◦ Change AGENT_MODEL and the llm session field to a supported ID such as google/gemini-2.5-flash (or another supported Gemini model).
◦ Example change in your code:
AGENT_MODEL = "google/gemini-2.5-flash"
...
session = AgentSession(
stt="deepgram/nova-3",
llm="google/gemini-2.5-flash",
tts="cartesia/sonic-2",
...
)
• Restart the agent after making the change.
If you want, tell me:
• Which Gemini model you want to use (I can confirm the exact supported ID), or
• Paste your current sanitized config and I’ll suggest the exact edit. Sources: Google Gemini LLM | LiveKit Documentation | LiveKit Inference | LiveKit Documentation, with interactive elementsnumerous-lighter-25835
05/07/2026, 11:32 AMtall-airline-16756
05/07/2026, 11:33 AM_on_agent_state_changed handler where last_eou_metrics.last_speaking_time is accessed.
Likely cause (based on the traceback)
• last_eou_metrics is a Pydantic model (or possibly None) that does not have last_speaking_time defined, so attribute access raises AttributeError.
To fix this I need one small code snippet and one detail:
1. Paste ~20–30 lines around your _on_agent_state_changed handler (show how ev and last_eou_metrics are created/assigned).
2. Share the model/structure for last_eou_metrics (or how it’s initialized) — just the class or the initialization site.
Quick defensive fixes you can try immediately
• Check existence before subtracting:
if getattr(last_eou_metrics, "last_speaking_time", None) is None:
# choose a default or skip delta calculation
delta = None
else:
delta = ev.created_at - last_eou_metrics.last_speaking_time
• Or initialize last_eou_metrics with a default last_speaking_time when created so the attribute always exists.
If you paste the handler + model/init, I’ll give an exact one-line patch and the preferred pattern (typing + default) to stop the exception.
, with interactive elementsnumerous-lighter-25835
05/07/2026, 11:34 AMtall-airline-16756
05/07/2026, 11:34 AM_on_agent_state_changed handler where last_eou_metrics.last_speaking_time is accessed.
Cause
• last_eou_metrics exists but does not have the attribute last_speaking_time, so Pydantic raises AttributeError when you try to read it.
Quick fixes (pick one)
1) Defensive check before using the attribute
if (
ev.new_state == "speaking"
and last_eou_metrics
and session.current_speech
and getattr(last_eou_metrics, "speech_id", None) == session.current_speech.id
and getattr(last_eou_metrics, "last_speaking_time", None) is not None
):
delta = ev.created_at - last_eou_metrics.last_speaking_time
logger.info("Time to first audio frame: %sms", delta.total_seconds() * 1000)
2) Initialize last_eou_metrics with sensible defaults so the attribute always exists
• Ensure the model or object used for last_eou_metrics includes last_speaking_time: Optional[datetime] = None (or a default datetime) when it’s created.
3) Use try/except if you prefer to log and continue on missing data
try:
delta = ev.created_at - last_eou_metrics.last_speaking_time
except AttributeError:
logger.warning("Missing last_speaking_time on last_eou_metrics; skipping delta calculation")
else:
logger.info("Time to first audio frame: %sms", delta.total_seconds() * 1000)
Next step I can help with
• Paste the class/initialization of last_eou_metrics (or where it’s set). I’ll give the exact minimal change to add a typed default and the preferred pattern to avoid this across your code., with interactive elementsnumerous-lighter-25835
05/07/2026, 11:45 AMtall-airline-16756
05/07/2026, 11:46 AMstt, llm, tts) — sanitized of secrets — and the value of AGENT_MODEL you used.
• Tell me which provider key you set in .env.local (e.g., XAI_API_KEY, GOOGLE_API_KEY, OPENAI_API_KEY).
If you want an immediate change: replace google/gemini-1.5-flash with a supported Gemini ID such as google/gemini-2.5-flash, ensure the matching provider API key is present, then restart the agent. Paste your session snippet and I’ll give the exact one-line edit if needed.
Sources: Function tool definition | LiveKit Documentation, with interactive elementsnumerous-lighter-25835
05/07/2026, 11:46 AMtall-airline-16756
05/07/2026, 11:47 AMgoogle/gemini-2.5-flash, openai/gpt-4.1-mini) — that fixes the earlier google/gemini-1.5-flash issue. Keep using the valid IDs you show.
2) APIStatusError in interruption/_main_task What to check now (do these in order):
• Confirm provider API keys exist in your .env.local and are exported at runtime (e.g., `XAI_API_KEY`/`GOOGLE_API_KEY` for Gemini, OPENAI_API_KEY for OpenAI). Redact keys when sharing.
• Inspect the full APIStatusError body (status code + message) from logs — that exact HTTP code identifies the cause (401 = auth, 429 = rate limit, 5xx = provider outage, 4xx = invalid request).
• Ensure provider mapping matches model: Google Gemini model must be served by the Google/XAI provider adapter; OpenAI models must use OpenAI credentials.
• If using FallbackAdapter, reproduce which adapter succeeded/failed by temporarily removing fallbacks and running each model singly to see which one triggers the error.
Quick configuration tests you can run
1. Print env and model resolution before session start:
import os
logger.info("XAI_API_KEY set: %s", bool(os.getenv("XAI_API_KEY")))
logger.info("OPENAI_API_KEY set: %s", bool(os.getenv("OPENAI_API_KEY")))
logger.info("LLM fallback list: %s", session.llm.adapters if hasattr(session, "llm") else "n/a")
1. Run with a single LLM (no fallback):
• Set llm=inference.LLM.from_model_string("google/gemini-2.5-flash") and restart. If error disappears, add back the fallback adapters one-by-one.
1. Add error handling around send_task to capture full APIStatusError details:
try:
# code that triggers send_task / generation
except APIStatusError as e:
logger.error("LLM APIStatusError: status=%s body=%s", getattr(e, "status_code", None), getattr(e, "body", None))
raise
If you share these two items I’ll give the exact next edit:
• The full APIStatusError body (status code + body text) from your logs.
• Which single-model test failed (if you ran the single-model run from step 2).
I can then tell you whether it’s an auth issue, rate limiting, unsupported model usage, or a provider error and give the minimal code/config fix.
, with interactive elementsnumerous-lighter-25835
05/07/2026, 11:50 AMtall-airline-16756
05/07/2026, 11:50 AMgoogle/gemini-2.5-flash
• google/gemini-2.5-flash-lite
• google/gemini-2.5-pro
• google/gemini-3-flash-preview
• google/gemini-3.1-flash-lite-preview
• google/gemini-3.1-pro-preview
Notes:
• Do not use retired/unsupported IDs (e.g., any 1.5 names or google/gemini-2.0-flash).
• Configure the LLM in your session with one of the IDs above (e.g., llm=inference.LLM.from_model_string("google/gemini-2.5-flash")) and restart the agent.
If you want, tell me which Gemini model you prefer and I’ll confirm the exact code line to use.
Sources: Google Gemini LLM | LiveKit Documentation, with interactive elementsnumerous-lighter-25835
05/07/2026, 12:01 PMtall-airline-16756
05/07/2026, 12:01 PMexcept APIStatusError as e:
logger.error("LLM APIStatusError: status=%s body=%s", getattr(e,"status_code",None), getattr(e,"body",None))
raise
Send the three items above (status/body, which single-model failed, API key presence) and I’ll tell you the exact fix (auth, model change, or adapter mapping).
, with interactive elementsnumerous-lighter-25835
05/07/2026, 12:05 PMtall-airline-16756
05/07/2026, 12:06 PMimport logging
logging.basicConfig(level=logging.DEBUG)
1. Also ensure your process shows stdout/stderr (no silent redirect) so debug logs appear.
Capture full APIStatusError details
1. Wrap the inference/send task to log status and body:
from livekit.agents._exceptions import APIStatusError
try:
# code that triggers generation/send_task
except APIStatusError as e:
logger.error("LLM APIStatusError: status=%s body=%s", getattr(e, "status_code", None), getattr(e, "body", None))
raise
1. Search your logs for those lines — the HTTP status code and response body tell you if it’s auth (401), rate limit (429), invalid model (400), or server error (5xx).
Narrow which adapter/model fails
1. Temporarily remove FallbackAdapter and run each model individually:
◦ Test Gemini only:
llm=inference.LLM.from_model_string("google/gemini-2.5-flash")
• Test OpenAI only:
llm=inference.LLM.from_model_string("openai/gpt-4.1-mini")
1. The model that reproduces the error is the failing provider.
Verify credentials & mapping
• Confirm presence (True/False) of relevant env vars in runtime:
import os
logger.info("XAI_API_KEY set: %s", bool(os.getenv("XAI_API_KEY")))
logger.info("OPENAI_API_KEY set: %s", bool(os.getenv("OPENAI_API_KEY")))
• Ensure model - provider mapping is correct (Google models via XAI/Google adapter, OpenAI models via OPENAI_API_KEY).
Instrument interruption/send_task for trace
1. Add timing and context logs around interruption code to know which request caused the error:
logger.debug("Sending interruption task: model=%s speech_id=%s", model_id, session.current_speech.id if session.current_speech else None)
1. Log task result or exception immediately so you can correlate with metrics/events.
Use LiveKit observability & console
• Check Agent Console/session metrics for request failures and rate limits.
• Inspect InterruptionMetrics and usage logs to correlate timing of the APIStatusError.
If you still see the error, please paste:
• The exact APIStatusError log lines you get after adding the logging (status code and body).
• Which single-model test reproduced the error (Gemini or OpenAI).
With those I’ll tell you whether it’s auth, rate limiting, unsupported model, or provider-side failure and the minimal fix.
Sources: Large language models (LLM) overview | LiveKit Documentation | Google Gemini LLM | LiveKit Documentation | Gemini Live API plugin | LiveKit Documentation | Troubleshooting 401 Unauthorized and Token Errors | LiveKit | Solving unwanted interruptions with Adaptive Interruption Handling | LiveKi..., with interactive elements