Skip to content

prod#378

Merged
ariksfaradi merged 7 commits intoprodfrom
main
Apr 29, 2026
Merged

prod#378
ariksfaradi merged 7 commits intoprodfrom
main

Conversation

@ariksfaradi
Copy link
Copy Markdown
Contributor

Pull Request Type

🔮 Feature
🐛 BugFix
⚒️ Refactor
🧹 Chore
🔥 HotFix
🚀 Release

Description

Reference Links

dariusz-did and others added 5 commits April 28, 2026 15:16
Wires the new tool-call/started, tool-call/done, and tool-call/error
data channel events into the existing Mixpanel pipeline as a single
agent-tool-call event with an event discriminator prop.

started ships call_id and name. done and error additionally ship
duration_ms and extra_keys (a count, not the content) so dashboards
can compute latency and error rate per tool name without leaking
input/output payloads.

Tracking is hooked at the same callbacks-spread layer in
connect-to-manager where connection / video / activity analytics
already live, keeping the streaming-manager unaware of analytics.
Adds an onToolEvent describe block exercising the started, done, and
error branches plus the missing-extra fallback. Restores Lines
coverage above the 87% global threshold (was 86.94%).
feat: track tool-call/* events to Mixpanel
…377)

The SDK appended a per-page-load random `_${sessionKey}` to the Client-Key
header. The backend authorizer captures it as part of `external_id`, which
silently broke per-user persistence (e.g. memory_id keys) by minting a new
identifier on every reload. No backend code consumes the suffix as a session
identifier; one analytics handler already strips it. Drop it from the SDK so
external_id stays stable across reloads.
* fix: skip text interrupts on expressive agents to avoid races

Text-typed interrupts on expressive (V2) streams caused race conditions
when the user kept typing while the agent was talking — each keystroke
that triggered chat send would also fire an extra interrupt on top of
prior unsettled ones.

Refactor: move per-transport interrupt logic into each StreamingManager
(livekit-manager skips type==='text'; webrtc-manager preserves the
existing validation + payload from sendInterrupt/validateInterrupt).
agent-manager just forwards the call. Removes services/interrupt module.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* lint

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#371)

* feat(livekit): add replaceMicrophoneTrack for seamless mic device swap

Adds replaceMicrophoneTrack(track) on the LiveKit streaming manager and
exposes it through the public AgentManager surface. Internally calls
LocalAudioTrack.replaceTrack on the existing publication, preserving the
publication (SSRC, trackSid) so the server's STT/VAD pipeline does not
reset across mic device swaps. Throws when there is no publication so
callers can fall back to publishMicrophoneStream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(livekit): tighten replaceMicrophoneTrack coverage

- Bake replaceTrack into the default mock audio track so each test gets
  a fresh spy without ad-hoc (mockTrack as any).replaceTrack = ... lines.
- Drop the misnamed "after disconnect clears the publication" test: it
  hit the 'Room is not connected' guard, which is already covered by
  the dedicated test. Replace with a publish + explicit unpublish path
  that actually reaches the 'No microphone publication to replace'
  branch with isConnected still true.
- Add a regression test that replaceTrack rejection resets the
  isPublishing flag so the next replace is not silently blocked.
- Extend the success test to assert the SDK still holds the original
  publication after replace, by checking that the subsequent disconnect
  unpublishes that exact publication's track.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(livekit): align replace error messages, log guard failures, doc resolution

- Log every guard failure in replaceMicrophoneTrack before throwing, to
  mirror publishTrackStream and give field debugging a console line that
  explains why a replace was skipped.
- Align error message style with the rest of livekit-manager:
  'replaceMicrophoneTrack requires an audio track' -> 'Microphone track
  must be an audio track', 'Microphone publish in progress, cannot
  replace' -> 'Microphone publish in progress'.
- Update the matching test assertions for the new strings.
- Note in the JSDoc on both the StreamingManager and AgentManager
  surfaces that the promise resolves once LiveKit has switched the
  underlying RTCRtpSender's track.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(agent-manager): drop unnecessary async wrappers; align JSDoc

Per PR review: publish/unpublish/replace passthroughs in agent-manager
have no awaits, so async is just a noisy wrapper over a Promise<void>
return. Switch to non-async with explicit Promise<void> return type;
use Promise.reject/resolve to preserve the rejected-promise contract
(rather than sync throw, which would change call-site semantics and
break tests using .rejects.toThrow()).

Also align the replaceMicrophoneTrack JSDoc with the sibling
"supported only for livekit manager" tagline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ariksfaradi ariksfaradi merged commit 1caf29a into prod Apr 29, 2026
17 checks passed
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