feat(amd): port AMDResult → AMDPredictionEvent + event emission from python#1393
Closed
toubatbrian wants to merge 1 commit intomainfrom
Closed
feat(amd): port AMDResult → AMDPredictionEvent + event emission from python#1393toubatbrian wants to merge 1 commit intomainfrom
toubatbrian wants to merge 1 commit intomainfrom
Conversation
…sion Ports livekit/agents#5621 to agents-js. The `AMD` detector now extends an `EventEmitter` and emits `amd_prediction` with an `AMDPredictionEvent` payload (`type: 'amd_prediction'`, plus the existing `category` / `reason` / `transcript` / `rawResponse` / `isMachine` fields and a new optional `speechDurationMs`). `AMDResult` is preserved as a deprecated type alias for backward compatibility. The remote-session wire serialization for AMD predictions is intentionally deferred until `@livekit/protocol` ships the corresponding `AmdPrediction` / `AmdCategory` message types; a TODO marker has been left in `voice/remote_session.ts`. https://claude.ai/code/session_01EKYkaTHopcXtBQXb8d4yrV
🦋 Changeset detectedLatest commit: 0116894 The changes in this PR will be included in the next version bump. This PR includes changesets to release 29 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 |
|
|
Member
|
This is a duplicate of #1394 |
Member
|
Going to close this as this is a duplicate. |
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.
Summary
Automated port of livekit/agents#5621 (
feat(amd): add remote session event for amd AGT-2828) — a core-runtime change to the Answering Machine Detection module.This is an automated Claude Code routine created by @toubatbrian. Right now it is in experimentation stage.
What's ported
agents/src/voice/amd.tsAMDResult→AMDPredictionEventto match Python's new event-shaped name.AMDResultis preserved as a@deprecatedtype alias re-exportingAMDPredictionEventso existing JS consumers don't immediately break (Python performed a hard rename; we soften this for the JS port — see Implementation nuances below).AMDnow extendsEventEmitter(typed via@livekit/typed-emitterwith anAMDCallbacksmap). It emits'amd_prediction'once a prediction settles, mirroring Python's_AMDClassifier→AMDevent chain. Subscribers register withamd.on('amd_prediction', listener).type: 'amd_prediction'discriminator on the payload. This makesAMDPredictionEventconsistent with the rest of the JS event types invoice/events.ts(e.g.UserInputTranscribedEvent,MetricsCollectedEvent) which all use atypeliteral.speechDurationMson the payload. Computed from existingspeechStartedAt/ newspeechEndedAttracking inside the detector, populated for both heuristic and LLM-driven verdicts. (See Implementation nuances for why this is in ms and optional.)finish()method nowemitsamd_predictionimmediately before resolving theexecute()promise, so listeners andawait amd.execute()callers see the same payload.agents/src/voice/amd.test.tstype: 'amd_prediction'discriminator on the resolved value.amd.on('amd_prediction', ...)subscriber that verifies the event fires exactly once and carries the right category, alongside the existingexecute()resolution assertion.agents/src/voice/remote_session.tsTODO(amd_prediction)marker onSessionHostnext to the otheron*handlers, pointing at the spot where Python's_on_amd_predictionbelongs. It is intentionally not wired up yet — see What's deferred.Implementation nuances (where exact parity wasn't possible)
AgentSessionEvent.AmdPredictionmessage and anAmdCategoryenum tolivekit/protocoland bumps the Python protocol dependency to>=1.1.8. The JS protocol package (@livekit/protocol@1.45.6) currently shipped inagents-jsdoes not yet contain those types. Rather than vendoring the protobuf or adding a hand-rolled serializer, this PR leaves a TODO at the wire-up site inremote_session.ts. Once@livekit/protocolships the AMD prediction types, a follow-up PR can:SessionHosttoamd.on('amd_prediction', this.onAmdPrediction)(or, more likely, expose the AMD instance through the session)_AMD_CATEGORY_MAPin TSspeechDurationMs→ seconds-typedDurationand forward viaemitEvent({ case: 'amdPrediction', value: ... })AMDResultkept as a deprecated alias. Python performed a hard rename (no backward-compat alias), but Python is mid-major (1.x) and ships AMD as part of the same release window. agents-js publishes against an installed user base, so we soften the rename withexport type AMDResult = AMDPredictionEvent;marked@deprecated. Same shape, no runtime impact, gives consumers one release to migrate.speechDurationMsisnumber | undefined(ms), notfloat(seconds). Python shipsspeech_duration: float(seconds) on the event. PerCLAUDE.mdJS time-unit conventions, the JS port uses milliseconds with noInSsuffix. It is also marked optional because there are paths (no-speech timeout before any VADspeakingtransition) where the detector legitimately has no measured speech duration; in Python those paths fall back toself.speech_durationwhich the classifier always tracks, but the JSAMDclass doesn't track a continuous speech duration outside an activeexecute()run.delayfield yet. Python'sAmdPredictionproto includes adelay(LLM detection delay). The JS detector doesn't currently instrument LLM-call timing for AMD, so adding adelayfield would require additional bookkeeping. Left out for this patch; will come naturally with the wire-format follow-up.livekit-protocolversion bump inpyproject.toml,uv.lockregeneration,# type: ignore[assignment]annotation inllm/_provider_format/openai.py, fal-pluginawaitcorrectness fix, spitch-plugin# type: ignorecleanup. None of these have JS equivalents.examples/telephony/amd.pyto make SIP optional. The agents-js examples don't ship a corresponding AMD telephony example, so there is nothing to mirror.Test plan
pnpm vitest run src/voice/amd.test.ts— 4/4 passpnpm vitest run src/voice/amd.test.ts src/voice/agent.test.ts— 22/22 passpnpm build:agents— clean buildpnpm format:write— formatting cleanpnpm linton touched files (amd.ts,amd.test.ts,remote_session.ts) — no new errors (pre-existing repo-wide warnings unrelated)Notes
.changeset/amd-prediction-event.md(@livekit/agents: patch).TODO(amd_prediction)invoice/remote_session.ts.cc @toubatbrian @livekit/agent-devs
https://claude.ai/code/session_01EKYkaTHopcXtBQXb8d4yrV
Generated by Claude Code