@voicethere/agent 0.7.2 → 0.7.4
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 +12 -11
- package/dist/agent.js +92 -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 +92 -4
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +45 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +285 -0
- package/dist/runtime.js.map +1 -1
- package/dist/templates/echo/agent.js +98 -1
- package/dist/templates/echo-dc/agent.js +98 -1
- package/dist/templates/game-sync/agent.js +98 -1
- package/dist/templates/positional-tts/agent.js +98 -1
- package/dist/templates/recording-consent/agent.js +98 -1
- package/dist/templates/voice-showcase/agent.js +98 -1
- package/dist/templates/voice-starter/agent.js +107 -1
- package/dist/templates/webhooks/agent.js +98 -1
- package/dist/templates/webhooks-redis/agent.js +98 -1
- package/dist/verify/lib.d.ts +1 -1
- package/dist/verify/lib.d.ts.map +1 -1
- package/dist/verify/lib.js +1 -0
- package/dist/verify/lib.js.map +1 -1
- package/package.json +5 -5
- package/templates/agent.ts +13 -0
- package/templates/mix-smoke.ts +72 -1
|
@@ -130,6 +130,24 @@ var SessionSerialQueue = class {
|
|
|
130
130
|
var SESSION_START_INIT_DELAY_ENABLED_ENV = "AGENT_SESSION_START_INIT_DELAY_ENABLED";
|
|
131
131
|
var SESSION_START_INIT_DELAY_MS_ENV = "AGENT_SESSION_START_INIT_DELAY_MS";
|
|
132
132
|
var DEFAULT_SESSION_START_INIT_DELAY_MS = 500;
|
|
133
|
+
function isPlayAckMessage(value) {
|
|
134
|
+
if (!value || typeof value !== "object")
|
|
135
|
+
return false;
|
|
136
|
+
const msg = value;
|
|
137
|
+
return msg.type === "play_ack" && typeof msg.requestId === "string";
|
|
138
|
+
}
|
|
139
|
+
function isPlayStatusAckMessage(value) {
|
|
140
|
+
if (!value || typeof value !== "object")
|
|
141
|
+
return false;
|
|
142
|
+
const msg = value;
|
|
143
|
+
return msg.type === "play_status_ack" && typeof msg.requestId === "string";
|
|
144
|
+
}
|
|
145
|
+
function isPlayStopAckMessage(value) {
|
|
146
|
+
if (!value || typeof value !== "object")
|
|
147
|
+
return false;
|
|
148
|
+
const msg = value;
|
|
149
|
+
return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
|
|
150
|
+
}
|
|
133
151
|
function isRecordingControlAckMessage(value) {
|
|
134
152
|
if (!value || typeof value !== "object")
|
|
135
153
|
return false;
|
|
@@ -190,7 +208,7 @@ function isParentMessage(value) {
|
|
|
190
208
|
if (!value || typeof value !== "object")
|
|
191
209
|
return false;
|
|
192
210
|
const msg = value;
|
|
193
|
-
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
211
|
+
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
194
212
|
}
|
|
195
213
|
function isSessionScopedParentMessage(value) {
|
|
196
214
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -207,7 +225,11 @@ var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
|
207
225
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
208
226
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
209
227
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
228
|
+
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
210
229
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
230
|
+
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
231
|
+
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
232
|
+
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
211
233
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
212
234
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
213
235
|
function handleRecordingControlAck(message) {
|
|
@@ -222,6 +244,46 @@ function handleRecordingControlAck(message) {
|
|
|
222
244
|
requestId: message.requestId
|
|
223
245
|
});
|
|
224
246
|
}
|
|
247
|
+
function handlePlayAck(message) {
|
|
248
|
+
const pending = pendingPlayAcks.get(message.requestId);
|
|
249
|
+
if (!pending)
|
|
250
|
+
return;
|
|
251
|
+
clearTimeout(pending.timer);
|
|
252
|
+
pendingPlayAcks.delete(message.requestId);
|
|
253
|
+
pending.resolve({
|
|
254
|
+
ok: message.ok,
|
|
255
|
+
...message.playId ? { playId: message.playId } : {},
|
|
256
|
+
reason: message.reason,
|
|
257
|
+
requestId: message.requestId
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function handlePlayStatusAck(message) {
|
|
261
|
+
const pending = pendingPlayStatusAcks.get(message.requestId);
|
|
262
|
+
if (!pending)
|
|
263
|
+
return;
|
|
264
|
+
clearTimeout(pending.timer);
|
|
265
|
+
pendingPlayStatusAcks.delete(message.requestId);
|
|
266
|
+
pending.resolve({
|
|
267
|
+
ok: message.ok,
|
|
268
|
+
playId: message.playId,
|
|
269
|
+
...message.status ? { status: message.status } : {},
|
|
270
|
+
reason: message.reason,
|
|
271
|
+
requestId: message.requestId
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function handlePlayStopAck(message) {
|
|
275
|
+
const pending = pendingPlayStopAcks.get(message.requestId);
|
|
276
|
+
if (!pending)
|
|
277
|
+
return;
|
|
278
|
+
clearTimeout(pending.timer);
|
|
279
|
+
pendingPlayStopAcks.delete(message.requestId);
|
|
280
|
+
pending.resolve({
|
|
281
|
+
ok: message.ok,
|
|
282
|
+
playId: message.playId,
|
|
283
|
+
reason: message.reason,
|
|
284
|
+
requestId: message.requestId
|
|
285
|
+
});
|
|
286
|
+
}
|
|
225
287
|
function handleMixControlAck(message) {
|
|
226
288
|
const pending = pendingMixAcks.get(message.requestId);
|
|
227
289
|
if (!pending)
|
|
@@ -307,6 +369,10 @@ function sendParentMessage(message) {
|
|
|
307
369
|
process.send?.(message);
|
|
308
370
|
return;
|
|
309
371
|
}
|
|
372
|
+
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
|
|
373
|
+
process.send?.(message);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
310
376
|
const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
|
|
311
377
|
if (!allowOutboundForSession(sessionId))
|
|
312
378
|
return;
|
|
@@ -382,6 +448,16 @@ async function handleWebhookMessage(message, handlers) {
|
|
|
382
448
|
});
|
|
383
449
|
}
|
|
384
450
|
}
|
|
451
|
+
function resolveUserLanguageCode(event) {
|
|
452
|
+
const withLanguage = event;
|
|
453
|
+
const candidates = [withLanguage.language, event.text];
|
|
454
|
+
for (const value of candidates) {
|
|
455
|
+
if (typeof value === "string" && value.trim()) {
|
|
456
|
+
return value.trim();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return void 0;
|
|
460
|
+
}
|
|
385
461
|
async function handleParentMessage(message, handlers) {
|
|
386
462
|
switch (message.type) {
|
|
387
463
|
case "session_start":
|
|
@@ -414,6 +490,15 @@ async function handleParentMessage(message, handlers) {
|
|
|
414
490
|
text: message.event.text.trim()
|
|
415
491
|
});
|
|
416
492
|
}
|
|
493
|
+
if (message.event.type === "user_language") {
|
|
494
|
+
const language = resolveUserLanguageCode(message.event);
|
|
495
|
+
if (language) {
|
|
496
|
+
await handlers.onUserLanguage?.({
|
|
497
|
+
sessionId: message.sessionId,
|
|
498
|
+
language
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
417
502
|
break;
|
|
418
503
|
case "data_channel_message":
|
|
419
504
|
await handlers.onDataChannelMessage?.({
|
|
@@ -458,6 +543,18 @@ function defineAgent(handlers) {
|
|
|
458
543
|
handleRecordingControlAck(message);
|
|
459
544
|
return;
|
|
460
545
|
}
|
|
546
|
+
if (isPlayAckMessage(message)) {
|
|
547
|
+
handlePlayAck(message);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (isPlayStatusAckMessage(message)) {
|
|
551
|
+
handlePlayStatusAck(message);
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
if (isPlayStopAckMessage(message)) {
|
|
555
|
+
handlePlayStopAck(message);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
461
558
|
if (isMixControlAckMessage(message)) {
|
|
462
559
|
handleMixControlAck(message);
|
|
463
560
|
return;
|
|
@@ -130,6 +130,24 @@ var SessionSerialQueue = class {
|
|
|
130
130
|
var SESSION_START_INIT_DELAY_ENABLED_ENV = "AGENT_SESSION_START_INIT_DELAY_ENABLED";
|
|
131
131
|
var SESSION_START_INIT_DELAY_MS_ENV = "AGENT_SESSION_START_INIT_DELAY_MS";
|
|
132
132
|
var DEFAULT_SESSION_START_INIT_DELAY_MS = 500;
|
|
133
|
+
function isPlayAckMessage(value) {
|
|
134
|
+
if (!value || typeof value !== "object")
|
|
135
|
+
return false;
|
|
136
|
+
const msg = value;
|
|
137
|
+
return msg.type === "play_ack" && typeof msg.requestId === "string";
|
|
138
|
+
}
|
|
139
|
+
function isPlayStatusAckMessage(value) {
|
|
140
|
+
if (!value || typeof value !== "object")
|
|
141
|
+
return false;
|
|
142
|
+
const msg = value;
|
|
143
|
+
return msg.type === "play_status_ack" && typeof msg.requestId === "string";
|
|
144
|
+
}
|
|
145
|
+
function isPlayStopAckMessage(value) {
|
|
146
|
+
if (!value || typeof value !== "object")
|
|
147
|
+
return false;
|
|
148
|
+
const msg = value;
|
|
149
|
+
return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
|
|
150
|
+
}
|
|
133
151
|
function isRecordingControlAckMessage(value) {
|
|
134
152
|
if (!value || typeof value !== "object")
|
|
135
153
|
return false;
|
|
@@ -190,7 +208,7 @@ function isParentMessage(value) {
|
|
|
190
208
|
if (!value || typeof value !== "object")
|
|
191
209
|
return false;
|
|
192
210
|
const msg = value;
|
|
193
|
-
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
211
|
+
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
194
212
|
}
|
|
195
213
|
function isSessionScopedParentMessage(value) {
|
|
196
214
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -207,7 +225,11 @@ var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
|
207
225
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
208
226
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
209
227
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
228
|
+
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
210
229
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
230
|
+
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
231
|
+
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
232
|
+
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
211
233
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
212
234
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
213
235
|
function handleRecordingControlAck(message) {
|
|
@@ -222,6 +244,46 @@ function handleRecordingControlAck(message) {
|
|
|
222
244
|
requestId: message.requestId
|
|
223
245
|
});
|
|
224
246
|
}
|
|
247
|
+
function handlePlayAck(message) {
|
|
248
|
+
const pending = pendingPlayAcks.get(message.requestId);
|
|
249
|
+
if (!pending)
|
|
250
|
+
return;
|
|
251
|
+
clearTimeout(pending.timer);
|
|
252
|
+
pendingPlayAcks.delete(message.requestId);
|
|
253
|
+
pending.resolve({
|
|
254
|
+
ok: message.ok,
|
|
255
|
+
...message.playId ? { playId: message.playId } : {},
|
|
256
|
+
reason: message.reason,
|
|
257
|
+
requestId: message.requestId
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function handlePlayStatusAck(message) {
|
|
261
|
+
const pending = pendingPlayStatusAcks.get(message.requestId);
|
|
262
|
+
if (!pending)
|
|
263
|
+
return;
|
|
264
|
+
clearTimeout(pending.timer);
|
|
265
|
+
pendingPlayStatusAcks.delete(message.requestId);
|
|
266
|
+
pending.resolve({
|
|
267
|
+
ok: message.ok,
|
|
268
|
+
playId: message.playId,
|
|
269
|
+
...message.status ? { status: message.status } : {},
|
|
270
|
+
reason: message.reason,
|
|
271
|
+
requestId: message.requestId
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function handlePlayStopAck(message) {
|
|
275
|
+
const pending = pendingPlayStopAcks.get(message.requestId);
|
|
276
|
+
if (!pending)
|
|
277
|
+
return;
|
|
278
|
+
clearTimeout(pending.timer);
|
|
279
|
+
pendingPlayStopAcks.delete(message.requestId);
|
|
280
|
+
pending.resolve({
|
|
281
|
+
ok: message.ok,
|
|
282
|
+
playId: message.playId,
|
|
283
|
+
reason: message.reason,
|
|
284
|
+
requestId: message.requestId
|
|
285
|
+
});
|
|
286
|
+
}
|
|
225
287
|
function handleMixControlAck(message) {
|
|
226
288
|
const pending = pendingMixAcks.get(message.requestId);
|
|
227
289
|
if (!pending)
|
|
@@ -307,6 +369,10 @@ function sendParentMessage(message) {
|
|
|
307
369
|
process.send?.(message);
|
|
308
370
|
return;
|
|
309
371
|
}
|
|
372
|
+
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
|
|
373
|
+
process.send?.(message);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
310
376
|
const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
|
|
311
377
|
if (!allowOutboundForSession(sessionId))
|
|
312
378
|
return;
|
|
@@ -382,6 +448,16 @@ async function handleWebhookMessage(message, handlers) {
|
|
|
382
448
|
});
|
|
383
449
|
}
|
|
384
450
|
}
|
|
451
|
+
function resolveUserLanguageCode(event) {
|
|
452
|
+
const withLanguage = event;
|
|
453
|
+
const candidates = [withLanguage.language, event.text];
|
|
454
|
+
for (const value of candidates) {
|
|
455
|
+
if (typeof value === "string" && value.trim()) {
|
|
456
|
+
return value.trim();
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return void 0;
|
|
460
|
+
}
|
|
385
461
|
async function handleParentMessage(message, handlers) {
|
|
386
462
|
switch (message.type) {
|
|
387
463
|
case "session_start":
|
|
@@ -414,6 +490,15 @@ async function handleParentMessage(message, handlers) {
|
|
|
414
490
|
text: message.event.text.trim()
|
|
415
491
|
});
|
|
416
492
|
}
|
|
493
|
+
if (message.event.type === "user_language") {
|
|
494
|
+
const language = resolveUserLanguageCode(message.event);
|
|
495
|
+
if (language) {
|
|
496
|
+
await handlers.onUserLanguage?.({
|
|
497
|
+
sessionId: message.sessionId,
|
|
498
|
+
language
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
417
502
|
break;
|
|
418
503
|
case "data_channel_message":
|
|
419
504
|
await handlers.onDataChannelMessage?.({
|
|
@@ -458,6 +543,18 @@ function defineAgent(handlers) {
|
|
|
458
543
|
handleRecordingControlAck(message);
|
|
459
544
|
return;
|
|
460
545
|
}
|
|
546
|
+
if (isPlayAckMessage(message)) {
|
|
547
|
+
handlePlayAck(message);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
if (isPlayStatusAckMessage(message)) {
|
|
551
|
+
handlePlayStatusAck(message);
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
if (isPlayStopAckMessage(message)) {
|
|
555
|
+
handlePlayStopAck(message);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
461
558
|
if (isMixControlAckMessage(message)) {
|
|
462
559
|
handleMixControlAck(message);
|
|
463
560
|
return;
|
|
@@ -674,6 +771,8 @@ function peerState(sessionId) {
|
|
|
674
771
|
return state;
|
|
675
772
|
}
|
|
676
773
|
function formatSpeechDetail(speech) {
|
|
774
|
+
const language = speech.language;
|
|
775
|
+
if (language) return language;
|
|
677
776
|
if (speech.text) return `"${speech.text}"`;
|
|
678
777
|
if (speech.error) return speech.error;
|
|
679
778
|
return "";
|
|
@@ -681,6 +780,10 @@ function formatSpeechDetail(speech) {
|
|
|
681
780
|
function handleSpeechEvent(sessionId, speech) {
|
|
682
781
|
const state = peerState(sessionId);
|
|
683
782
|
const detail = formatSpeechDetail(speech);
|
|
783
|
+
if (speech.type === "user_language") {
|
|
784
|
+
agentLog("info", `[${sessionId}] user_language ${detail}`);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
684
787
|
switch (speech.type) {
|
|
685
788
|
// --- User turn (VAD + STT) ---
|
|
686
789
|
case "user_speaking_start":
|
|
@@ -767,6 +870,9 @@ defineAgent({
|
|
|
767
870
|
onUserSpeechFinal({ sessionId, text }) {
|
|
768
871
|
speak(sessionId, `You said: ${text}`);
|
|
769
872
|
},
|
|
873
|
+
onUserLanguage({ sessionId, language }) {
|
|
874
|
+
agentLog("info", `user_language ${sessionId} ${language}`);
|
|
875
|
+
},
|
|
770
876
|
onSessionEnd({ sessionId }) {
|
|
771
877
|
peers.delete(sessionId);
|
|
772
878
|
agentLog("info", `session_end ${sessionId}`);
|
|
@@ -133,6 +133,24 @@ var SessionSerialQueue = class {
|
|
|
133
133
|
var SESSION_START_INIT_DELAY_ENABLED_ENV = "AGENT_SESSION_START_INIT_DELAY_ENABLED";
|
|
134
134
|
var SESSION_START_INIT_DELAY_MS_ENV = "AGENT_SESSION_START_INIT_DELAY_MS";
|
|
135
135
|
var DEFAULT_SESSION_START_INIT_DELAY_MS = 500;
|
|
136
|
+
function isPlayAckMessage(value) {
|
|
137
|
+
if (!value || typeof value !== "object")
|
|
138
|
+
return false;
|
|
139
|
+
const msg = value;
|
|
140
|
+
return msg.type === "play_ack" && typeof msg.requestId === "string";
|
|
141
|
+
}
|
|
142
|
+
function isPlayStatusAckMessage(value) {
|
|
143
|
+
if (!value || typeof value !== "object")
|
|
144
|
+
return false;
|
|
145
|
+
const msg = value;
|
|
146
|
+
return msg.type === "play_status_ack" && typeof msg.requestId === "string";
|
|
147
|
+
}
|
|
148
|
+
function isPlayStopAckMessage(value) {
|
|
149
|
+
if (!value || typeof value !== "object")
|
|
150
|
+
return false;
|
|
151
|
+
const msg = value;
|
|
152
|
+
return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
|
|
153
|
+
}
|
|
136
154
|
function isRecordingControlAckMessage(value) {
|
|
137
155
|
if (!value || typeof value !== "object")
|
|
138
156
|
return false;
|
|
@@ -193,7 +211,7 @@ function isParentMessage(value) {
|
|
|
193
211
|
if (!value || typeof value !== "object")
|
|
194
212
|
return false;
|
|
195
213
|
const msg = value;
|
|
196
|
-
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
214
|
+
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
197
215
|
}
|
|
198
216
|
function isSessionScopedParentMessage(value) {
|
|
199
217
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -210,7 +228,11 @@ var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
|
210
228
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
211
229
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
212
230
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
231
|
+
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
213
232
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
233
|
+
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
234
|
+
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
235
|
+
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
214
236
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
215
237
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
216
238
|
function handleRecordingControlAck(message) {
|
|
@@ -225,6 +247,46 @@ function handleRecordingControlAck(message) {
|
|
|
225
247
|
requestId: message.requestId
|
|
226
248
|
});
|
|
227
249
|
}
|
|
250
|
+
function handlePlayAck(message) {
|
|
251
|
+
const pending = pendingPlayAcks.get(message.requestId);
|
|
252
|
+
if (!pending)
|
|
253
|
+
return;
|
|
254
|
+
clearTimeout(pending.timer);
|
|
255
|
+
pendingPlayAcks.delete(message.requestId);
|
|
256
|
+
pending.resolve({
|
|
257
|
+
ok: message.ok,
|
|
258
|
+
...message.playId ? { playId: message.playId } : {},
|
|
259
|
+
reason: message.reason,
|
|
260
|
+
requestId: message.requestId
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
function handlePlayStatusAck(message) {
|
|
264
|
+
const pending = pendingPlayStatusAcks.get(message.requestId);
|
|
265
|
+
if (!pending)
|
|
266
|
+
return;
|
|
267
|
+
clearTimeout(pending.timer);
|
|
268
|
+
pendingPlayStatusAcks.delete(message.requestId);
|
|
269
|
+
pending.resolve({
|
|
270
|
+
ok: message.ok,
|
|
271
|
+
playId: message.playId,
|
|
272
|
+
...message.status ? { status: message.status } : {},
|
|
273
|
+
reason: message.reason,
|
|
274
|
+
requestId: message.requestId
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function handlePlayStopAck(message) {
|
|
278
|
+
const pending = pendingPlayStopAcks.get(message.requestId);
|
|
279
|
+
if (!pending)
|
|
280
|
+
return;
|
|
281
|
+
clearTimeout(pending.timer);
|
|
282
|
+
pendingPlayStopAcks.delete(message.requestId);
|
|
283
|
+
pending.resolve({
|
|
284
|
+
ok: message.ok,
|
|
285
|
+
playId: message.playId,
|
|
286
|
+
reason: message.reason,
|
|
287
|
+
requestId: message.requestId
|
|
288
|
+
});
|
|
289
|
+
}
|
|
228
290
|
function handleMixControlAck(message) {
|
|
229
291
|
const pending = pendingMixAcks.get(message.requestId);
|
|
230
292
|
if (!pending)
|
|
@@ -310,6 +372,10 @@ function sendParentMessage(message) {
|
|
|
310
372
|
process.send?.(message);
|
|
311
373
|
return;
|
|
312
374
|
}
|
|
375
|
+
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
|
|
376
|
+
process.send?.(message);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
313
379
|
const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
|
|
314
380
|
if (!allowOutboundForSession(sessionId))
|
|
315
381
|
return;
|
|
@@ -385,6 +451,16 @@ async function handleWebhookMessage(message, handlers) {
|
|
|
385
451
|
});
|
|
386
452
|
}
|
|
387
453
|
}
|
|
454
|
+
function resolveUserLanguageCode(event) {
|
|
455
|
+
const withLanguage = event;
|
|
456
|
+
const candidates = [withLanguage.language, event.text];
|
|
457
|
+
for (const value of candidates) {
|
|
458
|
+
if (typeof value === "string" && value.trim()) {
|
|
459
|
+
return value.trim();
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
return void 0;
|
|
463
|
+
}
|
|
388
464
|
async function handleParentMessage(message, handlers) {
|
|
389
465
|
switch (message.type) {
|
|
390
466
|
case "session_start":
|
|
@@ -417,6 +493,15 @@ async function handleParentMessage(message, handlers) {
|
|
|
417
493
|
text: message.event.text.trim()
|
|
418
494
|
});
|
|
419
495
|
}
|
|
496
|
+
if (message.event.type === "user_language") {
|
|
497
|
+
const language = resolveUserLanguageCode(message.event);
|
|
498
|
+
if (language) {
|
|
499
|
+
await handlers.onUserLanguage?.({
|
|
500
|
+
sessionId: message.sessionId,
|
|
501
|
+
language
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
420
505
|
break;
|
|
421
506
|
case "data_channel_message":
|
|
422
507
|
await handlers.onDataChannelMessage?.({
|
|
@@ -461,6 +546,18 @@ function defineAgent(handlers) {
|
|
|
461
546
|
handleRecordingControlAck(message);
|
|
462
547
|
return;
|
|
463
548
|
}
|
|
549
|
+
if (isPlayAckMessage(message)) {
|
|
550
|
+
handlePlayAck(message);
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
if (isPlayStatusAckMessage(message)) {
|
|
554
|
+
handlePlayStatusAck(message);
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
if (isPlayStopAckMessage(message)) {
|
|
558
|
+
handlePlayStopAck(message);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
464
561
|
if (isMixControlAckMessage(message)) {
|
|
465
562
|
handleMixControlAck(message);
|
|
466
563
|
return;
|
|
@@ -10885,6 +10885,24 @@ var SessionSerialQueue = class {
|
|
|
10885
10885
|
var SESSION_START_INIT_DELAY_ENABLED_ENV = "AGENT_SESSION_START_INIT_DELAY_ENABLED";
|
|
10886
10886
|
var SESSION_START_INIT_DELAY_MS_ENV = "AGENT_SESSION_START_INIT_DELAY_MS";
|
|
10887
10887
|
var DEFAULT_SESSION_START_INIT_DELAY_MS = 500;
|
|
10888
|
+
function isPlayAckMessage(value) {
|
|
10889
|
+
if (!value || typeof value !== "object")
|
|
10890
|
+
return false;
|
|
10891
|
+
const msg = value;
|
|
10892
|
+
return msg.type === "play_ack" && typeof msg.requestId === "string";
|
|
10893
|
+
}
|
|
10894
|
+
function isPlayStatusAckMessage(value) {
|
|
10895
|
+
if (!value || typeof value !== "object")
|
|
10896
|
+
return false;
|
|
10897
|
+
const msg = value;
|
|
10898
|
+
return msg.type === "play_status_ack" && typeof msg.requestId === "string";
|
|
10899
|
+
}
|
|
10900
|
+
function isPlayStopAckMessage(value) {
|
|
10901
|
+
if (!value || typeof value !== "object")
|
|
10902
|
+
return false;
|
|
10903
|
+
const msg = value;
|
|
10904
|
+
return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
|
|
10905
|
+
}
|
|
10888
10906
|
function isRecordingControlAckMessage(value) {
|
|
10889
10907
|
if (!value || typeof value !== "object")
|
|
10890
10908
|
return false;
|
|
@@ -10945,7 +10963,7 @@ function isParentMessage(value) {
|
|
|
10945
10963
|
if (!value || typeof value !== "object")
|
|
10946
10964
|
return false;
|
|
10947
10965
|
const msg = value;
|
|
10948
|
-
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
10966
|
+
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 === "mix_control_ack" || msg.type === "stt_control_ack" || msg.type === "webhook";
|
|
10949
10967
|
}
|
|
10950
10968
|
function isSessionScopedParentMessage(value) {
|
|
10951
10969
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -10962,7 +10980,11 @@ var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
|
10962
10980
|
var mixAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
10963
10981
|
var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
|
|
10964
10982
|
var endedSessionIds = /* @__PURE__ */ new Set();
|
|
10983
|
+
var PLAY_BYTES_MAX_DECODED_LENGTH = 64 * 1024;
|
|
10965
10984
|
var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
10985
|
+
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
10986
|
+
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
10987
|
+
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
10966
10988
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
10967
10989
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
10968
10990
|
function handleRecordingControlAck(message) {
|
|
@@ -10977,6 +10999,46 @@ function handleRecordingControlAck(message) {
|
|
|
10977
10999
|
requestId: message.requestId
|
|
10978
11000
|
});
|
|
10979
11001
|
}
|
|
11002
|
+
function handlePlayAck(message) {
|
|
11003
|
+
const pending = pendingPlayAcks.get(message.requestId);
|
|
11004
|
+
if (!pending)
|
|
11005
|
+
return;
|
|
11006
|
+
clearTimeout(pending.timer);
|
|
11007
|
+
pendingPlayAcks.delete(message.requestId);
|
|
11008
|
+
pending.resolve({
|
|
11009
|
+
ok: message.ok,
|
|
11010
|
+
...message.playId ? { playId: message.playId } : {},
|
|
11011
|
+
reason: message.reason,
|
|
11012
|
+
requestId: message.requestId
|
|
11013
|
+
});
|
|
11014
|
+
}
|
|
11015
|
+
function handlePlayStatusAck(message) {
|
|
11016
|
+
const pending = pendingPlayStatusAcks.get(message.requestId);
|
|
11017
|
+
if (!pending)
|
|
11018
|
+
return;
|
|
11019
|
+
clearTimeout(pending.timer);
|
|
11020
|
+
pendingPlayStatusAcks.delete(message.requestId);
|
|
11021
|
+
pending.resolve({
|
|
11022
|
+
ok: message.ok,
|
|
11023
|
+
playId: message.playId,
|
|
11024
|
+
...message.status ? { status: message.status } : {},
|
|
11025
|
+
reason: message.reason,
|
|
11026
|
+
requestId: message.requestId
|
|
11027
|
+
});
|
|
11028
|
+
}
|
|
11029
|
+
function handlePlayStopAck(message) {
|
|
11030
|
+
const pending = pendingPlayStopAcks.get(message.requestId);
|
|
11031
|
+
if (!pending)
|
|
11032
|
+
return;
|
|
11033
|
+
clearTimeout(pending.timer);
|
|
11034
|
+
pendingPlayStopAcks.delete(message.requestId);
|
|
11035
|
+
pending.resolve({
|
|
11036
|
+
ok: message.ok,
|
|
11037
|
+
playId: message.playId,
|
|
11038
|
+
reason: message.reason,
|
|
11039
|
+
requestId: message.requestId
|
|
11040
|
+
});
|
|
11041
|
+
}
|
|
10980
11042
|
function handleMixControlAck(message) {
|
|
10981
11043
|
const pending = pendingMixAcks.get(message.requestId);
|
|
10982
11044
|
if (!pending)
|
|
@@ -11062,6 +11124,10 @@ function sendParentMessage(message) {
|
|
|
11062
11124
|
process.send?.(message);
|
|
11063
11125
|
return;
|
|
11064
11126
|
}
|
|
11127
|
+
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
|
|
11128
|
+
process.send?.(message);
|
|
11129
|
+
return;
|
|
11130
|
+
}
|
|
11065
11131
|
const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
|
|
11066
11132
|
if (!allowOutboundForSession(sessionId))
|
|
11067
11133
|
return;
|
|
@@ -11137,6 +11203,16 @@ async function handleWebhookMessage(message, handlers) {
|
|
|
11137
11203
|
});
|
|
11138
11204
|
}
|
|
11139
11205
|
}
|
|
11206
|
+
function resolveUserLanguageCode(event) {
|
|
11207
|
+
const withLanguage = event;
|
|
11208
|
+
const candidates = [withLanguage.language, event.text];
|
|
11209
|
+
for (const value of candidates) {
|
|
11210
|
+
if (typeof value === "string" && value.trim()) {
|
|
11211
|
+
return value.trim();
|
|
11212
|
+
}
|
|
11213
|
+
}
|
|
11214
|
+
return void 0;
|
|
11215
|
+
}
|
|
11140
11216
|
async function handleParentMessage(message, handlers) {
|
|
11141
11217
|
switch (message.type) {
|
|
11142
11218
|
case "session_start":
|
|
@@ -11169,6 +11245,15 @@ async function handleParentMessage(message, handlers) {
|
|
|
11169
11245
|
text: message.event.text.trim()
|
|
11170
11246
|
});
|
|
11171
11247
|
}
|
|
11248
|
+
if (message.event.type === "user_language") {
|
|
11249
|
+
const language = resolveUserLanguageCode(message.event);
|
|
11250
|
+
if (language) {
|
|
11251
|
+
await handlers.onUserLanguage?.({
|
|
11252
|
+
sessionId: message.sessionId,
|
|
11253
|
+
language
|
|
11254
|
+
});
|
|
11255
|
+
}
|
|
11256
|
+
}
|
|
11172
11257
|
break;
|
|
11173
11258
|
case "data_channel_message":
|
|
11174
11259
|
await handlers.onDataChannelMessage?.({
|
|
@@ -11213,6 +11298,18 @@ function defineAgent(handlers) {
|
|
|
11213
11298
|
handleRecordingControlAck(message);
|
|
11214
11299
|
return;
|
|
11215
11300
|
}
|
|
11301
|
+
if (isPlayAckMessage(message)) {
|
|
11302
|
+
handlePlayAck(message);
|
|
11303
|
+
return;
|
|
11304
|
+
}
|
|
11305
|
+
if (isPlayStatusAckMessage(message)) {
|
|
11306
|
+
handlePlayStatusAck(message);
|
|
11307
|
+
return;
|
|
11308
|
+
}
|
|
11309
|
+
if (isPlayStopAckMessage(message)) {
|
|
11310
|
+
handlePlayStopAck(message);
|
|
11311
|
+
return;
|
|
11312
|
+
}
|
|
11216
11313
|
if (isMixControlAckMessage(message)) {
|
|
11217
11314
|
handleMixControlAck(message);
|
|
11218
11315
|
return;
|
package/dist/verify/lib.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ChildToParentMessage } from "../protocol.js";
|
|
|
2
2
|
export declare const VERIFY_SESSION_ID = "local-verify";
|
|
3
3
|
export declare const DEFAULT_VERIFY_BUNDLE = "dist/agent.js";
|
|
4
4
|
export declare const DEFAULT_VERIFY_ENTRY = "agent.ts";
|
|
5
|
-
export declare const VERIFY_CALLBACK_KEYS: readonly ["onSpeechEvent", "onUserSpeechFinal", "onDataChannelMessage", "onDataChannelBinary", "onWebhook", "onSessionStart"];
|
|
5
|
+
export declare const VERIFY_CALLBACK_KEYS: readonly ["onSpeechEvent", "onUserSpeechFinal", "onUserLanguage", "onDataChannelMessage", "onDataChannelBinary", "onWebhook", "onSessionStart"];
|
|
6
6
|
export type VerifyCallbackKey = (typeof VERIFY_CALLBACK_KEYS)[number];
|
|
7
7
|
export declare function parseBundleArg(argv: string[], env?: NodeJS.ProcessEnv, cwd?: string): string;
|
|
8
8
|
export declare function waitForSpeak(messages: ChildToParentMessage[], sessionId: string, timeoutMs: number): Promise<Extract<ChildToParentMessage, {
|
package/dist/verify/lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/verify/lib.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AACrD,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAC/C,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/verify/lib.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AACrD,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAC/C,eAAO,MAAM,oBAAoB,iJAQvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAWR;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAuB3D;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAAC,CAyBvE;AAED,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,iBAAiB,EAAE,CAqBrB;AAED,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAExE"}
|