Skip to content

fix(core): flip text content fields#2013

Open
rosetta-livekit-bot[bot] wants to merge 4 commits into
mainfrom
compos-howdah-reckoned
Open

fix(core): flip text content fields#2013
rosetta-livekit-bot[bot] wants to merge 4 commits into
mainfrom
compos-howdah-reckoned

Conversation

@rosetta-livekit-bot

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

Copy link
Copy Markdown
Contributor

Summary

Ports livekit/agents#6353 to agents-js: assistant textContent strips only LiveKit <expr/> markup, while provider/runtime paths use rawTextContent so model-facing expressive markup is preserved. The follow-up repair also strips unmatched opening and closing <expr> delimiters independently, matching Python's current _split_expr behavior for malformed model output.

Current main now contains the overlapping raw-content implementation from #2087. This branch merges main, adopts its current chat-context update API, and retains the verified expr-only helper and malformed-marker regressions without reintroducing obsolete remove/create diff behavior.

Source diff coverage

Coverage classification
  • livekit-agents/livekit/agents/llm/_provider_format/anthropic.py - represented by plugins/anthropic/src/llm.ts; Anthropic context building uses rawTextContent.
  • livekit-agents/livekit/agents/llm/_provider_format/aws.py - not applicable; agents-js has no AWS provider-format counterpart.
  • livekit-agents/livekit/agents/llm/_provider_format/google.py - represented by agents/src/llm/provider_format/google.ts; system messages use rawTextContent.
  • livekit-agents/livekit/agents/llm/_provider_format/utils.py - represented by agents/src/llm/provider_format/utils.ts; mid-conversation instructions preserve raw instruction text.
  • livekit-agents/livekit/agents/llm/chat_context.py - adapted to agents/src/llm/chat_context.ts and agents/src/tts/provider_format.ts; rawTextContent preserves exact model content, assistant textContent strips only expr markup, and stripMarkup JSON handling is assistant-only.
  • livekit-agents/livekit/agents/llm/utils.py - represented by agents/src/llm/utils.ts; current-main toUpdate operations compare same-ID messages by rawTextContent, matching Python's current API more directly than the branch's obsolete remove/create adaptation.
  • livekit-agents/livekit/agents/telemetry/traces.py - adapted/no additional diff; agents-js telemetry uses raw message content.
  • livekit-agents/livekit/agents/tts/_provider_format.py - adapted to agents/src/tts/provider_format.ts; paired, self-closing, and independent unmatched expr delimiters are removed while provider-native markup remains untouched.
  • livekit-agents/livekit/agents/voice/agent_activity.py - represented by agents/src/voice/agent_activity.ts; realtime reply input, preemptive transcript comparison, and user-input tracing use rawTextContent.
  • livekit-agents/livekit/agents/voice/agent_session.py - not applicable; the exact Python debug logging path does not exist in agents-js.
  • livekit-agents/livekit/agents/voice/remote_session.py - adapted/no additional diff; agents-js remote-session serialization transports raw message content.
  • Python-only AWS, LangChain, Ultravox, and xAI override paths have no direct agents-js counterparts. Keyterm/STT context paths intentionally use sanitized textContent, matching Python's behavior.
  • tests/test_expr_markup.py - represented by agents/src/llm/chat_context.test.ts; coverage includes expr-only stripping, assistant/non-assistant accessors, undefined text, JSON stripping, malformed delimiters, and stream-assembled markers. agents/src/llm/utils.test.ts covers same-ID raw-content updates through current-main toUpdate semantics.

Release decision

Per the explicit Rosetta release policy, every entry in .changeset/fuzzy-crabs-express.md is patch: core, Anthropic, and Phonic.

Verification

Exact head: 8164139685385cd78c4afcf02551977010f7b5da.

  • pnpm test agents/src/llm/chat_context.test.ts agents/src/llm/utils.test.ts agents/src/tts/tts.test.ts agents/src/voice/agent_activity.test.ts - passed: 4 files, 170 tests.
  • pnpm test agents/src/llm/provider_format/google.test.ts agents/src/llm/provider_format/utils.test.ts plugins/anthropic/src/llm.test.ts - passed: 3 files, 38 tests.
  • pnpm build - passed after merging current main and again before the temporary TypeScript Cue agent was run.
  • pnpm typecheck - passed.
  • pnpm lint - passed.
  • pnpm format:check - passed.
  • git diff --check - passed.

Known unrelated API tooling limitations:

  • Repo-wide pnpm api:check stops at plugins/bey, whose package defines api:check without an api-extractor.json.
  • Scoped pnpm --filter @livekit/agents api:check is blocked by API Extractor 7.43.7 rejecting generated TypeScript 5.9 export * as declarations. This PR does not add a public export.

Cue voice E2E

  • Session: sid_b18f4f9c7058.
  • Exact head: 8164139685385cd78c4afcf02551977010f7b5da (also embedded in the decisive debug event).
  • Mode/agent: fresh voice-mode session with temporary dispatchable deterministic agent pr2013-expr-final-81641396; the source file was removed and the worker stopped after verification.
  • Changed-path input: Alpha <expr type="break" label="1s"/> bravo.
  • Predicate: agent_state_changed(.new_state="AS_SPEAKING") -> debug_message(.payload.kind="expr_text_clean",.payload.text="Alpha bravo",.payload.head="8164139685385cd78c4afcf02551977010f7b5da").
  • Result: resolved after completed playout, exit code 0. The path-specific debug event carried the cleaned ChatMessage.textContent, and persisted JSON/events contained no literal expr markup.
  • TTS event: real LiveKit Inference cartesia/sonic-3, characters_count=12, audio_duration=0.734, confirming the cleaned text was sent to TTS.
  • Session WAV: stereo PCM s16le, 48 kHz, 20.513729 s, 3,938,680 bytes, SHA-256 c0acbe9654bb8adf33120721cd018007c44cae80210cf9bd9ea6083121d42a40.
  • Command WAV: stereo PCM s16le, 48 kHz, 2.679646 s, 514,536 bytes, SHA-256 77c74cc5db1b6e58f55ecfbc9d75e68fa84a2045bddb9f4187fb898a1d12f81e.
  • Independent Whisper transcription of both WAVs: Alpha Bravo. No markup was spoken.
  • Provider setup: real LiveKit Cloud transport and LiveKit Inference TTS; Whisper was used only to inspect persisted WAVs.
  • Limitations: the deterministic harness intentionally did not use STT or an LLM. Chat insertion was disabled so raw remote-session serialization could not be mistaken for the user-facing cleaned-text path.

Ported from livekit/agents#6353

Original PR description

Before:

  • text_content raw content, with expressive tags and bracket tags;
  • plain_text_content clean content, without any tags;

Now:

  • text_content clean content, without any expressive-only tags expr
  • raw_text_content raw content with expr tags

@rosetta-livekit-bot
rosetta-livekit-bot Bot requested a review from a team as a code owner July 9, 2026 19:19
@changeset-bot

changeset-bot Bot commented Jul 9, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8164139

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

This PR includes changesets to release 39 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anthropic Patch
@livekit/agents-plugin-phonic Patch
@livekit/agents-plugin-anam 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-krisp 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-protoface 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: No Issues Found

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

View in Devin Review to see 1 additional finding.

Open in Devin Review

toubatbrian and others added 2 commits July 15, 2026 10:45
Remove unmatched expressive delimiters so malformed model output cannot leak into user-facing text, and lock in raw-content diff behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve expr-markup behavior while adopting current chat-context update APIs and the Rosetta patch release policy.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant