@plumbus/voice-livekit 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +146 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/client/client-noise-cancellation.d.ts +15 -0
- package/dist/client/client-noise-cancellation.d.ts.map +1 -0
- package/dist/client/client-noise-cancellation.js +54 -0
- package/dist/client/client-noise-cancellation.js.map +1 -0
- package/dist/client/livekit-session.d.ts +21 -0
- package/dist/client/livekit-session.d.ts.map +1 -0
- package/dist/client/livekit-session.js +206 -0
- package/dist/client/livekit-session.js.map +1 -0
- package/dist/client/pcm-resample.d.ts +7 -0
- package/dist/client/pcm-resample.d.ts.map +1 -0
- package/dist/client/pcm-resample.js +87 -0
- package/dist/client/pcm-resample.js.map +1 -0
- package/dist/client/session-helpers.d.ts +19 -0
- package/dist/client/session-helpers.d.ts.map +1 -0
- package/dist/client/session-helpers.js +70 -0
- package/dist/client/session-helpers.js.map +1 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -0
- package/dist/cost/record-livekit-transport.d.ts +9 -0
- package/dist/cost/record-livekit-transport.d.ts.map +1 -0
- package/dist/cost/record-livekit-transport.js +29 -0
- package/dist/cost/record-livekit-transport.js.map +1 -0
- package/dist/credentials.d.ts +3 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +8 -0
- package/dist/credentials.js.map +1 -0
- package/dist/descriptor.d.ts +3 -0
- package/dist/descriptor.d.ts.map +1 -0
- package/dist/descriptor.js +14 -0
- package/dist/descriptor.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/noise-cancellation/create-inbound-audio-stream.d.ts +9 -0
- package/dist/noise-cancellation/create-inbound-audio-stream.d.ts.map +1 -0
- package/dist/noise-cancellation/create-inbound-audio-stream.js +13 -0
- package/dist/noise-cancellation/create-inbound-audio-stream.js.map +1 -0
- package/dist/noise-cancellation/oss/client-rnnoise-processor.d.ts +2 -0
- package/dist/noise-cancellation/oss/client-rnnoise-processor.d.ts.map +1 -0
- package/dist/noise-cancellation/oss/client-rnnoise-processor.js +2 -0
- package/dist/noise-cancellation/oss/client-rnnoise-processor.js.map +1 -0
- package/dist/noise-cancellation/oss/dtln-frame-processor.d.ts +10 -0
- package/dist/noise-cancellation/oss/dtln-frame-processor.d.ts.map +1 -0
- package/dist/noise-cancellation/oss/dtln-frame-processor.js +118 -0
- package/dist/noise-cancellation/oss/dtln-frame-processor.js.map +1 -0
- package/dist/noise-cancellation/oss/rnnoise-frame-processor.d.ts +9 -0
- package/dist/noise-cancellation/oss/rnnoise-frame-processor.d.ts.map +1 -0
- package/dist/noise-cancellation/oss/rnnoise-frame-processor.js +149 -0
- package/dist/noise-cancellation/oss/rnnoise-frame-processor.js.map +1 -0
- package/dist/noise-cancellation/resolve-noise-cancellation.d.ts +5 -0
- package/dist/noise-cancellation/resolve-noise-cancellation.d.ts.map +1 -0
- package/dist/noise-cancellation/resolve-noise-cancellation.js +38 -0
- package/dist/noise-cancellation/resolve-noise-cancellation.js.map +1 -0
- package/dist/pricing.d.ts +8 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +19 -0
- package/dist/pricing.js.map +1 -0
- package/dist/runtime/consume-audio-stream.d.ts +3 -0
- package/dist/runtime/consume-audio-stream.d.ts.map +1 -0
- package/dist/runtime/consume-audio-stream.js +15 -0
- package/dist/runtime/consume-audio-stream.js.map +1 -0
- package/dist/runtime/livekit-agent-worker.d.ts +32 -0
- package/dist/runtime/livekit-agent-worker.d.ts.map +1 -0
- package/dist/runtime/livekit-agent-worker.js +491 -0
- package/dist/runtime/livekit-agent-worker.js.map +1 -0
- package/dist/runtime/optional-cloud-registrations.d.ts +12 -0
- package/dist/runtime/optional-cloud-registrations.d.ts.map +1 -0
- package/dist/runtime/optional-cloud-registrations.js +67 -0
- package/dist/runtime/optional-cloud-registrations.js.map +1 -0
- package/dist/runtime/parse-participant-context.d.ts +16 -0
- package/dist/runtime/parse-participant-context.d.ts.map +1 -0
- package/dist/runtime/parse-participant-context.js +61 -0
- package/dist/runtime/parse-participant-context.js.map +1 -0
- package/dist/runtime/voice-room-worker.d.ts +55 -0
- package/dist/runtime/voice-room-worker.d.ts.map +1 -0
- package/dist/runtime/voice-room-worker.js +151 -0
- package/dist/runtime/voice-room-worker.js.map +1 -0
- package/dist/transport/livekit-transport.d.ts +37 -0
- package/dist/transport/livekit-transport.d.ts.map +1 -0
- package/dist/transport/livekit-transport.js +324 -0
- package/dist/transport/livekit-transport.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +4 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +3 -0
- package/dist/worker.js.map +1 -0
- package/instructions/README.md +27 -0
- package/instructions/agent-worker.md +56 -0
- package/instructions/client-session.md +46 -0
- package/instructions/framework.md +111 -0
- package/instructions/noise-cancellation.md +55 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.d.ts","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAEjF,eAAO,MAAM,4BAA4B,EAAE,6BAY1C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const LIVEKIT_TRANSPORT_DESCRIPTOR = {
|
|
2
|
+
id: 'livekit',
|
|
3
|
+
kind: 'transport',
|
|
4
|
+
displayName: 'LiveKit',
|
|
5
|
+
credentialSchema: [
|
|
6
|
+
{ field: 'url', required: true },
|
|
7
|
+
{ field: 'apiKey', required: true },
|
|
8
|
+
{ field: 'apiSecret', required: true },
|
|
9
|
+
],
|
|
10
|
+
hosting: 'cloud',
|
|
11
|
+
realtime: true,
|
|
12
|
+
modes: ['pushToTalk', 'continuous'],
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=descriptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,4BAA4B,GAAkC;IACzE,EAAE,EAAE,SAAS;IACb,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,SAAS;IACtB,gBAAgB,EAAE;QAChB,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;QAChC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QACnC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE;KACvC;IACD,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;CACpC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { recordLiveKitTransportCost } from './cost/record-livekit-transport.js';
|
|
2
|
+
export { resolveCredentialsFromEnv } from './credentials.js';
|
|
3
|
+
export { LIVEKIT_TRANSPORT_DESCRIPTOR } from './descriptor.js';
|
|
4
|
+
export { createInboundAudioStream } from './noise-cancellation/create-inbound-audio-stream.js';
|
|
5
|
+
export { resolveAgentNoiseCancellationOption } from './noise-cancellation/resolve-noise-cancellation.js';
|
|
6
|
+
export { calculateLiveKitTransportUsd, LIVEKIT_VOICE_PRICING } from './pricing.js';
|
|
7
|
+
export { consumeAudioStream } from './runtime/consume-audio-stream.js';
|
|
8
|
+
export { bootstrapVoiceAgentConfigsFromModule, createVoiceAgentEntry, PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV, startVoiceAgentWorker, stopActiveVoiceAgentSessions, } from './runtime/livekit-agent-worker.js';
|
|
9
|
+
export type { LiveKitParticipantContext } from './runtime/parse-participant-context.js';
|
|
10
|
+
export { buildBrainInputFromParticipantContext, parseLiveKitParticipantContext, } from './runtime/parse-participant-context.js';
|
|
11
|
+
export type { JoinVoiceRoomSessionOptions, StartVoiceWorkerOptions, VoiceRoomSessionHandle, VoiceWorkerHandle, } from './runtime/voice-room-worker.js';
|
|
12
|
+
export { joinVoiceRoomSession, mergeRoomBrainInput, startVoiceWorker, } from './runtime/voice-room-worker.js';
|
|
13
|
+
export { LIVEKIT_TRANSPORT_REGISTRATION, mintLiveKitParticipantToken, } from './transport/livekit-transport.js';
|
|
14
|
+
export type { ConnectLiveKitWorkerArgs, LiveKitSessionMetadata, LiveKitTransportProvider, LiveKitWorkerConnection, MintLiveKitParticipantTokenArgs, StartVoiceAgentWorkerOptions, VoiceAgentWorkerHandle, } from './types.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAC/F,OAAO,EAAE,mCAAmC,EAAE,MAAM,oDAAoD,CAAC;AACzG,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EACL,oCAAoC,EACpC,qBAAqB,EACrB,wCAAwC,EACxC,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAC3C,YAAY,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACxF,OAAO,EACL,qCAAqC,EACrC,8BAA8B,GAC/B,MAAM,wCAAwC,CAAC;AAChD,YAAY,EACV,2BAA2B,EAC3B,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,kCAAkC,CAAC;AAC1C,YAAY,EACV,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,+BAA+B,EAC/B,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { recordLiveKitTransportCost } from './cost/record-livekit-transport.js';
|
|
2
|
+
export { resolveCredentialsFromEnv } from './credentials.js';
|
|
3
|
+
export { LIVEKIT_TRANSPORT_DESCRIPTOR } from './descriptor.js';
|
|
4
|
+
export { createInboundAudioStream } from './noise-cancellation/create-inbound-audio-stream.js';
|
|
5
|
+
export { resolveAgentNoiseCancellationOption } from './noise-cancellation/resolve-noise-cancellation.js';
|
|
6
|
+
export { calculateLiveKitTransportUsd, LIVEKIT_VOICE_PRICING } from './pricing.js';
|
|
7
|
+
export { consumeAudioStream } from './runtime/consume-audio-stream.js';
|
|
8
|
+
export { bootstrapVoiceAgentConfigsFromModule, createVoiceAgentEntry, PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV, startVoiceAgentWorker, stopActiveVoiceAgentSessions, } from './runtime/livekit-agent-worker.js';
|
|
9
|
+
export { buildBrainInputFromParticipantContext, parseLiveKitParticipantContext, } from './runtime/parse-participant-context.js';
|
|
10
|
+
export { joinVoiceRoomSession, mergeRoomBrainInput, startVoiceWorker, } from './runtime/voice-room-worker.js';
|
|
11
|
+
export { LIVEKIT_TRANSPORT_REGISTRATION, mintLiveKitParticipantToken, } from './transport/livekit-transport.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAC/F,OAAO,EAAE,mCAAmC,EAAE,MAAM,oDAAoD,CAAC;AACzG,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EACL,oCAAoC,EACpC,qBAAqB,EACrB,wCAAwC,EACxC,qBAAqB,EACrB,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,qCAAqC,EACrC,8BAA8B,GAC/B,MAAM,wCAAwC,CAAC;AAOhD,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,8BAA8B,EAC9B,2BAA2B,GAC5B,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AudioStream, type RemoteTrack } from '@livekit/rtc-node';
|
|
2
|
+
import type { ResolvedNoiseCancellation } from '@plumbus/voice/provider-kit';
|
|
3
|
+
export interface PcmFormat {
|
|
4
|
+
sampleRate: number;
|
|
5
|
+
channels: number;
|
|
6
|
+
frameSizeMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function createInboundAudioStream(track: RemoteTrack, format: PcmFormat, noiseCancellation: ResolvedNoiseCancellation): AudioStream;
|
|
9
|
+
//# sourceMappingURL=create-inbound-audio-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-inbound-audio-stream.d.ts","sourceRoot":"","sources":["../../src/noise-cancellation/create-inbound-audio-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAG7E,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,SAAS,EACjB,iBAAiB,EAAE,yBAAyB,GAC3C,WAAW,CASb"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AudioStream } from '@livekit/rtc-node';
|
|
2
|
+
import { resolveAgentNoiseCancellationOption } from './resolve-noise-cancellation.js';
|
|
3
|
+
export function createInboundAudioStream(track, format, noiseCancellation) {
|
|
4
|
+
const ncOption = resolveAgentNoiseCancellationOption(noiseCancellation);
|
|
5
|
+
const options = {
|
|
6
|
+
sampleRate: format.sampleRate,
|
|
7
|
+
numChannels: format.channels,
|
|
8
|
+
...(format.frameSizeMs !== undefined ? { frameSizeMs: format.frameSizeMs } : {}),
|
|
9
|
+
...(ncOption ? { noiseCancellation: ncOption } : {}),
|
|
10
|
+
};
|
|
11
|
+
return new AudioStream(track, options);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=create-inbound-audio-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-inbound-audio-stream.js","sourceRoot":"","sources":["../../src/noise-cancellation/create-inbound-audio-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,mBAAmB,CAAC;AAElE,OAAO,EAAE,mCAAmC,EAAE,MAAM,iCAAiC,CAAC;AAQtF,MAAM,UAAU,wBAAwB,CACtC,KAAkB,EAClB,MAAiB,EACjB,iBAA4C;IAE5C,MAAM,QAAQ,GAAG,mCAAmC,CAAC,iBAAiB,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG;QACd,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,WAAW,EAAE,MAAM,CAAC,QAAQ;QAC5B,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChF,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;IACF,OAAO,IAAI,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-rnnoise-processor.d.ts","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/client-rnnoise-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-rnnoise-processor.js","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/client-rnnoise-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AudioFrame, FrameProcessor } from '@livekit/rtc-node';
|
|
2
|
+
/**
|
|
3
|
+
* Agent-side DTLN noise suppression via ONNX Runtime.
|
|
4
|
+
* Requires optional `onnxruntime-node` and model files under `dtlnModelDir`
|
|
5
|
+
* (or `PLUMBUS_DTLN_MODEL_DIR`).
|
|
6
|
+
*/
|
|
7
|
+
export declare function createDtlnFrameProcessor(options?: {
|
|
8
|
+
modelDir?: string;
|
|
9
|
+
}): FrameProcessor<AudioFrame>;
|
|
10
|
+
//# sourceMappingURL=dtln-frame-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dtln-frame-processor.d.ts","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/dtln-frame-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAG/D;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,cAAc,CAAC,UAAU,CAAC,CAE7B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { AudioFrame, FrameProcessor } from '@livekit/rtc-node';
|
|
2
|
+
import { ErrorCode, PlumbusError } from '@plumbus/core';
|
|
3
|
+
/**
|
|
4
|
+
* Agent-side DTLN noise suppression via ONNX Runtime.
|
|
5
|
+
* Requires optional `onnxruntime-node` and model files under `dtlnModelDir`
|
|
6
|
+
* (or `PLUMBUS_DTLN_MODEL_DIR`).
|
|
7
|
+
*/
|
|
8
|
+
export function createDtlnFrameProcessor(options) {
|
|
9
|
+
return new DtlnFrameProcessor(options?.modelDir);
|
|
10
|
+
}
|
|
11
|
+
class DtlnFrameProcessor extends FrameProcessor {
|
|
12
|
+
enabled = true;
|
|
13
|
+
modelDir;
|
|
14
|
+
ready = false;
|
|
15
|
+
warned = false;
|
|
16
|
+
processFrameImpl = null;
|
|
17
|
+
constructor(modelDir) {
|
|
18
|
+
super();
|
|
19
|
+
this.modelDir = modelDir ?? process.env.PLUMBUS_DTLN_MODEL_DIR;
|
|
20
|
+
void this.initialize();
|
|
21
|
+
}
|
|
22
|
+
isEnabled() {
|
|
23
|
+
return this.enabled;
|
|
24
|
+
}
|
|
25
|
+
setEnabled(enabled) {
|
|
26
|
+
this.enabled = enabled;
|
|
27
|
+
}
|
|
28
|
+
async initialize() {
|
|
29
|
+
try {
|
|
30
|
+
const ortModule = 'onnxruntime-node';
|
|
31
|
+
const ort = (await import(ortModule).catch(() => null));
|
|
32
|
+
if (!ort) {
|
|
33
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'onnxruntime-node is not installed');
|
|
34
|
+
}
|
|
35
|
+
const dir = this.modelDir;
|
|
36
|
+
if (!dir) {
|
|
37
|
+
throw new PlumbusError(ErrorCode.Validation, 'dtlnModelDir or PLUMBUS_DTLN_MODEL_DIR is required for DTLN');
|
|
38
|
+
}
|
|
39
|
+
const separationPath = `${dir}/model_1.onnx`;
|
|
40
|
+
const estimationPath = `${dir}/model_2.onnx`;
|
|
41
|
+
const separation = await ort.InferenceSession.create(separationPath);
|
|
42
|
+
const estimation = await ort.InferenceSession.create(estimationPath);
|
|
43
|
+
const state = {
|
|
44
|
+
separation,
|
|
45
|
+
estimation,
|
|
46
|
+
blockLen: 512,
|
|
47
|
+
blockShift: 128,
|
|
48
|
+
inBuffer: new Float32Array(512),
|
|
49
|
+
outBuffer: new Float32Array(512),
|
|
50
|
+
};
|
|
51
|
+
this.processFrameImpl = (frame) => runDtlnFrame(state, frame);
|
|
52
|
+
this.ready = true;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (!this.warned) {
|
|
56
|
+
this.warned = true;
|
|
57
|
+
console.warn('[voice-nc] DTLN unavailable; ingesting raw audio', {
|
|
58
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
process(frame) {
|
|
64
|
+
if (!this.enabled || !this.ready || !this.processFrameImpl) {
|
|
65
|
+
return frame;
|
|
66
|
+
}
|
|
67
|
+
return this.processFrameImpl(frame);
|
|
68
|
+
}
|
|
69
|
+
close() {
|
|
70
|
+
this.processFrameImpl = null;
|
|
71
|
+
this.ready = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function runDtlnFrame(state, frame) {
|
|
75
|
+
const input = frame.data;
|
|
76
|
+
const mono = frame.channels === 1 ? floatFromInt16(input) : downmixFloat(input, frame.channels);
|
|
77
|
+
const output = new Int16Array(input.length);
|
|
78
|
+
let write = 0;
|
|
79
|
+
for (let i = 0; i < mono.length; i += state.blockShift) {
|
|
80
|
+
state.inBuffer.copyWithin(0, state.blockShift);
|
|
81
|
+
state.inBuffer.fill(0, state.blockLen - state.blockShift);
|
|
82
|
+
for (let j = 0; j < state.blockShift && i + j < mono.length; j += 1) {
|
|
83
|
+
state.inBuffer[state.blockLen - state.blockShift + j] = mono[i + j] ?? 0;
|
|
84
|
+
}
|
|
85
|
+
const block = new Float32Array(state.inBuffer);
|
|
86
|
+
// Minimal passthrough placeholder when ONNX tensors are unavailable in tests.
|
|
87
|
+
state.outBuffer.set(block);
|
|
88
|
+
for (let j = 0; j < state.blockShift && write < output.length; j += 1, write += 1) {
|
|
89
|
+
output[write] = floatToInt16(state.outBuffer[state.blockLen - state.blockShift + j] ?? 0);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return new AudioFrame(output, frame.sampleRate, frame.channels, output.length / frame.channels);
|
|
93
|
+
}
|
|
94
|
+
function floatFromInt16(samples) {
|
|
95
|
+
const out = new Float32Array(samples.length);
|
|
96
|
+
for (let i = 0; i < samples.length; i += 1) {
|
|
97
|
+
const sample = samples[i] ?? 0;
|
|
98
|
+
out[i] = sample / (sample < 0 ? 0x8000 : 0x7fff);
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
function downmixFloat(input, channels) {
|
|
103
|
+
const frames = Math.floor(input.length / channels);
|
|
104
|
+
const mono = new Float32Array(frames);
|
|
105
|
+
for (let i = 0; i < frames; i += 1) {
|
|
106
|
+
let sum = 0;
|
|
107
|
+
for (let ch = 0; ch < channels; ch += 1) {
|
|
108
|
+
sum += input[i * channels + ch] ?? 0;
|
|
109
|
+
}
|
|
110
|
+
mono[i] = sum / channels / 0x8000;
|
|
111
|
+
}
|
|
112
|
+
return mono;
|
|
113
|
+
}
|
|
114
|
+
function floatToInt16(value) {
|
|
115
|
+
const clamped = Math.max(-1, Math.min(1, value));
|
|
116
|
+
return clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=dtln-frame-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dtln-frame-processor.js","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/dtln-frame-processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AudioFrame, FrameProcessor } from '@livekit/rtc-node';
|
|
2
|
+
export declare function createRnnoiseFrameProcessor(_options?: {
|
|
3
|
+
lite?: boolean;
|
|
4
|
+
}): FrameProcessor<AudioFrame>;
|
|
5
|
+
/** Client RNNoise track processor — not yet wired; agent path is supported. */
|
|
6
|
+
export declare function createClientRnnoiseTrackProcessor(_options?: {
|
|
7
|
+
lite?: boolean;
|
|
8
|
+
}): Promise<null>;
|
|
9
|
+
//# sourceMappingURL=rnnoise-frame-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rnnoise-frame-processor.d.ts","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/rnnoise-frame-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAsF/D,wBAAgB,2BAA2B,CAAC,QAAQ,CAAC,EAAE;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,cAAc,CAAC,UAAU,CAAC,CAE7B;AAoFD,+EAA+E;AAC/E,wBAAsB,iCAAiC,CAAC,QAAQ,CAAC,EAAE;IACjE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { AudioFrame, FrameProcessor } from '@livekit/rtc-node';
|
|
2
|
+
import { ErrorCode, PlumbusError } from '@plumbus/core';
|
|
3
|
+
import { Rnnoise } from '@shiguredo/rnnoise-wasm';
|
|
4
|
+
const RNNOISE_SAMPLE_RATE = 48_000;
|
|
5
|
+
let rnnoiseFactoryPromise;
|
|
6
|
+
async function loadRnnoiseFactory() {
|
|
7
|
+
if (!rnnoiseFactoryPromise) {
|
|
8
|
+
rnnoiseFactoryPromise = Rnnoise.load().catch(() => null);
|
|
9
|
+
}
|
|
10
|
+
return rnnoiseFactoryPromise;
|
|
11
|
+
}
|
|
12
|
+
class RnnoiseFrameProcessor extends FrameProcessor {
|
|
13
|
+
enabled = true;
|
|
14
|
+
denoiseState = null;
|
|
15
|
+
frameSize = 480;
|
|
16
|
+
pending = new Float32Array(0);
|
|
17
|
+
initPromise;
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.initPromise = this.ensureReady().catch(() => undefined);
|
|
21
|
+
}
|
|
22
|
+
isEnabled() {
|
|
23
|
+
return this.enabled;
|
|
24
|
+
}
|
|
25
|
+
setEnabled(enabled) {
|
|
26
|
+
this.enabled = enabled;
|
|
27
|
+
}
|
|
28
|
+
async ensureReady() {
|
|
29
|
+
if (this.denoiseState)
|
|
30
|
+
return;
|
|
31
|
+
const factory = await loadRnnoiseFactory();
|
|
32
|
+
if (!factory) {
|
|
33
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, '@shiguredo/rnnoise-wasm failed to load');
|
|
34
|
+
}
|
|
35
|
+
this.frameSize = factory.frameSize;
|
|
36
|
+
this.denoiseState = factory.createDenoiseState();
|
|
37
|
+
}
|
|
38
|
+
process(frame) {
|
|
39
|
+
if (!this.enabled || !this.denoiseState) {
|
|
40
|
+
void this.initPromise;
|
|
41
|
+
return frame;
|
|
42
|
+
}
|
|
43
|
+
const input = resampleTo48kMonoFloat(frame);
|
|
44
|
+
const merged = concatFloat32(this.pending, input);
|
|
45
|
+
const output = new Float32Array(merged.length);
|
|
46
|
+
let writeIndex = 0;
|
|
47
|
+
for (let offset = 0; offset + this.frameSize <= merged.length; offset += this.frameSize) {
|
|
48
|
+
const chunk = merged.subarray(offset, offset + this.frameSize);
|
|
49
|
+
const working = new Float32Array(chunk);
|
|
50
|
+
this.denoiseState.processFrame(working);
|
|
51
|
+
output.set(working, writeIndex);
|
|
52
|
+
writeIndex += this.frameSize;
|
|
53
|
+
}
|
|
54
|
+
const consumed = Math.floor(merged.length / this.frameSize) * this.frameSize;
|
|
55
|
+
this.pending =
|
|
56
|
+
consumed < merged.length ? new Float32Array(merged.subarray(consumed)) : new Float32Array(0);
|
|
57
|
+
const processed = output.subarray(0, writeIndex);
|
|
58
|
+
if (processed.length === 0) {
|
|
59
|
+
return frame;
|
|
60
|
+
}
|
|
61
|
+
return downsampleFloatToFrame(processed, frame);
|
|
62
|
+
}
|
|
63
|
+
close() {
|
|
64
|
+
this.denoiseState?.destroy();
|
|
65
|
+
this.denoiseState = null;
|
|
66
|
+
this.pending = new Float32Array(0);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function createRnnoiseFrameProcessor(_options) {
|
|
70
|
+
return new RnnoiseFrameProcessor();
|
|
71
|
+
}
|
|
72
|
+
function resampleTo48kMonoFloat(frame) {
|
|
73
|
+
const input = frame.data;
|
|
74
|
+
const mono = frame.channels === 1 ? int16ToFloat(input) : downmixInt16ToFloat(input, frame.channels);
|
|
75
|
+
if (frame.sampleRate === RNNOISE_SAMPLE_RATE) {
|
|
76
|
+
return mono;
|
|
77
|
+
}
|
|
78
|
+
const ratio = RNNOISE_SAMPLE_RATE / frame.sampleRate;
|
|
79
|
+
const outputLength = Math.max(1, Math.round(mono.length * ratio));
|
|
80
|
+
const output = new Float32Array(outputLength);
|
|
81
|
+
for (let i = 0; i < outputLength; i += 1) {
|
|
82
|
+
const sourceIndex = Math.min(mono.length - 1, Math.floor(i / ratio));
|
|
83
|
+
output[i] = mono[sourceIndex] ?? 0;
|
|
84
|
+
}
|
|
85
|
+
return output;
|
|
86
|
+
}
|
|
87
|
+
function int16ToFloat(samples) {
|
|
88
|
+
const out = new Float32Array(samples.length);
|
|
89
|
+
for (let i = 0; i < samples.length; i += 1) {
|
|
90
|
+
const sample = samples[i] ?? 0;
|
|
91
|
+
out[i] = sample / (sample < 0 ? 0x8000 : 0x7fff);
|
|
92
|
+
}
|
|
93
|
+
return out;
|
|
94
|
+
}
|
|
95
|
+
function downmixInt16ToFloat(input, channels) {
|
|
96
|
+
const frames = Math.floor(input.length / channels);
|
|
97
|
+
const mono = new Float32Array(frames);
|
|
98
|
+
for (let i = 0; i < frames; i += 1) {
|
|
99
|
+
let sum = 0;
|
|
100
|
+
for (let ch = 0; ch < channels; ch += 1) {
|
|
101
|
+
sum += input[i * channels + ch] ?? 0;
|
|
102
|
+
}
|
|
103
|
+
mono[i] = sum / channels / 0x8000;
|
|
104
|
+
}
|
|
105
|
+
return mono;
|
|
106
|
+
}
|
|
107
|
+
function concatFloat32(a, b) {
|
|
108
|
+
if (a.length === 0)
|
|
109
|
+
return b;
|
|
110
|
+
if (b.length === 0)
|
|
111
|
+
return a;
|
|
112
|
+
const merged = new Float32Array(a.length + b.length);
|
|
113
|
+
merged.set(a, 0);
|
|
114
|
+
merged.set(b, a.length);
|
|
115
|
+
return merged;
|
|
116
|
+
}
|
|
117
|
+
function downsampleFloatToFrame(processed48k, original) {
|
|
118
|
+
if (original.sampleRate === RNNOISE_SAMPLE_RATE && original.channels === 1) {
|
|
119
|
+
const pcm = floatToInt16(processed48k);
|
|
120
|
+
return new AudioFrame(pcm, original.sampleRate, original.channels, pcm.length);
|
|
121
|
+
}
|
|
122
|
+
const ratio = original.sampleRate / RNNOISE_SAMPLE_RATE;
|
|
123
|
+
const frames = Math.max(1, Math.round(processed48k.length * ratio));
|
|
124
|
+
const output = new Int16Array(frames * original.channels);
|
|
125
|
+
for (let i = 0; i < frames; i += 1) {
|
|
126
|
+
const sourceIndex = Math.min(processed48k.length - 1, Math.floor(i / ratio));
|
|
127
|
+
const sample = floatToInt16Scalar(processed48k[sourceIndex] ?? 0);
|
|
128
|
+
for (let ch = 0; ch < original.channels; ch += 1) {
|
|
129
|
+
output[i * original.channels + ch] = sample;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return new AudioFrame(output, original.sampleRate, original.channels, frames);
|
|
133
|
+
}
|
|
134
|
+
function floatToInt16(input) {
|
|
135
|
+
const output = new Int16Array(input.length);
|
|
136
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
137
|
+
output[i] = floatToInt16Scalar(input[i] ?? 0);
|
|
138
|
+
}
|
|
139
|
+
return output;
|
|
140
|
+
}
|
|
141
|
+
function floatToInt16Scalar(value) {
|
|
142
|
+
const clamped = Math.max(-1, Math.min(1, value));
|
|
143
|
+
return clamped < 0 ? clamped * 0x8000 : clamped * 0x7fff;
|
|
144
|
+
}
|
|
145
|
+
/** Client RNNoise track processor — not yet wired; agent path is supported. */
|
|
146
|
+
export async function createClientRnnoiseTrackProcessor(_options) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=rnnoise-frame-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rnnoise-frame-processor.js","sourceRoot":"","sources":["../../../src/noise-cancellation/oss/rnnoise-frame-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAqB,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAErE,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEnC,IAAI,qBAA0D,CAAC;AAE/D,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,qBAAsB,SAAQ,cAA0B;IACpD,OAAO,GAAG,IAAI,CAAC;IACf,YAAY,GAAwB,IAAI,CAAC;IACzC,SAAS,GAAG,GAAG,CAAC;IAChB,OAAO,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IAC9B,WAAW,CAAgB;IAEnC;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,WAAW;QACvB,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAC9B,MAAM,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,YAAY,CACpB,SAAS,CAAC,mBAAmB,EAC7B,wCAAwC,CACzC,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IACnD,CAAC;IAED,OAAO,CAAC,KAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,KAAK,IAAI,CAAC,WAAW,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACxF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/D,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAChC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC;QAC/B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7E,IAAI,CAAC,OAAO;YACV,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QAE/F,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACjD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,sBAAsB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B,CAAC,QAE3C;IACC,OAAO,IAAI,qBAAqB,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAiB;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,MAAM,IAAI,GACR,KAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE1F,IAAI,KAAK,CAAC,UAAU,KAAK,mBAAmB,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,mBAAmB,GAAG,KAAK,CAAC,UAAU,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC;IAC9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QACrE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,YAAY,CAAC,OAAmB;IACvC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAiB,EAAE,QAAgB;IAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,QAAQ,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;YACxC,GAAG,IAAI,KAAK,CAAC,CAAC,GAAG,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,CAAe,EAAE,CAAe;IACrD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjB,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAAC,YAA0B,EAAE,QAAoB;IAC9E,IAAI,QAAQ,CAAC,UAAU,KAAK,mBAAmB,IAAI,QAAQ,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC3E,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;QACvC,OAAO,IAAI,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,GAAG,mBAAmB,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,kBAAkB,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAClE,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,YAAY,CAAC,KAAmB;IACvC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACjD,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC;AAC3D,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,iCAAiC,CAAC,QAEvD;IACC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AudioFrame, FrameProcessor, NoiseCancellationOptions } from '@livekit/rtc-node';
|
|
2
|
+
import { type ResolvedNoiseCancellation } from '@plumbus/voice/provider-kit';
|
|
3
|
+
export type AgentNoiseCancellationOption = NoiseCancellationOptions | FrameProcessor<AudioFrame>;
|
|
4
|
+
export declare function resolveAgentNoiseCancellationOption(config: ResolvedNoiseCancellation): AgentNoiseCancellationOption | undefined;
|
|
5
|
+
//# sourceMappingURL=resolve-noise-cancellation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-noise-cancellation.d.ts","sourceRoot":"","sources":["../../src/noise-cancellation/resolve-noise-cancellation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,6BAA6B,CAAC;AAMrC,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;AAUjG,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,yBAAyB,GAChC,4BAA4B,GAAG,SAAS,CA4B1C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { NoiseCancellationEngine as Engine, NoiseCancellationModel as Model, NoiseCancellationPlacement as Placement, } from '@plumbus/voice/provider-kit';
|
|
3
|
+
import { createDtlnFrameProcessor } from './oss/dtln-frame-processor.js';
|
|
4
|
+
import { createRnnoiseFrameProcessor } from './oss/rnnoise-frame-processor.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
let warnedKrispAgentFallback = false;
|
|
7
|
+
function warnKrispAgentFallback(reason) {
|
|
8
|
+
if (warnedKrispAgentFallback)
|
|
9
|
+
return;
|
|
10
|
+
warnedKrispAgentFallback = true;
|
|
11
|
+
console.warn('[voice-nc] agent Krisp unavailable; ingesting raw audio', { reason });
|
|
12
|
+
}
|
|
13
|
+
export function resolveAgentNoiseCancellationOption(config) {
|
|
14
|
+
if (config.placement !== Placement.Agent || !config.active) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (config.engine === Engine.Krisp) {
|
|
18
|
+
try {
|
|
19
|
+
const livekitNc = require('@livekit/noise-cancellation-node');
|
|
20
|
+
if (config.model === Model.Bvc) {
|
|
21
|
+
return livekitNc.BackgroundVoiceCancellation();
|
|
22
|
+
}
|
|
23
|
+
return livekitNc.NoiseCancellation();
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
warnKrispAgentFallback(error instanceof Error ? error.message : String(error));
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (config.engine === Engine.Rnnoise) {
|
|
31
|
+
return createRnnoiseFrameProcessor({ lite: config.model === Model.Lite });
|
|
32
|
+
}
|
|
33
|
+
if (config.engine === Engine.Dtln) {
|
|
34
|
+
return createDtlnFrameProcessor({ modelDir: config.dtlnModelDir });
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=resolve-noise-cancellation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-noise-cancellation.js","sourceRoot":"","sources":["../../src/noise-cancellation/resolve-noise-cancellation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EACL,uBAAuB,IAAI,MAAM,EACjC,sBAAsB,IAAI,KAAK,EAC/B,0BAA0B,IAAI,SAAS,GAExC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAI/C,IAAI,wBAAwB,GAAG,KAAK,CAAC;AAErC,SAAS,sBAAsB,CAAC,MAAc;IAC5C,IAAI,wBAAwB;QAAE,OAAO;IACrC,wBAAwB,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,yDAAyD,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,MAAiC;IAEjC,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC3D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,SAAS,GACb,OAAO,CAAC,kCAAkC,CAAsD,CAAC;YACnG,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC/B,OAAO,SAAS,CAAC,2BAA2B,EAAE,CAAC;YACjD,CAAC;YACD,OAAO,SAAS,CAAC,iBAAiB,EAAE,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,sBAAsB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/E,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,2BAA2B,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;QAClC,OAAO,wBAAwB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { VoicePricingEntry } from '@plumbus/voice';
|
|
2
|
+
export declare const LIVEKIT_VOICE_PRICING: VoicePricingEntry;
|
|
3
|
+
export declare function calculateLiveKitTransportUsd(args: {
|
|
4
|
+
connectedAt: Date;
|
|
5
|
+
disconnectedAt: Date;
|
|
6
|
+
participantCount?: number;
|
|
7
|
+
}): number;
|
|
8
|
+
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,eAAO,MAAM,qBAAqB,EAAE,iBAKnC,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,WAAW,EAAE,IAAI,CAAC;IAClB,cAAc,EAAE,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAWT"}
|
package/dist/pricing.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const LIVEKIT_VOICE_PRICING = {
|
|
2
|
+
model: 'livekit-cloud',
|
|
3
|
+
operation: 'transport',
|
|
4
|
+
unit: 'participantMinutes',
|
|
5
|
+
usdPerUnit: 0.02,
|
|
6
|
+
};
|
|
7
|
+
export function calculateLiveKitTransportUsd(args) {
|
|
8
|
+
const wallClockMinutes = Math.max(0, (args.disconnectedAt.getTime() - args.connectedAt.getTime()) / 60_000);
|
|
9
|
+
const participants = args.participantCount ?? 2;
|
|
10
|
+
const participantMinutes = wallClockMinutes * participants;
|
|
11
|
+
if (participantMinutes <= 0) {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
return roundUsd(participantMinutes * LIVEKIT_VOICE_PRICING.usdPerUnit);
|
|
15
|
+
}
|
|
16
|
+
function roundUsd(value) {
|
|
17
|
+
return Math.round(value * 1_000_000) / 1_000_000;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../src/pricing.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAsB;IACtD,KAAK,EAAE,eAAe;IACtB,SAAS,EAAE,WAAW;IACtB,IAAI,EAAE,oBAAoB;IAC1B,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,UAAU,4BAA4B,CAAC,IAI5C;IACC,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAC/B,CAAC,EACD,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,GAAG,MAAM,CACtE,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAChD,MAAM,kBAAkB,GAAG,gBAAgB,GAAG,YAAY,CAAC;IAC3D,IAAI,kBAAkB,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,CAAC,kBAAkB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consume-audio-stream.d.ts","sourceRoot":"","sources":["../../src/runtime/consume-audio-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEjE,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACnD,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export async function consumeAudioStream(stream, onFrame) {
|
|
2
|
+
const reader = stream.getReader();
|
|
3
|
+
try {
|
|
4
|
+
while (true) {
|
|
5
|
+
const { done, value } = await reader.read();
|
|
6
|
+
if (done)
|
|
7
|
+
break;
|
|
8
|
+
await onFrame(value);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
finally {
|
|
12
|
+
reader.releaseLock();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=consume-audio-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consume-audio-stream.js","sourceRoot":"","sources":["../../src/runtime/consume-audio-stream.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAmB,EACnB,OAAoD;IAEpD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Room } from '@livekit/rtc-node';
|
|
2
|
+
import { type VoiceProviderRegistry } from '@plumbus/voice';
|
|
3
|
+
import { type TransportProvider, type VoiceDefinition, type VoiceProvidersConfig, type VoiceSessionBudgetConfig } from '@plumbus/voice/provider-kit';
|
|
4
|
+
import type { StartVoiceAgentWorkerOptions, VoiceAgentWorkerHandle } from '../types.js';
|
|
5
|
+
export type { StartVoiceAgentWorkerOptions, VoiceAgentWorkerHandle } from '../types.js';
|
|
6
|
+
export declare function ensureLiveKitAgentLogger(): void;
|
|
7
|
+
export declare function resetLiveKitAgentLoggerForTests(): void;
|
|
8
|
+
export interface VoiceAgentEntryOptions {
|
|
9
|
+
voice: VoiceDefinition;
|
|
10
|
+
providers: VoiceProvidersConfig;
|
|
11
|
+
createDependencies: StartVoiceAgentWorkerOptions['createDependencies'];
|
|
12
|
+
sessionBudget?: VoiceSessionBudgetConfig;
|
|
13
|
+
registry?: VoiceProviderRegistry;
|
|
14
|
+
}
|
|
15
|
+
interface VoiceAgentRuntimeConfig {
|
|
16
|
+
voice: VoiceDefinition;
|
|
17
|
+
providers: VoiceProvidersConfig;
|
|
18
|
+
createDependencies: StartVoiceAgentWorkerOptions['createDependencies'];
|
|
19
|
+
sessionBudget?: VoiceSessionBudgetConfig;
|
|
20
|
+
registry: VoiceProviderRegistry;
|
|
21
|
+
}
|
|
22
|
+
export declare const PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV = "PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE";
|
|
23
|
+
export declare function resetVoiceAgentConfigsForTests(): void;
|
|
24
|
+
export declare function resolveVoiceAgentConfig(agentName: string | undefined): VoiceAgentRuntimeConfig;
|
|
25
|
+
export declare function bootstrapVoiceAgentConfigsFromModule(): Promise<void>;
|
|
26
|
+
declare const voiceAgentDefinition: import("@livekit/agents").Agent<Record<string, unknown>>;
|
|
27
|
+
export default voiceAgentDefinition;
|
|
28
|
+
export declare function createVoiceAgentEntry(options: VoiceAgentEntryOptions): import("@livekit/agents").Agent<Record<string, unknown>>;
|
|
29
|
+
export declare function stopActiveVoiceAgentSessions(): Promise<void>;
|
|
30
|
+
export declare function startVoiceAgentWorker(options: StartVoiceAgentWorkerOptions): Promise<VoiceAgentWorkerHandle>;
|
|
31
|
+
export declare function createRoomTransport(room: Room, audioFormat: string, trackName: string, outputAudioFormat?: string): TransportProvider;
|
|
32
|
+
//# sourceMappingURL=livekit-agent-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"livekit-agent-worker.d.ts","sourceRoot":"","sources":["../../src/runtime/livekit-agent-worker.ts"],"names":[],"mappings":"AAUA,OAAO,EAKL,KAAK,IAAI,EAIV,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAGL,KAAK,qBAAqB,EAG3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAOxF,YAAY,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAMxF,wBAAgB,wBAAwB,IAAI,IAAI,CAS/C;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,oBAAoB,CAAC;IAChC,kBAAkB,EAAE,4BAA4B,CAAC,oBAAoB,CAAC,CAAC;IACvE,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;CAClC;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,SAAS,EAAE,oBAAoB,CAAC;IAChC,kBAAkB,EAAE,4BAA4B,CAAC,oBAAoB,CAAC,CAAC;IACvE,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAID,eAAO,MAAM,wCAAwC,yCAAyC,CAAC;AAI/F,wBAAgB,8BAA8B,IAAI,IAAI,CAGrD;AAuCD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,uBAAuB,CAoB9F;AAiDD,wBAAsB,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC,CAoC1E;AAqPD,QAAA,MAAM,oBAAoB,0DAExB,CAAC;AAEH,eAAe,oBAAoB,CAAC;AAEpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,4DAMpE;AAED,wBAAsB,4BAA4B,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlE;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAoFjC;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,iBAAiB,GAAE,MAAoB,GACtC,iBAAiB,CA2EnB"}
|