@voicethere/agent 0.7.11 → 0.7.13
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/dist/agent.js +24 -2
- 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 +24 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +3 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +68 -1
- package/dist/runtime.js.map +1 -1
- package/dist/templates/echo/agent.js +26 -2
- package/dist/templates/echo-dc/agent.js +26 -2
- package/dist/templates/game-sync/agent.js +26 -2
- package/dist/templates/positional-tts/agent.js +26 -2
- package/dist/templates/recording-consent/agent.js +26 -2
- package/dist/templates/registry.d.ts.map +1 -1
- package/dist/templates/registry.js +2 -1
- package/dist/templates/registry.js.map +1 -1
- package/dist/templates/spatial-showcase/agent.js +498 -29
- package/dist/templates/voice-showcase/agent.js +26 -2
- package/dist/templates/voice-starter/agent.js +26 -2
- package/dist/templates/webhooks/agent.js +26 -2
- package/dist/templates/webhooks-redis/agent.js +26 -2
- package/package.json +4 -4
- package/templates/README.md +10 -10
- package/templates/spatial-showcase/agent.ts +404 -34
- package/templates/spatial-showcase/protocol.ts +82 -1
- package/templates/spatial-showcase/sine.ts +66 -0
|
@@ -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;
|
|
@@ -10903,6 +10903,12 @@ function isPlayStopAckMessage(value) {
|
|
|
10903
10903
|
const msg = value;
|
|
10904
10904
|
return msg.type === "play_stop_ack" && typeof msg.requestId === "string";
|
|
10905
10905
|
}
|
|
10906
|
+
function isPlayPoseAckMessage(value) {
|
|
10907
|
+
if (!value || typeof value !== "object")
|
|
10908
|
+
return false;
|
|
10909
|
+
const msg = value;
|
|
10910
|
+
return msg.type === "play_pose_ack" && typeof msg.requestId === "string";
|
|
10911
|
+
}
|
|
10906
10912
|
function isRecordingControlAckMessage(value) {
|
|
10907
10913
|
if (!value || typeof value !== "object")
|
|
10908
10914
|
return false;
|
|
@@ -10963,7 +10969,7 @@ function isParentMessage(value) {
|
|
|
10963
10969
|
if (!value || typeof value !== "object")
|
|
10964
10970
|
return false;
|
|
10965
10971
|
const msg = value;
|
|
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";
|
|
10972
|
+
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";
|
|
10967
10973
|
}
|
|
10968
10974
|
function isSessionScopedParentMessage(value) {
|
|
10969
10975
|
return isParentMessage(value) && !isWebhookMessage(value);
|
|
@@ -10985,6 +10991,7 @@ var pendingRecordingAcks = /* @__PURE__ */ new Map();
|
|
|
10985
10991
|
var pendingPlayAcks = /* @__PURE__ */ new Map();
|
|
10986
10992
|
var pendingPlayStatusAcks = /* @__PURE__ */ new Map();
|
|
10987
10993
|
var pendingPlayStopAcks = /* @__PURE__ */ new Map();
|
|
10994
|
+
var pendingPlayPoseAcks = /* @__PURE__ */ new Map();
|
|
10988
10995
|
var pendingMixAcks = /* @__PURE__ */ new Map();
|
|
10989
10996
|
var pendingSttAcks = /* @__PURE__ */ new Map();
|
|
10990
10997
|
function handleRecordingControlAck(message) {
|
|
@@ -11039,6 +11046,19 @@ function handlePlayStopAck(message) {
|
|
|
11039
11046
|
requestId: message.requestId
|
|
11040
11047
|
});
|
|
11041
11048
|
}
|
|
11049
|
+
function handlePlayPoseAck(message) {
|
|
11050
|
+
const pending = pendingPlayPoseAcks.get(message.requestId);
|
|
11051
|
+
if (!pending)
|
|
11052
|
+
return;
|
|
11053
|
+
clearTimeout(pending.timer);
|
|
11054
|
+
pendingPlayPoseAcks.delete(message.requestId);
|
|
11055
|
+
pending.resolve({
|
|
11056
|
+
ok: message.ok,
|
|
11057
|
+
playId: message.playId,
|
|
11058
|
+
reason: message.reason,
|
|
11059
|
+
requestId: message.requestId
|
|
11060
|
+
});
|
|
11061
|
+
}
|
|
11042
11062
|
function handleMixControlAck(message) {
|
|
11043
11063
|
const pending = pendingMixAcks.get(message.requestId);
|
|
11044
11064
|
if (!pending)
|
|
@@ -11124,7 +11144,7 @@ function sendParentMessage(message) {
|
|
|
11124
11144
|
process.send?.(message);
|
|
11125
11145
|
return;
|
|
11126
11146
|
}
|
|
11127
|
-
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop") {
|
|
11147
|
+
if (msgType === "play" || msgType === "play_status" || msgType === "play_stop" || msgType === "play_pose") {
|
|
11128
11148
|
process.send?.(message);
|
|
11129
11149
|
return;
|
|
11130
11150
|
}
|
|
@@ -11310,6 +11330,10 @@ function defineAgent(handlers) {
|
|
|
11310
11330
|
handlePlayStopAck(message);
|
|
11311
11331
|
return;
|
|
11312
11332
|
}
|
|
11333
|
+
if (isPlayPoseAckMessage(message)) {
|
|
11334
|
+
handlePlayPoseAck(message);
|
|
11335
|
+
return;
|
|
11336
|
+
}
|
|
11313
11337
|
if (isMixControlAckMessage(message)) {
|
|
11314
11338
|
handleMixControlAck(message);
|
|
11315
11339
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voicethere/agent",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.13",
|
|
4
4
|
"description": "VoiceThere customer agent SDK — IPC types and runtime helpers for sandboxed child bundles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -95,9 +95,9 @@
|
|
|
95
95
|
"@node-webrtc-rust/sdk": ">=0.9.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@node-webrtc-rust/helpers": "0.9.
|
|
99
|
-
"@node-webrtc-rust/sdk": "0.9.
|
|
100
|
-
"@node-webrtc-rust/signaling": "0.9.
|
|
98
|
+
"@node-webrtc-rust/helpers": "0.9.9",
|
|
99
|
+
"@node-webrtc-rust/sdk": "0.9.9",
|
|
100
|
+
"@node-webrtc-rust/signaling": "0.9.9",
|
|
101
101
|
"@types/node": "22.20.1",
|
|
102
102
|
"http-server": "14.1.1",
|
|
103
103
|
"ioredis": "5.11.1",
|
package/templates/README.md
CHANGED
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
|
|
16
16
|
## Product vs e2e
|
|
17
17
|
|
|
18
|
-
| Kind | Dashboard create
|
|
19
|
-
| ----------- |
|
|
18
|
+
| Kind | Dashboard create | Prebuilt seed bundle | Typical consumer |
|
|
19
|
+
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ----------------------- |
|
|
20
20
|
| **product** | Yes (`echo`, `echo-dc`, `voice-starter`, `game-sync`, `voice-showcase`, `recording-consent`, `positional-tts`, `spatial-showcase`, `webhooks`, `webhooks-redis`) | Yes — `dist/templates/<id>/agent.js` | Platform project create |
|
|
21
|
-
| **e2e** | No
|
|
21
|
+
| **e2e** | No | No — build from sources at test time | `voicethere/e2e` smokes |
|
|
22
22
|
|
|
23
23
|
Product templates always set `seedOnCreate: true`. CI fails if a product template is missing its prebuilt bundle after `npm run build`.
|
|
24
24
|
|
|
@@ -83,17 +83,17 @@ Sources: `positional-tts/agent.ts` (defineAgent wiring), `positional-tts/orbit.t
|
|
|
83
83
|
|
|
84
84
|
Spatial audio showcase for `/showcase` — one agent template with three demos selected by `{ type: "join", demo }` on the control DataChannel:
|
|
85
85
|
|
|
86
|
-
| Demo
|
|
87
|
-
|
|
|
88
|
-
| `orbit`
|
|
89
|
-
| `soundboard` | Positional clip pads — browser sends `clipId` only (never URLs); agent resolves against an allowlisted `assetOrigin`
|
|
90
|
-
| `proximity`
|
|
86
|
+
| Demo | Behavior |
|
|
87
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `orbit` | Looping sine tone + TTS orbit the listener (`setPlayPose` + `setTtsPose`); STT echo off; `{ type: "orbit", action: "set" \| "say" }`; agent emits `{ type: "orbit_pose" }` |
|
|
89
|
+
| `soundboard` | Positional clip pads — browser sends `clipId` only (never URLs); agent resolves against an allowlisted `assetOrigin` |
|
|
90
|
+
| `proximity` | Shared mix room (`createMixGroup` + `setClientPose`); `{ type: "move" }`, `{ type: "mute_peer" }`; `{ type: "room_state" }` broadcast |
|
|
91
91
|
|
|
92
92
|
**Protocol:** inbound `join`, `orbit`, `pad`, `pad_stop`, `pad_status`, `move`, `mute_peer`, `leave`, `ping` — outbound `showcase_ack`, `orbit_pose`, `pad_progress`, `room_state`, `room_full`, `error`.
|
|
93
93
|
|
|
94
|
-
**Limits:** `MAX_ROOM_PEERS = 8`, `MAX_ACTIVE_PLAYS =
|
|
94
|
+
**Limits:** `MAX_ROOM_PEERS = 8`, `MAX_ACTIVE_PLAYS = 12` per session. Clip ids: `chime`, `bell`, `laser`, `impact`, `footsteps`, `rain-loop`, `cafe-loop`, `jingle`.
|
|
95
95
|
|
|
96
|
-
Sources: `spatial-showcase/agent.ts`, `protocol.ts`, `sounds.ts`, `room.ts`, `orbit.ts`.
|
|
96
|
+
Sources: `spatial-showcase/agent.ts`, `protocol.ts`, `sounds.ts`, `room.ts`, `orbit.ts`, `sine.ts`.
|
|
97
97
|
|
|
98
98
|
### `webhooks.ts` (`webhooks`)
|
|
99
99
|
|