Skip to content

feat(assemblyai): add language_codes steering param, enable agent_context_carryover by default#6443

Merged
tinalenguyen merged 9 commits into
livekit:mainfrom
dlange-aai:dlange/assemblyai-carryover-default
Jul 17, 2026
Merged

feat(assemblyai): add language_codes steering param, enable agent_context_carryover by default#6443
tinalenguyen merged 9 commits into
livekit:mainfrom
dlange-aai:dlange/assemblyai-carryover-default

Conversation

@dlange-aai

Copy link
Copy Markdown
Contributor

What

Two related upgrades to the AssemblyAI streaming STT plugin:

1. language_codes — multi-language steering

  • New language_codes: list[str] parameter: language_codes=["en", "es"] biases transcription toward that set of languages instead of open detection/code-switching (Universal-3 Pro family only). The existing singular language_code keeps working unchanged as documented shorthand for a one-element list; passing both raises ValueError.
  • Each entry is normalized to a bare ISO 639-1 code ("en-US" / "english""en") and deduped preserving order; server limits are validated client-side (max 10 codes, "multi" must be sent alone) so misconfiguration fails at construction instead of as a websocket error.
  • Mid-session re-steering via STT.update_options(language_codes=...) / SpeechStream.update_options(...), sent as an UpdateConfiguration message; an explicit [] clears steering back to the model default. Useful for agents that detect the caller's language and re-steer without reconnecting. Validation runs before any option mutation, so a rejected update never leaves options partially applied.
  • Wire format: sent as a JSON-array query param (language_codes=["en","es"]), the same convention as keyterms_prompt. Note for existing language_code users: the singular is now also sent as language_codes=["es"] — behaviorally identical, since the server declares language_code/language_codes/language as aliases for the same field.

2. agent_context_carryover — on by default, with a server-cap guard

  • Fixes a live-session kill: the server rejects agent_context longer than 1750 chars, and an invalid mid-stream UpdateConfiguration cancels the entire streaming session. The plugin now enforces the cap client-side: the auto-carryover handler truncates oversize assistant replies (keeping the tail — the end of the reply is what the user responds to), and explicit agent_context input fails fast with ValueError. Also fixes the stale "max 1500 characters" docstring (server cap is 1750).
  • With the guard in place, agent_context_carryover defaults to enabled on Universal-3 Pro family models (tri-state NotGivenOr[bool]): the server already carries prior user turns automatically, so assistant-reply carryover completes the conversation context the models are designed to use. Opt out with agent_context_carryover=False; setting previous_context_n_turns=0 (documented as "disable context carryover") also suppresses the default. On unsupported models the default is silently off; explicitly passing True there keeps today's warning.
  • Behavior change to be aware of: on supported models, assistant reply text now flows to AssemblyAI as transcription context by default, and each reply replaces any manually set agent_context (documented in the docstring; disable carryover to manage context manually).

Testing

  • tests/test_plugin_assemblyai_stt.py: 43 new tests — normalization/dedup, mutual exclusion, U3-Pro gating on both construction and update paths, max-10/multi validation, JSON-array wire format for both spellings, UpdateConfiguration enqueue incl. empty-list clear, no-partial-update on validation failure, STT→stream propagation, truncation boundaries at exactly 1750/1751, tail-keeping, the four tri-state carryover cases, and handler safety for user/textless/handoff conversation items. Full file: 101 passed; ruff and strict mypy clean.
  • Verified live against the AssemblyAI streaming API (console-mode voice agent, full multi-turn booking flow): steering param accepted at connect, 13 carryover context pushes and mid-stream config updates over one session with no errors or reconnects.

…ns mutations

Hoist language_codes normalization and validation to the start of both
STT.update_options and SpeechStream.update_options, before any _opts
mutations. This prevents partial updates when _normalize_language_codes
raises ValueError (e.g., too many codes, 'multi' combined with others).
@dlange-aai
dlange-aai requested a review from a team as a code owner July 15, 2026 15:40

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

Comment thread livekit-plugins/livekit-plugins-assemblyai/livekit/plugins/assemblyai/stt.py Outdated
@tinalenguyen
tinalenguyen merged commit 8dda6a1 into livekit:main Jul 17, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants