feat(voice): support granular RecordingOptions in session.start#1702
Merged
toubatbrian merged 2 commits intoJun 3, 2026
Conversation
🦋 Changeset detectedLatest commit: 20c8414 The changes in this PR will be included in the next version bump. This PR includes changesets to release 34 packages
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 |
toubatbrian
approved these changes
Jun 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
AgentSession.startcurrently acceptsrecord?: booleanonly. This PR lets it also accept a granular object so callers can toggle individual recording categories:recordnow acceptsboolean | RecordingOptions, where each key gates one part of the pipeline:audioRecorderIO/ uploadedrecording.oggtraceslogstranscriptA boolean still maps to all-on / all-off, so this is fully backward compatible.
Why
The observability docs already document this granular form for Node — docs.livekit.io/deploy/observability/insights/#recording-options shows:
…but the JS SDK only supports
record?: boolean(every published version through1.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/agents→livekit-agents/livekit/agents/voice/agent_session.py:RecordingOptions/_resolve_recording_options, plus the per-category gating injob.pyandtelemetry/traces.py). Same semantics: a partial object is merged onto all-on, so omitted keys default totrue.Two paths — your call:
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'srecordingOptionsdefault/passthrough + the_enableRecordingderivation.Verified:
pnpm --filter @livekit/agents build:types— ✅ typecheckseslinton changed files — ✅ no new errorsprettier --write— ✅vitest run(agent_session + report) — ✅ 14 passeduploadSessionReportagainst a real LiveKit Cloud project across the matrix: all-on,audio:falsewith 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 baselinerecord:truecase behaves identically, confirming no regression in the upload path.)