@voicethere/agent 0.8.0 → 0.8.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/README.md +10 -9
- package/dist/agent.js +45 -1
- 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 +36 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +21 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +112 -0
- package/dist/runtime.js.map +1 -1
- package/dist/templates/echo/agent.js +54 -5
- package/dist/templates/echo-dc/agent.js +39 -1
- package/dist/templates/game-sync/agent.js +39 -1
- package/dist/templates/positional-tts/agent.js +39 -1
- package/dist/templates/recording-consent/agent.js +51 -13
- package/dist/templates/spatial-showcase/agent.js +39 -1
- package/dist/templates/voice-showcase/agent.js +103 -26
- package/dist/templates/voice-starter/agent.js +39 -1
- package/dist/templates/webhooks/agent.js +39 -1
- package/dist/templates/webhooks-redis/agent.js +39 -1
- package/dist/templates/world-sync/agent.js +39 -1
- package/dist/templates/world-sync-binary/agent.js +39 -1
- package/package.json +1 -1
- package/templates/echo/agent.ts +3 -5
- package/templates/voice-showcase/agent.ts +3 -1
- package/templates/voice-showcase/conversation.ts +9 -5
- package/templates/voice-showcase/delivery.ts +40 -10
|
@@ -163,6 +163,12 @@ function isRecordingControlAckMessage(value) {
|
|
|
163
163
|
const msg = value;
|
|
164
164
|
return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
|
|
165
165
|
}
|
|
166
|
+
function isConversationHistoryControlAckMessage(value) {
|
|
167
|
+
if (!value || typeof value !== "object")
|
|
168
|
+
return false;
|
|
169
|
+
const msg = value;
|
|
170
|
+
return msg.type === "conversation_history_control_ack" && typeof msg.requestId === "string";
|
|
171
|
+
}
|
|
166
172
|
function isMixControlAckMessage(value) {
|
|
167
173
|
if (!value || typeof value !== "object")
|
|
168
174
|
return false;
|
|
@@ -217,7 +223,7 @@ function isParentMessage(value) {
|
|
|
217
223
|
if (!value || typeof value !== "object")
|
|
218
224
|
return false;
|
|
219
225
|
const msg = value;
|
|
220
|
-
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 === "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";
|
|
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";
|
|
221
227
|
}
|
|
222
228
|
function isSessionScopedParentMessage(value) {
|
|
223
229
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -231,11 +237,13 @@ function parseDataChannelPayload(raw) {
|
|
|
231
237
|
}
|
|
232
238
|
var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
233
239
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
240
|
+
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
234
241
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
235
242
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
236
243
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
237
244
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
238
245
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
246
|
+
var pendingConversationHistoryAcks = /* @__PURE__ */ new Map();
|
|
239
247
|
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
240
248
|
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
241
249
|
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
@@ -255,6 +263,18 @@ function handleRecordingControlAck(message) {
|
|
|
255
263
|
requestId: message.requestId
|
|
256
264
|
});
|
|
257
265
|
}
|
|
266
|
+
function handleConversationHistoryControlAck(message) {
|
|
267
|
+
const pending = pendingConversationHistoryAcks.get(message.requestId);
|
|
268
|
+
if (!pending)
|
|
269
|
+
return;
|
|
270
|
+
clearTimeout(pending.timer);
|
|
271
|
+
pendingConversationHistoryAcks.delete(message.requestId);
|
|
272
|
+
pending.resolve({
|
|
273
|
+
ok: message.ok,
|
|
274
|
+
reason: message.reason,
|
|
275
|
+
requestId: message.requestId
|
|
276
|
+
});
|
|
277
|
+
}
|
|
258
278
|
function handlePlayAck(message) {
|
|
259
279
|
const pending = pendingPlayAcks.get(message.requestId);
|
|
260
280
|
if (!pending)
|
|
@@ -354,6 +374,15 @@ function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
|
354
374
|
pending.resolve({ ok: false, reason, requestId });
|
|
355
375
|
}
|
|
356
376
|
}
|
|
377
|
+
function clearPendingConversationHistoryAcksForSession(sessionId, reason) {
|
|
378
|
+
for (const [requestId, pending] of pendingConversationHistoryAcks) {
|
|
379
|
+
if (pending.sessionId !== sessionId)
|
|
380
|
+
continue;
|
|
381
|
+
clearTimeout(pending.timer);
|
|
382
|
+
pendingConversationHistoryAcks.delete(requestId);
|
|
383
|
+
pending.resolve({ ok: false, reason, requestId });
|
|
384
|
+
}
|
|
385
|
+
}
|
|
357
386
|
function isVoicethereAgentChild() {
|
|
358
387
|
return typeof process.send === "function" && process.connected !== false && typeof process.env.__CHILD_BUNDLE_PATH__ === "string" && process.env.__CHILD_BUNDLE_PATH__.trim().length > 0;
|
|
359
388
|
}
|
|
@@ -503,6 +532,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
503
532
|
endedSessionIds.delete(message.sessionId);
|
|
504
533
|
peerEnvBySessionId.set(message.sessionId, message.env);
|
|
505
534
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
535
|
+
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
506
536
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
507
537
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
508
538
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
@@ -513,6 +543,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
513
543
|
sessionId: message.sessionId,
|
|
514
544
|
env: message.env,
|
|
515
545
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
546
|
+
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
516
547
|
mixAvailable: message.mixAvailable ?? false,
|
|
517
548
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
518
549
|
});
|
|
@@ -559,8 +590,10 @@ async function handleParentMessage(message, handlers) {
|
|
|
559
590
|
break;
|
|
560
591
|
case "session_end":
|
|
561
592
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
593
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
562
594
|
peerEnvBySessionId.delete(message.sessionId);
|
|
563
595
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
596
|
+
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
564
597
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
565
598
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
566
599
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
@@ -582,6 +615,10 @@ function defineAgent(handlers) {
|
|
|
582
615
|
handleRecordingControlAck(message);
|
|
583
616
|
return;
|
|
584
617
|
}
|
|
618
|
+
if (isConversationHistoryControlAckMessage(message)) {
|
|
619
|
+
handleConversationHistoryControlAck(message);
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
585
622
|
if (isPlayAckMessage(message)) {
|
|
586
623
|
handlePlayAck(message);
|
|
587
624
|
return;
|
|
@@ -615,6 +652,7 @@ function defineAgent(handlers) {
|
|
|
615
652
|
if (message.type === "session_end") {
|
|
616
653
|
endedSessionIds.add(message.sessionId);
|
|
617
654
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
655
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
618
656
|
inboundBySession.clear(message.sessionId);
|
|
619
657
|
}
|
|
620
658
|
if (message.type === "session_start") {
|
|
@@ -160,6 +160,12 @@ function isRecordingControlAckMessage(value) {
|
|
|
160
160
|
const msg = value;
|
|
161
161
|
return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
|
|
162
162
|
}
|
|
163
|
+
function isConversationHistoryControlAckMessage(value) {
|
|
164
|
+
if (!value || typeof value !== "object")
|
|
165
|
+
return false;
|
|
166
|
+
const msg = value;
|
|
167
|
+
return msg.type === "conversation_history_control_ack" && typeof msg.requestId === "string";
|
|
168
|
+
}
|
|
163
169
|
function isMixControlAckMessage(value) {
|
|
164
170
|
if (!value || typeof value !== "object")
|
|
165
171
|
return false;
|
|
@@ -214,7 +220,7 @@ function isParentMessage(value) {
|
|
|
214
220
|
if (!value || typeof value !== "object")
|
|
215
221
|
return false;
|
|
216
222
|
const msg = value;
|
|
217
|
-
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 === "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";
|
|
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";
|
|
218
224
|
}
|
|
219
225
|
function isSessionScopedParentMessage(value) {
|
|
220
226
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -228,12 +234,14 @@ function parseDataChannelPayload(raw) {
|
|
|
228
234
|
}
|
|
229
235
|
var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
230
236
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
237
|
+
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
231
238
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
232
239
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
233
240
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
234
241
|
var RECORDING_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
235
242
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
236
243
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
244
|
+
var pendingConversationHistoryAcks = /* @__PURE__ */ new Map();
|
|
237
245
|
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
238
246
|
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
239
247
|
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
@@ -252,6 +260,18 @@ function handleRecordingControlAck(message) {
|
|
|
252
260
|
requestId: message.requestId
|
|
253
261
|
});
|
|
254
262
|
}
|
|
263
|
+
function handleConversationHistoryControlAck(message) {
|
|
264
|
+
const pending = pendingConversationHistoryAcks.get(message.requestId);
|
|
265
|
+
if (!pending)
|
|
266
|
+
return;
|
|
267
|
+
clearTimeout(pending.timer);
|
|
268
|
+
pendingConversationHistoryAcks.delete(message.requestId);
|
|
269
|
+
pending.resolve({
|
|
270
|
+
ok: message.ok,
|
|
271
|
+
reason: message.reason,
|
|
272
|
+
requestId: message.requestId
|
|
273
|
+
});
|
|
274
|
+
}
|
|
255
275
|
function handlePlayAck(message) {
|
|
256
276
|
const pending = pendingPlayAcks.get(message.requestId);
|
|
257
277
|
if (!pending)
|
|
@@ -339,6 +359,15 @@ function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
|
339
359
|
pending.resolve({ ok: false, reason, requestId });
|
|
340
360
|
}
|
|
341
361
|
}
|
|
362
|
+
function clearPendingConversationHistoryAcksForSession(sessionId, reason) {
|
|
363
|
+
for (const [requestId, pending] of pendingConversationHistoryAcks) {
|
|
364
|
+
if (pending.sessionId !== sessionId)
|
|
365
|
+
continue;
|
|
366
|
+
clearTimeout(pending.timer);
|
|
367
|
+
pendingConversationHistoryAcks.delete(requestId);
|
|
368
|
+
pending.resolve({ ok: false, reason, requestId });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
342
371
|
function isVoicethereAgentChild() {
|
|
343
372
|
return typeof process.send === "function" && process.connected !== false && typeof process.env.__CHILD_BUNDLE_PATH__ === "string" && process.env.__CHILD_BUNDLE_PATH__.trim().length > 0;
|
|
344
373
|
}
|
|
@@ -488,6 +517,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
488
517
|
endedSessionIds.delete(message.sessionId);
|
|
489
518
|
peerEnvBySessionId.set(message.sessionId, message.env);
|
|
490
519
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
520
|
+
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
491
521
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
492
522
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
493
523
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
@@ -498,6 +528,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
498
528
|
sessionId: message.sessionId,
|
|
499
529
|
env: message.env,
|
|
500
530
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
531
|
+
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
501
532
|
mixAvailable: message.mixAvailable ?? false,
|
|
502
533
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
503
534
|
});
|
|
@@ -544,8 +575,10 @@ async function handleParentMessage(message, handlers) {
|
|
|
544
575
|
break;
|
|
545
576
|
case "session_end":
|
|
546
577
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
578
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
547
579
|
peerEnvBySessionId.delete(message.sessionId);
|
|
548
580
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
581
|
+
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
549
582
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
550
583
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
551
584
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
@@ -567,6 +600,10 @@ function defineAgent(handlers) {
|
|
|
567
600
|
handleRecordingControlAck(message);
|
|
568
601
|
return;
|
|
569
602
|
}
|
|
603
|
+
if (isConversationHistoryControlAckMessage(message)) {
|
|
604
|
+
handleConversationHistoryControlAck(message);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
570
607
|
if (isPlayAckMessage(message)) {
|
|
571
608
|
handlePlayAck(message);
|
|
572
609
|
return;
|
|
@@ -600,6 +637,7 @@ function defineAgent(handlers) {
|
|
|
600
637
|
if (message.type === "session_end") {
|
|
601
638
|
endedSessionIds.add(message.sessionId);
|
|
602
639
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
640
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
603
641
|
inboundBySession.clear(message.sessionId);
|
|
604
642
|
}
|
|
605
643
|
if (message.type === "session_start") {
|
|
@@ -849,7 +887,7 @@ function createInitialState(recordingAvailable) {
|
|
|
849
887
|
consentSkipped: true
|
|
850
888
|
};
|
|
851
889
|
}
|
|
852
|
-
function
|
|
890
|
+
function speakAndChat2(text) {
|
|
853
891
|
return {
|
|
854
892
|
speakLines: [text],
|
|
855
893
|
messages: [{ type: "chat_reply", text }]
|
|
@@ -858,7 +896,7 @@ function speakAndChat(text) {
|
|
|
858
896
|
function beginSession(recordingAvailable) {
|
|
859
897
|
const state = createInitialState(recordingAvailable);
|
|
860
898
|
if (recordingAvailable) {
|
|
861
|
-
const prompt =
|
|
899
|
+
const prompt = speakAndChat2(CONSENT_PROMPT);
|
|
862
900
|
return {
|
|
863
901
|
state,
|
|
864
902
|
speakLines: prompt.speakLines,
|
|
@@ -866,8 +904,8 @@ function beginSession(recordingAvailable) {
|
|
|
866
904
|
recordingAction: null
|
|
867
905
|
};
|
|
868
906
|
}
|
|
869
|
-
const skip =
|
|
870
|
-
const name =
|
|
907
|
+
const skip = speakAndChat2(RECORDING_DISABLED_SKIP_MESSAGE);
|
|
908
|
+
const name = speakAndChat2(NAME_PROMPT);
|
|
871
909
|
return {
|
|
872
910
|
state,
|
|
873
911
|
speakLines: [...skip.speakLines, ...name.speakLines],
|
|
@@ -951,7 +989,7 @@ function sanitizeToken(raw, maxLen) {
|
|
|
951
989
|
return value;
|
|
952
990
|
}
|
|
953
991
|
function askNameAgain(state) {
|
|
954
|
-
const prompt =
|
|
992
|
+
const prompt = speakAndChat2(
|
|
955
993
|
"Sorry, I didn't catch your name. May I have your name please?"
|
|
956
994
|
);
|
|
957
995
|
return {
|
|
@@ -962,7 +1000,7 @@ function askNameAgain(state) {
|
|
|
962
1000
|
};
|
|
963
1001
|
}
|
|
964
1002
|
function askBirthdateAgain(state) {
|
|
965
|
-
const prompt =
|
|
1003
|
+
const prompt = speakAndChat2(
|
|
966
1004
|
"Sorry, I didn't catch your date of birth. Could you repeat it?"
|
|
967
1005
|
);
|
|
968
1006
|
return {
|
|
@@ -974,7 +1012,7 @@ function askBirthdateAgain(state) {
|
|
|
974
1012
|
}
|
|
975
1013
|
function finishAfterPii(state) {
|
|
976
1014
|
const next = { ...state, phase: "complete" };
|
|
977
|
-
const thankYou =
|
|
1015
|
+
const thankYou = speakAndChat2(
|
|
978
1016
|
`Thank you, ${state.name}. We have your date of birth on file.`
|
|
979
1017
|
);
|
|
980
1018
|
let recordingAction = null;
|
|
@@ -997,7 +1035,7 @@ function handleUtterance(state, utterance) {
|
|
|
997
1035
|
phase: "awaitingName",
|
|
998
1036
|
consent: false
|
|
999
1037
|
};
|
|
1000
|
-
const name =
|
|
1038
|
+
const name = speakAndChat2(NAME_PROMPT);
|
|
1001
1039
|
return {
|
|
1002
1040
|
state: next,
|
|
1003
1041
|
speakLines: name.speakLines,
|
|
@@ -1011,7 +1049,7 @@ function handleUtterance(state, utterance) {
|
|
|
1011
1049
|
phase: "awaitingName",
|
|
1012
1050
|
consent: true
|
|
1013
1051
|
};
|
|
1014
|
-
const name =
|
|
1052
|
+
const name = speakAndChat2(NAME_PROMPT);
|
|
1015
1053
|
return {
|
|
1016
1054
|
state: next,
|
|
1017
1055
|
speakLines: name.speakLines,
|
|
@@ -1019,7 +1057,7 @@ function handleUtterance(state, utterance) {
|
|
|
1019
1057
|
recordingAction: "pause"
|
|
1020
1058
|
};
|
|
1021
1059
|
}
|
|
1022
|
-
const retry =
|
|
1060
|
+
const retry = speakAndChat2(
|
|
1023
1061
|
"Please say yes or no \u2014 may we record this conversation?"
|
|
1024
1062
|
);
|
|
1025
1063
|
return {
|
|
@@ -1039,7 +1077,7 @@ function handleUtterance(state, utterance) {
|
|
|
1039
1077
|
phase: "awaitingBirthdate",
|
|
1040
1078
|
name
|
|
1041
1079
|
};
|
|
1042
|
-
const birthdate =
|
|
1080
|
+
const birthdate = speakAndChat2(BIRTHDATE_PROMPT);
|
|
1043
1081
|
return {
|
|
1044
1082
|
state: next,
|
|
1045
1083
|
speakLines: birthdate.speakLines,
|
|
@@ -1055,7 +1093,7 @@ function handleUtterance(state, utterance) {
|
|
|
1055
1093
|
return finishAfterPii({ ...state, birthdate });
|
|
1056
1094
|
}
|
|
1057
1095
|
case "complete": {
|
|
1058
|
-
const done =
|
|
1096
|
+
const done = speakAndChat2("We are all set. How can I help you today?");
|
|
1059
1097
|
return {
|
|
1060
1098
|
state,
|
|
1061
1099
|
speakLines: done.speakLines,
|
|
@@ -164,6 +164,12 @@ function isRecordingControlAckMessage(value) {
|
|
|
164
164
|
const msg = value;
|
|
165
165
|
return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
|
|
166
166
|
}
|
|
167
|
+
function isConversationHistoryControlAckMessage(value) {
|
|
168
|
+
if (!value || typeof value !== "object")
|
|
169
|
+
return false;
|
|
170
|
+
const msg = value;
|
|
171
|
+
return msg.type === "conversation_history_control_ack" && typeof msg.requestId === "string";
|
|
172
|
+
}
|
|
167
173
|
function isMixControlAckMessage(value) {
|
|
168
174
|
if (!value || typeof value !== "object")
|
|
169
175
|
return false;
|
|
@@ -218,7 +224,7 @@ function isParentMessage(value) {
|
|
|
218
224
|
if (!value || typeof value !== "object")
|
|
219
225
|
return false;
|
|
220
226
|
const msg = value;
|
|
221
|
-
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 === "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";
|
|
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";
|
|
222
228
|
}
|
|
223
229
|
function isSessionScopedParentMessage(value) {
|
|
224
230
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -232,12 +238,14 @@ function parseDataChannelPayload(raw) {
|
|
|
232
238
|
}
|
|
233
239
|
var peerEnvBySessionId = /* @__PURE__ */ new Map();
|
|
234
240
|
var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
241
|
+
var conversationHistoryAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
235
242
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
236
243
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
237
244
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
238
245
|
var PLAY_CONTROL_ACK_TIMEOUT_MS = 5e3;
|
|
239
246
|
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
240
247
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
248
|
+
var pendingConversationHistoryAcks = /* @__PURE__ */ new Map();
|
|
241
249
|
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
242
250
|
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
243
251
|
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
@@ -258,6 +266,18 @@ function handleRecordingControlAck(message) {
|
|
|
258
266
|
requestId: message.requestId
|
|
259
267
|
});
|
|
260
268
|
}
|
|
269
|
+
function handleConversationHistoryControlAck(message) {
|
|
270
|
+
const pending = pendingConversationHistoryAcks.get(message.requestId);
|
|
271
|
+
if (!pending)
|
|
272
|
+
return;
|
|
273
|
+
clearTimeout(pending.timer);
|
|
274
|
+
pendingConversationHistoryAcks.delete(message.requestId);
|
|
275
|
+
pending.resolve({
|
|
276
|
+
ok: message.ok,
|
|
277
|
+
reason: message.reason,
|
|
278
|
+
requestId: message.requestId
|
|
279
|
+
});
|
|
280
|
+
}
|
|
261
281
|
function handlePlayAck(message) {
|
|
262
282
|
const pending = pendingPlayAcks.get(message.requestId);
|
|
263
283
|
if (!pending)
|
|
@@ -369,6 +389,15 @@ function clearPendingRecordingAcksForSession(sessionId, reason) {
|
|
|
369
389
|
pending.resolve({ ok: false, reason, requestId });
|
|
370
390
|
}
|
|
371
391
|
}
|
|
392
|
+
function clearPendingConversationHistoryAcksForSession(sessionId, reason) {
|
|
393
|
+
for (const [requestId, pending] of pendingConversationHistoryAcks) {
|
|
394
|
+
if (pending.sessionId !== sessionId)
|
|
395
|
+
continue;
|
|
396
|
+
clearTimeout(pending.timer);
|
|
397
|
+
pendingConversationHistoryAcks.delete(requestId);
|
|
398
|
+
pending.resolve({ ok: false, reason, requestId });
|
|
399
|
+
}
|
|
400
|
+
}
|
|
372
401
|
function isVoicethereAgentChild() {
|
|
373
402
|
return typeof process.send === "function" && process.connected !== false && typeof process.env.__CHILD_BUNDLE_PATH__ === "string" && process.env.__CHILD_BUNDLE_PATH__.trim().length > 0;
|
|
374
403
|
}
|
|
@@ -518,6 +547,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
518
547
|
endedSessionIds.delete(message.sessionId);
|
|
519
548
|
peerEnvBySessionId.set(message.sessionId, message.env);
|
|
520
549
|
recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
|
|
550
|
+
conversationHistoryAvailableBySessionId.set(message.sessionId, message.conversationHistoryAvailable ?? false);
|
|
521
551
|
mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
|
|
522
552
|
ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
|
|
523
553
|
const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
|
|
@@ -528,6 +558,7 @@ async function handleParentMessage(message, handlers) {
|
|
|
528
558
|
sessionId: message.sessionId,
|
|
529
559
|
env: message.env,
|
|
530
560
|
recordingAvailable: message.recordingAvailable ?? false,
|
|
561
|
+
conversationHistoryAvailable: message.conversationHistoryAvailable ?? false,
|
|
531
562
|
mixAvailable: message.mixAvailable ?? false,
|
|
532
563
|
ttsPoseAvailable: message.ttsPoseAvailable ?? false
|
|
533
564
|
});
|
|
@@ -574,8 +605,10 @@ async function handleParentMessage(message, handlers) {
|
|
|
574
605
|
break;
|
|
575
606
|
case "session_end":
|
|
576
607
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
608
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
577
609
|
peerEnvBySessionId.delete(message.sessionId);
|
|
578
610
|
recordingAvailableBySessionId.delete(message.sessionId);
|
|
611
|
+
conversationHistoryAvailableBySessionId.delete(message.sessionId);
|
|
579
612
|
mixAvailableBySessionId.delete(message.sessionId);
|
|
580
613
|
ttsPoseAvailableBySessionId.delete(message.sessionId);
|
|
581
614
|
await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
|
|
@@ -597,6 +630,10 @@ function defineAgent(handlers) {
|
|
|
597
630
|
handleRecordingControlAck(message);
|
|
598
631
|
return;
|
|
599
632
|
}
|
|
633
|
+
if (isConversationHistoryControlAckMessage(message)) {
|
|
634
|
+
handleConversationHistoryControlAck(message);
|
|
635
|
+
return;
|
|
636
|
+
}
|
|
600
637
|
if (isPlayAckMessage(message)) {
|
|
601
638
|
handlePlayAck(message);
|
|
602
639
|
return;
|
|
@@ -630,6 +667,7 @@ function defineAgent(handlers) {
|
|
|
630
667
|
if (message.type === "session_end") {
|
|
631
668
|
endedSessionIds.add(message.sessionId);
|
|
632
669
|
clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
|
|
670
|
+
clearPendingConversationHistoryAcksForSession(message.sessionId, "session_ended");
|
|
633
671
|
inboundBySession.clear(message.sessionId);
|
|
634
672
|
}
|
|
635
673
|
if (message.type === "session_start") {
|