Skip to content

Support AssemblyAI inference context carryover#2057

Open
rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
interim-prevue-pate
Open

Support AssemblyAI inference context carryover#2057
rosetta-livekit-bot[bot] wants to merge 1 commit into
mainfrom
interim-prevue-pate

Conversation

@rosetta-livekit-bot

@rosetta-livekit-bot rosetta-livekit-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Port AssemblyAI inference STT agent_context carryover for supported U3 Pro family models.
  • Add agentContextCarryover constructor control, previous_context_n_turns: 0 default suppression, and assistant reply truncation to the last 1750 chars.
  • Port the source capability-gating and _pushConversationItem tests into the existing inference STT Vitest suite.
Source diff coverage
Source file Classification Target coverage
livekit-agents/livekit/agents/inference/stt.py Ported agents/src/inference/stt.ts ports the AssemblyAI U3 Pro carryover model gate, max context size update, previous_context_n_turns option, agentContextCarryover constructor option, chatContext capability wiring, unsupported-model warning, and assistant-message _pushConversationItem forwarding via agent_context. Adapted Python overloads/TypedDicts into TypeScript option interfaces and constructor option handling.
tests/test_inference_stt_context.py Ported agents/src/inference/stt.test.ts ports the added tests for default capability gating, unsupported-model warnings, explicit opt-out/override, previous_context_n_turns: 0, assistant text forwarding, 1750-char tail truncation, ignored user/textless/handoff items, and explicit agent_context preservation/overwrite. Adapted pytest/caplog assertions to Vitest and the target ChatMessage/AgentHandoffItem event helpers.

No source diff files were omitted. No target infrastructure gap was found; the target already had STT chatContext capability plumbing and AgentSession conversation-item forwarding.

Validation

  • pnpm exec prettier --write agents/src/inference/stt.ts agents/src/inference/stt.test.ts
  • pnpm test agents/src/inference/stt.test.ts passed: 64 passed, 1 skipped.
  • pnpm --filter @livekit/agents typecheck passed.
  • pnpm --filter @livekit/agents lint passed with existing warnings.
  • pnpm --filter @livekit/agents build passed.
  • pnpm build passed.
  • pnpm lint passed with existing warnings.
  • cue-cli text-mode runtime validation passed: a temporary JS agent using inference.STT({ model: 'assemblyai/universal-3-5-pro' }) emitted debug_message with chatContext: true and agentContext: "Carry this assistant reply into STT context." after an assistant turn.

Known Test Failure

  • pnpm test agents failed due to 11 pre-existing/baseline failures in agents/src/voice/amd.test.ts.
  • Reproduced independently with pnpm test agents/src/voice/amd.test.ts, which failed the same 11 AMD assertions/timeouts while the ported inference STT test file passes.

Ported from livekit/agents#6466

Original PR description

already introduced in the assembly ai plugin

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner July 18, 2026 00:55
@changeset-bot

changeset-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 466ba88

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 37 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-assemblyai Patch
@livekit/agents-plugin-azure Patch
@livekit/agents-plugin-baseten Patch
@livekit/agents-plugin-bey Patch
@livekit/agents-plugin-cartesia Patch
@livekit/agents-plugin-cerebras Patch
@livekit/agents-plugin-deepgram Patch
@livekit/agents-plugin-did Patch
@livekit/agents-plugin-elevenlabs Patch
@livekit/agents-plugin-fishaudio Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-hume Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-liveavatar Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-mistralai Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai Patch
@livekit/agents-plugin-perplexity Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-resemble Patch
@livekit/agents-plugin-rime Patch
@livekit/agents-plugin-runway Patch
@livekit/agents-plugin-sarvam Patch
@livekit/agents-plugin-silero Patch
@livekit/agents-plugin-soniox Patch
@livekit/agents-plugin-tavus Patch
@livekit/agents-plugins-test Patch
@livekit/agents-plugin-trugen Patch
@livekit/agents-plugin-xai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@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 found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Comment on lines +643 to +656
override _pushConversationItem(ev: ConversationItemAddedEvent): void {
const chatItem = ev.item;
if (chatItem instanceof ChatMessage && chatItem.role === 'assistant' && chatItem.textContent) {
let text = chatItem.textContent;
if (text.length > ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS) {
this.#logger.debug(
{ fromChars: text.length, toChars: ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS },
'truncating agent_context carryover',
);
text = text.slice(-ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS);
}
this.updateOptions({ modelOptions: { agent_context: text } as STTOptions<TModel> });
}
}

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.

🟡 Turned-off conversation context can still be applied to a speech model that rejects it

The assistant reply is written into the speech engine's context option (updateOptions({ modelOptions: { agent_context: text } }) at agents/src/inference/stt.ts:654) without first checking whether context carryover is actually enabled, so a model that had carryover turned off can still have the context applied.
Impact: A speech model configured without carryover (or one that doesn't support it) can still receive assistant context, which for unsupported models can cause the transcription request to be rejected or behave unexpectedly.

How the capability guard is bypassed via the fallback adapter

The base implementation agents/src/stt/stt.ts:265-275 guards on this.#capabilities.chatContext and warn-and-skips when carryover is unsupported/disabled. The agent activity only registers the forwarder when the STT's own chatContext capability is true (agents/src/voice/agent_activity.ts:624), so a directly-used inference STT with carryover disabled is safe.

However, FallbackAdapter._pushConversationItem (agents/src/stt/fallback_adapter.ts:199-204) forwards the item to every wrapped STT, explicitly relying on the comment that "unsupported ones warn-and-skip internally". Its own chatContext capability is true if any child supports it (agents/src/stt/fallback_adapter.ts:144). Because this inference override does not call super._pushConversationItem and does not check this.capabilities.chatContext, a wrapped inference STT whose carryover is disabled (unsupported model, agentContextCarryover: false, or previous_context_n_turns: 0) will still set agent_context in its modelOptions, which is then sent to the gateway even though agent_context is only supported for the U3 Pro carryover models.

Suggested change
override _pushConversationItem(ev: ConversationItemAddedEvent): void {
const chatItem = ev.item;
if (chatItem instanceof ChatMessage && chatItem.role === 'assistant' && chatItem.textContent) {
let text = chatItem.textContent;
if (text.length > ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS) {
this.#logger.debug(
{ fromChars: text.length, toChars: ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS },
'truncating agent_context carryover',
);
text = text.slice(-ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS);
}
this.updateOptions({ modelOptions: { agent_context: text } as STTOptions<TModel> });
}
}
override _pushConversationItem(ev: ConversationItemAddedEvent): void {
if (!this.capabilities.chatContext) return;
const chatItem = ev.item;
if (chatItem instanceof ChatMessage && chatItem.role === 'assistant' && chatItem.textContent) {
let text = chatItem.textContent;
if (text.length > ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS) {
this.#logger.debug(
{ fromChars: text.length, toChars: ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS },
'truncating agent_context carryover',
);
text = text.slice(-ASSEMBLYAI_MAX_AGENT_CONTEXT_CHARS);
}
this.updateOptions({ modelOptions: { agent_context: text } as STTOptions<TModel> });
}
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

0 participants