@voicethere/agent 0.7.10 → 0.7.12

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.
@@ -152,6 +152,12 @@ function isPlayStopAckMessage(value) {
152
152
  const msg = value;
153
153
  return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
154
154
  }
155
+ function isPlayPoseAckMessage(value) {
156
+ if (!value || typeof value !== "object")
157
+ return false;
158
+ const msg = value;
159
+ return msg.type === "play_pose_ack" && typeof msg.requestId === "string";
160
+ }
155
161
  function isRecordingControlAckMessage(value) {
156
162
  if (!value || typeof value !== "object")
157
163
  return false;
@@ -212,7 +218,7 @@ function isParentMessage(value) {
212
218
  if (!value || typeof value !== "object")
213
219
  return false;
214
220
  const msg = value;
215
- 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";
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";
216
222
  }
217
223
  function isSessionScopedParentMessage(value) {
218
224
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -235,7 +241,9 @@ var pendingRecordingAcks = /* @__PURE__ */ new Map();
235
241
  var pendingPlayAcks = /* @__PURE__ */ new Map();
236
242
  var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
237
243
  var pendingPlayStopAcks = /* @__PURE__ */ new Map();
244
+ var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
238
245
  var MIX_CONTROL_ACK_TIMEOUT_MS = 5e3;
246
+ var STT_CONTROL_ACK_TIMEOUT_MS = 5e3;
239
247
  var pendingMixAcks = /* @__PURE__ */ new Map();
240
248
  var pendingSttAcks = /* @__PURE__ */ new Map();
241
249
  function handleRecordingControlAck(message) {
@@ -290,6 +298,19 @@ function handlePlayStopAck(message) {
290
298
  requestId: message.requestId
291
299
  });
292
300
  }
301
+ function handlePlayPoseAck(message) {
302
+ const pending = pendingPlayPoseAcks.get(message.requestId);
303
+ if (!pending)
304
+ return;
305
+ clearTimeout(pending.timer);
306
+ pendingPlayPoseAcks.delete(message.requestId);
307
+ pending.resolve({
308
+ ok: message.ok,
309
+ playId: message.playId,
310
+ reason: message.reason,
311
+ requestId: message.requestId
312
+ });
313
+ }
293
314
  function handleMixControlAck(message) {
294
315
  const pending = pendingMixAcks.get(message.requestId);
295
316
  if (!pending)
@@ -402,7 +423,7 @@ function sendParentMessage(message) {
402
423
  process.send?.(message);
403
424
  return;
404
425
  }
405
- if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
426
+ if (msgType === "play" || msgType === "play_status" || msgType === "play_stop" || msgType === "play_pose") {
406
427
  process.send?.(message);
407
428
  return;
408
429
  }
@@ -588,6 +609,10 @@ function defineAgent(handlers) {
588
609
  handlePlayStopAck(message);
589
610
  return;
590
611
  }
612
+ if (isPlayPoseAckMessage(message)) {
613
+ handlePlayPoseAck(message);
614
+ return;
615
+ }
591
616
  if (isMixControlAckMessage(message)) {
592
617
  handleMixControlAck(message);
593
618
  return;
@@ -778,6 +803,26 @@ async function sendTtsPoseControl(action, payload) {
778
803
  });
779
804
  });
780
805
  }
806
+ async function sendSttControl(options) {
807
+ const requestId = randomUUID();
808
+ if (!isVoicethereAgentChild()) {
809
+ return { ok: true, reason: "local_mock", requestId };
810
+ }
811
+ return new Promise((resolve) => {
812
+ const timer = setTimeout(() => {
813
+ pendingSttAcks.delete(requestId);
814
+ resolve({ ok: false, reason: "timeout", requestId });
815
+ }, STT_CONTROL_ACK_TIMEOUT_MS);
816
+ pendingSttAcks.set(requestId, { resolve, timer });
817
+ sendParentMessage({
818
+ type: "stt_control",
819
+ requestId,
820
+ enabled: options.enabled,
821
+ ...options.clientId ? { clientId: options.clientId } : {},
822
+ ...options.sessionId ? { sessionId: options.sessionId } : {}
823
+ });
824
+ });
825
+ }
781
826
  function createMixGroup(options) {
782
827
  return sendMixControl("create_group", {
783
828
  groupId: options.id,
@@ -809,6 +854,9 @@ function setListenerMute(options) {
809
854
  muted: options.muted
810
855
  });
811
856
  }
857
+ function setSttEnabled(options) {
858
+ return sendSttControl(options);
859
+ }
812
860
  function validatePlayOptions(options) {
813
861
  const requestId = randomUUID();
814
862
  const url = options.url?.trim();
@@ -928,6 +976,36 @@ function getPlay(playId) {
928
976
  function stopPlay(playId) {
929
977
  return sendPlayStop(playId);
930
978
  }
979
+ async function sendPlayPose(playId, pose) {
980
+ const requestId = randomUUID();
981
+ if (!playId?.trim() || !pose) {
982
+ return {
983
+ ok: false,
984
+ playId: playId ?? "",
985
+ reason: "invalid_payload",
986
+ requestId
987
+ };
988
+ }
989
+ if (!isVoicethereAgentChild()) {
990
+ return { ok: true, playId, reason: "local_mock", requestId };
991
+ }
992
+ return new Promise((resolve) => {
993
+ const timer = setTimeout(() => {
994
+ pendingPlayPoseAcks.delete(requestId);
995
+ resolve({ ok: false, playId, reason: "timeout", requestId });
996
+ }, PLAY_CONTROL_ACK_TIMEOUT_MS);
997
+ pendingPlayPoseAcks.set(requestId, { playId, resolve, timer });
998
+ sendParentMessage({
999
+ type: "play_pose",
1000
+ requestId,
1001
+ playId,
1002
+ pose
1003
+ });
1004
+ });
1005
+ }
1006
+ function setPlayPose(playId, pose) {
1007
+ return sendPlayPose(playId, pose);
1008
+ }
931
1009
  function sendToClient(sessionId, payload) {
932
1010
  sendParentMessage({ type: "send_to_client", sessionId, payload });
933
1011
  }
@@ -1286,12 +1364,49 @@ var ProximityRoom = class {
1286
1364
  }
1287
1365
  };
1288
1366
 
1367
+ // templates/spatial-showcase/sine.ts
1368
+ var ORBIT_SINE_DURATION_MS = 2e3;
1369
+ var ORBIT_SINE_FREQUENCY_HZ = 440;
1370
+ var ORBIT_SINE_AMPLITUDE = 8e3;
1371
+ var ORBIT_SINE_INLINE_URL = "https://example.com/inline-orbit-sine.wav";
1372
+ function buildOrbitSineInlineClipBase64(durationMs = ORBIT_SINE_DURATION_MS, frequencyHz = ORBIT_SINE_FREQUENCY_HZ, amplitude = ORBIT_SINE_AMPLITUDE) {
1373
+ const sampleRate = 16e3;
1374
+ const channels = 1;
1375
+ const bytesPerSample = 2;
1376
+ const numSamples = Math.floor(sampleRate * durationMs / 1e3);
1377
+ const dataSize = numSamples * channels * bytesPerSample;
1378
+ const buffer = Buffer.alloc(44 + dataSize);
1379
+ buffer.write("RIFF", 0);
1380
+ buffer.writeUInt32LE(36 + dataSize, 4);
1381
+ buffer.write("WAVE", 8);
1382
+ buffer.write("fmt ", 12);
1383
+ buffer.writeUInt32LE(16, 16);
1384
+ buffer.writeUInt16LE(1, 20);
1385
+ buffer.writeUInt16LE(channels, 22);
1386
+ buffer.writeUInt32LE(sampleRate, 24);
1387
+ buffer.writeUInt32LE(sampleRate * channels * bytesPerSample, 28);
1388
+ buffer.writeUInt16LE(channels * bytesPerSample, 32);
1389
+ buffer.writeUInt16LE(16, 34);
1390
+ buffer.write("data", 36);
1391
+ buffer.writeUInt32LE(dataSize, 40);
1392
+ for (let i = 0; i < numSamples; i++) {
1393
+ const t = i / sampleRate;
1394
+ const sample = Math.round(
1395
+ amplitude * Math.sin(2 * Math.PI * frequencyHz * t)
1396
+ );
1397
+ buffer.writeInt16LE(sample, 44 + i * 2);
1398
+ }
1399
+ return buffer.toString("base64");
1400
+ }
1401
+
1289
1402
  // templates/spatial-showcase/agent.ts
1290
1403
  var ORBIT_TICK_MS = 50;
1291
1404
  var ORBIT_POSE_EMIT_MS = 100;
1292
1405
  var ROOM_STATE_TICK_MS = 100;
1293
1406
  var LOOP_PAD_POLL_MS = 250;
1294
- var MAX_ACTIVE_PLAYS = 4;
1407
+ var ORBIT_SINE_POLL_MS = 250;
1408
+ var ORBIT_SINE_VOLUME = 0.25;
1409
+ var MAX_ACTIVE_PLAYS = 12;
1295
1410
  var SHOWCASE_ROOM_GROUP_ID = "showcase-room";
1296
1411
  var sessions = /* @__PURE__ */ new Map();
1297
1412
  var proximityRoom = new ProximityRoom();
@@ -1314,12 +1429,13 @@ function ack(sessionId, action, extra) {
1314
1429
  ...extra
1315
1430
  });
1316
1431
  }
1317
- function ackError(sessionId, action, error) {
1432
+ function ackError(sessionId, action, error, extra) {
1318
1433
  sendToClient(sessionId, {
1319
1434
  type: "showcase_ack",
1320
1435
  action,
1321
1436
  ok: false,
1322
- error
1437
+ error,
1438
+ ...extra?.clipId !== void 0 ? { clipId: extra.clipId } : {}
1323
1439
  });
1324
1440
  }
1325
1441
  async function safeMixCall(sessionId, label, fn) {
@@ -1360,6 +1476,14 @@ function clearRoomStateTimer(state) {
1360
1476
  state.roomStateTimer = void 0;
1361
1477
  }
1362
1478
  }
1479
+ function stopLoopPadsForClip(sessionId, state, clipId) {
1480
+ for (const [playId, pad] of [...state.loopPads.entries()]) {
1481
+ if (pad.clipId === clipId) {
1482
+ void stopPlay(playId);
1483
+ clearLoopPad(sessionId, state, playId);
1484
+ }
1485
+ }
1486
+ }
1363
1487
  function clearLoopPad(sessionId, state, playId) {
1364
1488
  const timer = state.loopPollTimers.get(playId);
1365
1489
  if (timer) {
@@ -1383,6 +1507,78 @@ function clearAllPlays(sessionId, state) {
1383
1507
  state.loopPads.clear();
1384
1508
  state.loopPollTimers.clear();
1385
1509
  }
1510
+ function currentOrbitPose(state) {
1511
+ if (!state.orbitStartMs) {
1512
+ return orbitTtsPose(0, state.orbit);
1513
+ }
1514
+ const elapsedSec = (Date.now() - state.orbitStartMs) / 1e3;
1515
+ return orbitTtsPose(elapsedSec, state.orbit);
1516
+ }
1517
+ function clearOrbitSinePoll(state) {
1518
+ if (state.orbitSinePollTimer) {
1519
+ clearInterval(state.orbitSinePollTimer);
1520
+ state.orbitSinePollTimer = void 0;
1521
+ }
1522
+ }
1523
+ async function stopOrbitSine(state) {
1524
+ clearOrbitSinePoll(state);
1525
+ const playId = state.orbitSinePlayId;
1526
+ state.orbitSinePlayId = void 0;
1527
+ if (playId) {
1528
+ await stopPlay(playId);
1529
+ }
1530
+ }
1531
+ function startOrbitSineLoopPoll(sessionId, state) {
1532
+ clearOrbitSinePoll(state);
1533
+ const playId = state.orbitSinePlayId;
1534
+ if (!playId) {
1535
+ return;
1536
+ }
1537
+ state.orbitSinePollTimer = setInterval(() => {
1538
+ void (async () => {
1539
+ if (!state.orbitSinePlayId) {
1540
+ clearOrbitSinePoll(state);
1541
+ return;
1542
+ }
1543
+ const status = await getPlay(state.orbitSinePlayId);
1544
+ if (!status.ok) {
1545
+ return;
1546
+ }
1547
+ if (status.status === "ended") {
1548
+ const replay = await play({
1549
+ url: ORBIT_SINE_INLINE_URL,
1550
+ bytes: buildOrbitSineInlineClipBase64(),
1551
+ sessionIds: [sessionId],
1552
+ volume: ORBIT_SINE_VOLUME,
1553
+ pose: currentOrbitPose(state)
1554
+ });
1555
+ if (replay.ok && replay.playId) {
1556
+ state.orbitSinePlayId = replay.playId;
1557
+ }
1558
+ }
1559
+ })();
1560
+ }, ORBIT_SINE_POLL_MS);
1561
+ }
1562
+ async function startOrbitSinePlay(sessionId, state) {
1563
+ await stopOrbitSine(state);
1564
+ const result = await play({
1565
+ url: ORBIT_SINE_INLINE_URL,
1566
+ bytes: buildOrbitSineInlineClipBase64(),
1567
+ sessionIds: [sessionId],
1568
+ volume: ORBIT_SINE_VOLUME,
1569
+ pose: currentOrbitPose(state)
1570
+ });
1571
+ if (!result.ok || !result.playId) {
1572
+ agentLog(
1573
+ "warn",
1574
+ `spatial-showcase orbit sine play failed: ${result.reason ?? "play_failed"}`,
1575
+ sessionId
1576
+ );
1577
+ return;
1578
+ }
1579
+ state.orbitSinePlayId = result.playId;
1580
+ startOrbitSineLoopPoll(sessionId, state);
1581
+ }
1386
1582
  function emitOrbitPose(sessionId, state) {
1387
1583
  if (!state.orbitStartMs) {
1388
1584
  return;
@@ -1405,18 +1601,27 @@ function emitOrbitPose(sessionId, state) {
1405
1601
  function startOrbitDemo(sessionId, state) {
1406
1602
  stopOrbitInterval(state);
1407
1603
  beginOrbitClock(state);
1604
+ void startOrbitSinePlay(sessionId, state);
1408
1605
  state.orbitTimer = setInterval(() => {
1409
1606
  if (state.orbit.paused || !state.orbitStartMs) {
1410
1607
  return;
1411
1608
  }
1412
- const elapsedSec = (Date.now() - state.orbitStartMs) / 1e3;
1609
+ const pose = currentOrbitPose(state);
1610
+ if (state.orbitSinePlayId) {
1611
+ void safeMixCall(
1612
+ sessionId,
1613
+ "setPlayPose",
1614
+ () => setPlayPose(state.orbitSinePlayId, pose)
1615
+ );
1616
+ }
1413
1617
  void safeMixCall(
1414
1618
  sessionId,
1415
1619
  "setTtsPose",
1416
- () => setTtsPose(sessionId, orbitTtsPose(elapsedSec, state.orbit))
1620
+ () => setTtsPose(sessionId, pose)
1417
1621
  );
1418
1622
  emitOrbitPose(sessionId, state);
1419
1623
  }, ORBIT_TICK_MS);
1624
+ emitOrbitPose(sessionId, state);
1420
1625
  speak(sessionId, "I'll circle around you.");
1421
1626
  }
1422
1627
  function broadcastRoomStateIfChanged() {
@@ -1481,6 +1686,13 @@ async function startLoopPadPoll(sessionId, state, playId, pad) {
1481
1686
  clearLoopPad(sessionId, state, playId);
1482
1687
  state.playIds.add(replay.playId);
1483
1688
  state.loopPads.set(replay.playId, pad);
1689
+ ack(sessionId, "pad", {
1690
+ playId: replay.playId,
1691
+ clipId: pad.clipId,
1692
+ x: pad.x,
1693
+ z: pad.z,
1694
+ ...pad.placement !== void 0 ? { placement: pad.placement } : {}
1695
+ });
1484
1696
  void startLoopPadPoll(sessionId, state, replay.playId, pad);
1485
1697
  }
1486
1698
  } else if (status.status) {
@@ -1495,21 +1707,24 @@ async function startLoopPadPoll(sessionId, state, playId, pad) {
1495
1707
  state.loopPollTimers.set(playId, timer);
1496
1708
  }
1497
1709
  async function handlePadPlay(sessionId, state, clipId, x, z, volume, placement) {
1498
- if (state.playIds.size >= MAX_ACTIVE_PLAYS) {
1499
- ackError(sessionId, "pad", "busy");
1500
- return;
1501
- }
1502
1710
  const assetOrigin = state.assetOrigin;
1503
1711
  if (!assetOrigin) {
1504
- ackError(sessionId, "pad", "missing_asset_origin");
1712
+ ackError(sessionId, "pad", "missing_asset_origin", { clipId });
1505
1713
  return;
1506
1714
  }
1507
1715
  const url = resolveClipUrl(assetOrigin, clipId);
1508
1716
  if (!url) {
1509
- ackError(sessionId, "pad", "invalid_asset_origin");
1717
+ ackError(sessionId, "pad", "invalid_asset_origin", { clipId });
1510
1718
  return;
1511
1719
  }
1512
1720
  const sound = SHOWCASE_SOUND_FILES[clipId];
1721
+ if (sound.loop) {
1722
+ stopLoopPadsForClip(sessionId, state, clipId);
1723
+ }
1724
+ if (state.playIds.size >= MAX_ACTIVE_PLAYS) {
1725
+ ackError(sessionId, "pad", "busy", { clipId });
1726
+ return;
1727
+ }
1513
1728
  const playVolume = volume ?? sound.defaultVolume;
1514
1729
  const options = {
1515
1730
  url,
@@ -1519,11 +1734,17 @@ async function handlePadPlay(sessionId, state, clipId, x, z, volume, placement)
1519
1734
  };
1520
1735
  const result = await play(options);
1521
1736
  if (!result.ok || !result.playId) {
1522
- ackError(sessionId, "pad", result.reason ?? "play_failed");
1737
+ ackError(sessionId, "pad", result.reason ?? "play_failed", { clipId });
1523
1738
  return;
1524
1739
  }
1525
1740
  state.playIds.add(result.playId);
1526
- ack(sessionId, "pad", { playId: result.playId });
1741
+ ack(sessionId, "pad", {
1742
+ playId: result.playId,
1743
+ clipId,
1744
+ x,
1745
+ z,
1746
+ ...placement !== void 0 ? { placement } : {}
1747
+ });
1527
1748
  if (sound.loop) {
1528
1749
  const pad = {
1529
1750
  clipId,
@@ -1552,9 +1773,15 @@ async function handleJoin(sessionId, demo, assetOrigin) {
1552
1773
  }
1553
1774
  ack(sessionId, "join");
1554
1775
  switch (demo) {
1555
- case "orbit":
1776
+ case "orbit": {
1777
+ void safeMixCall(
1778
+ sessionId,
1779
+ "setSttEnabled",
1780
+ () => setSttEnabled({ enabled: false, sessionId })
1781
+ );
1556
1782
  startOrbitDemo(sessionId, state);
1557
1783
  break;
1784
+ }
1558
1785
  case "soundboard":
1559
1786
  break;
1560
1787
  case "proximity": {
@@ -1581,13 +1808,13 @@ async function handleJoin(sessionId, demo, assetOrigin) {
1581
1808
  return;
1582
1809
  }
1583
1810
  state.inProximityRoom = true;
1811
+ startProximityRoomBroadcast(sessionId, state);
1584
1812
  speak(sessionId, "Welcome to the proximity room.");
1585
1813
  await safeMixCall(
1586
1814
  sessionId,
1587
1815
  "setTtsPose",
1588
1816
  () => setTtsPose(sessionId, poseAt(0, 0))
1589
1817
  );
1590
- startProximityRoomBroadcast(sessionId, state);
1591
1818
  break;
1592
1819
  }
1593
1820
  }
@@ -1599,8 +1826,14 @@ function teardownSession(sessionId) {
1599
1826
  }
1600
1827
  resetOrbitSession(state);
1601
1828
  clearRoomStateTimer(state);
1829
+ void stopOrbitSine(state);
1602
1830
  clearAllPlays(sessionId, state);
1603
1831
  void safeMixCall(sessionId, "clearTtsPose", () => clearTtsPose(sessionId));
1832
+ void safeMixCall(
1833
+ sessionId,
1834
+ "setSttEnabled",
1835
+ () => setSttEnabled({ enabled: true, sessionId })
1836
+ );
1604
1837
  if (state.inProximityRoom) {
1605
1838
  proximityRoom.leave(sessionId);
1606
1839
  void safeMixCall(
@@ -1665,6 +1898,10 @@ async function dispatchMessage(sessionId, message) {
1665
1898
  ackError(sessionId, "pad", "wrong_demo");
1666
1899
  return;
1667
1900
  }
1901
+ if (!isShowcaseClipId(message.clipId)) {
1902
+ ackError(sessionId, "pad", "invalid_clip_id");
1903
+ return;
1904
+ }
1668
1905
  await handlePadPlay(
1669
1906
  sessionId,
1670
1907
  state,
@@ -1783,13 +2020,6 @@ defineAgent({
1783
2020
  ok: true
1784
2021
  });
1785
2022
  },
1786
- onUserSpeechFinal({ sessionId, text }) {
1787
- const state = sessions.get(sessionId);
1788
- if (!state || state.demo !== "orbit") {
1789
- return;
1790
- }
1791
- speak(sessionId, `You said: ${text}`);
1792
- },
1793
2023
  onDataChannelMessage(ctx) {
1794
2024
  const message = parseShowcaseMessage(ctx.message);
1795
2025
  if (!message) {
@@ -1803,5 +2033,6 @@ defineAgent({
1803
2033
  }
1804
2034
  });
1805
2035
  export {
2036
+ MAX_ACTIVE_PLAYS,
1806
2037
  handlePadPlay
1807
2038
  };
@@ -148,6 +148,12 @@ function isPlayStopAckMessage(value) {
148
148
  const msg = value;
149
149
  return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
150
150
  }
151
+ function isPlayPoseAckMessage(value) {
152
+ if (!value || typeof value !== "object")
153
+ return false;
154
+ const msg = value;
155
+ return msg.type === "play_pose_ack" && typeof msg.requestId === "string";
156
+ }
151
157
  function isRecordingControlAckMessage(value) {
152
158
  if (!value || typeof value !== "object")
153
159
  return false;
@@ -208,7 +214,7 @@ function isParentMessage(value) {
208
214
  if (!value || typeof value !== "object")
209
215
  return false;
210
216
  const msg = value;
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";
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";
212
218
  }
213
219
  function isSessionScopedParentMessage(value) {
214
220
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -230,6 +236,7 @@ var pendingRecordingAcks = /* @__PURE__ */ new Map();
230
236
  var pendingPlayAcks = /* @__PURE__ */ new Map();
231
237
  var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
232
238
  var pendingPlayStopAcks = /* @__PURE__ */ new Map();
239
+ var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
233
240
  var pendingMixAcks = /* @__PURE__ */ new Map();
234
241
  var pendingSttAcks = /* @__PURE__ */ new Map();
235
242
  function handleRecordingControlAck(message) {
@@ -284,6 +291,19 @@ function handlePlayStopAck(message) {
284
291
  requestId: message.requestId
285
292
  });
286
293
  }
294
+ function handlePlayPoseAck(message) {
295
+ const pending = pendingPlayPoseAcks.get(message.requestId);
296
+ if (!pending)
297
+ return;
298
+ clearTimeout(pending.timer);
299
+ pendingPlayPoseAcks.delete(message.requestId);
300
+ pending.resolve({
301
+ ok: message.ok,
302
+ playId: message.playId,
303
+ reason: message.reason,
304
+ requestId: message.requestId
305
+ });
306
+ }
287
307
  function handleMixControlAck(message) {
288
308
  const pending = pendingMixAcks.get(message.requestId);
289
309
  if (!pending)
@@ -369,7 +389,7 @@ function sendParentMessage(message) {
369
389
  process.send?.(message);
370
390
  return;
371
391
  }
372
- if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
392
+ if (msgType === "play" || msgType === "play_status" || msgType === "play_stop" || msgType === "play_pose") {
373
393
  process.send?.(message);
374
394
  return;
375
395
  }
@@ -555,6 +575,10 @@ function defineAgent(handlers) {
555
575
  handlePlayStopAck(message);
556
576
  return;
557
577
  }
578
+ if (isPlayPoseAckMessage(message)) {
579
+ handlePlayPoseAck(message);
580
+ return;
581
+ }
558
582
  if (isMixControlAckMessage(message)) {
559
583
  handleMixControlAck(message);
560
584
  return;
@@ -148,6 +148,12 @@ function isPlayStopAckMessage(value) {
148
148
  const msg = value;
149
149
  return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
150
150
  }
151
+ function isPlayPoseAckMessage(value) {
152
+ if (!value || typeof value !== "object")
153
+ return false;
154
+ const msg = value;
155
+ return msg.type === "play_pose_ack" && typeof msg.requestId === "string";
156
+ }
151
157
  function isRecordingControlAckMessage(value) {
152
158
  if (!value || typeof value !== "object")
153
159
  return false;
@@ -208,7 +214,7 @@ function isParentMessage(value) {
208
214
  if (!value || typeof value !== "object")
209
215
  return false;
210
216
  const msg = value;
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";
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";
212
218
  }
213
219
  function isSessionScopedParentMessage(value) {
214
220
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -230,6 +236,7 @@ var pendingRecordingAcks = /* @__PURE__ */ new Map();
230
236
  var pendingPlayAcks = /* @__PURE__ */ new Map();
231
237
  var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
232
238
  var pendingPlayStopAcks = /* @__PURE__ */ new Map();
239
+ var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
233
240
  var pendingMixAcks = /* @__PURE__ */ new Map();
234
241
  var pendingSttAcks = /* @__PURE__ */ new Map();
235
242
  function handleRecordingControlAck(message) {
@@ -284,6 +291,19 @@ function handlePlayStopAck(message) {
284
291
  requestId: message.requestId
285
292
  });
286
293
  }
294
+ function handlePlayPoseAck(message) {
295
+ const pending = pendingPlayPoseAcks.get(message.requestId);
296
+ if (!pending)
297
+ return;
298
+ clearTimeout(pending.timer);
299
+ pendingPlayPoseAcks.delete(message.requestId);
300
+ pending.resolve({
301
+ ok: message.ok,
302
+ playId: message.playId,
303
+ reason: message.reason,
304
+ requestId: message.requestId
305
+ });
306
+ }
287
307
  function handleMixControlAck(message) {
288
308
  const pending = pendingMixAcks.get(message.requestId);
289
309
  if (!pending)
@@ -369,7 +389,7 @@ function sendParentMessage(message) {
369
389
  process.send?.(message);
370
390
  return;
371
391
  }
372
- if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
392
+ if (msgType === "play" || msgType === "play_status" || msgType === "play_stop" || msgType === "play_pose") {
373
393
  process.send?.(message);
374
394
  return;
375
395
  }
@@ -555,6 +575,10 @@ function defineAgent(handlers) {
555
575
  handlePlayStopAck(message);
556
576
  return;
557
577
  }
578
+ if (isPlayPoseAckMessage(message)) {
579
+ handlePlayPoseAck(message);
580
+ return;
581
+ }
558
582
  if (isMixControlAckMessage(message)) {
559
583
  handleMixControlAck(message);
560
584
  return;
@@ -151,6 +151,12 @@ function isPlayStopAckMessage(value) {
151
151
  const msg = value;
152
152
  return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
153
153
  }
154
+ function isPlayPoseAckMessage(value) {
155
+ if (!value || typeof value !== "object")
156
+ return false;
157
+ const msg = value;
158
+ return msg.type === "play_pose_ack" && typeof msg.requestId === "string";
159
+ }
154
160
  function isRecordingControlAckMessage(value) {
155
161
  if (!value || typeof value !== "object")
156
162
  return false;
@@ -211,7 +217,7 @@ function isParentMessage(value) {
211
217
  if (!value || typeof value !== "object")
212
218
  return false;
213
219
  const msg = value;
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";
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";
215
221
  }
216
222
  function isSessionScopedParentMessage(value) {
217
223
  return isParentMessage(value) && !isWebhookMessage(value);
@@ -233,6 +239,7 @@ var pendingRecordingAcks = /* @__PURE__ */ new Map();
233
239
  var pendingPlayAcks = /* @__PURE__ */ new Map();
234
240
  var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
235
241
  var pendingPlayStopAcks = /* @__PURE__ */ new Map();
242
+ var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
236
243
  var pendingMixAcks = /* @__PURE__ */ new Map();
237
244
  var pendingSttAcks = /* @__PURE__ */ new Map();
238
245
  function handleRecordingControlAck(message) {
@@ -287,6 +294,19 @@ function handlePlayStopAck(message) {
287
294
  requestId: message.requestId
288
295
  });
289
296
  }
297
+ function handlePlayPoseAck(message) {
298
+ const pending = pendingPlayPoseAcks.get(message.requestId);
299
+ if (!pending)
300
+ return;
301
+ clearTimeout(pending.timer);
302
+ pendingPlayPoseAcks.delete(message.requestId);
303
+ pending.resolve({
304
+ ok: message.ok,
305
+ playId: message.playId,
306
+ reason: message.reason,
307
+ requestId: message.requestId
308
+ });
309
+ }
290
310
  function handleMixControlAck(message) {
291
311
  const pending = pendingMixAcks.get(message.requestId);
292
312
  if (!pending)
@@ -372,7 +392,7 @@ function sendParentMessage(message) {
372
392
  process.send?.(message);
373
393
  return;
374
394
  }
375
- if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
395
+ if (msgType === "play" || msgType === "play_status" || msgType === "play_stop" || msgType === "play_pose") {
376
396
  process.send?.(message);
377
397
  return;
378
398
  }
@@ -558,6 +578,10 @@ function defineAgent(handlers) {
558
578
  handlePlayStopAck(message);
559
579
  return;
560
580
  }
581
+ if (isPlayPoseAckMessage(message)) {
582
+ handlePlayPoseAck(message);
583
+ return;
584
+ }
561
585
  if (isMixControlAckMessage(message)) {
562
586
  handleMixControlAck(message);
563
587
  return;