@voicethere/agent 0.7.12 → 0.8.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.
- package/README.md +14 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +11 -2
- package/dist/runtime.js.map +1 -1
- package/dist/templates/echo/agent.js +1 -1
- package/dist/templates/echo-dc/agent.js +1 -1
- package/dist/templates/game-sync/agent.js +162 -125
- package/dist/templates/registry.d.ts +1 -1
- package/dist/templates/registry.d.ts.map +1 -1
- package/dist/templates/registry.js +42 -26
- package/dist/templates/registry.js.map +1 -1
- package/dist/templates/spatial-showcase/agent.js +261 -22
- package/dist/templates/voice-starter/agent.js +1 -1
- package/dist/templates/webhooks/agent.js +2 -2
- package/dist/templates/webhooks-redis/agent.js +11 -4
- package/dist/templates/world-sync/agent.js +829 -0
- package/dist/templates/world-sync-binary/agent.js +1031 -0
- package/package.json +3 -2
- package/templates/README.md +41 -69
- package/templates/crash/README.md +13 -0
- package/templates/echo/README.md +13 -0
- package/templates/{echo.ts → echo/agent.ts} +1 -1
- package/templates/echo-dc/README.md +13 -0
- package/templates/{echo-dc.ts → echo-dc/agent.ts} +1 -1
- package/templates/echo-smoke/README.md +13 -0
- package/templates/game-sync/README.md +21 -0
- package/templates/{game-sync.ts → game-sync/agent.ts} +126 -94
- package/templates/{game-sync-redis.ts → game-sync/redis.ts} +4 -13
- package/templates/{game-sync-sim.ts → game-sync/sim.ts} +14 -7
- package/templates/{game-sync-world-layout.ts → game-sync/world-layout.ts} +72 -30
- package/templates/game-sync-smoke/README.md +13 -0
- package/templates/mix-smoke/README.md +13 -0
- package/templates/positional-tts/README.md +13 -0
- package/templates/recording-consent/README.md +13 -0
- package/templates/redis-sync/README.md +23 -0
- package/templates/redis-sync/agent.ts +72 -95
- package/templates/redis-sync/world-layout.ts +103 -26
- package/templates/spatial-showcase/README.md +13 -0
- package/templates/spatial-showcase/agent.ts +245 -18
- package/templates/spatial-showcase/protocol.ts +79 -0
- package/templates/spatial-showcase/sine.ts +28 -5
- package/templates/voice-showcase/README.md +13 -0
- package/templates/voice-starter/README.md +13 -0
- package/templates/webhooks/README.md +13 -0
- package/templates/{webhooks.ts → webhooks/agent.ts} +1 -1
- package/templates/webhooks-redis/README.md +13 -0
- package/templates/{webhooks-redis.ts → webhooks-redis/agent.ts} +9 -9
- package/templates/world-sync/README.md +20 -0
- package/templates/world-sync/agent.ts +62 -0
- package/templates/world-sync-binary/README.md +21 -0
- package/templates/world-sync-binary/agent.ts +107 -0
- package/templates/world-sync-binary/protocol.ts +281 -0
- /package/templates/{crash.ts → crash/agent.ts} +0 -0
- /package/templates/{echo-smoke.ts → echo-smoke/agent.ts} +0 -0
- /package/templates/{game-sync-protocol.ts → game-sync/protocol.ts} +0 -0
- /package/templates/{game-sync-smoke.ts → game-sync-smoke/agent.ts} +0 -0
- /package/templates/{mix-smoke.ts → mix-smoke/agent.ts} +0 -0
- /package/templates/{agent.ts → voice-starter/agent.ts} +0 -0
|
@@ -1137,6 +1137,8 @@ function resolveClipUrl(assetOrigin, clipId) {
|
|
|
1137
1137
|
var SHOWCASE_DEMOS = /* @__PURE__ */ new Set(["orbit", "soundboard", "proximity"]);
|
|
1138
1138
|
var MAX_SAY_TEXT_LENGTH = 200;
|
|
1139
1139
|
var MAX_XZ = 5;
|
|
1140
|
+
var ORBIT_SINE_MIN_FREQUENCY_HZ = 110;
|
|
1141
|
+
var ORBIT_SINE_MAX_FREQUENCY_HZ = 1760;
|
|
1140
1142
|
function isFiniteNumber(value) {
|
|
1141
1143
|
return typeof value === "number" && Number.isFinite(value);
|
|
1142
1144
|
}
|
|
@@ -1146,6 +1148,9 @@ function clampVolume(value) {
|
|
|
1146
1148
|
function isInXzRange(value) {
|
|
1147
1149
|
return value >= -MAX_XZ && value <= MAX_XZ;
|
|
1148
1150
|
}
|
|
1151
|
+
function isOrbitSineFrequencyHz(value) {
|
|
1152
|
+
return value >= ORBIT_SINE_MIN_FREQUENCY_HZ && value <= ORBIT_SINE_MAX_FREQUENCY_HZ;
|
|
1153
|
+
}
|
|
1149
1154
|
function isMixPlacement(value) {
|
|
1150
1155
|
return value === "center" || value === "left" || value === "right" || value === "front" || value === "behind" || value === "below" || value === "above";
|
|
1151
1156
|
}
|
|
@@ -1194,15 +1199,33 @@ function parseShowcaseMessage(message) {
|
|
|
1194
1199
|
if (set.paused !== void 0 && typeof set.paused !== "boolean") {
|
|
1195
1200
|
return null;
|
|
1196
1201
|
}
|
|
1202
|
+
if (set.frequencyHz !== void 0 && (!isFiniteNumber(set.frequencyHz) || !isOrbitSineFrequencyHz(set.frequencyHz))) {
|
|
1203
|
+
return null;
|
|
1204
|
+
}
|
|
1205
|
+
if (set.sinePlaying !== void 0 && typeof set.sinePlaying !== "boolean") {
|
|
1206
|
+
return null;
|
|
1207
|
+
}
|
|
1197
1208
|
return {
|
|
1198
1209
|
type: "orbit",
|
|
1199
1210
|
action: "set",
|
|
1200
1211
|
...set.radius !== void 0 ? { radius: set.radius } : {},
|
|
1201
1212
|
...set.periodSec !== void 0 ? { periodSec: set.periodSec } : {},
|
|
1202
1213
|
...set.elevation !== void 0 ? { elevation: set.elevation } : {},
|
|
1203
|
-
...set.paused !== void 0 ? { paused: set.paused } : {}
|
|
1214
|
+
...set.paused !== void 0 ? { paused: set.paused } : {},
|
|
1215
|
+
...set.frequencyHz !== void 0 ? { frequencyHz: set.frequencyHz } : {},
|
|
1216
|
+
...set.sinePlaying !== void 0 ? { sinePlaying: set.sinePlaying } : {}
|
|
1204
1217
|
};
|
|
1205
1218
|
}
|
|
1219
|
+
if (orbit.action === "place") {
|
|
1220
|
+
const place = message;
|
|
1221
|
+
if (!isFiniteNumber(place.x) || !isInXzRange(place.x)) {
|
|
1222
|
+
return null;
|
|
1223
|
+
}
|
|
1224
|
+
if (!isFiniteNumber(place.z) || !isInXzRange(place.z)) {
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1227
|
+
return { type: "orbit", action: "place", x: place.x, z: place.z };
|
|
1228
|
+
}
|
|
1206
1229
|
if (orbit.action === "say") {
|
|
1207
1230
|
const say = message;
|
|
1208
1231
|
if (typeof say.text !== "string" || say.text.length === 0 || say.text.length > MAX_SAY_TEXT_LENGTH) {
|
|
@@ -1254,6 +1277,24 @@ function parseShowcaseMessage(message) {
|
|
|
1254
1277
|
}
|
|
1255
1278
|
return { type: "pad_status", playId: status.playId.trim() };
|
|
1256
1279
|
}
|
|
1280
|
+
case "pad_move": {
|
|
1281
|
+
const padMove = message;
|
|
1282
|
+
if (!isNonEmptyString(padMove.playId)) {
|
|
1283
|
+
return null;
|
|
1284
|
+
}
|
|
1285
|
+
if (!isFiniteNumber(padMove.x) || !isInXzRange(padMove.x)) {
|
|
1286
|
+
return null;
|
|
1287
|
+
}
|
|
1288
|
+
if (!isFiniteNumber(padMove.z) || !isInXzRange(padMove.z)) {
|
|
1289
|
+
return null;
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
type: "pad_move",
|
|
1293
|
+
playId: padMove.playId.trim(),
|
|
1294
|
+
x: padMove.x,
|
|
1295
|
+
z: padMove.z
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1257
1298
|
case "move": {
|
|
1258
1299
|
const move = message;
|
|
1259
1300
|
if (!isFiniteNumber(move.x) || !isInXzRange(move.x)) {
|
|
@@ -1368,12 +1409,22 @@ var ProximityRoom = class {
|
|
|
1368
1409
|
var ORBIT_SINE_DURATION_MS = 2e3;
|
|
1369
1410
|
var ORBIT_SINE_FREQUENCY_HZ = 440;
|
|
1370
1411
|
var ORBIT_SINE_AMPLITUDE = 8e3;
|
|
1412
|
+
var ORBIT_SINE_SAMPLE_RATE = 16e3;
|
|
1371
1413
|
var ORBIT_SINE_INLINE_URL = "https://example.com/inline-orbit-sine.wav";
|
|
1372
|
-
function
|
|
1373
|
-
const
|
|
1414
|
+
function orbitSineSampleCount(durationMs = ORBIT_SINE_DURATION_MS, frequencyHz = ORBIT_SINE_FREQUENCY_HZ, sampleRate = ORBIT_SINE_SAMPLE_RATE) {
|
|
1415
|
+
const targetCycles = durationMs / 1e3 * frequencyHz;
|
|
1416
|
+
const cycles = Math.max(1, Math.floor(targetCycles));
|
|
1417
|
+
return Math.round(cycles * sampleRate / frequencyHz);
|
|
1418
|
+
}
|
|
1419
|
+
function orbitSineClipDurationMs(durationMs = ORBIT_SINE_DURATION_MS, frequencyHz = ORBIT_SINE_FREQUENCY_HZ, sampleRate = ORBIT_SINE_SAMPLE_RATE) {
|
|
1420
|
+
const numSamples = orbitSineSampleCount(durationMs, frequencyHz, sampleRate);
|
|
1421
|
+
return numSamples / sampleRate * 1e3;
|
|
1422
|
+
}
|
|
1423
|
+
function buildOrbitSineInlineClipBase64(durationMs = ORBIT_SINE_DURATION_MS, frequencyHz = ORBIT_SINE_FREQUENCY_HZ, amplitude = ORBIT_SINE_AMPLITUDE, phaseRad = 0) {
|
|
1424
|
+
const sampleRate = ORBIT_SINE_SAMPLE_RATE;
|
|
1374
1425
|
const channels = 1;
|
|
1375
1426
|
const bytesPerSample = 2;
|
|
1376
|
-
const numSamples =
|
|
1427
|
+
const numSamples = orbitSineSampleCount(durationMs, frequencyHz, sampleRate);
|
|
1377
1428
|
const dataSize = numSamples * channels * bytesPerSample;
|
|
1378
1429
|
const buffer = Buffer.alloc(44 + dataSize);
|
|
1379
1430
|
buffer.write("RIFF", 0);
|
|
@@ -1392,7 +1443,7 @@ function buildOrbitSineInlineClipBase64(durationMs = ORBIT_SINE_DURATION_MS, fre
|
|
|
1392
1443
|
for (let i = 0; i < numSamples; i++) {
|
|
1393
1444
|
const t = i / sampleRate;
|
|
1394
1445
|
const sample = Math.round(
|
|
1395
|
-
amplitude * Math.sin(2 * Math.PI * frequencyHz * t)
|
|
1446
|
+
amplitude * Math.sin(2 * Math.PI * frequencyHz * t + phaseRad)
|
|
1396
1447
|
);
|
|
1397
1448
|
buffer.writeInt16LE(sample, 44 + i * 2);
|
|
1398
1449
|
}
|
|
@@ -1405,6 +1456,7 @@ var ORBIT_POSE_EMIT_MS = 100;
|
|
|
1405
1456
|
var ROOM_STATE_TICK_MS = 100;
|
|
1406
1457
|
var LOOP_PAD_POLL_MS = 250;
|
|
1407
1458
|
var ORBIT_SINE_POLL_MS = 250;
|
|
1459
|
+
var ORBIT_SINE_GAPLESS_LEAD_MS = 200;
|
|
1408
1460
|
var ORBIT_SINE_VOLUME = 0.25;
|
|
1409
1461
|
var MAX_ACTIVE_PLAYS = 12;
|
|
1410
1462
|
var SHOWCASE_ROOM_GROUP_ID = "showcase-room";
|
|
@@ -1467,6 +1519,9 @@ function defaultSessionState(demo, assetOrigin) {
|
|
|
1467
1519
|
playIds: /* @__PURE__ */ new Set(),
|
|
1468
1520
|
loopPads: /* @__PURE__ */ new Map(),
|
|
1469
1521
|
loopPollTimers: /* @__PURE__ */ new Map(),
|
|
1522
|
+
orbitSineFrequencyHz: 440,
|
|
1523
|
+
orbitSineEnabled: true,
|
|
1524
|
+
orbitSinePhaseRad: 0,
|
|
1470
1525
|
inProximityRoom: false
|
|
1471
1526
|
};
|
|
1472
1527
|
}
|
|
@@ -1508,27 +1563,114 @@ function clearAllPlays(sessionId, state) {
|
|
|
1508
1563
|
state.loopPollTimers.clear();
|
|
1509
1564
|
}
|
|
1510
1565
|
function currentOrbitPose(state) {
|
|
1566
|
+
if (state.orbitManualPose) {
|
|
1567
|
+
const elevation = state.orbit.elevation ?? 0;
|
|
1568
|
+
return {
|
|
1569
|
+
position: {
|
|
1570
|
+
x: state.orbitManualPose.x,
|
|
1571
|
+
y: elevation,
|
|
1572
|
+
z: state.orbitManualPose.z
|
|
1573
|
+
},
|
|
1574
|
+
orientation: { x: 0, y: 0, z: 0, w: 1 }
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1511
1577
|
if (!state.orbitStartMs) {
|
|
1512
1578
|
return orbitTtsPose(0, state.orbit);
|
|
1513
1579
|
}
|
|
1514
1580
|
const elapsedSec = (Date.now() - state.orbitStartMs) / 1e3;
|
|
1515
1581
|
return orbitTtsPose(elapsedSec, state.orbit);
|
|
1516
1582
|
}
|
|
1583
|
+
function orbitPoseFromXz(state, x, z) {
|
|
1584
|
+
const elevation = state.orbit.elevation ?? 0;
|
|
1585
|
+
return {
|
|
1586
|
+
position: { x, y: elevation, z },
|
|
1587
|
+
orientation: { x: 0, y: 0, z: 0, w: 1 }
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
function syncOrbitClockFromManualPose(state) {
|
|
1591
|
+
const manual = state.orbitManualPose;
|
|
1592
|
+
if (!manual) {
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
const periodSec = state.orbit.periodSec ?? 2 * Math.PI;
|
|
1596
|
+
const angleRad = Math.atan2(manual.z, manual.x);
|
|
1597
|
+
const elapsedSec = angleRad * periodSec / (2 * Math.PI);
|
|
1598
|
+
state.orbitStartMs = Date.now() - elapsedSec * 1e3;
|
|
1599
|
+
state.orbitManualPose = void 0;
|
|
1600
|
+
}
|
|
1517
1601
|
function clearOrbitSinePoll(state) {
|
|
1518
1602
|
if (state.orbitSinePollTimer) {
|
|
1519
1603
|
clearInterval(state.orbitSinePollTimer);
|
|
1520
1604
|
state.orbitSinePollTimer = void 0;
|
|
1521
1605
|
}
|
|
1522
1606
|
}
|
|
1607
|
+
function clearOrbitSineRestartTimer(state) {
|
|
1608
|
+
if (state.orbitSineRestartTimer) {
|
|
1609
|
+
clearTimeout(state.orbitSineRestartTimer);
|
|
1610
|
+
state.orbitSineRestartTimer = void 0;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1523
1613
|
async function stopOrbitSine(state) {
|
|
1524
1614
|
clearOrbitSinePoll(state);
|
|
1615
|
+
clearOrbitSineRestartTimer(state);
|
|
1525
1616
|
const playId = state.orbitSinePlayId;
|
|
1526
1617
|
state.orbitSinePlayId = void 0;
|
|
1527
1618
|
if (playId) {
|
|
1528
1619
|
await stopPlay(playId);
|
|
1529
1620
|
}
|
|
1530
1621
|
}
|
|
1622
|
+
function orbitSineClipBytes(state) {
|
|
1623
|
+
return buildOrbitSineInlineClipBase64(
|
|
1624
|
+
ORBIT_SINE_DURATION_MS,
|
|
1625
|
+
state.orbitSineFrequencyHz,
|
|
1626
|
+
void 0,
|
|
1627
|
+
state.orbitSinePhaseRad
|
|
1628
|
+
);
|
|
1629
|
+
}
|
|
1630
|
+
function orbitSineClipDuration(state) {
|
|
1631
|
+
return orbitSineClipDurationMs(
|
|
1632
|
+
ORBIT_SINE_DURATION_MS,
|
|
1633
|
+
state.orbitSineFrequencyHz
|
|
1634
|
+
);
|
|
1635
|
+
}
|
|
1636
|
+
function scheduleOrbitSineGaplessRestart(sessionId, state) {
|
|
1637
|
+
clearOrbitSineRestartTimer(state);
|
|
1638
|
+
const durationMs = orbitSineClipDuration(state);
|
|
1639
|
+
const delayMs = Math.max(0, durationMs - ORBIT_SINE_GAPLESS_LEAD_MS);
|
|
1640
|
+
state.orbitSineRestartTimer = setTimeout(() => {
|
|
1641
|
+
state.orbitSineRestartTimer = void 0;
|
|
1642
|
+
void restartOrbitSineGapless(sessionId, state);
|
|
1643
|
+
}, delayMs);
|
|
1644
|
+
}
|
|
1645
|
+
async function restartOrbitSineGapless(sessionId, state) {
|
|
1646
|
+
if (!state.orbitSineEnabled || !state.orbitSinePlayId) {
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
const previousPlayId = state.orbitSinePlayId;
|
|
1650
|
+
const result = await play({
|
|
1651
|
+
url: ORBIT_SINE_INLINE_URL,
|
|
1652
|
+
bytes: orbitSineClipBytes(state),
|
|
1653
|
+
sessionIds: [sessionId],
|
|
1654
|
+
volume: ORBIT_SINE_VOLUME,
|
|
1655
|
+
pose: currentOrbitPose(state)
|
|
1656
|
+
});
|
|
1657
|
+
if (!result.ok || !result.playId) {
|
|
1658
|
+
agentLog(
|
|
1659
|
+
"warn",
|
|
1660
|
+
`spatial-showcase orbit sine gapless restart failed: ${result.reason ?? "play_failed"}`,
|
|
1661
|
+
sessionId
|
|
1662
|
+
);
|
|
1663
|
+
startOrbitSineLoopPoll(sessionId, state);
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
state.orbitSinePlayId = result.playId;
|
|
1667
|
+
void stopPlay(previousPlayId);
|
|
1668
|
+
scheduleOrbitSineGaplessRestart(sessionId, state);
|
|
1669
|
+
}
|
|
1531
1670
|
function startOrbitSineLoopPoll(sessionId, state) {
|
|
1671
|
+
if (state.orbitSineRestartTimer) {
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1532
1674
|
clearOrbitSinePoll(state);
|
|
1533
1675
|
const playId = state.orbitSinePlayId;
|
|
1534
1676
|
if (!playId) {
|
|
@@ -1536,7 +1678,7 @@ function startOrbitSineLoopPoll(sessionId, state) {
|
|
|
1536
1678
|
}
|
|
1537
1679
|
state.orbitSinePollTimer = setInterval(() => {
|
|
1538
1680
|
void (async () => {
|
|
1539
|
-
if (!state.orbitSinePlayId) {
|
|
1681
|
+
if (!state.orbitSinePlayId || state.orbitSineRestartTimer) {
|
|
1540
1682
|
clearOrbitSinePoll(state);
|
|
1541
1683
|
return;
|
|
1542
1684
|
}
|
|
@@ -1545,25 +1687,19 @@ function startOrbitSineLoopPoll(sessionId, state) {
|
|
|
1545
1687
|
return;
|
|
1546
1688
|
}
|
|
1547
1689
|
if (status.status === "ended") {
|
|
1548
|
-
|
|
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
|
-
}
|
|
1690
|
+
await restartOrbitSineGapless(sessionId, state);
|
|
1558
1691
|
}
|
|
1559
1692
|
})();
|
|
1560
1693
|
}, ORBIT_SINE_POLL_MS);
|
|
1561
1694
|
}
|
|
1562
1695
|
async function startOrbitSinePlay(sessionId, state) {
|
|
1696
|
+
if (!state.orbitSineEnabled) {
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1563
1699
|
await stopOrbitSine(state);
|
|
1564
1700
|
const result = await play({
|
|
1565
1701
|
url: ORBIT_SINE_INLINE_URL,
|
|
1566
|
-
bytes:
|
|
1702
|
+
bytes: orbitSineClipBytes(state),
|
|
1567
1703
|
sessionIds: [sessionId],
|
|
1568
1704
|
volume: ORBIT_SINE_VOLUME,
|
|
1569
1705
|
pose: currentOrbitPose(state)
|
|
@@ -1577,10 +1713,11 @@ async function startOrbitSinePlay(sessionId, state) {
|
|
|
1577
1713
|
return;
|
|
1578
1714
|
}
|
|
1579
1715
|
state.orbitSinePlayId = result.playId;
|
|
1716
|
+
scheduleOrbitSineGaplessRestart(sessionId, state);
|
|
1580
1717
|
startOrbitSineLoopPoll(sessionId, state);
|
|
1581
1718
|
}
|
|
1582
1719
|
function emitOrbitPose(sessionId, state) {
|
|
1583
|
-
if (!state.orbitStartMs) {
|
|
1720
|
+
if (!state.orbitStartMs && !state.orbitManualPose) {
|
|
1584
1721
|
return;
|
|
1585
1722
|
}
|
|
1586
1723
|
const now = Date.now();
|
|
@@ -1588,9 +1725,8 @@ function emitOrbitPose(sessionId, state) {
|
|
|
1588
1725
|
return;
|
|
1589
1726
|
}
|
|
1590
1727
|
state.lastOrbitPoseEmitMs = now;
|
|
1591
|
-
const
|
|
1592
|
-
const
|
|
1593
|
-
const angleRad = 2 * Math.PI * elapsedSec / (state.orbit.periodSec ?? 2 * Math.PI);
|
|
1728
|
+
const pose = currentOrbitPose(state);
|
|
1729
|
+
const angleRad = state.orbitManualPose ? Math.atan2(state.orbitManualPose.z, state.orbitManualPose.x) : 2 * Math.PI * (now - state.orbitStartMs) / 1e3 / (state.orbit.periodSec ?? 2 * Math.PI);
|
|
1594
1730
|
sendToClient(sessionId, {
|
|
1595
1731
|
type: "orbit_pose",
|
|
1596
1732
|
angleDeg: angleRad * 180 / Math.PI,
|
|
@@ -1598,12 +1734,22 @@ function emitOrbitPose(sessionId, state) {
|
|
|
1598
1734
|
z: pose.position.z
|
|
1599
1735
|
});
|
|
1600
1736
|
}
|
|
1737
|
+
function emitOrbitPlacePose(sessionId, state, x, z) {
|
|
1738
|
+
state.lastOrbitPoseEmitMs = Date.now();
|
|
1739
|
+
const angleRad = Math.atan2(z, x);
|
|
1740
|
+
sendToClient(sessionId, {
|
|
1741
|
+
type: "orbit_pose",
|
|
1742
|
+
angleDeg: angleRad * 180 / Math.PI,
|
|
1743
|
+
x,
|
|
1744
|
+
z
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1601
1747
|
function startOrbitDemo(sessionId, state) {
|
|
1602
1748
|
stopOrbitInterval(state);
|
|
1603
1749
|
beginOrbitClock(state);
|
|
1604
1750
|
void startOrbitSinePlay(sessionId, state);
|
|
1605
1751
|
state.orbitTimer = setInterval(() => {
|
|
1606
|
-
if (state.orbit.paused || !state.orbitStartMs) {
|
|
1752
|
+
if (state.orbit.paused || !state.orbitStartMs && !state.orbitManualPose) {
|
|
1607
1753
|
return;
|
|
1608
1754
|
}
|
|
1609
1755
|
const pose = currentOrbitPose(state);
|
|
@@ -1758,6 +1904,24 @@ async function handlePadPlay(sessionId, state, clipId, x, z, volume, placement)
|
|
|
1758
1904
|
void startLoopPadPoll(sessionId, state, result.playId, pad);
|
|
1759
1905
|
}
|
|
1760
1906
|
}
|
|
1907
|
+
async function handlePadMove(sessionId, state, playId, x, z) {
|
|
1908
|
+
if (!state.playIds.has(playId)) {
|
|
1909
|
+
ackError(sessionId, "pad_move", "unknown_play");
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1912
|
+
const poseResult = await setPlayPose(playId, poseAt(x, z));
|
|
1913
|
+
if (!poseResult.ok) {
|
|
1914
|
+
ackError(sessionId, "pad_move", poseResult.reason ?? "set_pose_failed");
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
const loopPad = state.loopPads.get(playId);
|
|
1918
|
+
if (loopPad) {
|
|
1919
|
+
loopPad.x = x;
|
|
1920
|
+
loopPad.z = z;
|
|
1921
|
+
delete loopPad.placement;
|
|
1922
|
+
}
|
|
1923
|
+
ack(sessionId, "pad_move", { playId, x, z });
|
|
1924
|
+
}
|
|
1761
1925
|
async function handleJoin(sessionId, demo, assetOrigin) {
|
|
1762
1926
|
teardownSession(sessionId);
|
|
1763
1927
|
const state = defaultSessionState(demo, assetOrigin);
|
|
@@ -1884,11 +2048,54 @@ async function dispatchMessage(sessionId, message) {
|
|
|
1884
2048
|
state.orbit.elevation = message.elevation;
|
|
1885
2049
|
}
|
|
1886
2050
|
if (message.paused !== void 0) {
|
|
2051
|
+
if (message.paused === false && state.orbitManualPose) {
|
|
2052
|
+
syncOrbitClockFromManualPose(state);
|
|
2053
|
+
}
|
|
1887
2054
|
state.orbit.paused = message.paused;
|
|
1888
2055
|
}
|
|
2056
|
+
if (message.frequencyHz !== void 0) {
|
|
2057
|
+
state.orbitSineFrequencyHz = message.frequencyHz;
|
|
2058
|
+
if (state.orbitSineEnabled && state.orbitSinePlayId) {
|
|
2059
|
+
void startOrbitSinePlay(sessionId, state);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
if (message.sinePlaying !== void 0) {
|
|
2063
|
+
state.orbitSineEnabled = message.sinePlaying;
|
|
2064
|
+
if (message.sinePlaying) {
|
|
2065
|
+
if (!state.orbitSinePlayId) {
|
|
2066
|
+
void startOrbitSinePlay(sessionId, state);
|
|
2067
|
+
}
|
|
2068
|
+
} else {
|
|
2069
|
+
void stopOrbitSine(state);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
1889
2072
|
ack(sessionId, "orbit_set");
|
|
1890
2073
|
return;
|
|
1891
2074
|
}
|
|
2075
|
+
if (message.action === "place") {
|
|
2076
|
+
state.orbit.paused = true;
|
|
2077
|
+
state.orbitManualPose = { x: message.x, z: message.z };
|
|
2078
|
+
const pose = orbitPoseFromXz(state, message.x, message.z);
|
|
2079
|
+
if (state.orbitSinePlayId) {
|
|
2080
|
+
void safeMixCall(
|
|
2081
|
+
sessionId,
|
|
2082
|
+
"setPlayPose",
|
|
2083
|
+
() => setPlayPose(state.orbitSinePlayId, pose)
|
|
2084
|
+
);
|
|
2085
|
+
}
|
|
2086
|
+
void safeMixCall(
|
|
2087
|
+
sessionId,
|
|
2088
|
+
"setTtsPose",
|
|
2089
|
+
() => setTtsPose(sessionId, pose)
|
|
2090
|
+
);
|
|
2091
|
+
emitOrbitPlacePose(sessionId, state, message.x, message.z);
|
|
2092
|
+
ack(sessionId, "orbit_place");
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
sendToClient(sessionId, {
|
|
2096
|
+
type: "orbit_say_status",
|
|
2097
|
+
status: "playing"
|
|
2098
|
+
});
|
|
1892
2099
|
speak(sessionId, message.text);
|
|
1893
2100
|
ack(sessionId, "orbit_say");
|
|
1894
2101
|
return;
|
|
@@ -1945,6 +2152,20 @@ async function dispatchMessage(sessionId, message) {
|
|
|
1945
2152
|
}
|
|
1946
2153
|
return;
|
|
1947
2154
|
}
|
|
2155
|
+
case "pad_move": {
|
|
2156
|
+
if (state.demo !== "soundboard") {
|
|
2157
|
+
ackError(sessionId, "pad_move", "wrong_demo");
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
await handlePadMove(
|
|
2161
|
+
sessionId,
|
|
2162
|
+
state,
|
|
2163
|
+
message.playId,
|
|
2164
|
+
message.x,
|
|
2165
|
+
message.z
|
|
2166
|
+
);
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
1948
2169
|
case "move": {
|
|
1949
2170
|
if (state.demo !== "proximity") {
|
|
1950
2171
|
ackError(sessionId, "move", "wrong_demo");
|
|
@@ -2027,6 +2248,23 @@ defineAgent({
|
|
|
2027
2248
|
}
|
|
2028
2249
|
void dispatchMessage(ctx.sessionId, message);
|
|
2029
2250
|
},
|
|
2251
|
+
onSpeechEvent(ctx, event) {
|
|
2252
|
+
const state = sessions.get(ctx.sessionId);
|
|
2253
|
+
if (!state || state.demo !== "orbit") {
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
2256
|
+
if (event.type === "agent_speaking_start") {
|
|
2257
|
+
sendToClient(ctx.sessionId, {
|
|
2258
|
+
type: "orbit_say_status",
|
|
2259
|
+
status: "playing"
|
|
2260
|
+
});
|
|
2261
|
+
} else if (event.type === "agent_speaking_end") {
|
|
2262
|
+
sendToClient(ctx.sessionId, {
|
|
2263
|
+
type: "orbit_say_status",
|
|
2264
|
+
status: "ended"
|
|
2265
|
+
});
|
|
2266
|
+
}
|
|
2267
|
+
},
|
|
2030
2268
|
onSessionEnd({ sessionId }) {
|
|
2031
2269
|
teardownSession(sessionId);
|
|
2032
2270
|
agentLog("info", `spatial-showcase session_end ${sessionId}`, sessionId);
|
|
@@ -2034,5 +2272,6 @@ defineAgent({
|
|
|
2034
2272
|
});
|
|
2035
2273
|
export {
|
|
2036
2274
|
MAX_ACTIVE_PLAYS,
|
|
2275
|
+
handlePadMove,
|
|
2037
2276
|
handlePadPlay
|
|
2038
2277
|
};
|
|
@@ -779,7 +779,7 @@ function agentLog(level, message, fieldsOrSessionId, sessionId) {
|
|
|
779
779
|
sendParentMessage(buildAgentLogPayload(level, message, fields, resolvedSessionId));
|
|
780
780
|
}
|
|
781
781
|
|
|
782
|
-
// templates/agent.ts
|
|
782
|
+
// templates/voice-starter/agent.ts
|
|
783
783
|
var peers = /* @__PURE__ */ new Map();
|
|
784
784
|
function peerState(sessionId) {
|
|
785
785
|
let state = peers.get(sessionId);
|
|
@@ -2,7 +2,7 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
const require = createRequire(import.meta.url);
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
// templates/webhooks.ts
|
|
5
|
+
// templates/webhooks/agent.ts
|
|
6
6
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
7
7
|
|
|
8
8
|
// dist/runtime.js
|
|
@@ -790,7 +790,7 @@ function agentLog(level, message, fieldsOrSessionId, sessionId) {
|
|
|
790
790
|
sendParentMessage(buildAgentLogPayload(level, message, fields, resolvedSessionId));
|
|
791
791
|
}
|
|
792
792
|
|
|
793
|
-
// templates/webhooks.ts
|
|
793
|
+
// templates/webhooks/agent.ts
|
|
794
794
|
var WEBHOOK_SIGNATURE_HEADER = "x-agent-webhook-signature";
|
|
795
795
|
var connectedSessions = /* @__PURE__ */ new Set();
|
|
796
796
|
function getHeaderCaseInsensitive(headers, name) {
|
|
@@ -10753,7 +10753,7 @@ var require_built3 = __commonJS({
|
|
|
10753
10753
|
}
|
|
10754
10754
|
});
|
|
10755
10755
|
|
|
10756
|
-
// templates/webhooks-redis.ts
|
|
10756
|
+
// templates/webhooks-redis/agent.ts
|
|
10757
10757
|
var import_ioredis = __toESM(require_built3(), 1);
|
|
10758
10758
|
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
10759
10759
|
|
|
@@ -11539,7 +11539,7 @@ function agentLog(level, message, fieldsOrSessionId, sessionId) {
|
|
|
11539
11539
|
sendParentMessage(buildAgentLogPayload(level, message, fields, resolvedSessionId));
|
|
11540
11540
|
}
|
|
11541
11541
|
|
|
11542
|
-
// templates/webhooks-redis.ts
|
|
11542
|
+
// templates/webhooks-redis/agent.ts
|
|
11543
11543
|
var WEBHOOK_SIGNATURE_HEADER = "x-agent-webhook-signature";
|
|
11544
11544
|
var REDIS_COUNTER_KEY = "agent:webhook:event_count";
|
|
11545
11545
|
var LUA_INCREMENT_COUNTER = `
|
|
@@ -11582,7 +11582,7 @@ defineAgent({
|
|
|
11582
11582
|
);
|
|
11583
11583
|
return;
|
|
11584
11584
|
}
|
|
11585
|
-
redis = new import_ioredis.
|
|
11585
|
+
redis = new import_ioredis.Redis(redisUrl, {
|
|
11586
11586
|
maxRetriesPerRequest: 3,
|
|
11587
11587
|
lazyConnect: true
|
|
11588
11588
|
});
|
|
@@ -11614,7 +11614,11 @@ defineAgent({
|
|
|
11614
11614
|
}
|
|
11615
11615
|
let eventCount = null;
|
|
11616
11616
|
if (redis) {
|
|
11617
|
-
const result = await redis.eval(
|
|
11617
|
+
const result = await redis.eval(
|
|
11618
|
+
LUA_INCREMENT_COUNTER,
|
|
11619
|
+
1,
|
|
11620
|
+
REDIS_COUNTER_KEY
|
|
11621
|
+
);
|
|
11618
11622
|
eventCount = typeof result === "number" ? result : Number(result);
|
|
11619
11623
|
}
|
|
11620
11624
|
const sessionIds = ctx.sessionIds.length > 0 ? ctx.sessionIds : [...connectedSessions];
|
|
@@ -11641,3 +11645,6 @@ defineAgent({
|
|
|
11641
11645
|
);
|
|
11642
11646
|
}
|
|
11643
11647
|
});
|
|
11648
|
+
export {
|
|
11649
|
+
LUA_INCREMENT_COUNTER
|
|
11650
|
+
};
|