Add Krisp Viva frame processor plugin - #2026
Conversation
🦋 Changeset detectedLatest commit: a81e470 The changes in this PR will be included in the next version bump. This PR includes changesets to release 37 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 |
| close(): void { | ||
| this.session = null; | ||
| this.inBuf = new Int16Array(0); | ||
| this.outBuf = new Int16Array(0); | ||
| } |
There was a problem hiding this comment.
🔴 Native SDK resource is never released when the processor is closed
The native Krisp SDK is acquired but never released when the processor is closed (close() at plugins/krisp/src/krisp.ts:337-341), because the release logic lives in a separate destroy() method that nothing ever calls, so the SDK leaks for the lifetime of the process.
Impact: The native Krisp Audio SDK global state is never cleaned up, leaking native resources each time a session ends.
SDK acquire/release lifecycle mismatch
When using the Krisp license auth path, KrispLicenseSDKManager.acquire() is called during KrispLicenseFrameProcessor.create() at plugins/krisp/src/krisp.ts:207, incrementing a reference count. The matching KrispLicenseSDKManager.release() call exists only in destroy() at plugins/krisp/src/krisp.ts:343-349.
However, the framework's teardown path calls close(), not destroy():
agents/src/voice/room_io/_input.ts:178callsthis.frameProcessor?.close()plugins/krisp/src/viva_filter.ts:211-213(the facade) callsthis.inner?.close()plugins/krisp/src/krisp.ts:337-341(close()) only nulls the session and buffers — it never callsKrispLicenseSDKManager.release()
The destroy() method is not part of the FrameProcessor base class interface and is never invoked by any caller in the codebase. As a result, referenceCount never decrements and globalDestroy() is never called.
| close(): void { | |
| this.session = null; | |
| this.inBuf = new Int16Array(0); | |
| this.outBuf = new Int16Array(0); | |
| } | |
| close(): void { | |
| this.session = null; | |
| this.inBuf = new Int16Array(0); | |
| this.outBuf = new Int16Array(0); | |
| if (this.sdkAcquired) { | |
| KrispLicenseSDKManager.release(); | |
| this.sdkAcquired = false; | |
| } | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
@livekit/agents-plugin-krispwith the Krisp VIVAFrameProcessorfacade, auth providers, plugin registration, README, API report, and changeset.Source diff coverage
File-by-file classification
examples/voice_agents/basic_agent.py: adapted toexamples/src/basic_agent.ts; updated the target example comments/import guidance from BVC/noise-cancellation to Krisp Viva.livekit-plugins/livekit-plugins-krisp/README.md: adapted toplugins/krisp/README.md; translated install/import/API examples to npm/TypeScript and documented the JS backend package/runtime-auth behavior.livekit-plugins/livekit-plugins-krisp/examples/krisp_agent_example.py: not applicable; target has no per-plugin Krisp example directory counterpart. Parity is represented through README usage andbasic_agent.ts, without inventing new examples.livekit-plugins/livekit-plugins-krisp/examples/krisp_minimal_example.py: not applicable for the same reason: no target counterpart and no existing JS Krisp example to modify.livekit-plugins/livekit-plugins-krisp/livekit/plugins/krisp/__init__.py: ported toplugins/krisp/src/index.ts; exports the public processor/auth namespace and registers the plugin.livekit-plugins/livekit-plugins-krisp/livekit/plugins/krisp/_krisp.py: adapted toplugins/krisp/src/krisp.ts; ports license-mode frame buffering, mono passthrough, sample-rate adaptation, runtimenoiseSuppressionLevel, and SDK lifecycle as far as the Node SDK backend permits.livekit-plugins/livekit-plugins-krisp/livekit/plugins/krisp/auth.py: ported toplugins/krisp/src/auth.ts; provides LiveKit Cloud and Krisp license auth providers plus JS aliasesauth.livekitCloud/auth.krispLicense.livekit-plugins/livekit-plugins-krisp/livekit/plugins/krisp/krisp_instance.py: not applicable as a deleted source file; its responsibilities are replaced by the new facade/license implementation inplugins/krisp/src/krisp.ts.livekit-plugins/livekit-plugins-krisp/livekit/plugins/krisp/viva_filter.py: adapted toplugins/krisp/src/viva_filter.ts; ports provider resolution, default LiveKit Cloud backend selection, deprecatedmodelPath/sampleRate/frameDurationMshandling, forwarding hooks, enabled state, close, and runtime suppression-level APIs.livekit-plugins/livekit-plugins-krisp/pyproject.toml: adapted toplugins/krisp/package.json,tsconfig.json,tsup.config.ts, and API Extractor config; creates the JS package with equivalent workspace metadata.pyproject.toml: not applicable; source-only Python workspace/pytest formatting changes have no target counterpart. Target workspace already includesplugins/*.tests/test_krisp_frame_buffer.py: ported toplugins/krisp/src/krisp.test.ts; translates the buffering regression tests to Vitest without adding unrelated tests.uv.lock: not applicable; Python lockfile changes map to targetpackage.json/pnpm-lock.yamlupdates only as needed by the new JS package.Backend gap
The Python source PR depends on published Python backend wheels (
livekit-plugins-krisp-internalfor LiveKit Cloud andkrisp_audiofor license mode). I could not find an equivalent published Node backend package in this target repo or npm. This PR ports the public JS facade, provider resolution,FrameProcessorlifecycle hooks, and license-mode buffering against expected Node module shapes, but real runtime cloud/license audio processing requires those Node backend packages to exist:@livekit/agents-plugin-krisp-internaland expects it to exportKrispVivaFilterFrameProcessor.krisp-audioand expects a Krisp SDK API equivalent to the Python SDK.Without those backend packages installed, constructors throw explicit runtime errors rather than silently bypassing noise reduction.
Verification
pnpm test -- plugins/krisp: passed.pnpm --filter @livekit/agents-plugin-krisp lint: passed.pnpm --filter @livekit/agents-plugin-krisp... build: passed.pnpm --filter @livekit/agents-plugin-krisp api:check: passed.pnpm --filter livekit-agents-examples... build: passed.pnpm --filter livekit-agents-examples lint: completed with pre-existing warnings inexamples/src/testing/survey_agent.test.ts.pnpm lint: passed with existing warnings across the repo.pnpm exec turbo run build --concurrency=1: passed. A prior plainpnpm buildattempt was killed with exit 137 while building unrelated packages in parallel.pnpm --filter livekit-agents-examples test: failed in existing example tests unrelated to the Krisp changes (src/drive-thru/test_agent.test.ts,src/testing/agent_task.test.ts, and unhandled FakeLLM errors reported fromsrc/testing/survey_agent.test.ts).Ported from livekit/agents#5914
Original PR description
simplified default usage for cloud users now looks like