@runtypelabs/persona 4.25.0 → 4.26.1

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 (236) hide show
  1. package/dist/animations/glyph-cycle.d.cts +1 -1
  2. package/dist/animations/glyph-cycle.d.ts +1 -1
  3. package/dist/animations/{types-Db61aI9J.d.cts → types-BwKTZhg9.d.cts} +14 -0
  4. package/dist/animations/{types-Db61aI9J.d.ts → types-BwKTZhg9.d.ts} +14 -0
  5. package/dist/animations/wipe.d.cts +1 -1
  6. package/dist/animations/wipe.d.ts +1 -1
  7. package/dist/animations-extra.d.cts +14 -0
  8. package/dist/animations-extra.d.ts +14 -0
  9. package/dist/approval-ui-QAKWNFNM.js +1 -0
  10. package/dist/approval-ui.cjs +2 -2
  11. package/dist/approval-ui.d.cts +186 -8
  12. package/dist/approval-ui.d.ts +186 -8
  13. package/dist/approval-ui.js +2 -2
  14. package/dist/{artifacts-ui-IGB5YKLO.js → artifacts-ui-NJGMM27I.js} +1 -1
  15. package/dist/artifacts-ui.cjs +4 -4
  16. package/dist/artifacts-ui.d.cts +186 -8
  17. package/dist/artifacts-ui.d.ts +186 -8
  18. package/dist/artifacts-ui.js +5 -5
  19. package/dist/chunk-2ANTRKTV.js +1 -0
  20. package/dist/chunk-4HPTPUC6.js +1 -0
  21. package/dist/chunk-6V3MNEKB.js +1 -0
  22. package/dist/chunk-GKPCIQPB.js +1 -0
  23. package/dist/chunk-HGUCGM3K.js +9 -0
  24. package/dist/chunk-IO5VVUKP.js +3 -0
  25. package/dist/chunk-J4J3Y2P2.js +1 -0
  26. package/dist/chunk-K6HKIP5K.js +1 -0
  27. package/dist/chunk-K7NA7G7J.js +1 -0
  28. package/dist/chunk-MXUTS3LB.js +1 -0
  29. package/dist/chunk-PDPVORUF.js +1 -0
  30. package/dist/chunk-QRKGQPU7.js +1 -0
  31. package/dist/chunk-S6PBWE75.js +1 -0
  32. package/dist/chunk-T7QM7YMF.js +1 -0
  33. package/dist/chunk-TR2H475E.js +1 -0
  34. package/dist/chunk-UPO4GUFC.js +1 -0
  35. package/dist/chunk-ZC66NAIR.js +1 -0
  36. package/dist/client-history-GOZWBDA5.js +1 -0
  37. package/dist/client-history.js +1 -0
  38. package/dist/client-stream-42FOI3EC.js +4 -0
  39. package/dist/client-stream.js +5 -0
  40. package/dist/codegen.cjs +1 -1
  41. package/dist/codegen.js +1 -1
  42. package/dist/context-mentions-E7HJYWO6.js +161 -0
  43. package/dist/{context-mentions-inline-I2RDEBAK.js → context-mentions-inline-QVESLW55.js} +1 -1
  44. package/dist/context-mentions.cjs +7 -7
  45. package/dist/context-mentions.d.cts +186 -8
  46. package/dist/context-mentions.d.ts +186 -8
  47. package/dist/context-mentions.js +8 -8
  48. package/dist/event-stream-view-FOIJHFQO.js +1 -0
  49. package/dist/event-stream-view.cjs +1 -1
  50. package/dist/event-stream-view.d.cts +189 -31
  51. package/dist/event-stream-view.d.ts +189 -31
  52. package/dist/event-stream-view.js +1 -1
  53. package/dist/forms-ui.d.cts +227 -667
  54. package/dist/forms-ui.d.ts +227 -667
  55. package/dist/history-shell-QDQ44PSE.js +3 -0
  56. package/dist/history-shell.js +3 -0
  57. package/dist/{history-view-BD6OXLNA.js → history-view-NCFBI5GR.js} +2 -2
  58. package/dist/history-view.cjs +2 -2
  59. package/dist/history-view.d.cts +35 -1
  60. package/dist/history-view.d.ts +35 -1
  61. package/dist/history-view.js +2 -2
  62. package/dist/index.cjs +80 -74
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +233 -738
  65. package/dist/index.d.ts +233 -738
  66. package/dist/index.global.js +3 -215
  67. package/dist/index.global.js.map +1 -1
  68. package/dist/index.js +81 -75
  69. package/dist/index.js.map +1 -1
  70. package/dist/install.global.js +1 -1
  71. package/dist/install.global.js.map +1 -1
  72. package/dist/launcher.global.js +3 -67
  73. package/dist/launcher.global.js.map +1 -1
  74. package/dist/markdown-parsers.js +22 -22
  75. package/dist/runtype-tts-entry-NFBVWR7N.js +1 -0
  76. package/dist/runtype-tts.js +1 -1
  77. package/dist/session-actions-ISSKSI66.js +1 -0
  78. package/dist/session-actions.js +1 -0
  79. package/dist/session-reconnect.d.cts +186 -8
  80. package/dist/session-reconnect.d.ts +186 -8
  81. package/dist/smart-dom-reader.cjs +13 -13
  82. package/dist/smart-dom-reader.d.cts +186 -8
  83. package/dist/smart-dom-reader.d.ts +186 -8
  84. package/dist/smart-dom-reader.js +11 -11
  85. package/dist/theme-editor-preview.cjs +116 -98
  86. package/dist/theme-editor-preview.d.cts +188 -8
  87. package/dist/theme-editor-preview.d.ts +188 -8
  88. package/dist/theme-editor-preview.js +49 -54
  89. package/dist/theme-editor.cjs +2 -2
  90. package/dist/theme-editor.d.cts +187 -23
  91. package/dist/theme-editor.d.ts +187 -23
  92. package/dist/theme-editor.js +2 -2
  93. package/dist/theme-reference.d.cts +14 -0
  94. package/dist/theme-reference.d.ts +14 -0
  95. package/dist/ui-extras-entry-WAYFKVNW.js +3 -0
  96. package/dist/ui-extras.js +72 -0
  97. package/dist/voice-runtime-XLU6YK2N.js +17 -0
  98. package/dist/voice-runtime.cjs +17 -1
  99. package/dist/voice-runtime.d.cts +11656 -232
  100. package/dist/voice-runtime.d.ts +11656 -232
  101. package/dist/voice-runtime.js +17 -1
  102. package/dist/voice-worklet-player.cjs +19 -4
  103. package/dist/voice-worklet-player.d.cts +9 -10
  104. package/dist/voice-worklet-player.d.ts +9 -10
  105. package/dist/voice-worklet-player.js +19 -4
  106. package/dist/webmcp-polyfill.js +1 -1
  107. package/dist/webmcp-runtime-V6ZWW3PI.js +6 -0
  108. package/dist/webmcp-runtime.cjs +2 -2
  109. package/dist/webmcp-runtime.d.cts +1 -33
  110. package/dist/webmcp-runtime.d.ts +1 -33
  111. package/dist/webmcp-runtime.js +2 -2
  112. package/dist/widget.css +1 -1
  113. package/package.json +11 -5
  114. package/src/approval-paused-tool-settle.test.ts +325 -0
  115. package/src/client-approve.test.ts +311 -0
  116. package/src/client-history-eager.ts +9 -0
  117. package/src/client-history-loader.ts +23 -0
  118. package/src/client-history.ts +579 -0
  119. package/src/client-resume.ts +177 -0
  120. package/src/client-stream-eager.ts +12 -0
  121. package/src/client-stream-loader.ts +25 -0
  122. package/src/client-stream.ts +1880 -0
  123. package/src/client.test.ts +31 -1
  124. package/src/client.ts +293 -2607
  125. package/src/components/approval-actions.test.ts +27 -0
  126. package/src/components/approval-actions.ts +27 -3
  127. package/src/components/message-bubble.test.ts +19 -0
  128. package/src/components/message-bubble.ts +2 -0
  129. package/src/components/registry.ts +6 -6
  130. package/src/components/tool-bubble.test.ts +9 -0
  131. package/src/components/tool-bubble.ts +1 -0
  132. package/src/history-shell-bundle.test.ts +54 -0
  133. package/src/history-shell-eager.ts +12 -0
  134. package/src/history-shell-loader.ts +27 -0
  135. package/src/history-shell.ts +2362 -0
  136. package/src/history-view-loader.ts +2 -0
  137. package/src/history-view.ts +3 -0
  138. package/src/index-core.ts +6 -0
  139. package/src/index-global.ts +90 -248
  140. package/src/index.ts +13 -0
  141. package/src/install.ts +6 -4
  142. package/src/internal/runtype-history-provider.test.ts +1 -0
  143. package/src/internal/runtype-history-provider.ts +28 -13
  144. package/src/plugins/registry.ts +8 -8
  145. package/src/session-actions-chunk.test.ts +55 -0
  146. package/src/session-actions-eager.ts +11 -0
  147. package/src/session-actions-loader.ts +37 -0
  148. package/src/session-actions.ts +909 -0
  149. package/src/session-history.test.ts +3 -1
  150. package/src/session.ts +895 -1538
  151. package/src/session.voice.test.ts +1171 -5
  152. package/src/styles/widget.css +58 -0
  153. package/src/theme-editor/state.ts +91 -91
  154. package/src/types.ts +204 -5
  155. package/src/ui-ask-user-sheet.ts +382 -0
  156. package/src/ui-extras-eager.ts +10 -0
  157. package/src/ui-extras-entry.ts +9 -0
  158. package/src/ui-extras-loader.ts +26 -0
  159. package/src/ui.artifact-rail-resize.test.ts +2 -1
  160. package/src/ui.ask-user-chunk.test.ts +93 -0
  161. package/src/ui.history-chunk.test.ts +2 -1
  162. package/src/ui.history-config-provider.test.ts +2 -1
  163. package/src/ui.history-confirm-fallback.test.ts +142 -0
  164. package/src/ui.history-controller.test.ts +2 -1
  165. package/src/ui.history-lifecycle.test.ts +2 -1
  166. package/src/ui.history-render-hooks.test.ts +2 -1
  167. package/src/ui.history-shell.test.ts +2 -1
  168. package/src/ui.rail-overlay.test.ts +2 -1
  169. package/src/ui.rail-resize.test.ts +2 -1
  170. package/src/ui.rail-trigger-pending.test.ts +2 -1
  171. package/src/ui.ts +340 -2770
  172. package/src/utils/attachment-manager.ts +67 -67
  173. package/src/utils/constants.ts +3 -0
  174. package/src/utils/context-mention-controller.ts +323 -323
  175. package/src/utils/context-mention-manager.ts +40 -40
  176. package/src/utils/context-mention-orchestrator.ts +28 -0
  177. package/src/utils/event-stream-buffer.ts +50 -50
  178. package/src/utils/event-stream-store.ts +43 -43
  179. package/src/utils/throughput-tracker.ts +34 -34
  180. package/src/utils/virtual-scroller.ts +67 -67
  181. package/src/utils/visitor-store.test.ts +50 -0
  182. package/src/utils/visitor-store.ts +23 -5
  183. package/src/voice/__fixtures__/voice-wire/README.md +1 -0
  184. package/src/voice/__fixtures__/voice-wire/client/cancel.json +3 -0
  185. package/src/voice/__fixtures__/voice-wire/client/context.json +4 -0
  186. package/src/voice/__fixtures__/voice-wire/client/delegation_result.json +6 -0
  187. package/src/voice/__fixtures__/voice-wire/client/delegation_update.json +6 -0
  188. package/src/voice/__fixtures__/voice-wire/client/ping.json +3 -0
  189. package/src/voice/__fixtures__/voice-wire/client/playback_progress.json +5 -0
  190. package/src/voice/__fixtures__/voice-wire/client/start.json +3 -0
  191. package/src/voice/__fixtures__/voice-wire/server/artifact.json +11 -0
  192. package/src/voice/__fixtures__/voice-wire/server/attached.json +4 -0
  193. package/src/voice/__fixtures__/voice-wire/server/audio_clear.json +4 -0
  194. package/src/voice/__fixtures__/voice-wire/server/audio_end.json +3 -0
  195. package/src/voice/__fixtures__/voice-wire/server/delegation_cancelled.json +5 -0
  196. package/src/voice/__fixtures__/voice-wire/server/delegation_completed.json +8 -0
  197. package/src/voice/__fixtures__/voice-wire/server/delegation_started.json +15 -0
  198. package/src/voice/__fixtures__/voice-wire/server/error.json +6 -0
  199. package/src/voice/__fixtures__/voice-wire/server/metrics.json +10 -0
  200. package/src/voice/__fixtures__/voice-wire/server/pong.json +3 -0
  201. package/src/voice/__fixtures__/voice-wire/server/session_config.json +16 -0
  202. package/src/voice/__fixtures__/voice-wire/server/transcript_final.json +7 -0
  203. package/src/voice/__fixtures__/voice-wire/server/transcript_interim.json +4 -0
  204. package/src/voice/__fixtures__/voice-wire/server/transcript_partial.json +6 -0
  205. package/src/voice/__fixtures__/voice-wire/server/transcript_update.json +10 -0
  206. package/src/voice/__fixtures__/voice-wire/server/warning.json +5 -0
  207. package/src/voice/audio-playback-manager.test.ts +57 -0
  208. package/src/voice/audio-playback-manager.ts +120 -98
  209. package/src/voice/browser-voice-provider.ts +37 -37
  210. package/src/voice/fallback-speech-engine.ts +22 -16
  211. package/src/voice/keyed-voice-transcript.ts +314 -0
  212. package/src/voice/mic-state-styles.ts +182 -0
  213. package/src/voice/read-aloud-controller.ts +46 -44
  214. package/src/voice/runtype-speech-engine.ts +35 -33
  215. package/src/voice/runtype-voice-provider.ts +680 -189
  216. package/src/voice/session-voice-wiring.ts +266 -0
  217. package/src/voice/voice-delegation.test.ts +71 -0
  218. package/src/voice/voice-delegation.ts +364 -0
  219. package/src/voice/voice-turn-tracker.ts +6 -6
  220. package/src/voice/voice.test.ts +1060 -8
  221. package/src/voice/worklet-playback-engine.test.ts +81 -0
  222. package/src/voice/worklet-playback-engine.ts +21 -3
  223. package/src/voice-runtime-loader.ts +4 -1
  224. package/src/voice-runtime.ts +7 -0
  225. package/src/webmcp-runtime-entry.ts +41 -39
  226. package/dist/approval-ui-3NMYNXBD.js +0 -1
  227. package/dist/chunk-5EIIHQLQ.js +0 -1
  228. package/dist/chunk-7CO4T5KB.js +0 -1
  229. package/dist/chunk-EFJBUH5F.js +0 -1
  230. package/dist/chunk-R2TMIMDI.js +0 -3
  231. package/dist/chunk-UTVLOTWB.js +0 -9
  232. package/dist/context-mentions-45MODWOY.js +0 -161
  233. package/dist/event-stream-view-GL3ADRY2.js +0 -1
  234. package/dist/runtype-tts-entry-UJAEF7NZ.js +0 -1
  235. package/dist/voice-runtime-7DA7MJH4.js +0 -1
  236. package/dist/webmcp-runtime-JI7T4QYF.js +0 -6
@@ -18,37 +18,39 @@ export type ReadAloudListener = (
18
18
  ) => void;
19
19
 
20
20
  export class ReadAloudController {
21
- private engine: SpeechEngine | null = null;
22
- private activeId: string | null = null;
23
- private state: ReadAloudState = "idle";
24
- private listeners = new Set<ReadAloudListener>();
21
+ #engine: SpeechEngine | null = null;
22
+ #activeId: string | null = null;
23
+ #state: ReadAloudState = "idle";
24
+ #listeners = new Set<ReadAloudListener>();
25
25
  // Bumped on every play/stop so a late async engine creation or a stale
26
26
  // utterance callback from a superseded request can't mutate current state.
27
- private generation = 0;
27
+ #generation = 0;
28
28
 
29
+ #resolveEngine: () => SpeechEngine | Promise<SpeechEngine> | null;
29
30
  constructor(
30
- private resolveEngine: () => SpeechEngine | Promise<SpeechEngine> | null
31
- ) {}
31
+ resolveEngine: () => SpeechEngine | Promise<SpeechEngine> | null
32
+ ) {
33
+ this.#resolveEngine = resolveEngine;}
32
34
 
33
35
  /** Whether the active engine supports pause/resume (vs. stop-only). */
34
36
  get supportsPause(): boolean {
35
- return this.engine?.supportsPause ?? true;
37
+ return this.#engine?.supportsPause ?? true;
36
38
  }
37
39
 
38
40
  /** Playback state for a message id (`idle` unless it's the active message). */
39
41
  stateFor(id: string): ReadAloudState {
40
- return this.activeId === id ? this.state : "idle";
42
+ return this.#activeId === id ? this.#state : "idle";
41
43
  }
42
44
 
43
45
  /** The message currently being read aloud, if any. */
44
46
  activeMessageId(): string | null {
45
- return this.activeId;
47
+ return this.#activeId;
46
48
  }
47
49
 
48
50
  /** Subscribe to state changes. Returns an unsubscribe function. */
49
51
  onChange(listener: ReadAloudListener): () => void {
50
- this.listeners.add(listener);
51
- return () => this.listeners.delete(listener);
52
+ this.#listeners.add(listener);
53
+ return () => this.#listeners.delete(listener);
52
54
  }
53
55
 
54
56
  /**
@@ -57,22 +59,22 @@ export class ReadAloudController {
57
59
  * start fresh when a different message is requested.
58
60
  */
59
61
  toggle(id: string, request: SpeechRequest): void {
60
- if (this.activeId === id) {
61
- if (this.state === "playing") {
62
- if (this.engine?.supportsPause) {
63
- this.engine.pause();
64
- this.set(id, "paused");
62
+ if (this.#activeId === id) {
63
+ if (this.#state === "playing") {
64
+ if (this.#engine?.supportsPause) {
65
+ this.#engine.pause();
66
+ this.#set(id, "paused");
65
67
  } else {
66
68
  this.stop();
67
69
  }
68
70
  return;
69
71
  }
70
- if (this.state === "paused") {
71
- this.engine?.resume();
72
- this.set(id, "playing");
72
+ if (this.#state === "paused") {
73
+ this.#engine?.resume();
74
+ this.#set(id, "playing");
73
75
  return;
74
76
  }
75
- if (this.state === "loading") {
77
+ if (this.#state === "loading") {
76
78
  this.stop();
77
79
  return;
78
80
  }
@@ -82,55 +84,55 @@ export class ReadAloudController {
82
84
 
83
85
  /** Start (or restart) playback for a message, stopping any current playback. */
84
86
  async play(id: string, request: SpeechRequest): Promise<void> {
85
- const generation = ++this.generation;
86
- this.engine?.stop();
87
- this.set(id, "loading");
87
+ const generation = ++this.#generation;
88
+ this.#engine?.stop();
89
+ this.#set(id, "loading");
88
90
 
89
91
  try {
90
- if (!this.engine) {
91
- const resolved = await this.resolveEngine();
92
- if (generation !== this.generation) return; // superseded mid-resolve
92
+ if (!this.#engine) {
93
+ const resolved = await this.#resolveEngine();
94
+ if (generation !== this.#generation) return; // superseded mid-resolve
93
95
  if (!resolved) {
94
- this.set(null, "idle");
96
+ this.#set(null, "idle");
95
97
  return;
96
98
  }
97
- this.engine = resolved;
99
+ this.#engine = resolved;
98
100
  }
99
101
 
100
- this.engine.speak(request, {
102
+ this.#engine.speak(request, {
101
103
  onStart: () => {
102
- if (generation === this.generation) this.set(id, "playing");
104
+ if (generation === this.#generation) this.#set(id, "playing");
103
105
  },
104
106
  onEnd: () => {
105
- if (generation === this.generation) this.set(null, "idle");
107
+ if (generation === this.#generation) this.#set(null, "idle");
106
108
  },
107
109
  onError: () => {
108
- if (generation === this.generation) this.set(null, "idle");
110
+ if (generation === this.#generation) this.#set(null, "idle");
109
111
  },
110
112
  });
111
113
  } catch {
112
- if (generation === this.generation) this.set(null, "idle");
114
+ if (generation === this.#generation) this.#set(null, "idle");
113
115
  }
114
116
  }
115
117
 
116
118
  /** Stop playback and return to idle. */
117
119
  stop(): void {
118
- this.generation++;
119
- this.engine?.stop();
120
- this.set(null, "idle");
120
+ this.#generation++;
121
+ this.#engine?.stop();
122
+ this.#set(null, "idle");
121
123
  }
122
124
 
123
125
  /** Drop the controller and its engine (called on widget teardown). */
124
126
  destroy(): void {
125
127
  this.stop();
126
- this.engine?.destroy?.();
127
- this.engine = null;
128
- this.listeners.clear();
128
+ this.#engine?.destroy?.();
129
+ this.#engine = null;
130
+ this.#listeners.clear();
129
131
  }
130
132
 
131
- private set(id: string | null, state: ReadAloudState): void {
132
- this.activeId = state === "idle" ? null : id;
133
- this.state = state;
134
- for (const listener of this.listeners) listener(this.activeId, this.state);
133
+ #set(id: string | null, state: ReadAloudState): void {
134
+ this.#activeId = state === "idle" ? null : id;
135
+ this.#state = state;
136
+ for (const listener of this.#listeners) listener(this.#activeId, this.#state);
135
137
  }
136
138
  }
@@ -85,42 +85,44 @@ export class RuntypeSpeechEngine implements SpeechEngine {
85
85
  // speechSynthesis.pause().
86
86
  readonly supportsPause = true;
87
87
 
88
- private player: PcmStreamPlayer | null = null;
89
- private playerPromise: Promise<PcmStreamPlayer> | null = null;
88
+ #player: PcmStreamPlayer | null = null;
89
+ #playerPromise: Promise<PcmStreamPlayer> | null = null;
90
90
  // Bumped on every speak()/stop() so a superseded request's async callbacks and
91
91
  // its in-flight stream read loop become no-ops.
92
- private generation = 0;
92
+ #generation = 0;
93
93
 
94
- constructor(private readonly opts: RuntypeSpeechEngineOptions) {}
94
+ readonly #opts: RuntypeSpeechEngineOptions;
95
+ constructor(opts: RuntypeSpeechEngineOptions) {
96
+ this.#opts = opts;}
95
97
 
96
98
  // Create one player lazily (a worklet engine's addModule is async), then reuse
97
99
  // it across speaks; flush() between replies clears the queue without tearing
98
100
  // down the AudioContext. Defaults to the in-bundle AudioPlaybackManager.
99
- private ensurePlayer(): Promise<PcmStreamPlayer> {
100
- return (this.playerPromise ??= Promise.resolve(
101
- this.opts.createPlaybackEngine
102
- ? this.opts.createPlaybackEngine()
101
+ #ensurePlayer(): Promise<PcmStreamPlayer> {
102
+ return (this.#playerPromise ??= Promise.resolve(
103
+ this.#opts.createPlaybackEngine
104
+ ? this.#opts.createPlaybackEngine()
103
105
  : new AudioPlaybackManager(24000, {
104
- prebufferMs: this.opts.prebufferMs ?? 200,
106
+ prebufferMs: this.#opts.prebufferMs ?? 200,
105
107
  }),
106
- ).then((player) => (this.player = player)));
108
+ ).then((player) => (this.#player = player)));
107
109
  }
108
110
 
109
111
  speak(request: SpeechRequest, callbacks: SpeechCallbacks): void {
110
- const gen = ++this.generation;
112
+ const gen = ++this.#generation;
111
113
  // Run the async fetch/stream without making speak() itself async — the
112
114
  // widget surfaces the time until audio starts as the "loading" state.
113
- void this.run(gen, request, callbacks);
115
+ void this.#run(gen, request, callbacks);
114
116
  }
115
117
 
116
- private async run(
118
+ async #run(
117
119
  gen: number,
118
120
  request: SpeechRequest,
119
121
  callbacks: SpeechCallbacks,
120
122
  ): Promise<void> {
121
123
  try {
122
- const player = await this.ensurePlayer();
123
- if (gen !== this.generation) return; // superseded while the worklet booted
124
+ const player = await this.#ensurePlayer();
125
+ if (gen !== this.#generation) return; // superseded while the worklet booted
124
126
  player.flush(); // drop any prior playback (and its callbacks)
125
127
  player.resume(); // clear a prior pause so this reply isn't stuck suspended
126
128
 
@@ -130,14 +132,14 @@ export class RuntypeSpeechEngine implements SpeechEngine {
130
132
  // no onStarted and an immediate onFinished, so the UI skips straight back
131
133
  // to idle without a phantom "playing".
132
134
  player.onStarted(() => {
133
- if (gen === this.generation) callbacks.onStart?.();
135
+ if (gen === this.#generation) callbacks.onStart?.();
134
136
  });
135
137
  player.onFinished(() => {
136
- if (gen === this.generation) callbacks.onEnd?.();
138
+ if (gen === this.#generation) callbacks.onEnd?.();
137
139
  });
138
140
 
139
- const url = `${normalizeHost(this.opts.host)}/v1/agents/${encodeURIComponent(
140
- this.opts.agentId,
141
+ const url = `${normalizeHost(this.#opts.host)}/v1/agents/${encodeURIComponent(
142
+ this.#opts.agentId,
141
143
  )}/speak`;
142
144
  const res = await fetch(url, {
143
145
  method: "POST",
@@ -145,21 +147,21 @@ export class RuntypeSpeechEngine implements SpeechEngine {
145
147
  "Content-Type": "application/json",
146
148
  // Match Runtype's client-token auth convention. Never placed in the
147
149
  // URL/query string.
148
- Authorization: `Bearer ${this.opts.clientToken}`,
150
+ Authorization: `Bearer ${this.#opts.clientToken}`,
149
151
  },
150
152
  body: JSON.stringify({
151
153
  text: request.text,
152
- voice: request.voice ?? this.opts.voice,
154
+ voice: request.voice ?? this.#opts.voice,
153
155
  format: "pcm",
154
156
  }),
155
157
  });
156
- if (gen !== this.generation) return; // superseded while awaiting headers
158
+ if (gen !== this.#generation) return; // superseded while awaiting headers
157
159
  if (!res.ok || !res.body) throw new Error(await describeError(res));
158
160
 
159
161
  const reader = res.body.getReader();
160
162
  for (;;) {
161
163
  const { done, value } = await reader.read();
162
- if (gen !== this.generation) {
164
+ if (gen !== this.#generation) {
163
165
  // A newer speak()/stop() won — stop pulling and release the stream.
164
166
  await reader.cancel().catch(() => {});
165
167
  return;
@@ -170,31 +172,31 @@ export class RuntypeSpeechEngine implements SpeechEngine {
170
172
 
171
173
  player.markStreamEnd();
172
174
  } catch (err) {
173
- if (gen !== this.generation) return; // error from a superseded request
175
+ if (gen !== this.#generation) return; // error from a superseded request
174
176
  const error = err instanceof Error ? err : new Error(String(err));
175
- this.opts.onError?.(error); // surface the reason (log, telemetry, …)
177
+ this.#opts.onError?.(error); // surface the reason (log, telemetry, …)
176
178
  callbacks.onError?.(error); // and let the widget (or fallback) react
177
179
  }
178
180
  }
179
181
 
180
182
  pause(): void {
181
- this.player?.pause();
183
+ this.#player?.pause();
182
184
  }
183
185
 
184
186
  resume(): void {
185
- this.player?.resume();
187
+ this.#player?.resume();
186
188
  }
187
189
 
188
190
  stop(): void {
189
- this.generation++; // invalidate any in-flight stream + pending onFinished
190
- this.player?.flush();
191
+ this.#generation++; // invalidate any in-flight stream + pending onFinished
192
+ this.#player?.flush();
191
193
  }
192
194
 
193
195
  destroy(): void {
194
- this.generation++;
195
- void this.player?.destroy();
196
- this.player = null;
197
- this.playerPromise = null;
196
+ this.#generation++;
197
+ void this.#player?.destroy();
198
+ this.#player = null;
199
+ this.#playerPromise = null;
198
200
  }
199
201
  }
200
202