@voicethere/agent 0.8.3 → 0.9.1
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/README.md +36 -20
- package/dist/agent.js +55 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +81 -3
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +69 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +152 -1
- package/dist/runtime.js.map +1 -1
- package/dist/templates/echo/agent.js +51 -2
- package/dist/templates/echo-dc/agent.js +51 -2
- package/dist/templates/game-sync/agent.js +51 -2
- package/dist/templates/language-switch/agent.js +1112 -0
- package/dist/templates/positional-tts/agent.js +51 -2
- package/dist/templates/recording-consent/agent.js +51 -2
- package/dist/templates/registry.d.ts.map +1 -1
- package/dist/templates/registry.js +8 -0
- package/dist/templates/registry.js.map +1 -1
- package/dist/templates/spatial-showcase/agent.js +51 -2
- package/dist/templates/voice-showcase/agent.js +51 -2
- package/dist/templates/voice-starter/agent.js +51 -2
- package/dist/templates/webhooks/agent.js +51 -2
- package/dist/templates/webhooks-redis/agent.js +51 -2
- package/dist/templates/world-sync/agent.js +51 -2
- package/dist/templates/world-sync-binary/agent.js +51 -2
- package/package.json +1 -1
- package/templates/README.md +31 -30
- package/templates/language-switch/README.md +31 -0
- package/templates/language-switch/agent.ts +233 -0
- package/templates/voice-starter/agent.ts +3 -1
|
@@ -181,6 +181,12 @@ function isSttControlAckMessage(value) {
|
|
|
181
181
|
const msg = value;
|
|
182
182
|
return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
|
|
183
183
|
}
|
|
184
|
+
function isVoiceLanguageControlAckMessage(value) {
|
|
185
|
+
if (!value || typeof value !== "object")
|
|
186
|
+
return false;
|
|
187
|
+
const msg = value;
|
|
188
|
+
return msg.type === "voice_language_control_ack" && typeof msg.requestId === "string";
|
|
189
|
+
}
|
|
184
190
|
function isWebhookMessage(value) {
|
|
185
191
|
if (!value || typeof value !== "object")
|
|
186
192
|
return false;
|
|
@@ -223,7 +229,7 @@ function isParentMessage(value) {
|
|
|
223
229
|
if (!value || typeof value !== "object")
|
|
224
230
|
return false;
|
|
225
231
|
const msg = value;
|
|
226
|
-
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
232
|
+
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "voice_language_control_ack" || msg.type === "webhook";
|
|
227
233
|
}
|
|
228
234
|
function isSessionScopedParentMessage(value) {
|
|
229
235
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -239,6 +245,8 @@ var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
|
239
245
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
240
246
|
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
241
247
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
248
|
+
var voiceLanguageSwitchAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
249
|
+
var lastVoiceLanguageBySessionId = /* @__PURE__ */ new Map();
|
|
242
250
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
243
251
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
244
252
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
@@ -251,6 +259,7 @@ var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
|
251
259
|
var MIX_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
252
260
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
253
261
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
262
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
254
263
|
function handleRecordingControlAck(message) {
|
|
255
264
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
256
265
|
if (!pending)
|
|
@@ -353,6 +362,27 @@ function handleSttControlAck(message) {
|
|
|
353
362
|
requestId: message.requestId
|
|
354
363
|
});
|
|
355
364
|
}
|
|
365
|
+
function handleVoiceLanguageControlAck(message) {
|
|
366
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
367
|
+
if (!pending)
|
|
368
|
+
return;
|
|
369
|
+
clearTimeout(pending.timer);
|
|
370
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
371
|
+
if (message.ok && message.language?.trim()) {
|
|
372
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
373
|
+
}
|
|
374
|
+
pending.resolve({
|
|
375
|
+
ok: message.ok,
|
|
376
|
+
reason: message.reason,
|
|
377
|
+
requestId: message.requestId,
|
|
378
|
+
...message.language ? { language: message.language } : {},
|
|
379
|
+
...message.voice ? { voice: message.voice } : {},
|
|
380
|
+
...message.stt ? { stt: message.stt } : {},
|
|
381
|
+
...message.scope ? { scope: message.scope } : {},
|
|
382
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
383
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
356
386
|
function isTtsPoseAvailableInProcess() {
|
|
357
387
|
for (const available of ttsPoseAvailableBySessionId.values()) {
|
|
358
388
|
if (available)
|
|
@@ -433,7 +463,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
433
463
|
}
|
|
434
464
|
function sendParentMessage(message) {
|
|
435
465
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
436
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
466
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
437
467
|
process.send?.(message);
|
|
438
468
|
return;
|
|
439
469
|
}
|
|
@@ -534,6 +564,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
534
564
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
535
565
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
536
566
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
567
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
537
568
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
538
569
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
539
570
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -545,6 +576,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
545
576
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
546
577
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
547
578
|
mixAvailable: message.mixAvailable ?? false,
|
|
579
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
548
580
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
549
581
|
});
|
|
550
582
|
sendParentMessage({
|
|
@@ -563,12 +595,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
563
595
|
if (message.event.type === "user_language") {
|
|
564
596
|
const language = resolveUserLanguageCode(message.event);
|
|
565
597
|
if (language) {
|
|
598
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
566
599
|
await handlers.onUserLanguage?.({
|
|
567
600
|
sessionId: message.sessionId,
|
|
568
601
|
language
|
|
569
602
|
});
|
|
570
603
|
}
|
|
571
604
|
}
|
|
605
|
+
if (message.event.type === "voice_language_changed") {
|
|
606
|
+
const language = resolveUserLanguageCode(message.event);
|
|
607
|
+
if (language) {
|
|
608
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
609
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
610
|
+
sessionId: message.sessionId,
|
|
611
|
+
language
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
572
615
|
break;
|
|
573
616
|
case "data_channel_message":
|
|
574
617
|
await handlers.onDataChannelMessage?.({
|
|
@@ -595,6 +638,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
595
638
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
596
639
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
597
640
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
641
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
642
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
598
643
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
599
644
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
600
645
|
sessionId: message.sessionId
|
|
@@ -643,6 +688,10 @@ function defineAgent(handlers) {
|
|
|
643
688
|
handleSttControlAck(message);
|
|
644
689
|
return;
|
|
645
690
|
}
|
|
691
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
692
|
+
handleVoiceLanguageControlAck(message);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
646
695
|
if (isWebhookMessage(message)) {
|
|
647
696
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
648
697
|
return;
|
|
@@ -178,6 +178,12 @@ function isSttControlAckMessage(value) {
|
|
|
178
178
|
const msg = value;
|
|
179
179
|
return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
|
|
180
180
|
}
|
|
181
|
+
function isVoiceLanguageControlAckMessage(value) {
|
|
182
|
+
if (!value || typeof value !== "object")
|
|
183
|
+
return false;
|
|
184
|
+
const msg = value;
|
|
185
|
+
return msg.type === "voice_language_control_ack" && typeof msg.requestId === "string";
|
|
186
|
+
}
|
|
181
187
|
function isWebhookMessage(value) {
|
|
182
188
|
if (!value || typeof value !== "object")
|
|
183
189
|
return false;
|
|
@@ -220,7 +226,7 @@ function isParentMessage(value) {
|
|
|
220
226
|
if (!value || typeof value !== "object")
|
|
221
227
|
return false;
|
|
222
228
|
const msg = value;
|
|
223
|
-
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
229
|
+
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "voice_language_control_ack" || msg.type === "webhook";
|
|
224
230
|
}
|
|
225
231
|
function isSessionScopedParentMessage(value) {
|
|
226
232
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -236,6 +242,8 @@ var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
|
236
242
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
237
243
|
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
238
244
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
245
|
+
var voiceLanguageSwitchAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
246
|
+
var lastVoiceLanguageBySessionId = /* @__PURE__ */ new Map();
|
|
239
247
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
240
248
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
241
249
|
var RECORDING_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
@@ -248,6 +256,7 @@ var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
|
248
256
|
var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
249
257
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
250
258
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
259
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
251
260
|
function handleRecordingControlAck(message) {
|
|
252
261
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
253
262
|
if (!pending)
|
|
@@ -350,6 +359,27 @@ function handleSttControlAck(message) {
|
|
|
350
359
|
requestId: message.requestId
|
|
351
360
|
});
|
|
352
361
|
}
|
|
362
|
+
function handleVoiceLanguageControlAck(message) {
|
|
363
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
364
|
+
if (!pending)
|
|
365
|
+
return;
|
|
366
|
+
clearTimeout(pending.timer);
|
|
367
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
368
|
+
if (message.ok && message.language?.trim()) {
|
|
369
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
370
|
+
}
|
|
371
|
+
pending.resolve({
|
|
372
|
+
ok: message.ok,
|
|
373
|
+
reason: message.reason,
|
|
374
|
+
requestId: message.requestId,
|
|
375
|
+
...message.language ? { language: message.language } : {},
|
|
376
|
+
...message.voice ? { voice: message.voice } : {},
|
|
377
|
+
...message.stt ? { stt: message.stt } : {},
|
|
378
|
+
...message.scope ? { scope: message.scope } : {},
|
|
379
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
380
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
381
|
+
});
|
|
382
|
+
}
|
|
353
383
|
function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
354
384
|
for (const [requestId, pending] of pendingRecordingAcks) {
|
|
355
385
|
if (pending.sessionId !== sessionId)
|
|
@@ -418,7 +448,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
418
448
|
}
|
|
419
449
|
function sendParentMessage(message) {
|
|
420
450
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
421
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
451
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
422
452
|
process.send?.(message);
|
|
423
453
|
return;
|
|
424
454
|
}
|
|
@@ -519,6 +549,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
519
549
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
520
550
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
521
551
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
552
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
522
553
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
523
554
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
524
555
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -530,6 +561,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
530
561
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
531
562
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
532
563
|
mixAvailable: message.mixAvailable ?? false,
|
|
564
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
533
565
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
534
566
|
});
|
|
535
567
|
sendParentMessage({
|
|
@@ -548,12 +580,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
548
580
|
if (message.event.type === "user_language") {
|
|
549
581
|
const language = resolveUserLanguageCode(message.event);
|
|
550
582
|
if (language) {
|
|
583
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
551
584
|
await handlers.onUserLanguage?.({
|
|
552
585
|
sessionId: message.sessionId,
|
|
553
586
|
language
|
|
554
587
|
});
|
|
555
588
|
}
|
|
556
589
|
}
|
|
590
|
+
if (message.event.type === "voice_language_changed") {
|
|
591
|
+
const language = resolveUserLanguageCode(message.event);
|
|
592
|
+
if (language) {
|
|
593
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
594
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
595
|
+
sessionId: message.sessionId,
|
|
596
|
+
language
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
}
|
|
557
600
|
break;
|
|
558
601
|
case "data_channel_message":
|
|
559
602
|
await handlers.onDataChannelMessage?.({
|
|
@@ -580,6 +623,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
580
623
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
581
624
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
582
625
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
626
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
627
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
583
628
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
584
629
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
585
630
|
sessionId: message.sessionId
|
|
@@ -628,6 +673,10 @@ function defineAgent(handlers) {
|
|
|
628
673
|
handleSttControlAck(message);
|
|
629
674
|
return;
|
|
630
675
|
}
|
|
676
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
677
|
+
handleVoiceLanguageControlAck(message);
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
631
680
|
if (isWebhookMessage(message)) {
|
|
632
681
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
633
682
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,uBAAuB,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,uBAAuB,EA8LpD,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAMrE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,eAAe,CAEnE;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,CAMnE;AAED,wBAAgB,yBAAyB,IAAI,uBAAuB,EAAE,CAErE"}
|
|
@@ -15,6 +15,14 @@ export const AGENT_TEMPLATES = [
|
|
|
15
15
|
description: "Data-channel-only echo — relays speech events and chat without TTS.",
|
|
16
16
|
sourceFiles: ["echo-dc/agent.ts"],
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
id: "language-switch",
|
|
20
|
+
entry: "language-switch/agent.ts",
|
|
21
|
+
kind: "product",
|
|
22
|
+
seedOnCreate: true,
|
|
23
|
+
description: "Switches STT and TTS independently from onUserLanguage, and can change one vendor mid-conversation. Detection does not change either side until this agent calls setVoiceLanguage.",
|
|
24
|
+
sourceFiles: ["language-switch/agent.ts"],
|
|
25
|
+
},
|
|
18
26
|
{
|
|
19
27
|
id: "voice-starter",
|
|
20
28
|
entry: "voice-starter/agent.ts",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -182,6 +182,12 @@ function isSttControlAckMessage(value) {
|
|
|
182
182
|
const msg = value;
|
|
183
183
|
return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
|
|
184
184
|
}
|
|
185
|
+
function isVoiceLanguageControlAckMessage(value) {
|
|
186
|
+
if (!value || typeof value !== "object")
|
|
187
|
+
return false;
|
|
188
|
+
const msg = value;
|
|
189
|
+
return msg.type === "voice_language_control_ack" && typeof msg.requestId === "string";
|
|
190
|
+
}
|
|
185
191
|
function isWebhookMessage(value) {
|
|
186
192
|
if (!value || typeof value !== "object")
|
|
187
193
|
return false;
|
|
@@ -224,7 +230,7 @@ function isParentMessage(value) {
|
|
|
224
230
|
if (!value || typeof value !== "object")
|
|
225
231
|
return false;
|
|
226
232
|
const msg = value;
|
|
227
|
-
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
233
|
+
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "voice_language_control_ack" || msg.type === "webhook";
|
|
228
234
|
}
|
|
229
235
|
function isSessionScopedParentMessage(value) {
|
|
230
236
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -240,6 +246,8 @@ var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
|
240
246
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
241
247
|
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
242
248
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
249
|
+
var voiceLanguageSwitchAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
250
|
+
var lastVoiceLanguageBySessionId = /* @__PURE__ */ new Map();
|
|
243
251
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
244
252
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
245
253
|
var PLAY_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
@@ -254,6 +262,7 @@ var MIX_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
|
254
262
|
var STT_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
255
263
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
256
264
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
265
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
257
266
|
function handleRecordingControlAck(message) {
|
|
258
267
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
259
268
|
if (!pending)
|
|
@@ -356,6 +365,27 @@ function handleSttControlAck(message) {
|
|
|
356
365
|
requestId: message.requestId
|
|
357
366
|
});
|
|
358
367
|
}
|
|
368
|
+
function handleVoiceLanguageControlAck(message) {
|
|
369
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
370
|
+
if (!pending)
|
|
371
|
+
return;
|
|
372
|
+
clearTimeout(pending.timer);
|
|
373
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
374
|
+
if (message.ok && message.language?.trim()) {
|
|
375
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
376
|
+
}
|
|
377
|
+
pending.resolve({
|
|
378
|
+
ok: message.ok,
|
|
379
|
+
reason: message.reason,
|
|
380
|
+
requestId: message.requestId,
|
|
381
|
+
...message.language ? { language: message.language } : {},
|
|
382
|
+
...message.voice ? { voice: message.voice } : {},
|
|
383
|
+
...message.stt ? { stt: message.stt } : {},
|
|
384
|
+
...message.scope ? { scope: message.scope } : {},
|
|
385
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
386
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
359
389
|
function isMixAvailableInProcess() {
|
|
360
390
|
for (const available of mixAvailableBySessionId.values()) {
|
|
361
391
|
if (available)
|
|
@@ -448,7 +478,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
448
478
|
}
|
|
449
479
|
function sendParentMessage(message) {
|
|
450
480
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
451
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
481
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
452
482
|
process.send?.(message);
|
|
453
483
|
return;
|
|
454
484
|
}
|
|
@@ -549,6 +579,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
549
579
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
550
580
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
551
581
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
582
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
552
583
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
553
584
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
554
585
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -560,6 +591,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
560
591
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
561
592
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
562
593
|
mixAvailable: message.mixAvailable ?? false,
|
|
594
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
563
595
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
564
596
|
});
|
|
565
597
|
sendParentMessage({
|
|
@@ -578,12 +610,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
578
610
|
if (message.event.type === "user_language") {
|
|
579
611
|
const language = resolveUserLanguageCode(message.event);
|
|
580
612
|
if (language) {
|
|
613
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
581
614
|
await handlers.onUserLanguage?.({
|
|
582
615
|
sessionId: message.sessionId,
|
|
583
616
|
language
|
|
584
617
|
});
|
|
585
618
|
}
|
|
586
619
|
}
|
|
620
|
+
if (message.event.type === "voice_language_changed") {
|
|
621
|
+
const language = resolveUserLanguageCode(message.event);
|
|
622
|
+
if (language) {
|
|
623
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
624
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
625
|
+
sessionId: message.sessionId,
|
|
626
|
+
language
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
}
|
|
587
630
|
break;
|
|
588
631
|
case "data_channel_message":
|
|
589
632
|
await handlers.onDataChannelMessage?.({
|
|
@@ -610,6 +653,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
610
653
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
611
654
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
612
655
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
656
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
657
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
613
658
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
614
659
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
615
660
|
sessionId: message.sessionId
|
|
@@ -658,6 +703,10 @@ function defineAgent(handlers) {
|
|
|
658
703
|
handleSttControlAck(message);
|
|
659
704
|
return;
|
|
660
705
|
}
|
|
706
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
707
|
+
handleVoiceLanguageControlAck(message);
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
661
710
|
if (isWebhookMessage(message)) {
|
|
662
711
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
663
712
|
return;
|
|
@@ -178,6 +178,12 @@ function isSttControlAckMessage(value) {
|
|
|
178
178
|
const msg = value;
|
|
179
179
|
return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
|
|
180
180
|
}
|
|
181
|
+
function isVoiceLanguageControlAckMessage(value) {
|
|
182
|
+
if (!value || typeof value !== "object")
|
|
183
|
+
return false;
|
|
184
|
+
const msg = value;
|
|
185
|
+
return msg.type === "voice_language_control_ack" && typeof msg.requestId === "string";
|
|
186
|
+
}
|
|
181
187
|
function isWebhookMessage(value) {
|
|
182
188
|
if (!value || typeof value !== "object")
|
|
183
189
|
return false;
|
|
@@ -220,7 +226,7 @@ function isParentMessage(value) {
|
|
|
220
226
|
if (!value || typeof value !== "object")
|
|
221
227
|
return false;
|
|
222
228
|
const msg = value;
|
|
223
|
-
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
229
|
+
return msg.type === "session_start" || msg.type === "speech_event" || msg.type === "session_end" || msg.type === "data_channel_message" || msg.type === "data_channel_binary" || msg.type === "idle_timeout" || msg.type === "recording_control_ack" || msg.type === "conversation_history_control_ack" || msg.type === "play_ack" || msg.type === "play_status_ack" || msg.type === "play_stop_ack" || msg.type === "play_pose_ack" || msg.type === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "voice_language_control_ack" || msg.type === "webhook";
|
|
224
230
|
}
|
|
225
231
|
function isSessionScopedParentMessage(value) {
|
|
226
232
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -236,6 +242,8 @@ var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
|
236
242
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
237
243
|
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
238
244
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
245
|
+
var voiceLanguageSwitchAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
246
|
+
var lastVoiceLanguageBySessionId = /* @__PURE__ */ new Map();
|
|
239
247
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
240
248
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
241
249
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
@@ -247,6 +255,7 @@ var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
|
247
255
|
var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
248
256
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
249
257
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
258
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
250
259
|
function handleRecordingControlAck(message) {
|
|
251
260
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
252
261
|
if (!pending)
|
|
@@ -349,6 +358,27 @@ function handleSttControlAck(message) {
|
|
|
349
358
|
requestId: message.requestId
|
|
350
359
|
});
|
|
351
360
|
}
|
|
361
|
+
function handleVoiceLanguageControlAck(message) {
|
|
362
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
363
|
+
if (!pending)
|
|
364
|
+
return;
|
|
365
|
+
clearTimeout(pending.timer);
|
|
366
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
367
|
+
if (message.ok && message.language?.trim()) {
|
|
368
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
369
|
+
}
|
|
370
|
+
pending.resolve({
|
|
371
|
+
ok: message.ok,
|
|
372
|
+
reason: message.reason,
|
|
373
|
+
requestId: message.requestId,
|
|
374
|
+
...message.language ? { language: message.language } : {},
|
|
375
|
+
...message.voice ? { voice: message.voice } : {},
|
|
376
|
+
...message.stt ? { stt: message.stt } : {},
|
|
377
|
+
...message.scope ? { scope: message.scope } : {},
|
|
378
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
379
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
352
382
|
function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
353
383
|
for (const [requestId, pending] of pendingRecordingAcks) {
|
|
354
384
|
if (pending.sessionId !== sessionId)
|
|
@@ -414,7 +444,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
414
444
|
}
|
|
415
445
|
function sendParentMessage(message) {
|
|
416
446
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
417
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
447
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
418
448
|
process.send?.(message);
|
|
419
449
|
return;
|
|
420
450
|
}
|
|
@@ -515,6 +545,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
515
545
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
516
546
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
517
547
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
548
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
518
549
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
519
550
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
520
551
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -526,6 +557,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
526
557
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
527
558
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
528
559
|
mixAvailable: message.mixAvailable ?? false,
|
|
560
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
529
561
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
530
562
|
});
|
|
531
563
|
sendParentMessage({
|
|
@@ -544,12 +576,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
544
576
|
if (message.event.type === "user_language") {
|
|
545
577
|
const language = resolveUserLanguageCode(message.event);
|
|
546
578
|
if (language) {
|
|
579
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
547
580
|
await handlers.onUserLanguage?.({
|
|
548
581
|
sessionId: message.sessionId,
|
|
549
582
|
language
|
|
550
583
|
});
|
|
551
584
|
}
|
|
552
585
|
}
|
|
586
|
+
if (message.event.type === "voice_language_changed") {
|
|
587
|
+
const language = resolveUserLanguageCode(message.event);
|
|
588
|
+
if (language) {
|
|
589
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
590
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
591
|
+
sessionId: message.sessionId,
|
|
592
|
+
language
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
553
596
|
break;
|
|
554
597
|
case "data_channel_message":
|
|
555
598
|
await handlers.onDataChannelMessage?.({
|
|
@@ -576,6 +619,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
576
619
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
577
620
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
578
621
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
622
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
623
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
579
624
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
580
625
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
581
626
|
sessionId: message.sessionId
|
|
@@ -624,6 +669,10 @@ function defineAgent(handlers) {
|
|
|
624
669
|
handleSttControlAck(message);
|
|
625
670
|
return;
|
|
626
671
|
}
|
|
672
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
673
|
+
handleVoiceLanguageControlAck(message);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
627
676
|
if (isWebhookMessage(message)) {
|
|
628
677
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
629
678
|
return;
|