@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
|
@@ -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;
|
|
@@ -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;
|
|
@@ -250,6 +258,7 @@ var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
|
250
258
|
var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
251
259
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
252
260
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
261
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
253
262
|
function handleRecordingControlAck(message) {
|
|
254
263
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
255
264
|
if (!pending)
|
|
@@ -352,6 +361,27 @@ function handleSttControlAck(message) {
|
|
|
352
361
|
requestId: message.requestId
|
|
353
362
|
});
|
|
354
363
|
}
|
|
364
|
+
function handleVoiceLanguageControlAck(message) {
|
|
365
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
366
|
+
if (!pending)
|
|
367
|
+
return;
|
|
368
|
+
clearTimeout(pending.timer);
|
|
369
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
370
|
+
if (message.ok && message.language?.trim()) {
|
|
371
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
372
|
+
}
|
|
373
|
+
pending.resolve({
|
|
374
|
+
ok: message.ok,
|
|
375
|
+
reason: message.reason,
|
|
376
|
+
requestId: message.requestId,
|
|
377
|
+
...message.language ? { language: message.language } : {},
|
|
378
|
+
...message.voice ? { voice: message.voice } : {},
|
|
379
|
+
...message.stt ? { stt: message.stt } : {},
|
|
380
|
+
...message.scope ? { scope: message.scope } : {},
|
|
381
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
382
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
355
385
|
function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
356
386
|
for (const [requestId, pending] of pendingRecordingAcks) {
|
|
357
387
|
if (pending.sessionId !== sessionId)
|
|
@@ -417,7 +447,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
417
447
|
}
|
|
418
448
|
function sendParentMessage(message) {
|
|
419
449
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
420
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
450
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
421
451
|
process.send?.(message);
|
|
422
452
|
return;
|
|
423
453
|
}
|
|
@@ -518,6 +548,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
518
548
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
519
549
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
520
550
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
551
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
521
552
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
522
553
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
523
554
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -529,6 +560,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
529
560
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
530
561
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
531
562
|
mixAvailable: message.mixAvailable ?? false,
|
|
563
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
532
564
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
533
565
|
});
|
|
534
566
|
sendParentMessage({
|
|
@@ -547,12 +579,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
547
579
|
if (message.event.type === "user_language") {
|
|
548
580
|
const language = resolveUserLanguageCode(message.event);
|
|
549
581
|
if (language) {
|
|
582
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
550
583
|
await handlers.onUserLanguage?.({
|
|
551
584
|
sessionId: message.sessionId,
|
|
552
585
|
language
|
|
553
586
|
});
|
|
554
587
|
}
|
|
555
588
|
}
|
|
589
|
+
if (message.event.type === "voice_language_changed") {
|
|
590
|
+
const language = resolveUserLanguageCode(message.event);
|
|
591
|
+
if (language) {
|
|
592
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
593
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
594
|
+
sessionId: message.sessionId,
|
|
595
|
+
language
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
}
|
|
556
599
|
break;
|
|
557
600
|
case "data_channel_message":
|
|
558
601
|
await handlers.onDataChannelMessage?.({
|
|
@@ -579,6 +622,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
579
622
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
580
623
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
581
624
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
625
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
626
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
582
627
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
583
628
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
584
629
|
sessionId: message.sessionId
|
|
@@ -627,6 +672,10 @@ function defineAgent(handlers) {
|
|
|
627
672
|
handleSttControlAck(message);
|
|
628
673
|
return;
|
|
629
674
|
}
|
|
675
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
676
|
+
handleVoiceLanguageControlAck(message);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
630
679
|
if (isWebhookMessage(message)) {
|
|
631
680
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
632
681
|
return;
|
|
@@ -10933,6 +10933,12 @@ function isSttControlAckMessage(value) {
|
|
|
10933
10933
|
const msg = value;
|
|
10934
10934
|
return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
|
|
10935
10935
|
}
|
|
10936
|
+
function isVoiceLanguageControlAckMessage(value) {
|
|
10937
|
+
if (!value || typeof value !== "object")
|
|
10938
|
+
return false;
|
|
10939
|
+
const msg = value;
|
|
10940
|
+
return msg.type === "voice_language_control_ack" && typeof msg.requestId === "string";
|
|
10941
|
+
}
|
|
10936
10942
|
function isWebhookMessage(value) {
|
|
10937
10943
|
if (!value || typeof value !== "object")
|
|
10938
10944
|
return false;
|
|
@@ -10975,7 +10981,7 @@ function isParentMessage(value) {
|
|
|
10975
10981
|
if (!value || typeof value !== "object")
|
|
10976
10982
|
return false;
|
|
10977
10983
|
const msg = value;
|
|
10978
|
-
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";
|
|
10984
|
+
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";
|
|
10979
10985
|
}
|
|
10980
10986
|
function isSessionScopedParentMessage(value) {
|
|
10981
10987
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -10991,6 +10997,8 @@ var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
|
10991
10997
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
10992
10998
|
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
10993
10999
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
11000
|
+
var voiceLanguageSwitchAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
11001
|
+
var lastVoiceLanguageBySessionId = /* @__PURE__ */ new Map();
|
|
10994
11002
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
10995
11003
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
10996
11004
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
@@ -11002,6 +11010,7 @@ var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
|
11002
11010
|
var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
11003
11011
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
11004
11012
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
11013
|
+
var pendingVoiceLanguageAcks = /* @__PURE__ */ new Map();
|
|
11005
11014
|
function handleRecordingControlAck(message) {
|
|
11006
11015
|
const pending = pendingRecordingAcks.get(message.requestId);
|
|
11007
11016
|
if (!pending)
|
|
@@ -11104,6 +11113,27 @@ function handleSttControlAck(message) {
|
|
|
11104
11113
|
requestId: message.requestId
|
|
11105
11114
|
});
|
|
11106
11115
|
}
|
|
11116
|
+
function handleVoiceLanguageControlAck(message) {
|
|
11117
|
+
const pending = pendingVoiceLanguageAcks.get(message.requestId);
|
|
11118
|
+
if (!pending)
|
|
11119
|
+
return;
|
|
11120
|
+
clearTimeout(pending.timer);
|
|
11121
|
+
pendingVoiceLanguageAcks.delete(message.requestId);
|
|
11122
|
+
if (message.ok && message.language?.trim()) {
|
|
11123
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, message.language.trim());
|
|
11124
|
+
}
|
|
11125
|
+
pending.resolve({
|
|
11126
|
+
ok: message.ok,
|
|
11127
|
+
reason: message.reason,
|
|
11128
|
+
requestId: message.requestId,
|
|
11129
|
+
...message.language ? { language: message.language } : {},
|
|
11130
|
+
...message.voice ? { voice: message.voice } : {},
|
|
11131
|
+
...message.stt ? { stt: message.stt } : {},
|
|
11132
|
+
...message.scope ? { scope: message.scope } : {},
|
|
11133
|
+
...message.sttProvider ? { sttProvider: message.sttProvider } : {},
|
|
11134
|
+
...message.ttsProvider ? { ttsProvider: message.ttsProvider } : {}
|
|
11135
|
+
});
|
|
11136
|
+
}
|
|
11107
11137
|
function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
11108
11138
|
for (const [requestId, pending] of pendingRecordingAcks) {
|
|
11109
11139
|
if (pending.sessionId !== sessionId)
|
|
@@ -11169,7 +11199,7 @@ function allowOutboundForSession(sessionId) {
|
|
|
11169
11199
|
}
|
|
11170
11200
|
function sendParentMessage(message) {
|
|
11171
11201
|
const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
|
|
11172
|
-
if (msgType === "mix_control" || msgType === "stt_control") {
|
|
11202
|
+
if (msgType === "mix_control" || msgType === "stt_control" || msgType === "voice_language_control") {
|
|
11173
11203
|
process.send?.(message);
|
|
11174
11204
|
return;
|
|
11175
11205
|
}
|
|
@@ -11270,6 +11300,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
11270
11300
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
11271
11301
|
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
11272
11302
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
11303
|
+
voiceLanguageSwitchAvailableBySessionId.set(message.sessionId, message.voiceLanguageSwitchAvailable ?? false);
|
|
11273
11304
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
11274
11305
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
11275
11306
|
if (sessionStartInitDelayMs > 0) {
|
|
@@ -11281,6 +11312,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
11281
11312
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
11282
11313
|
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
11283
11314
|
mixAvailable: message.mixAvailable ?? false,
|
|
11315
|
+
voiceLanguageSwitchAvailable: message.voiceLanguageSwitchAvailable ?? false,
|
|
11284
11316
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
11285
11317
|
});
|
|
11286
11318
|
sendParentMessage({
|
|
@@ -11299,12 +11331,23 @@ async function handleParentMessage(message, handlers) {
|
|
|
11299
11331
|
if (message.event.type === "user_language") {
|
|
11300
11332
|
const language = resolveUserLanguageCode(message.event);
|
|
11301
11333
|
if (language) {
|
|
11334
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
11302
11335
|
await handlers.onUserLanguage?.({
|
|
11303
11336
|
sessionId: message.sessionId,
|
|
11304
11337
|
language
|
|
11305
11338
|
});
|
|
11306
11339
|
}
|
|
11307
11340
|
}
|
|
11341
|
+
if (message.event.type === "voice_language_changed") {
|
|
11342
|
+
const language = resolveUserLanguageCode(message.event);
|
|
11343
|
+
if (language) {
|
|
11344
|
+
lastVoiceLanguageBySessionId.set(message.sessionId, language);
|
|
11345
|
+
await handlers.onVoiceLanguageChanged?.({
|
|
11346
|
+
sessionId: message.sessionId,
|
|
11347
|
+
language
|
|
11348
|
+
});
|
|
11349
|
+
}
|
|
11350
|
+
}
|
|
11308
11351
|
break;
|
|
11309
11352
|
case "data_channel_message":
|
|
11310
11353
|
await handlers.onDataChannelMessage?.({
|
|
@@ -11331,6 +11374,8 @@ async function handleParentMessage(message, handlers) {
|
|
|
11331
11374
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
11332
11375
|
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
11333
11376
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
11377
|
+
voiceLanguageSwitchAvailableBySessionId.delete(message.sessionId);
|
|
11378
|
+
lastVoiceLanguageBySessionId.delete(message.sessionId);
|
|
11334
11379
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
11335
11380
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
11336
11381
|
sessionId: message.sessionId
|
|
@@ -11379,6 +11424,10 @@ function defineAgent(handlers) {
|
|
|
11379
11424
|
handleSttControlAck(message);
|
|
11380
11425
|
return;
|
|
11381
11426
|
}
|
|
11427
|
+
if (isVoiceLanguageControlAckMessage(message)) {
|
|
11428
|
+
handleVoiceLanguageControlAck(message);
|
|
11429
|
+
return;
|
|
11430
|
+
}
|
|
11382
11431
|
if (isWebhookMessage(message)) {
|
|
11383
11432
|
void agentStartReady.then(() => handleWebhookMessage(message, handlers));
|
|
11384
11433
|
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;
|
|
@@ -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;
|