@voicethere/agent 0.6.0 → 0.7.0

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.
@@ -136,6 +136,18 @@ function isRecordingControlAckMessage(value) {
136
136
  const msg = value;
137
137
  return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
138
138
  }
139
+ function isMixControlAckMessage(value) {
140
+ if (!value || typeof value !== "object")
141
+ return false;
142
+ const msg = value;
143
+ return msg.type === "mix_control_ack" && typeof msg.requestId === "string";
144
+ }
145
+ function isSttControlAckMessage(value) {
146
+ if (!value || typeof value !== "object")
147
+ return false;
148
+ const msg = value;
149
+ return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
150
+ }
139
151
  function isWebhookMessage(value) {
140
152
  if (!value || typeof value !== "object")
141
153
  return false;
@@ -178,7 +190,7 @@ function isParentMessage(value) {
178
190
  if (!value || typeof value !== "object")
179
191
  return false;
180
192
  const msg = value;
181
- 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 === "webhook";
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";
182
194
  }
183
195
  function isSessionScopedParentMessage(value) {
184
196
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -192,9 +204,13 @@ function parseDataChannelPayload(raw) {
192
204
  }
193
205
  var peerEnvBySessionId = /* @__PURE__ */ new Map();
194
206
  var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
207
+ var mixAvailableBySessionId = /* @__PURE__ */ new Map();
208
+ var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
195
209
  var endedSessionIds = /* @__PURE__ */ new Set();
196
210
  var RECORDING_CONTROL_ACK_TIMEOUT_MS = 5e3;
197
211
  var pendingRecordingAcks = /* @__PURE__ */ new Map();
212
+ var pendingMixAcks = /* @__PURE__ */ new Map();
213
+ var pendingSttAcks = /* @__PURE__ */ new Map();
198
214
  function handleRecordingControlAck(message) {
199
215
  const pending = pendingRecordingAcks.get(message.requestId);
200
216
  if (!pending)
@@ -207,6 +223,30 @@ function handleRecordingControlAck(message) {
207
223
  requestId: message.requestId
208
224
  });
209
225
  }
226
+ function handleMixControlAck(message) {
227
+ const pending = pendingMixAcks.get(message.requestId);
228
+ if (!pending)
229
+ return;
230
+ clearTimeout(pending.timer);
231
+ pendingMixAcks.delete(message.requestId);
232
+ pending.resolve({
233
+ ok: message.ok,
234
+ reason: message.reason,
235
+ requestId: message.requestId
236
+ });
237
+ }
238
+ function handleSttControlAck(message) {
239
+ const pending = pendingSttAcks.get(message.requestId);
240
+ if (!pending)
241
+ return;
242
+ clearTimeout(pending.timer);
243
+ pendingSttAcks.delete(message.requestId);
244
+ pending.resolve({
245
+ ok: message.ok,
246
+ reason: message.reason,
247
+ requestId: message.requestId
248
+ });
249
+ }
210
250
  function clearPendingRecordingAcksForSession(sessionId, reason) {
211
251
  for (const [requestId, pending] of pendingRecordingAcks) {
212
252
  if (pending.sessionId !== sessionId)
@@ -265,6 +305,11 @@ function allowOutboundForSession(sessionId) {
265
305
  return queue.isLive(sessionId);
266
306
  }
267
307
  function sendParentMessage(message) {
308
+ const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
309
+ if (msgType === "mix_control" || msgType === "stt_control") {
310
+ process.send?.(message);
311
+ return;
312
+ }
268
313
  const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
269
314
  if (!allowOutboundForSession(sessionId))
270
315
  return;
@@ -346,6 +391,8 @@ async function handleParentMessage(message, handlers) {
346
391
  endedSessionIds.delete(message.sessionId);
347
392
  peerEnvBySessionId.set(message.sessionId, message.env);
348
393
  recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
394
+ mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
395
+ ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
349
396
  const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
350
397
  if (sessionStartInitDelayMs > 0) {
351
398
  await new Promise((resolve) => setTimeout(resolve, sessionStartInitDelayMs));
@@ -353,7 +400,9 @@ async function handleParentMessage(message, handlers) {
353
400
  await (handlers.onClientJoin ?? handlers.onSessionStart)?.({
354
401
  sessionId: message.sessionId,
355
402
  env: message.env,
356
- recordingAvailable: message.recordingAvailable ?? false
403
+ recordingAvailable: message.recordingAvailable ?? false,
404
+ mixAvailable: message.mixAvailable ?? false,
405
+ ttsPoseAvailable: message.ttsPoseAvailable ?? false
357
406
  });
358
407
  sendParentMessage({
359
408
  type: "session_start_ack",
@@ -391,6 +440,8 @@ async function handleParentMessage(message, handlers) {
391
440
  clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
392
441
  peerEnvBySessionId.delete(message.sessionId);
393
442
  recordingAvailableBySessionId.delete(message.sessionId);
443
+ mixAvailableBySessionId.delete(message.sessionId);
444
+ ttsPoseAvailableBySessionId.delete(message.sessionId);
394
445
  await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
395
446
  sessionId: message.sessionId
396
447
  });
@@ -410,6 +461,14 @@ function defineAgent(handlers) {
410
461
  handleRecordingControlAck(message);
411
462
  return;
412
463
  }
464
+ if (isMixControlAckMessage(message)) {
465
+ handleMixControlAck(message);
466
+ return;
467
+ }
468
+ if (isSttControlAckMessage(message)) {
469
+ handleSttControlAck(message);
470
+ return;
471
+ }
413
472
  if (isWebhookMessage(message)) {
414
473
  void agentStartReady.then(() => handleWebhookMessage(message, handlers));
415
474
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,uBAAuB,EA6HpD,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAMrE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,eAAe,CAEnE;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,CAMnE;AAED,wBAAgB,yBAAyB,IAAI,uBAAuB,EAAE,CAErE"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,KAAK,CAAC;AAE7C,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,mFAAmF;IACnF,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,SAAS,uBAAuB,EA+IpD,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAMrE,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,eAAe,CAEnE;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,CAMnE;AAED,wBAAgB,yBAAyB,IAAI,uBAAuB,EAAE,CAErE"}
@@ -63,6 +63,14 @@ export const AGENT_TEMPLATES = [
63
63
  "recording-consent/conversation.ts",
64
64
  ],
65
65
  },
66
+ {
67
+ id: "positional-tts",
68
+ entry: "positional-tts/agent.ts",
69
+ kind: "product",
70
+ seedOnCreate: true,
71
+ description: "Voice+Data demo — TTS speaker orbits each listener with per-client setTtsPose.",
72
+ sourceFiles: ["positional-tts/agent.ts", "positional-tts/orbit.ts"],
73
+ },
66
74
  {
67
75
  id: "webhooks",
68
76
  entry: "webhooks.ts",
@@ -111,6 +119,14 @@ export const AGENT_TEMPLATES = [
111
119
  description: "Redis-backed world buffer sync for redis-sync-smoke (Advanced tier + project Redis).",
112
120
  sourceFiles: ["redis-sync/agent.ts", "redis-sync/world-layout.ts"],
113
121
  },
122
+ {
123
+ id: "mix-smoke",
124
+ entry: "mix-smoke.ts",
125
+ kind: "e2e",
126
+ seedOnCreate: false,
127
+ description: "Positional mix DC commands for voice-data-mix-smoke (Voice+Data, shared child).",
128
+ sourceFiles: ["mix-smoke.ts"],
129
+ },
114
130
  ];
115
131
  const TEMPLATE_BY_ID = new Map(AGENT_TEMPLATES.map((template) => [template.id, template]));
116
132
  export function isAgentTemplateId(id) {
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"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"}
@@ -136,6 +136,18 @@ function isRecordingControlAckMessage(value) {
136
136
  const msg = value;
137
137
  return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
138
138
  }
139
+ function isMixControlAckMessage(value) {
140
+ if (!value || typeof value !== "object")
141
+ return false;
142
+ const msg = value;
143
+ return msg.type === "mix_control_ack" && typeof msg.requestId === "string";
144
+ }
145
+ function isSttControlAckMessage(value) {
146
+ if (!value || typeof value !== "object")
147
+ return false;
148
+ const msg = value;
149
+ return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
150
+ }
139
151
  function isWebhookMessage(value) {
140
152
  if (!value || typeof value !== "object")
141
153
  return false;
@@ -178,7 +190,7 @@ function isParentMessage(value) {
178
190
  if (!value || typeof value !== "object")
179
191
  return false;
180
192
  const msg = value;
181
- 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 === "webhook";
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";
182
194
  }
183
195
  function isSessionScopedParentMessage(value) {
184
196
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -192,8 +204,12 @@ function parseDataChannelPayload(raw) {
192
204
  }
193
205
  var peerEnvBySessionId = /* @__PURE__ */ new Map();
194
206
  var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
207
+ var mixAvailableBySessionId = /* @__PURE__ */ new Map();
208
+ var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
195
209
  var endedSessionIds = /* @__PURE__ */ new Set();
196
210
  var pendingRecordingAcks = /* @__PURE__ */ new Map();
211
+ var pendingMixAcks = /* @__PURE__ */ new Map();
212
+ var pendingSttAcks = /* @__PURE__ */ new Map();
197
213
  function handleRecordingControlAck(message) {
198
214
  const pending = pendingRecordingAcks.get(message.requestId);
199
215
  if (!pending)
@@ -206,6 +222,30 @@ function handleRecordingControlAck(message) {
206
222
  requestId: message.requestId
207
223
  });
208
224
  }
225
+ function handleMixControlAck(message) {
226
+ const pending = pendingMixAcks.get(message.requestId);
227
+ if (!pending)
228
+ return;
229
+ clearTimeout(pending.timer);
230
+ pendingMixAcks.delete(message.requestId);
231
+ pending.resolve({
232
+ ok: message.ok,
233
+ reason: message.reason,
234
+ requestId: message.requestId
235
+ });
236
+ }
237
+ function handleSttControlAck(message) {
238
+ const pending = pendingSttAcks.get(message.requestId);
239
+ if (!pending)
240
+ return;
241
+ clearTimeout(pending.timer);
242
+ pendingSttAcks.delete(message.requestId);
243
+ pending.resolve({
244
+ ok: message.ok,
245
+ reason: message.reason,
246
+ requestId: message.requestId
247
+ });
248
+ }
209
249
  function clearPendingRecordingAcksForSession(sessionId, reason) {
210
250
  for (const [requestId, pending] of pendingRecordingAcks) {
211
251
  if (pending.sessionId !== sessionId)
@@ -261,6 +301,11 @@ function allowOutboundForSession(sessionId) {
261
301
  return queue.isLive(sessionId);
262
302
  }
263
303
  function sendParentMessage(message) {
304
+ const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
305
+ if (msgType === "mix_control" || msgType === "stt_control") {
306
+ process.send?.(message);
307
+ return;
308
+ }
264
309
  const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
265
310
  if (!allowOutboundForSession(sessionId))
266
311
  return;
@@ -342,6 +387,8 @@ async function handleParentMessage(message, handlers) {
342
387
  endedSessionIds.delete(message.sessionId);
343
388
  peerEnvBySessionId.set(message.sessionId, message.env);
344
389
  recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
390
+ mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
391
+ ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
345
392
  const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
346
393
  if (sessionStartInitDelayMs > 0) {
347
394
  await new Promise((resolve) => setTimeout(resolve, sessionStartInitDelayMs));
@@ -349,7 +396,9 @@ async function handleParentMessage(message, handlers) {
349
396
  await (handlers.onClientJoin ?? handlers.onSessionStart)?.({
350
397
  sessionId: message.sessionId,
351
398
  env: message.env,
352
- recordingAvailable: message.recordingAvailable ?? false
399
+ recordingAvailable: message.recordingAvailable ?? false,
400
+ mixAvailable: message.mixAvailable ?? false,
401
+ ttsPoseAvailable: message.ttsPoseAvailable ?? false
353
402
  });
354
403
  sendParentMessage({
355
404
  type: "session_start_ack",
@@ -387,6 +436,8 @@ async function handleParentMessage(message, handlers) {
387
436
  clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
388
437
  peerEnvBySessionId.delete(message.sessionId);
389
438
  recordingAvailableBySessionId.delete(message.sessionId);
439
+ mixAvailableBySessionId.delete(message.sessionId);
440
+ ttsPoseAvailableBySessionId.delete(message.sessionId);
390
441
  await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
391
442
  sessionId: message.sessionId
392
443
  });
@@ -406,6 +457,14 @@ function defineAgent(handlers) {
406
457
  handleRecordingControlAck(message);
407
458
  return;
408
459
  }
460
+ if (isMixControlAckMessage(message)) {
461
+ handleMixControlAck(message);
462
+ return;
463
+ }
464
+ if (isSttControlAckMessage(message)) {
465
+ handleSttControlAck(message);
466
+ return;
467
+ }
409
468
  if (isWebhookMessage(message)) {
410
469
  void agentStartReady.then(() => handleWebhookMessage(message, handlers));
411
470
  return;
@@ -136,6 +136,18 @@ function isRecordingControlAckMessage(value) {
136
136
  const msg = value;
137
137
  return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
138
138
  }
139
+ function isMixControlAckMessage(value) {
140
+ if (!value || typeof value !== "object")
141
+ return false;
142
+ const msg = value;
143
+ return msg.type === "mix_control_ack" && typeof msg.requestId === "string";
144
+ }
145
+ function isSttControlAckMessage(value) {
146
+ if (!value || typeof value !== "object")
147
+ return false;
148
+ const msg = value;
149
+ return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
150
+ }
139
151
  function isWebhookMessage(value) {
140
152
  if (!value || typeof value !== "object")
141
153
  return false;
@@ -178,7 +190,7 @@ function isParentMessage(value) {
178
190
  if (!value || typeof value !== "object")
179
191
  return false;
180
192
  const msg = value;
181
- 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 === "webhook";
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";
182
194
  }
183
195
  function isSessionScopedParentMessage(value) {
184
196
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -192,8 +204,12 @@ function parseDataChannelPayload(raw) {
192
204
  }
193
205
  var peerEnvBySessionId = /* @__PURE__ */ new Map();
194
206
  var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
207
+ var mixAvailableBySessionId = /* @__PURE__ */ new Map();
208
+ var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
195
209
  var endedSessionIds = /* @__PURE__ */ new Set();
196
210
  var pendingRecordingAcks = /* @__PURE__ */ new Map();
211
+ var pendingMixAcks = /* @__PURE__ */ new Map();
212
+ var pendingSttAcks = /* @__PURE__ */ new Map();
197
213
  function handleRecordingControlAck(message) {
198
214
  const pending = pendingRecordingAcks.get(message.requestId);
199
215
  if (!pending)
@@ -206,6 +222,30 @@ function handleRecordingControlAck(message) {
206
222
  requestId: message.requestId
207
223
  });
208
224
  }
225
+ function handleMixControlAck(message) {
226
+ const pending = pendingMixAcks.get(message.requestId);
227
+ if (!pending)
228
+ return;
229
+ clearTimeout(pending.timer);
230
+ pendingMixAcks.delete(message.requestId);
231
+ pending.resolve({
232
+ ok: message.ok,
233
+ reason: message.reason,
234
+ requestId: message.requestId
235
+ });
236
+ }
237
+ function handleSttControlAck(message) {
238
+ const pending = pendingSttAcks.get(message.requestId);
239
+ if (!pending)
240
+ return;
241
+ clearTimeout(pending.timer);
242
+ pendingSttAcks.delete(message.requestId);
243
+ pending.resolve({
244
+ ok: message.ok,
245
+ reason: message.reason,
246
+ requestId: message.requestId
247
+ });
248
+ }
209
249
  function clearPendingRecordingAcksForSession(sessionId, reason) {
210
250
  for (const [requestId, pending] of pendingRecordingAcks) {
211
251
  if (pending.sessionId !== sessionId)
@@ -261,6 +301,11 @@ function allowOutboundForSession(sessionId) {
261
301
  return queue.isLive(sessionId);
262
302
  }
263
303
  function sendParentMessage(message) {
304
+ const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
305
+ if (msgType === "mix_control" || msgType === "stt_control") {
306
+ process.send?.(message);
307
+ return;
308
+ }
264
309
  const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
265
310
  if (!allowOutboundForSession(sessionId))
266
311
  return;
@@ -342,6 +387,8 @@ async function handleParentMessage(message, handlers) {
342
387
  endedSessionIds.delete(message.sessionId);
343
388
  peerEnvBySessionId.set(message.sessionId, message.env);
344
389
  recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
390
+ mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
391
+ ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
345
392
  const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
346
393
  if (sessionStartInitDelayMs > 0) {
347
394
  await new Promise((resolve) => setTimeout(resolve, sessionStartInitDelayMs));
@@ -349,7 +396,9 @@ async function handleParentMessage(message, handlers) {
349
396
  await (handlers.onClientJoin ?? handlers.onSessionStart)?.({
350
397
  sessionId: message.sessionId,
351
398
  env: message.env,
352
- recordingAvailable: message.recordingAvailable ?? false
399
+ recordingAvailable: message.recordingAvailable ?? false,
400
+ mixAvailable: message.mixAvailable ?? false,
401
+ ttsPoseAvailable: message.ttsPoseAvailable ?? false
353
402
  });
354
403
  sendParentMessage({
355
404
  type: "session_start_ack",
@@ -387,6 +436,8 @@ async function handleParentMessage(message, handlers) {
387
436
  clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
388
437
  peerEnvBySessionId.delete(message.sessionId);
389
438
  recordingAvailableBySessionId.delete(message.sessionId);
439
+ mixAvailableBySessionId.delete(message.sessionId);
440
+ ttsPoseAvailableBySessionId.delete(message.sessionId);
390
441
  await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
391
442
  sessionId: message.sessionId
392
443
  });
@@ -406,6 +457,14 @@ function defineAgent(handlers) {
406
457
  handleRecordingControlAck(message);
407
458
  return;
408
459
  }
460
+ if (isMixControlAckMessage(message)) {
461
+ handleMixControlAck(message);
462
+ return;
463
+ }
464
+ if (isSttControlAckMessage(message)) {
465
+ handleSttControlAck(message);
466
+ return;
467
+ }
409
468
  if (isWebhookMessage(message)) {
410
469
  void agentStartReady.then(() => handleWebhookMessage(message, handlers));
411
470
  return;
@@ -139,6 +139,18 @@ function isRecordingControlAckMessage(value) {
139
139
  const msg = value;
140
140
  return msg.type === "recording_control_ack" && typeof msg.requestId === "string";
141
141
  }
142
+ function isMixControlAckMessage(value) {
143
+ if (!value || typeof value !== "object")
144
+ return false;
145
+ const msg = value;
146
+ return msg.type === "mix_control_ack" && typeof msg.requestId === "string";
147
+ }
148
+ function isSttControlAckMessage(value) {
149
+ if (!value || typeof value !== "object")
150
+ return false;
151
+ const msg = value;
152
+ return msg.type === "stt_control_ack" && typeof msg.requestId === "string";
153
+ }
142
154
  function isWebhookMessage(value) {
143
155
  if (!value || typeof value !== "object")
144
156
  return false;
@@ -181,7 +193,7 @@ function isParentMessage(value) {
181
193
  if (!value || typeof value !== "object")
182
194
  return false;
183
195
  const msg = value;
184
- 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 === "webhook";
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";
185
197
  }
186
198
  function isSessionScopedParentMessage(value) {
187
199
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -195,8 +207,12 @@ function parseDataChannelPayload(raw) {
195
207
  }
196
208
  var peerEnvBySessionId = /* @__PURE__ */ new Map();
197
209
  var recordingAvailableBySessionId = /* @__PURE__ */ new Map();
210
+ var mixAvailableBySessionId = /* @__PURE__ */ new Map();
211
+ var ttsPoseAvailableBySessionId = /* @__PURE__ */ new Map();
198
212
  var endedSessionIds = /* @__PURE__ */ new Set();
199
213
  var pendingRecordingAcks = /* @__PURE__ */ new Map();
214
+ var pendingMixAcks = /* @__PURE__ */ new Map();
215
+ var pendingSttAcks = /* @__PURE__ */ new Map();
200
216
  function handleRecordingControlAck(message) {
201
217
  const pending = pendingRecordingAcks.get(message.requestId);
202
218
  if (!pending)
@@ -209,6 +225,30 @@ function handleRecordingControlAck(message) {
209
225
  requestId: message.requestId
210
226
  });
211
227
  }
228
+ function handleMixControlAck(message) {
229
+ const pending = pendingMixAcks.get(message.requestId);
230
+ if (!pending)
231
+ return;
232
+ clearTimeout(pending.timer);
233
+ pendingMixAcks.delete(message.requestId);
234
+ pending.resolve({
235
+ ok: message.ok,
236
+ reason: message.reason,
237
+ requestId: message.requestId
238
+ });
239
+ }
240
+ function handleSttControlAck(message) {
241
+ const pending = pendingSttAcks.get(message.requestId);
242
+ if (!pending)
243
+ return;
244
+ clearTimeout(pending.timer);
245
+ pendingSttAcks.delete(message.requestId);
246
+ pending.resolve({
247
+ ok: message.ok,
248
+ reason: message.reason,
249
+ requestId: message.requestId
250
+ });
251
+ }
212
252
  function clearPendingRecordingAcksForSession(sessionId, reason) {
213
253
  for (const [requestId, pending] of pendingRecordingAcks) {
214
254
  if (pending.sessionId !== sessionId)
@@ -264,6 +304,11 @@ function allowOutboundForSession(sessionId) {
264
304
  return queue.isLive(sessionId);
265
305
  }
266
306
  function sendParentMessage(message) {
307
+ const msgType = message && typeof message === "object" && "type" in message ? message.type : void 0;
308
+ if (msgType === "mix_control" || msgType === "stt_control") {
309
+ process.send?.(message);
310
+ return;
311
+ }
267
312
  const sessionId = message && typeof message === "object" && "sessionId" in message && typeof message.sessionId === "string" ? message.sessionId : void 0;
268
313
  if (!allowOutboundForSession(sessionId))
269
314
  return;
@@ -345,6 +390,8 @@ async function handleParentMessage(message, handlers) {
345
390
  endedSessionIds.delete(message.sessionId);
346
391
  peerEnvBySessionId.set(message.sessionId, message.env);
347
392
  recordingAvailableBySessionId.set(message.sessionId, message.recordingAvailable ?? false);
393
+ mixAvailableBySessionId.set(message.sessionId, message.mixAvailable ?? false);
394
+ ttsPoseAvailableBySessionId.set(message.sessionId, message.ttsPoseAvailable ?? false);
348
395
  const sessionStartInitDelayMs = resolveSessionStartInitDelayMs();
349
396
  if (sessionStartInitDelayMs > 0) {
350
397
  await new Promise((resolve) => setTimeout(resolve, sessionStartInitDelayMs));
@@ -352,7 +399,9 @@ async function handleParentMessage(message, handlers) {
352
399
  await (handlers.onClientJoin ?? handlers.onSessionStart)?.({
353
400
  sessionId: message.sessionId,
354
401
  env: message.env,
355
- recordingAvailable: message.recordingAvailable ?? false
402
+ recordingAvailable: message.recordingAvailable ?? false,
403
+ mixAvailable: message.mixAvailable ?? false,
404
+ ttsPoseAvailable: message.ttsPoseAvailable ?? false
356
405
  });
357
406
  sendParentMessage({
358
407
  type: "session_start_ack",
@@ -390,6 +439,8 @@ async function handleParentMessage(message, handlers) {
390
439
  clearPendingRecordingAcksForSession(message.sessionId, "session_ended");
391
440
  peerEnvBySessionId.delete(message.sessionId);
392
441
  recordingAvailableBySessionId.delete(message.sessionId);
442
+ mixAvailableBySessionId.delete(message.sessionId);
443
+ ttsPoseAvailableBySessionId.delete(message.sessionId);
393
444
  await (handlers.onClientLeave ?? handlers.onSessionEnd)?.({
394
445
  sessionId: message.sessionId
395
446
  });
@@ -409,6 +460,14 @@ function defineAgent(handlers) {
409
460
  handleRecordingControlAck(message);
410
461
  return;
411
462
  }
463
+ if (isMixControlAckMessage(message)) {
464
+ handleMixControlAck(message);
465
+ return;
466
+ }
467
+ if (isSttControlAckMessage(message)) {
468
+ handleSttControlAck(message);
469
+ return;
470
+ }
412
471
  if (isWebhookMessage(message)) {
413
472
  void agentStartReady.then(() => handleWebhookMessage(message, handlers));
414
473
  return;