Skip to content

feat(voice): support granular RecordingOptions in session.start#1702

Merged
toubatbrian merged 2 commits into
livekit:mainfrom
anzemur:feat/granular-recording-options
Jun 3, 2026
Merged

feat(voice): support granular RecordingOptions in session.start#1702
toubatbrian merged 2 commits into
livekit:mainfrom
anzemur:feat/granular-recording-options

Conversation

@anzemur
Copy link
Copy Markdown
Contributor

@anzemur anzemur commented Jun 3, 2026

What

AgentSession.start currently accepts record?: boolean only. This PR lets it also accept a granular object so callers can toggle individual recording categories:

// all on / all off (unchanged)
await session.start({ agent, record: true });
await session.start({ agent, record: false });

// granular — omitted keys default to true
await session.start({ agent, record: { audio: false } }); // drop audio, keep traces/logs/transcript
await session.start({
  agent,
  record: { audio: true, traces: false, logs: false, transcript: false },
});

record now accepts boolean | RecordingOptions, where each key gates one part of the pipeline:

key gates
audio the audio RecorderIO / uploaded recording.ogg
traces the OTLP trace exporter (cloud tracer)
logs the OTel / pino log exporter
transcript the chat-history upload

A boolean still maps to all-on / all-off, so this is fully backward compatible.

Why

The observability docs already document this granular form for Nodedocs.livekit.io/deploy/observability/insights/#recording-options shows:

await session.start({
  agent,
  record: { audio: true, traces: false, logs: false, transcript: false },
});

…but the JS SDK only supports record?: boolean (every published version through 1.4.5, plus the canary). So the documented API doesn't type-check, and passing the object silently enables recording (a non-empty object is truthy). This PR makes the SDK match the docs.

Approach

Direct port of the Python implementation (livekit/agentslivekit-agents/livekit/agents/voice/agent_session.py: RecordingOptions / _resolve_recording_options, plus the per-category gating in job.py and telemetry/traces.py). Same semantics: a partial object is merged onto all-on, so omitted keys default to true.

Two paths — your call:

  1. Land this to give JS parity with Python and make the existing docs correct, or
  2. if granular control isn't wanted in JS yet, I'm happy to instead open a docs PR correcting the Node example back to record: boolean.

Tests

Added unit tests for resolveRecordingOptions (bool → all-on/off, partial-merge incl. the exact docs example, and mutation-safety) and for the report's recordingOptions default/passthrough + the _enableRecording derivation.

Verified:

  • pnpm --filter @livekit/agents build:types — ✅ typechecks
  • eslint on changed files — ✅ no new errors
  • prettier --write — ✅
  • vitest run (agent_session + report) — ✅ 14 passed
  • Live LiveKit Cloud check — ran the patched uploadSessionReport against a real LiveKit Cloud project across the matrix: all-on, audio:false with an audio file present locally, transcript:false + audio, transcript-only, and logs/traces-only (→ early return). The observability logs endpoint and the recordings multipart endpoint accept every partial-upload shape the change produces — including audio omitted while a recording file exists — 5/5 accepted. (The baseline record:true case behaves identically, confirming no regression in the upload path.)

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 3, 2026

🦋 Changeset detected

Latest commit: 20c8414

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

This PR includes changesets to release 34 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-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

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jun 3, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Contributor

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

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 4 additional findings.

Open in Devin Review

@toubatbrian toubatbrian merged commit 36b4f75 into livekit:main Jun 3, 2026
6 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 3, 2026
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.

3 participants