hci-atrium 0.3.1 → 0.4.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.
Files changed (77) hide show
  1. package/README.md +75 -24
  2. package/dist/atrium.d.ts +126 -42
  3. package/dist/atrium.d.ts.map +1 -1
  4. package/dist/atrium.js +192 -87
  5. package/dist/atrium.js.map +1 -1
  6. package/dist/dash.d.ts +3 -3
  7. package/dist/dash.d.ts.map +1 -1
  8. package/dist/dash.js +1 -2
  9. package/dist/dash.js.map +1 -1
  10. package/dist/env.d.ts +14 -0
  11. package/dist/env.d.ts.map +1 -1
  12. package/dist/env.js +22 -0
  13. package/dist/env.js.map +1 -1
  14. package/dist/index.d.ts +4 -4
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +11 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/models.d.ts +84 -31
  19. package/dist/models.d.ts.map +1 -1
  20. package/dist/models.js +97 -25
  21. package/dist/models.js.map +1 -1
  22. package/dist/player/play-command.d.ts +6 -6
  23. package/dist/player/play-command.d.ts.map +1 -1
  24. package/dist/player/play-intent.d.ts.map +1 -1
  25. package/dist/player/play-intent.js +2 -1
  26. package/dist/player/play-intent.js.map +1 -1
  27. package/dist/player/runtime.d.ts +7 -3
  28. package/dist/player/runtime.d.ts.map +1 -1
  29. package/dist/player/runtime.js.map +1 -1
  30. package/dist/react/use-room-connection.d.ts +4 -1
  31. package/dist/react/use-room-connection.d.ts.map +1 -1
  32. package/dist/react/use-room-connection.js +5 -1
  33. package/dist/react/use-room-connection.js.map +1 -1
  34. package/dist/rooms/index.d.ts +3 -1
  35. package/dist/rooms/index.d.ts.map +1 -1
  36. package/dist/rooms/index.js +4 -3
  37. package/dist/rooms/index.js.map +1 -1
  38. package/dist/rooms/offer-transcription.d.ts +1 -1
  39. package/dist/rooms/offer-transcription.js +1 -1
  40. package/dist/rooms/owned-room.d.ts +251 -0
  41. package/dist/rooms/owned-room.d.ts.map +1 -0
  42. package/dist/rooms/owned-room.js +844 -0
  43. package/dist/rooms/owned-room.js.map +1 -0
  44. package/dist/rooms/recorder.d.ts +1 -1
  45. package/dist/rooms/recorder.js +1 -1
  46. package/dist/rooms/room.d.ts +82 -278
  47. package/dist/rooms/room.d.ts.map +1 -1
  48. package/dist/rooms/room.js +60 -854
  49. package/dist/rooms/room.js.map +1 -1
  50. package/dist/rooms/standing-source.d.ts +1 -1
  51. package/dist/rooms/standing-source.js +1 -1
  52. package/dist/rooms/transcriber.d.ts +3 -3
  53. package/dist/rooms/transcriber.d.ts.map +1 -1
  54. package/dist/rooms/transcriber.js +2 -2
  55. package/dist/rooms/transport.d.ts +1 -1
  56. package/dist/rooms/transport.js +2 -2
  57. package/dist/shaping/assets.d.ts +13 -0
  58. package/dist/shaping/assets.d.ts.map +1 -1
  59. package/dist/shaping/assets.js +27 -0
  60. package/dist/shaping/assets.js.map +1 -1
  61. package/dist/shaping/chat.d.ts +3 -1
  62. package/dist/shaping/chat.d.ts.map +1 -1
  63. package/dist/shaping/chat.js +4 -2
  64. package/dist/shaping/chat.js.map +1 -1
  65. package/dist/shaping/rooms.d.ts +78 -1
  66. package/dist/shaping/rooms.d.ts.map +1 -1
  67. package/dist/shaping/rooms.js +58 -6
  68. package/dist/shaping/rooms.js.map +1 -1
  69. package/dist/shaping/sources.d.ts +7 -3
  70. package/dist/shaping/sources.d.ts.map +1 -1
  71. package/dist/shaping/sources.js +9 -10
  72. package/dist/shaping/sources.js.map +1 -1
  73. package/dist/transcribe-stream.d.ts +1 -1
  74. package/dist/transcribe-stream.js +1 -1
  75. package/dist/transcribe.d.ts +2 -2
  76. package/dist/transcribe.js +2 -2
  77. package/package.json +11 -2
@@ -1,6 +1,6 @@
1
1
  /** The live rooms surface — the {@link Room} handle, its audio codec, and the loginless
2
2
  * {@link joinRoom} entry (no client needed, just a connect code). */
3
- import { DEFAULT_BASE_URL, readEnv } from "../env.js";
3
+ import { resolveBaseUrl } from "../env.js";
4
4
  import { raiseForStatus } from "../errors.js";
5
5
  import { httpFetch } from "../http.js";
6
6
  import { Room } from "./room.js";
@@ -9,6 +9,7 @@ export { BrokerError, CAPTURE_OFFER_ROLE, CHAT_BROKER_ROLE, DEFAULT_CHAT_MAX_TOK
9
9
  export { AUDIO_ROLE, AUDIO_SIGNAL, decodeAudioFrame, encodeAudioFrame, isAudioFrame, } from "./codec.js";
10
10
  export { OfferedCapture } from "./offer-capture.js";
11
11
  export { OfferedTranscription } from "./offer-transcription.js";
12
+ export { OwnedRoom } from "./owned-room.js";
12
13
  export { mergeRoles, parseParticipant, participantMatches, } from "./participant.js";
13
14
  export { Recorder } from "./recorder.js";
14
15
  export { Room, } from "./room.js";
@@ -22,7 +23,7 @@ export { TRANSCRIBER_SOURCE, Transcriber } from "./transcriber.js";
22
23
  * signals (but not manage the room — that needs the owner). Mirrors the Python SDK's ``join_room``.
23
24
  */
24
25
  export async function joinRoom(code, opts = {}) {
25
- const baseUrl = (opts.baseUrl ?? readEnv("ATRIUM_BASE_URL") ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
26
+ const baseUrl = resolveBaseUrl(opts.baseUrl);
26
27
  const res = await httpFetch(`${baseUrl}/v1/rooms/resolve?code=${encodeURIComponent(code)}`);
27
28
  if (!res.ok)
28
29
  await raiseForStatus(res);
@@ -36,7 +37,7 @@ export async function joinRoom(code, opts = {}) {
36
37
  requestTimeout: opts.requestTimeout,
37
38
  reconnect: opts.reconnect,
38
39
  transport: opts.transport,
39
- WebSocketCtor: opts.WebSocketCtor,
40
+ webSocketCtor: opts.webSocketCtor,
40
41
  fetchImpl: opts.fetchImpl,
41
42
  signal: opts.signal,
42
43
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rooms/index.ts"],"names":[],"mappings":"AAAA;qEACqE;AAErE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,IAAI,EAAyC,MAAM,WAAW,CAAA;AAIvE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAEL,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,UAAU,EACV,YAAY,EAOZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAA+C,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EAAE,oBAAoB,EAA+B,MAAM,0BAA0B,CAAA;AAC5F,OAAO,EACL,UAAU,EAGV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,QAAQ,EAA2B,MAAM,eAAe,CAAA;AACjE,OAAO,EAIL,IAAI,GAML,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EAEvB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAkB,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC7E,OAAO,EAEL,iBAAiB,EAEjB,cAAc,GACf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAwB,MAAM,kBAAkB,CAAA;AA0BxF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IACrE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,IAAI,gBAAgB,CAAC,CAAC,OAAO,CACtF,MAAM,EACN,EAAE,CACH,CAAA;IACD,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,OAAO,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3F,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2C,CAAA;IACzE,MAAM,IAAI,GAAa;QACrB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;QACtC,OAAO;QACP,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAA;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rooms/index.ts"],"names":[],"mappings":"AAAA;qEACqE;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,IAAI,EAAyC,MAAM,WAAW,CAAA;AAIvE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAEL,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,UAAU,EACV,YAAY,EAOZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,MAAM,YAAY,CAAA;AACnB,OAAO,EAA+C,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,EAAE,oBAAoB,EAA+B,MAAM,0BAA0B,CAAA;AAC5F,OAAO,EAAE,SAAS,EAAsB,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EACL,UAAU,EAGV,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,QAAQ,EAA2B,MAAM,eAAe,CAAA;AACjE,OAAO,EAIL,IAAI,GAML,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EAEvB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAkB,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AAC7E,OAAO,EAEL,iBAAiB,EAEjB,cAAc,GACf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAwB,MAAM,kBAAkB,CAAA;AA2BxF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAwB,EAAE;IACrE,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,OAAO,0BAA0B,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC3F,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,cAAc,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2C,CAAA;IACzE,MAAM,IAAI,GAAa;QACrB,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;QACtC,OAAO;QACP,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAA;IACD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC"}
@@ -6,7 +6,7 @@
6
6
  * Engage is **sender-scoped** (see {@link ./armed-set.ArmedSet}): only armed sources are transcribed
7
7
  * — an unarmed source's frames are dropped at the demux (no engine spawns). While engaged it
8
8
  * subscribes the room's ``audio.snippet`` stream, demuxes frames per source, and runs one
9
- * transcription engine per source (the same engine as {@link ./room.Room.transcribe}), stamping each
9
+ * transcription engine per source (the same engine as {@link ./owned-room.OwnedRoom.transcribe}), stamping each
10
10
  * ``transcript.*`` signal's payload with the source's connection id and roster-resolved
11
11
  * ``source_name``. Up to ``maxSources`` sources; a departed source's engine is reaped promptly.
12
12
  */
@@ -6,7 +6,7 @@
6
6
  * Engage is **sender-scoped** (see {@link ./armed-set.ArmedSet}): only armed sources are transcribed
7
7
  * — an unarmed source's frames are dropped at the demux (no engine spawns). While engaged it
8
8
  * subscribes the room's ``audio.snippet`` stream, demuxes frames per source, and runs one
9
- * transcription engine per source (the same engine as {@link ./room.Room.transcribe}), stamping each
9
+ * transcription engine per source (the same engine as {@link ./owned-room.OwnedRoom.transcribe}), stamping each
10
10
  * ``transcript.*`` signal's payload with the source's connection id and roster-resolved
11
11
  * ``source_name``. Up to ``maxSources`` sources; a departed source's engine is reaped promptly.
12
12
  */
@@ -0,0 +1,251 @@
1
+ /**
2
+ * The **owned** room handle — {@link ./room.Room} plus every surface that needs the account
3
+ * credential behind it. Returned by ``client.rooms.open`` / ``.get`` / ``.list``, which inject the
4
+ * authenticated REST caller and the client slice this class is built on.
5
+ *
6
+ * The split is deliberate: a loginless ``joinRoom(code)`` handle is a plain {@link ./room.Room}, so
7
+ * the members here are not merely guarded at runtime — they are absent from its type. Everything on
8
+ * this class assumes a credential and calls it directly ({@link OwnedRoomDeps} makes ``rest`` /
9
+ * ``client`` required), so nothing here needs a runtime credential guard.
10
+ *
11
+ * Durable & reactive: {@link OwnedRoom.record} bridges the room into a session over an SSE-observe
12
+ * {@link ./recorder.Recorder} (a room stores nothing itself, so durable capture rides the observe
13
+ * stream); {@link OwnedRoom.audioVectors} embeds the live snippet stream and
14
+ * {@link OwnedRoom.audioScores} fuses it against named anchors for a {@link ../decider.Decider};
15
+ * the standing offers and capability brokers serve code-joined peers on your credential.
16
+ */
17
+ import { type AnchorLike } from "../by.js";
18
+ import { Dashboard, type DashboardOptions } from "../dash.js";
19
+ import type { Session, Transcript } from "../models.js";
20
+ import type { ShapedRequest } from "../shaping/index.js";
21
+ import { RoomTrace } from "../trace.js";
22
+ import { OfferedCapture } from "./offer-capture.js";
23
+ import { OfferedTranscription } from "./offer-transcription.js";
24
+ import { Recorder } from "./recorder.js";
25
+ import { type AudioVector, Room, type RoomAudioClient, type RoomDeps, type ScoredAudio } from "./room.js";
26
+ import { Transcriber } from "./transcriber.js";
27
+ /** {@link RoomDeps} plus the account credential an {@link OwnedRoom} is defined by — both required,
28
+ * which is what lets this class call them without a guard. */
29
+ export interface OwnedRoomDeps extends RoomDeps {
30
+ /** Authenticated REST caller for management + the durable writes (rotate / delete / signal POST). */
31
+ rest: (req: ShapedRequest) => Promise<unknown>;
32
+ /** The authenticated client's embed / chat / compare / transcribe slice. */
33
+ client: RoomAudioClient;
34
+ }
35
+ export declare class OwnedRoom extends Room {
36
+ protected readonly deps: OwnedRoomDeps;
37
+ private readonly recorderListeners;
38
+ constructor(deps: OwnedRoomDeps);
39
+ /**
40
+ * Start capturing this room's live signals into a durable ``session`` — the single durable binding
41
+ * between a room (pure transport) and a session (an append-only log). A **side effect**: it starts
42
+ * immediately in the background and returns a live {@link Recorder} handle. Stop it with
43
+ * ``rec.stop()``, or let {@link close} (an ``await using`` room) stop it. It skips ``ephemeral``
44
+ * signals and presence traffic — only durable-worthy signals are recorded, each stamped with
45
+ * ``via`` provenance (``{ room_id, room_name, from, to }``). Mirror of Python's ``room.record``.
46
+ *
47
+ * A dropped stream reconnects with backoff (the gap is lost — rooms have no replay); only a
48
+ * terminal end stops it cleanly with a {@link Recorder.stoppedReason} (a code rotation, or the
49
+ * room being gone / its code rejected — the latter also sets {@link Recorder.error}).
50
+ */
51
+ record(into: Session): Recorder;
52
+ /** The recorders currently running on this handle (membership **and** liveness — a stopped one no
53
+ * longer counts) — the source of truth a wave-4 ``offerAudioCapture`` reads for audio-capture
54
+ * availability, and binds its capture to the first active recorder's session. */
55
+ activeRecorders(): Recorder[];
56
+ /** Register a listener fired whenever the active-recorder set changes (a {@link record} started, or
57
+ * a recorder stopped/terminated) — the seam a wave-4 ``offerAudioCapture`` binds to, so it can
58
+ * re-derive availability and disengage when the recorder it wrote under is gone. Returns an
59
+ * unsubscribe function. Mirror of Python's ``_notify_recorders_changed`` registration. */
60
+ onRecordersChanged(listener: () => void | Promise<void>): () => void;
61
+ private notifyRecordersChanged;
62
+ /**
63
+ * Transcribe this room's live audio into ``transcript.*`` signals — the in-room broker. Consumes the
64
+ * room's ``audio.snippet`` stream (announcing the snippet-consumer role, so a Player starts
65
+ * capturing), pushes it through the same engine as {@link ../atrium.Atrium.transcribeLive} on
66
+ * **your** credentials/compute, and publishes back:
67
+ *
68
+ * * ``transcript.partial`` — ``{ text }``, **ephemeral** (a live caption the recorder skips).
69
+ * Wholesale-replaced — render the latest, don't append.
70
+ * * ``transcript.final`` — ``{ text, start, end, seq }``, durable (the {@link record} bridge persists
71
+ * it — no new recording API). ``seq`` is a per-handle counter from 0; the signal's ``source`` is
72
+ * ``"transcriber"``.
73
+ *
74
+ * Any consumer — including a loginless code-joined tool — just does ``room.on("transcript.final")``.
75
+ * Like {@link record}, it's a **side effect**: it starts immediately in the background and is stopped
76
+ * when the room closes, or via ``await handle.stop()`` / ``await using``.
77
+ */
78
+ transcribe(opts?: {
79
+ model?: string;
80
+ language?: string;
81
+ }): Transcriber;
82
+ /**
83
+ * Subscribe to the room's live ``audio.snippet`` stream and transcribe it, yielding a
84
+ * {@link ../models.Transcript} per finalized sentence — the speech-to-text sibling of
85
+ * {@link audioVectors}, and the *raw* counterpart of the {@link transcribe} broker (which publishes
86
+ * ``transcript.*`` signals for every peer instead of handing you the stream).
87
+ *
88
+ * Subscribing *is* the demand signal (it announces the ``audio-snippet-consumer`` role, so a
89
+ * producer's own default-off "Share audio clips" toggle actually captures). Break out of the
90
+ * ``for await`` loop — or abort ``signal`` — to end the subscription and close the socket.
91
+ *
92
+ * Snippets run through the same engine as {@link ../atrium.Atrium.transcribeLive}: true streaming
93
+ * (per-sentence finals, plus revisable partials with ``partials``) when the backend's live route is
94
+ * reachable, degrading silently to per-clip batch transcription otherwise (finals only).
95
+ * Transcription runs on *your* credentials/compute — a rejected credential raises rather than
96
+ * falling back.
97
+ *
98
+ * The two paths differ in one detail (mirror of Python's ``audio_transcripts``): on the **fallback**
99
+ * path each transcript carries its source frame's ``sequence`` / ``window_seconds`` under
100
+ * ``transcript.raw.snippet`` (a cheap ordering/correlation handle) and the clip's format comes from
101
+ * that frame's own MIME type; on the **streaming** path transcripts are per-sentence, so there is no
102
+ * 1:1 snippet correlation and ``raw.snippet`` is omitted (``raw`` carries ``start`` / ``end``).
103
+ */
104
+ audioTranscripts(opts?: {
105
+ model?: string;
106
+ language?: string;
107
+ partials?: boolean;
108
+ skipEmpty?: boolean;
109
+ signal?: AbortSignal;
110
+ }): AsyncGenerator<Transcript>;
111
+ private snippetBytesFor;
112
+ private requirePreConnect;
113
+ private offerDeps;
114
+ private offerService;
115
+ /**
116
+ * Offer live transcription as a peer-toggleable standing service — a code-joined tool turns it on
117
+ * with a ``transcription.start`` request and off with ``transcription.stop`` (both idempotent).
118
+ * Announces the discoverable ``transcription-offer`` role. **Scoped, multi-source**: ``start`` /
119
+ * ``stop`` are scoped to the requesting connection unless the payload carries ``{ all: true }``;
120
+ * only armed sources are transcribed (up to ``maxSources``, default 8). While on it runs the same
121
+ * engine as {@link transcribe} on **your** credentials, publishing source-attributed ``transcript.*``
122
+ * signals. Register **before** ``connect()``.
123
+ * Returns the handle (for ``handle.start({ all: true })`` from the host). Mirror of Python's
124
+ * ``offer_transcription``.
125
+ */
126
+ offerTranscription(opts?: {
127
+ model?: string;
128
+ language?: string;
129
+ maxSources?: number;
130
+ }): OfferedTranscription;
131
+ /**
132
+ * Offer audio capture as a peer-toggleable standing service — **session-less**: it writes into the
133
+ * **active recorder's** session ({@link record} is the single durable binding), so a ``capture.start``
134
+ * with no active recorder replies an error. A code-joined tool toggles it via ``capture.start`` /
135
+ * ``capture.stop`` (idempotent). Announces the discoverable ``capture-offer`` role. **Scoped,
136
+ * multi-source** (up to ``maxSources``, default 8): only armed sources are recorded; a same-name
137
+ * reconnect within grace resumes one file, two simultaneous same-name producers get their own files.
138
+ * Register **before** ``connect()``. Returns the
139
+ * handle (for ``handle.start({ all: true })``). Mirror of Python's ``offer_audio_capture``.
140
+ */
141
+ offerAudioCapture(opts?: {
142
+ maxSources?: number;
143
+ }): OfferedCapture;
144
+ private resolveEmbedSpace;
145
+ private resolveAnchorVector;
146
+ /**
147
+ * Handle ``embed.resolve`` requests from code-joined peers (e.g. a loginless Unity scene) — resolve
148
+ * named operand descriptors (``{ text }`` / ``{ concept, collection? }`` / ``{ vector }`` /
149
+ * ``{ asset, match_by? }``) to vectors in ONE embedding space, so a peer with no credentials can
150
+ * compare live signals against library concepts/text/assets. **The requester chooses the space**
151
+ * (omitted → the default text space). A per-anchor
152
+ * failure lands in ``errors`` without failing the others; a malformed / over-``maxAnchors`` request
153
+ * or a ``space`` outside ``spaces`` gets a whole-request ``{ error }``. Announces the discoverable
154
+ * ``embed-broker`` role — call before ``connect()``. Mirror of Python's ``offer_embeds``.
155
+ */
156
+ offerEmbeds(opts?: {
157
+ spaces?: string[];
158
+ maxAnchors?: number;
159
+ }): void;
160
+ /**
161
+ * Handle ``chat.generate`` requests from code-joined peers — a stateless chat completion (no history
162
+ * broker-side), so a loginless peer gets an LLM reply without its own credentials. Reply:
163
+ * ``{ text, model }``, or ``{ error }`` if ``messages`` is malformed / over the payload cap. The
164
+ * **broker** pins ``model`` (the requester cannot choose it — cost control); ``maxTokens`` caps each
165
+ * reply. Announces the discoverable ``chat-broker`` role — call before ``connect()``. Every peer
166
+ * holding the connect code can trigger a reply on **your** billing. Mirror of Python's ``offer_chat``.
167
+ */
168
+ offerChat(opts?: {
169
+ model?: string;
170
+ maxTokens?: number;
171
+ }): void;
172
+ /**
173
+ * Build the host-side {@link ../dash.Dashboard} for this room — the live observation-dashboard
174
+ * state an app holds as a grid of tiles. It answers each joining ``/tools/dashboard`` with a full
175
+ * ``dash.snapshot`` and broadcasts ``dash.delta`` patches as things change, all **ephemeral** (the
176
+ * room stores nothing — the durable record is the session).
177
+ *
178
+ * Prefer this over ``new Dashboard(room)``: it publishes over the REST ``/signal`` POST, which
179
+ * preserves the dialect's ephemerality (the WS inbound path forces ``ephemeral: false``). Mirror of
180
+ * Python's ``Dashboard(room)``.
181
+ */
182
+ dashboard(opts?: DashboardOptions): Dashboard;
183
+ /**
184
+ * Mirror the SDK's own activity into this room as ``trace.*`` signals — one line turns it on. The
185
+ * operation folds into the signal type (``label`` still rides the payload), and ephemerality is
186
+ * per-signal (see {@link ../trace.isTraceEphemeral}). While tracing:
187
+ *
188
+ * * **library/model calls** made through the same client (``search`` / ``searchByExamples`` /
189
+ * ``enrich`` / ``play`` / ``chat``) surface a ``trace.<label>`` (``trace.library.search`` /
190
+ * ``trace.chat`` / ``trace.play``) — a glanceable summary (``"rain" → 8 hits (top: Forest Rain
191
+ * 0.83)``) plus a capped detail (top-N results, never full payloads);
192
+ * * **SDK-internal state** — a recorder start/stop (with its session + event count), a transcriber
193
+ * start/stop, a standing offer's armed/active roster — surfaces a ``trace.state.<label>``.
194
+ *
195
+ * Default OFF (it broadcasts app internals to anyone with the code, and it's noise on the happy
196
+ * path). Returns a handle: ``const t = room.trace()`` then ``t.stop()``, or ``using t =
197
+ * room.trace()`` for a scope; stopped when the room closes. A trace failure never breaks the traced
198
+ * call. ``play`` and the state seam are scoped to **this** room; client-wide calls mirror into every
199
+ * armed room. Mirror of Python's ``room.trace()``.
200
+ */
201
+ trace(): RoomTrace;
202
+ private traceState;
203
+ private resolveAudioSpace;
204
+ private snippetStream;
205
+ /**
206
+ * Subscribe to the room's live ``audio.snippet`` stream and embed each ~10s window, yielding an
207
+ * {@link AudioVector} per snippet — a live vector of "what the room sounds like right now".
208
+ * Subscribing *is* the demand signal (announces the ``audio-snippet-consumer`` role, so a
209
+ * producer's default-off "Share audio clips" toggle actually captures). Break out of the
210
+ * ``for await`` loop to end it. Mirror of Python's ``audio_vectors``.
211
+ *
212
+ * ``space`` pins the search space snippets are labeled with (default: the deployment's default
213
+ * audio space, so a no-arg vector is comparable against library-derived vectors); ``model`` the
214
+ * embedding model (default: the resolved space's configured model). ``relay: true`` also relays
215
+ * each vector into the room as an ephemeral ``audio.vector`` signal — so a loginless code-joined
216
+ * peer can consume the live mood vector without credentials of its own. Binary rides the
217
+ * WebSocket only.
218
+ */
219
+ audioVectors(opts?: {
220
+ space?: string;
221
+ model?: string;
222
+ relay?: boolean;
223
+ }): AsyncGenerator<AudioVector>;
224
+ private preflightConceptAnchors;
225
+ /**
226
+ * Fuse {@link audioVectors} with per-anchor ``library.compare`` scoring — a live "which anchor does
227
+ * the room sound like right now" signal. ``anchors`` maps a name to anything the ``by`` grammar
228
+ * accepts (a bare string / {@link "../by".Asset} / ``by.*`` marker), **or an array** of those (a
229
+ * few-shot category, scored as the mean of its top-``topN`` members' calibrated compare scores;
230
+ * default ``topN: 1`` — the nearest member wins). Each frame's anchors are scored concurrently.
231
+ *
232
+ * Each {@link ScoredAudio} carries the calibrated ``scores`` plus ``mix`` (normalized to sum 1,
233
+ * uniform when every score is 0 — gate on ``max(scores)`` for silence). No smoothing — ease the
234
+ * stream with a {@link ../decider.Decider}. ``relay: true`` forwards to {@link audioVectors} (it
235
+ * relays the raw ``audio.vector``, not the computed scores). Concept anchors are validated once up
236
+ * front (a typo raises before any frame); a mid-stream compare failure re-throws named by anchor.
237
+ * Mirror of Python's ``audio_scores``.
238
+ */
239
+ audioScores(anchors: Record<string, AnchorLike>, opts?: {
240
+ space?: string;
241
+ model?: string;
242
+ topN?: number;
243
+ relay?: boolean;
244
+ }): AsyncGenerator<ScoredAudio>;
245
+ /** Rotate the connect code (owner only); updates ``connectCode`` and returns it. */
246
+ rotateCode(): Promise<string>;
247
+ /** Delete the room for good (its connect code dies with it). */
248
+ delete(): Promise<void>;
249
+ protected teardown(): Promise<void>;
250
+ }
251
+ //# sourceMappingURL=owned-room.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owned-room.d.ts","sourceRoot":"","sources":["../../src/rooms/owned-room.ts"],"names":[],"mappings":"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"}