Skip to content

feat(telemetry): expose provider request ids on STT/TTS/LLM spans#1319

Merged
toubatbrian merged 4 commits into
mainfrom
claude/jolly-lovelace-2NfO8
Apr 29, 2026
Merged

feat(telemetry): expose provider request ids on STT/TTS/LLM spans#1319
toubatbrian merged 4 commits into
mainfrom
claude/jolly-lovelace-2NfO8

Conversation

@toubatbrian
Copy link
Copy Markdown
Contributor

Summary

Automated port of livekit/agents#5546 into agents-js.

Adds a new span attribute lk.provider_request_ids (string[], deduped) on the user_turn (STT), tts_request_run (TTS), and llm_request_run (LLM) spans for debugging and reporting STT/TTS issues to providers. The id can either be one we sent to the provider (e.g. WS context_id / segment_id) or one returned by the provider (e.g. response request_id / session_id) – both can be cross-referenced with the provider's server-side logs.

cc @toubatbrian @livekit/agent-devs

Ported features

  • agents/src/telemetry/trace_types.ts – new ATTR_PROVIDER_REQUEST_IDS = 'lk.provider_request_ids' constant.
  • agents/src/llm/llm.tsLLMStream now collects ChatChunk.id values seen in monitorMetrics, resets the list at the start of each retry attempt, and writes them onto the llm_request_run span in a finally block (mirrors Python LLM._main_task / _metrics_monitor_task).
  • agents/src/tts/tts.tsSynthesizeStream exposes a new protected noteProviderRequestId(contextId) helper (the JS equivalent of Python's AudioEmitter._note_provider_request_id). It dedupes and writes onto the current tts_request_run (attempt) span; the metrics monitor calls it automatically for every unique segmentId it sees on emitted audio frames, and plugins can call it directly when the provider-known id becomes available later.
  • agents/src/voice/audio_recognition.ts – the user-turn pipeline now collects requestId from incoming SpeechEvents (deduped) and writes them onto the user_turn span when it ends.

Implementation nuances vs. Python

  • TTS – no AudioEmitter equivalent. The Python 1.0 PR threads ids through AudioEmitter.start_segment() / _note_provider_request_id. agents-js has no AudioEmitter; plugins push frames carrying requestId / segmentId directly into the TTS queue, so the monitor task uses audio.segmentId for automatic collection. A protected noteProviderRequestId is still exposed for plugins that learn a provider id later (or want to call it from run() directly, matching the Python ergonomics).
  • TTS – attempt span lifetime. Python uses trace.get_current_span() in _note_provider_request_id; in JS the metrics monitor runs as a separate background task, so the current tts_request_run span is captured into a member field (#currentAttemptSpan) at the start of each attempt and cleared in finally. noteProviderRequestId writes to the saved span only while it is still recording, with the same best-effort timing as Python.
  • LLM. The Python patch resets _provider_request_ids per attempt and writes in finally; the JS port does the same on attemptSpan. The dedup-and-collect step in monitorMetrics mirrors the _metrics_monitor_task change.
  • STT. Python collects ids in _on_stt_event and writes them when the user-turn span ends; the JS port mirrors that exactly in onSTTEvent / _endUserTurnSpan, then resets the list when the user turn ends.

Plugin updates skipped (out of scope for JS)

The Python PR also updated three plugins (openai/stt.py, sarvam/stt.py, sarvam/tts.py, upliftai/tts.py). Status in agents-js:

  • openai/stt.py is the OpenAI WebSocket transcription session. agents-js's @livekit/agents-plugin-openai STT is the Whisper REST client – no equivalent surface to port.
  • upliftai plugin does not exist in agents-js.
  • sarvam plugin already passes requestId directly on FINAL_TRANSCRIPT events (no JSON-wrapped original_id bug to fix). It will now flow into the new lk.provider_request_ids attribute via the core change above without any plugin-level edits.

Test plan

  • pnpm build:agents succeeds.
  • pnpm exec eslint clean for the four touched files.
  • pnpm exec prettier --check clean for the four touched files.
  • pnpm exec vitest run agents/src/llm (244 passed / 2 skipped).
  • pnpm exec vitest run agents/src/tts agents/src/voice/audio_recognition_span.test.ts (7 passed).
  • Manual verification of lk.provider_request_ids on real STT/TTS/LLM spans through the agent playground.

https://claude.ai/code/session_01TSGPGRzv6SwoTks2rtCTej


Generated by Claude Code

Port of livekit/agents#5546 to agents-js.

Adds `lk.provider_request_ids` (string[], deduped) on the `user_turn`
(STT), `tts_request_run` (TTS), and `llm_request_run` (LLM) spans so
traces can be cross-referenced with the provider's server-side logs.

- LLM: collected from `ChatChunk.id` in `monitorMetrics`, reset per
  attempt and written on the `llm_request_run` span in finally.
- TTS: `noteProviderRequestId()` helper records ids on the current
  `tts_request_run` (attempt) span; metrics monitor calls it for every
  unique `segmentId` on emitted audio frames.
- STT: `audio_recognition` collects `requestId` from incoming
  `SpeechEvent`s for the user turn and writes them when the
  `user_turn` span ends.

https://claude.ai/code/session_01TSGPGRzv6SwoTks2rtCTej
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 27, 2026

🦋 Changeset detected

Latest commit: 99887f9

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

This PR includes changesets to release 27 packages
Name Type
@livekit/agents Patch
@livekit/agents-plugin-anam Patch
@livekit/agents-plugin-assemblyai 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-elevenlabs Patch
@livekit/agents-plugin-google Patch
@livekit/agents-plugin-hedra Patch
@livekit/agents-plugin-inworld Patch
@livekit/agents-plugin-lemonslice Patch
@livekit/agents-plugin-livekit Patch
@livekit/agents-plugin-minimax Patch
@livekit/agents-plugin-mistral Patch
@livekit/agents-plugin-neuphonic Patch
@livekit/agents-plugin-openai 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-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

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 27, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ toubatbrian
❌ claude
You have signed the CLA already but the status is still pending? Let us recheck it.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@toubatbrian toubatbrian merged commit f93cace into main Apr 29, 2026
7 of 9 checks passed
@toubatbrian toubatbrian deleted the claude/jolly-lovelace-2NfO8 branch April 29, 2026 08:56
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.

4 participants