@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,491 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
|
+
import { AgentServer, AutoSubscribe, defineAgent, initializeLogger, ServerOptions, } from '@livekit/agents';
|
|
4
|
+
import { AudioFrame, AudioSource, LocalAudioTrack, RoomEvent, TrackKind, TrackPublishOptions, } from '@livekit/rtc-node';
|
|
5
|
+
import { createExecutionContext, ErrorCode, PlumbusError } from '@plumbus/core';
|
|
6
|
+
import { createSTTProvider, createTTSProvider, VoiceSessionController, validateVoiceProviders, } from '@plumbus/voice';
|
|
7
|
+
import { createVoiceSessionBudget, readNoiseCancellationFromTransportOptions, } from '@plumbus/voice/provider-kit';
|
|
8
|
+
import { DEFAULT_AGENT_AUDIO_TRACK_NAME } from '../client/session-helpers.js';
|
|
9
|
+
import { recordLiveKitTransportCost } from '../cost/record-livekit-transport.js';
|
|
10
|
+
import { createInboundAudioStream } from '../noise-cancellation/create-inbound-audio-stream.js';
|
|
11
|
+
import { consumeAudioStream } from './consume-audio-stream.js';
|
|
12
|
+
import { buildBrainInputFromParticipantContext, parseLiveKitParticipantContext, } from './parse-participant-context.js';
|
|
13
|
+
const activeSessions = new Set();
|
|
14
|
+
let liveKitAgentLoggerReady = false;
|
|
15
|
+
export function ensureLiveKitAgentLogger() {
|
|
16
|
+
if (liveKitAgentLoggerReady) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
initializeLogger({
|
|
20
|
+
pretty: process.env.NODE_ENV !== 'production',
|
|
21
|
+
level: process.env.LIVEKIT_LOG_LEVEL ?? 'info',
|
|
22
|
+
});
|
|
23
|
+
liveKitAgentLoggerReady = true;
|
|
24
|
+
}
|
|
25
|
+
export function resetLiveKitAgentLoggerForTests() {
|
|
26
|
+
liveKitAgentLoggerReady = false;
|
|
27
|
+
}
|
|
28
|
+
const voiceAgentConfigs = new Map();
|
|
29
|
+
export const PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV = 'PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE';
|
|
30
|
+
let bootstrapInFlight;
|
|
31
|
+
export function resetVoiceAgentConfigsForTests() {
|
|
32
|
+
voiceAgentConfigs.clear();
|
|
33
|
+
bootstrapInFlight = undefined;
|
|
34
|
+
}
|
|
35
|
+
function buildVoiceAgentRuntimeConfig(options) {
|
|
36
|
+
if (!options.registry) {
|
|
37
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'Voice agent entry requires an explicit provider registry');
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
voice: options.voice,
|
|
41
|
+
providers: options.providers,
|
|
42
|
+
createDependencies: options.createDependencies,
|
|
43
|
+
sessionBudget: options.sessionBudget,
|
|
44
|
+
registry: assertLiveKitTransport(options.registry),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function assertLiveKitTransport(registry) {
|
|
48
|
+
if (registry.transport.has('livekit')) {
|
|
49
|
+
return registry;
|
|
50
|
+
}
|
|
51
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'LiveKit worker registry must include transport.livekit (LIVEKIT_TRANSPORT_REGISTRATION)', { installPackage: '@plumbus/voice-livekit' });
|
|
52
|
+
}
|
|
53
|
+
function resolveAgentProviderRegistry(existing) {
|
|
54
|
+
if (!existing) {
|
|
55
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'LiveKit worker requires an explicit registry (pass LIVEKIT_TRANSPORT_REGISTRATION and STT/TTS registrations via createProviderRegistry, or export voiceProviderRegistry from app/voice/registry.ts)');
|
|
56
|
+
}
|
|
57
|
+
return assertLiveKitTransport(existing);
|
|
58
|
+
}
|
|
59
|
+
export function resolveVoiceAgentConfig(agentName) {
|
|
60
|
+
if (agentName) {
|
|
61
|
+
const named = voiceAgentConfigs.get(agentName);
|
|
62
|
+
if (named) {
|
|
63
|
+
return named;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (voiceAgentConfigs.size === 1) {
|
|
67
|
+
const only = voiceAgentConfigs.values().next().value;
|
|
68
|
+
if (only) {
|
|
69
|
+
return only;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'Voice agent runtime is not configured for this agent dispatch', { agentName });
|
|
73
|
+
}
|
|
74
|
+
async function registerVoiceAgentBootstrapPayload(payload) {
|
|
75
|
+
const registry = resolveAgentProviderRegistry(payload.registry);
|
|
76
|
+
const validation = validateVoiceProviders({
|
|
77
|
+
voices: payload.voices,
|
|
78
|
+
providers: payload.providers,
|
|
79
|
+
registry,
|
|
80
|
+
});
|
|
81
|
+
if (!validation.ok) {
|
|
82
|
+
const detail = validation.issues.map((issue) => issue.message).join('; ');
|
|
83
|
+
throw new PlumbusError(ErrorCode.Validation, `Voice agent bootstrap has invalid providers: ${detail}`);
|
|
84
|
+
}
|
|
85
|
+
const livekitVoices = payload.voices.filter((voice) => voice.transport.provider === 'livekit');
|
|
86
|
+
if (livekitVoices.length === 0) {
|
|
87
|
+
throw new PlumbusError(ErrorCode.Validation, 'Voice agent bootstrap requires at least one livekit voice');
|
|
88
|
+
}
|
|
89
|
+
for (const voice of livekitVoices) {
|
|
90
|
+
voiceAgentConfigs.set(voice.name, buildVoiceAgentRuntimeConfig({
|
|
91
|
+
voice,
|
|
92
|
+
providers: payload.providers,
|
|
93
|
+
createDependencies: payload.createDependencies,
|
|
94
|
+
sessionBudget: payload.sessionBudget,
|
|
95
|
+
registry,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function bootstrapVoiceAgentConfigsFromModule() {
|
|
100
|
+
if (bootstrapInFlight) {
|
|
101
|
+
await bootstrapInFlight;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
bootstrapInFlight = (async () => {
|
|
105
|
+
const modulePath = process.env[PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV];
|
|
106
|
+
if (!modulePath) {
|
|
107
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'Voice agent child process bootstrap module is not configured', { env: PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV });
|
|
108
|
+
}
|
|
109
|
+
const mod = (await import(pathToFileURL(modulePath).href));
|
|
110
|
+
const bootstrap = mod.bootstrapVoiceAgentRuntime;
|
|
111
|
+
if (typeof bootstrap !== 'function') {
|
|
112
|
+
throw new PlumbusError(ErrorCode.DependencyViolation, 'Voice agent bootstrap module must export bootstrapVoiceAgentRuntime()', { modulePath });
|
|
113
|
+
}
|
|
114
|
+
const payload = (await bootstrap());
|
|
115
|
+
await registerVoiceAgentBootstrapPayload(payload);
|
|
116
|
+
})();
|
|
117
|
+
try {
|
|
118
|
+
await bootstrapInFlight;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
bootstrapInFlight = undefined;
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function resolveVoiceAgentConfigForJob(agentName) {
|
|
126
|
+
try {
|
|
127
|
+
return resolveVoiceAgentConfig(agentName);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (!(error instanceof PlumbusError) || error.code !== ErrorCode.DependencyViolation) {
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
console.info('[voice-agent] bootstrapping runtime config in child process', { agentName });
|
|
134
|
+
await bootstrapVoiceAgentConfigsFromModule();
|
|
135
|
+
return resolveVoiceAgentConfig(agentName);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function resolveAgentTrackName(voice) {
|
|
139
|
+
const configured = voice.transport.options?.agentAudioTrackName;
|
|
140
|
+
return typeof configured === 'string' && configured.length > 0
|
|
141
|
+
? configured
|
|
142
|
+
: DEFAULT_AGENT_AUDIO_TRACK_NAME;
|
|
143
|
+
}
|
|
144
|
+
function resolveLiveKitVoice(voices, agentName) {
|
|
145
|
+
const livekitVoices = voices.filter((voice) => voice.transport.provider === 'livekit');
|
|
146
|
+
if (livekitVoices.length === 0) {
|
|
147
|
+
throw new PlumbusError(ErrorCode.Validation, 'startVoiceAgentWorker requires at least one livekit voice');
|
|
148
|
+
}
|
|
149
|
+
const selectedName = agentName ?? livekitVoices[0]?.name;
|
|
150
|
+
if (!selectedName) {
|
|
151
|
+
throw new PlumbusError(ErrorCode.Validation, 'startVoiceAgentWorker could not resolve a livekit voice name');
|
|
152
|
+
}
|
|
153
|
+
const voice = livekitVoices.find((candidate) => candidate.name === selectedName);
|
|
154
|
+
if (!voice) {
|
|
155
|
+
throw new PlumbusError(ErrorCode.NotFound, `No livekit voice definition found for agent name "${selectedName}"`, { agentName: selectedName });
|
|
156
|
+
}
|
|
157
|
+
return voice;
|
|
158
|
+
}
|
|
159
|
+
function resolveLiveKitHost(url) {
|
|
160
|
+
if (!url) {
|
|
161
|
+
return 'unknown';
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const normalized = url.replace(/^wss:/, 'https:').replace(/^ws:/, 'http:');
|
|
165
|
+
return new URL(normalized).host;
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return 'unknown';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function normalizeVoiceLanguage(language) {
|
|
172
|
+
const normalized = language?.toLowerCase();
|
|
173
|
+
if (!normalized) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
if (normalized.startsWith('he')) {
|
|
177
|
+
return 'he';
|
|
178
|
+
}
|
|
179
|
+
if (normalized.startsWith('en')) {
|
|
180
|
+
return 'en';
|
|
181
|
+
}
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
function applySessionLanguageToVoice(voice, language) {
|
|
185
|
+
const normalizedLanguage = normalizeVoiceLanguage(language);
|
|
186
|
+
if (!normalizedLanguage) {
|
|
187
|
+
return voice;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
...voice,
|
|
191
|
+
stt: {
|
|
192
|
+
...voice.stt,
|
|
193
|
+
languages: [normalizedLanguage],
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
async function runVoiceAgentEntry(ctx, config) {
|
|
198
|
+
const { voice, providers, createDependencies, sessionBudget } = config;
|
|
199
|
+
const registry = assertLiveKitTransport(config.registry);
|
|
200
|
+
await ctx.connect(undefined, AutoSubscribe.AUDIO_ONLY);
|
|
201
|
+
const connectedAt = new Date();
|
|
202
|
+
console.info('[voice-agent] job started', {
|
|
203
|
+
voice: voice.name,
|
|
204
|
+
room: ctx.room.name ?? '',
|
|
205
|
+
});
|
|
206
|
+
const participant = await ctx.waitForParticipant();
|
|
207
|
+
const participantIdentity = participant.identity ?? 'voice-user';
|
|
208
|
+
const participantContext = parseLiveKitParticipantContext({
|
|
209
|
+
roomName: ctx.room.name ?? '',
|
|
210
|
+
participantIdentity,
|
|
211
|
+
participantMetadata: participant.metadata,
|
|
212
|
+
participantAttributes: participant.attributes,
|
|
213
|
+
});
|
|
214
|
+
const sessionId = participantContext.sessionId;
|
|
215
|
+
const brainInput = buildBrainInputFromParticipantContext(participantContext);
|
|
216
|
+
const sessionVoice = applySessionLanguageToVoice(voice, participantContext.language);
|
|
217
|
+
console.info('[voice-agent] participant joined', {
|
|
218
|
+
voice: sessionVoice.name,
|
|
219
|
+
room: ctx.room.name ?? '',
|
|
220
|
+
participant: participantIdentity,
|
|
221
|
+
sessionId,
|
|
222
|
+
language: participantContext.language,
|
|
223
|
+
});
|
|
224
|
+
const executionCtx = createExecutionContext(createDependencies({
|
|
225
|
+
userId: participantContext.userId,
|
|
226
|
+
tenantId: participantContext.tenantId,
|
|
227
|
+
roles: ['user'],
|
|
228
|
+
scopes: [],
|
|
229
|
+
provider: 'voice',
|
|
230
|
+
}));
|
|
231
|
+
const trackName = resolveAgentTrackName(sessionVoice);
|
|
232
|
+
const ttsSampleRate = typeof sessionVoice.tts.options?.sampleRate === 'number'
|
|
233
|
+
? sessionVoice.tts.options.sampleRate
|
|
234
|
+
: undefined;
|
|
235
|
+
const outputAudioFormat = ttsSampleRate
|
|
236
|
+
? `pcm16;rate=${ttsSampleRate};channels=1`
|
|
237
|
+
: (sessionVoice.transport.audioFormat ?? 'pcm16-16k');
|
|
238
|
+
const transport = createRoomTransport(ctx.room, sessionVoice.transport.audioFormat ?? 'pcm16-16k', trackName, outputAudioFormat);
|
|
239
|
+
const sttProvider = createSTTProvider({ registry, providers, voiceSlice: sessionVoice.stt });
|
|
240
|
+
const ttsProvider = createTTSProvider({ registry, providers, voiceSlice: sessionVoice.tts });
|
|
241
|
+
const budget = createVoiceSessionBudget(sessionBudget);
|
|
242
|
+
const controller = new VoiceSessionController({
|
|
243
|
+
voice: sessionVoice,
|
|
244
|
+
sessionId,
|
|
245
|
+
userId: participantContext.userId,
|
|
246
|
+
ctx: executionCtx,
|
|
247
|
+
sttProvider,
|
|
248
|
+
ttsProvider,
|
|
249
|
+
transportProvider: transport,
|
|
250
|
+
budget,
|
|
251
|
+
brainInput,
|
|
252
|
+
onEvent: async (event) => {
|
|
253
|
+
await transport.sendData?.(event);
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
ctx.room.on(RoomEvent.TrackSubscribed, (track) => {
|
|
257
|
+
const isAudio = track.kind === TrackKind.KIND_AUDIO || track.kind === 1;
|
|
258
|
+
if (!isAudio)
|
|
259
|
+
return;
|
|
260
|
+
let loggedFirstAudio = false;
|
|
261
|
+
void forwardRemoteAudio(track, sessionVoice.transport.audioFormat, readNoiseCancellationFromTransportOptions(sessionVoice.transport.options), async (audio) => {
|
|
262
|
+
if (!loggedFirstAudio) {
|
|
263
|
+
loggedFirstAudio = true;
|
|
264
|
+
console.info('[voice-agent] first remote audio frame received', {
|
|
265
|
+
voice: sessionVoice.name,
|
|
266
|
+
room: ctx.room.name ?? '',
|
|
267
|
+
participant: participantIdentity,
|
|
268
|
+
sessionId,
|
|
269
|
+
bytes: audio.byteLength,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
await controller.handleAudioChunk(audio, sessionVoice.transport.audioFormat);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
ctx.room.on(RoomEvent.DataReceived, (payload) => {
|
|
276
|
+
void (async () => {
|
|
277
|
+
let parsed;
|
|
278
|
+
try {
|
|
279
|
+
parsed = JSON.parse(Buffer.from(payload).toString('utf8'));
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (!parsed || typeof parsed !== 'object')
|
|
285
|
+
return;
|
|
286
|
+
await controller.handleControlMessage(parsed);
|
|
287
|
+
})();
|
|
288
|
+
});
|
|
289
|
+
await controller.hello();
|
|
290
|
+
console.info('[voice-agent] session hello sent', {
|
|
291
|
+
voice: sessionVoice.name,
|
|
292
|
+
sessionId,
|
|
293
|
+
room: ctx.room.name ?? '',
|
|
294
|
+
});
|
|
295
|
+
activeSessions.add(controller);
|
|
296
|
+
ctx.addShutdownCallback(async () => {
|
|
297
|
+
activeSessions.delete(controller);
|
|
298
|
+
if (participantContext.projectId) {
|
|
299
|
+
await recordLiveKitTransportCost(executionCtx, {
|
|
300
|
+
sessionId,
|
|
301
|
+
connectedAt,
|
|
302
|
+
disconnectedAt: new Date(),
|
|
303
|
+
costContext: {
|
|
304
|
+
projectId: participantContext.projectId,
|
|
305
|
+
relatedEntityType: 'InterviewSession',
|
|
306
|
+
relatedEntityId: sessionId,
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
await controller.dispose();
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
async function voiceAgentEntry(ctx) {
|
|
314
|
+
const jobRecord = ctx.job;
|
|
315
|
+
const agentName = jobRecord.agentName ?? jobRecord.agent_name;
|
|
316
|
+
const config = await resolveVoiceAgentConfigForJob(typeof agentName === 'string' && agentName.length > 0 ? agentName : undefined);
|
|
317
|
+
await runVoiceAgentEntry(ctx, config);
|
|
318
|
+
}
|
|
319
|
+
const voiceAgentDefinition = defineAgent({
|
|
320
|
+
entry: voiceAgentEntry,
|
|
321
|
+
});
|
|
322
|
+
export default voiceAgentDefinition;
|
|
323
|
+
export function createVoiceAgentEntry(options) {
|
|
324
|
+
const config = buildVoiceAgentRuntimeConfig(options);
|
|
325
|
+
voiceAgentConfigs.set(options.voice.name, config);
|
|
326
|
+
return defineAgent({
|
|
327
|
+
entry: (ctx) => runVoiceAgentEntry(ctx, config),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
export async function stopActiveVoiceAgentSessions() {
|
|
331
|
+
const sessions = [...activeSessions];
|
|
332
|
+
activeSessions.clear();
|
|
333
|
+
await Promise.all(sessions.map((session) => session.dispose()));
|
|
334
|
+
}
|
|
335
|
+
export async function startVoiceAgentWorker(options) {
|
|
336
|
+
if (options.signal?.aborted) {
|
|
337
|
+
throw new PlumbusError(ErrorCode.Validation, 'Voice agent worker start aborted before initialization');
|
|
338
|
+
}
|
|
339
|
+
const voice = resolveLiveKitVoice(options.voices, options.agentName);
|
|
340
|
+
const registry = resolveAgentProviderRegistry(options.registry);
|
|
341
|
+
const validation = validateVoiceProviders({
|
|
342
|
+
voices: options.voices,
|
|
343
|
+
providers: options.providers,
|
|
344
|
+
registry,
|
|
345
|
+
});
|
|
346
|
+
if (!validation.ok) {
|
|
347
|
+
const detail = validation.issues.map((issue) => issue.message).join('; ');
|
|
348
|
+
throw new PlumbusError(ErrorCode.Validation, `Voice agent worker cannot start with invalid providers: ${detail}`);
|
|
349
|
+
}
|
|
350
|
+
const runtimeConfig = buildVoiceAgentRuntimeConfig({
|
|
351
|
+
voice,
|
|
352
|
+
providers: options.providers,
|
|
353
|
+
createDependencies: options.createDependencies,
|
|
354
|
+
sessionBudget: options.sessionBudget,
|
|
355
|
+
registry,
|
|
356
|
+
});
|
|
357
|
+
voiceAgentConfigs.set(voice.name, runtimeConfig);
|
|
358
|
+
const bootstrapModule = options.bootstrapModule ?? process.env[PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV];
|
|
359
|
+
if (bootstrapModule) {
|
|
360
|
+
process.env[PLUMBUS_VOICE_AGENT_BOOTSTRAP_MODULE_ENV] = bootstrapModule;
|
|
361
|
+
}
|
|
362
|
+
ensureLiveKitAgentLogger();
|
|
363
|
+
const resolvedAgentName = options.agentName ?? voice.name;
|
|
364
|
+
const wsURL = options.wsURL ?? process.env.LIVEKIT_URL;
|
|
365
|
+
console.info('[voice-agent] worker started', {
|
|
366
|
+
agentName: resolvedAgentName,
|
|
367
|
+
livekitHost: resolveLiveKitHost(wsURL),
|
|
368
|
+
});
|
|
369
|
+
const server = new AgentServer(new ServerOptions({
|
|
370
|
+
agent: fileURLToPath(import.meta.url),
|
|
371
|
+
agentName: resolvedAgentName,
|
|
372
|
+
wsURL,
|
|
373
|
+
apiKey: options.apiKey ?? process.env.LIVEKIT_API_KEY,
|
|
374
|
+
apiSecret: options.apiSecret ?? process.env.LIVEKIT_API_SECRET,
|
|
375
|
+
requestFunc: async (job) => {
|
|
376
|
+
await job.accept();
|
|
377
|
+
},
|
|
378
|
+
}));
|
|
379
|
+
const runPromise = server.run();
|
|
380
|
+
if (options.signal) {
|
|
381
|
+
options.signal.addEventListener('abort', () => {
|
|
382
|
+
void server.close();
|
|
383
|
+
}, { once: true });
|
|
384
|
+
}
|
|
385
|
+
void runPromise.catch(() => {
|
|
386
|
+
// Startup failures are surfaced when callers invoke stop().
|
|
387
|
+
});
|
|
388
|
+
return {
|
|
389
|
+
started: true,
|
|
390
|
+
async stop() {
|
|
391
|
+
await stopActiveVoiceAgentSessions();
|
|
392
|
+
await server.close();
|
|
393
|
+
voiceAgentConfigs.delete(voice.name);
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
export function createRoomTransport(room, audioFormat, trackName, outputAudioFormat = audioFormat) {
|
|
398
|
+
let audioSource;
|
|
399
|
+
let localTrack;
|
|
400
|
+
let loggedFirstDataEvent = false;
|
|
401
|
+
let loggedFirstAudioPublish = false;
|
|
402
|
+
const ensurePublished = async () => {
|
|
403
|
+
if (localTrack)
|
|
404
|
+
return;
|
|
405
|
+
const format = parsePcmFormat(outputAudioFormat);
|
|
406
|
+
audioSource = new AudioSource(format.sampleRate, format.channels);
|
|
407
|
+
localTrack = LocalAudioTrack.createAudioTrack(trackName, audioSource);
|
|
408
|
+
const publishOptions = new TrackPublishOptions();
|
|
409
|
+
publishOptions.name = trackName;
|
|
410
|
+
await room.localParticipant?.publishTrack(localTrack, publishOptions);
|
|
411
|
+
console.info('[voice-agent] audio track published', {
|
|
412
|
+
trackName,
|
|
413
|
+
sampleRate: format.sampleRate,
|
|
414
|
+
channels: format.channels,
|
|
415
|
+
});
|
|
416
|
+
};
|
|
417
|
+
return {
|
|
418
|
+
async mintSession(args) {
|
|
419
|
+
return {
|
|
420
|
+
sessionId: `livekit:${args.voiceName}:${args.userId ?? 'anonymous'}:${randomUUID()}`,
|
|
421
|
+
transport: 'livekit',
|
|
422
|
+
};
|
|
423
|
+
},
|
|
424
|
+
async publishAudio(audio) {
|
|
425
|
+
await ensurePublished();
|
|
426
|
+
if (!audioSource)
|
|
427
|
+
return;
|
|
428
|
+
const format = parsePcmFormat(outputAudioFormat);
|
|
429
|
+
const frame = new AudioFrame(pcmBytesToInt16(audio), format.sampleRate, format.channels, Math.max(1, audio.byteLength / (2 * format.channels)));
|
|
430
|
+
await audioSource.captureFrame(frame);
|
|
431
|
+
if (!loggedFirstAudioPublish) {
|
|
432
|
+
loggedFirstAudioPublish = true;
|
|
433
|
+
console.info('[voice-agent] first agent audio frame published', {
|
|
434
|
+
trackName,
|
|
435
|
+
bytes: audio.byteLength,
|
|
436
|
+
samplesPerChannel: Math.max(1, audio.byteLength / (2 * format.channels)),
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
async sendData(payload) {
|
|
441
|
+
const payloadType = typeof payload === 'object' && payload !== null
|
|
442
|
+
? payload.type
|
|
443
|
+
: undefined;
|
|
444
|
+
if (!room.localParticipant) {
|
|
445
|
+
console.warn('[voice-agent] data event dropped before local participant was ready', {
|
|
446
|
+
type: payloadType,
|
|
447
|
+
});
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
const encoded = new TextEncoder().encode(JSON.stringify(payload));
|
|
451
|
+
await room.localParticipant.publishData(encoded, { reliable: true, topic: 'voice.events' });
|
|
452
|
+
if (!loggedFirstDataEvent) {
|
|
453
|
+
loggedFirstDataEvent = true;
|
|
454
|
+
console.info('[voice-agent] first data event published', {
|
|
455
|
+
type: payloadType,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
async disconnect() {
|
|
460
|
+
if (localTrack)
|
|
461
|
+
await localTrack.close();
|
|
462
|
+
if (audioSource)
|
|
463
|
+
await audioSource.close();
|
|
464
|
+
localTrack = undefined;
|
|
465
|
+
audioSource = undefined;
|
|
466
|
+
},
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
async function forwardRemoteAudio(track, audioFormat, noiseCancellation, onAudio) {
|
|
470
|
+
const format = parsePcmFormat(audioFormat);
|
|
471
|
+
const stream = createInboundAudioStream(track, format, noiseCancellation);
|
|
472
|
+
await consumeAudioStream(stream, async (frame) => {
|
|
473
|
+
await onAudio(new Uint8Array(frame.data.buffer.slice(frame.data.byteOffset, frame.data.byteOffset + frame.data.byteLength)));
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function parsePcmFormat(audioFormat) {
|
|
477
|
+
const normalized = audioFormat ?? 'pcm16;rate=16000;channels=1';
|
|
478
|
+
const rateMatch = normalized.match(/rate=(\d+)/);
|
|
479
|
+
const channelsMatch = normalized.match(/channels=(\d+)/);
|
|
480
|
+
return {
|
|
481
|
+
sampleRate: Number(rateMatch?.[1] ?? 16000),
|
|
482
|
+
channels: Number(channelsMatch?.[1] ?? 1),
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function pcmBytesToInt16(audio) {
|
|
486
|
+
const buffer = audio.byteOffset === 0 && audio.byteLength === audio.buffer.byteLength
|
|
487
|
+
? audio.buffer
|
|
488
|
+
: audio.buffer.slice(audio.byteOffset, audio.byteOffset + audio.byteLength);
|
|
489
|
+
return new Int16Array(buffer);
|
|
490
|
+
}
|
|
491
|
+
//# sourceMappingURL=livekit-agent-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"livekit-agent-worker.js","sourceRoot":"","sources":["../../src/runtime/livekit-agent-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { STTProviderRegistration, TTSProviderRegistration, TransportProviderRegistration } from '@plumbus/voice/provider-kit';
|
|
2
|
+
/**
|
|
3
|
+
* Best-effort import of installed cloud STT/TTS add-ons for the LiveKit agent worker.
|
|
4
|
+
* Does not live in `@plumbus/voice` — apps using `registerVoiceRoutes` must still
|
|
5
|
+
* pass explicit registrations.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveOptionalCloudRegistrations(): Promise<{
|
|
8
|
+
stt: Record<string, STTProviderRegistration>;
|
|
9
|
+
tts: Record<string, TTSProviderRegistration>;
|
|
10
|
+
transport: Record<string, TransportProviderRegistration>;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=optional-cloud-registrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optional-cloud-registrations.d.ts","sourceRoot":"","sources":["../../src/runtime/optional-cloud-registrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACvB,6BAA6B,EAC9B,MAAM,6BAA6B,CAAC;AAwCrC;;;;GAIG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC;IACjE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAC7C,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;CAC1D,CAAC,CA0BD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { LIVEKIT_TRANSPORT_REGISTRATION } from '../transport/livekit-transport.js';
|
|
2
|
+
const CLOUD_ADDON_IMPORTS = [
|
|
3
|
+
{
|
|
4
|
+
id: 'soniox',
|
|
5
|
+
kind: 'stt',
|
|
6
|
+
pkg: '@plumbus/voice-soniox',
|
|
7
|
+
exportName: 'SONIOX_STT_REGISTRATION',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: 'deepdub',
|
|
11
|
+
kind: 'tts',
|
|
12
|
+
pkg: '@plumbus/voice-deepdub',
|
|
13
|
+
exportName: 'DEEPDUB_TTS_REGISTRATION',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: 'elevenlabs',
|
|
17
|
+
kind: 'tts',
|
|
18
|
+
pkg: '@plumbus/voice-elevenlabs',
|
|
19
|
+
exportName: 'ELEVENLABS_TTS_REGISTRATION',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'minimax',
|
|
23
|
+
kind: 'tts',
|
|
24
|
+
pkg: '@plumbus/voice-minimax',
|
|
25
|
+
exportName: 'MINIMAX_TTS_REGISTRATION',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
function isRegistrationLike(value) {
|
|
29
|
+
return (typeof value === 'object' &&
|
|
30
|
+
value !== null &&
|
|
31
|
+
'descriptor' in value &&
|
|
32
|
+
'create' in value &&
|
|
33
|
+
typeof value.create === 'function');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Best-effort import of installed cloud STT/TTS add-ons for the LiveKit agent worker.
|
|
37
|
+
* Does not live in `@plumbus/voice` — apps using `registerVoiceRoutes` must still
|
|
38
|
+
* pass explicit registrations.
|
|
39
|
+
*/
|
|
40
|
+
export async function resolveOptionalCloudRegistrations() {
|
|
41
|
+
const stt = {};
|
|
42
|
+
const tts = {};
|
|
43
|
+
const transport = {
|
|
44
|
+
livekit: LIVEKIT_TRANSPORT_REGISTRATION,
|
|
45
|
+
};
|
|
46
|
+
for (const spec of CLOUD_ADDON_IMPORTS) {
|
|
47
|
+
try {
|
|
48
|
+
const pkg = spec.pkg;
|
|
49
|
+
const mod = (await import(pkg));
|
|
50
|
+
const registration = mod[spec.exportName];
|
|
51
|
+
if (!isRegistrationLike(registration)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (spec.kind === 'stt') {
|
|
55
|
+
stt[spec.id] = registration;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
tts[spec.id] = registration;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// package not installed — skip
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { stt, tts, transport };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=optional-cloud-registrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optional-cloud-registrations.js","sourceRoot":"","sources":["../../src/runtime/optional-cloud-registrations.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAEnF,MAAM,mBAAmB,GAAG;IAC1B;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,KAAc;QACpB,GAAG,EAAE,uBAAuB;QAC5B,UAAU,EAAE,yBAAyB;KACtC;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,KAAc;QACpB,GAAG,EAAE,wBAAwB;QAC7B,UAAU,EAAE,0BAA0B;KACvC;IACD;QACE,EAAE,EAAE,YAAY;QAChB,IAAI,EAAE,KAAc;QACpB,GAAG,EAAE,2BAA2B;QAChC,UAAU,EAAE,6BAA6B;KAC1C;IACD;QACE,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,KAAc;QACpB,GAAG,EAAE,wBAAwB;QAC7B,UAAU,EAAE,0BAA0B;KACvC;CACO,CAAC;AAEX,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,YAAY,IAAI,KAAK;QACrB,QAAQ,IAAI,KAAK;QACjB,OAAQ,KAA6B,CAAC,MAAM,KAAK,UAAU,CAC5D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iCAAiC;IAKrD,MAAM,GAAG,GAA4C,EAAE,CAAC;IACxD,MAAM,GAAG,GAA4C,EAAE,CAAC;IACxD,MAAM,SAAS,GAAkD;QAC/D,OAAO,EAAE,8BAA8B;KACxC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,CAAC;YAC7B,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAA4B,CAAC;YAC3D,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;gBACtC,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACxB,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,YAAuC,CAAC;YACzD,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,YAAuC,CAAC;YACzD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface LiveKitParticipantContext {
|
|
2
|
+
userId: string;
|
|
3
|
+
tenantId?: string;
|
|
4
|
+
projectId?: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
metadata: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseLiveKitParticipantContext(args: {
|
|
10
|
+
roomName: string;
|
|
11
|
+
participantIdentity: string;
|
|
12
|
+
participantMetadata?: string;
|
|
13
|
+
participantAttributes?: Record<string, string>;
|
|
14
|
+
}): LiveKitParticipantContext;
|
|
15
|
+
export declare function buildBrainInputFromParticipantContext(context: LiveKitParticipantContext): Record<string, unknown>;
|
|
16
|
+
//# sourceMappingURL=parse-participant-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-participant-context.d.ts","sourceRoot":"","sources":["../../src/runtime/parse-participant-context.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AA2BD,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChD,GAAG,yBAAyB,CA8B5B;AAED,wBAAgB,qCAAqC,CACnD,OAAO,EAAE,yBAAyB,GACjC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
|