@runtypelabs/persona 4.25.0 → 4.26.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 (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 +180 -8
  12. package/dist/approval-ui.d.ts +180 -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 +180 -8
  17. package/dist/artifacts-ui.d.ts +180 -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-HGUCGM3K.js +9 -0
  23. package/dist/chunk-IO5VVUKP.js +3 -0
  24. package/dist/chunk-J4J3Y2P2.js +1 -0
  25. package/dist/chunk-K6HKIP5K.js +1 -0
  26. package/dist/chunk-K7NA7G7J.js +1 -0
  27. package/dist/chunk-MXUTS3LB.js +1 -0
  28. package/dist/chunk-PDPVORUF.js +1 -0
  29. package/dist/chunk-QPPJUSZH.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-YPEG45Q4.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 +180 -8
  46. package/dist/context-mentions.d.ts +180 -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 +183 -31
  51. package/dist/event-stream-view.d.ts +183 -31
  52. package/dist/event-stream-view.js +1 -1
  53. package/dist/forms-ui.d.cts +221 -667
  54. package/dist/forms-ui.d.ts +221 -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 +227 -738
  65. package/dist/index.d.ts +227 -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 +180 -8
  80. package/dist/session-reconnect.d.ts +180 -8
  81. package/dist/smart-dom-reader.cjs +13 -13
  82. package/dist/smart-dom-reader.d.cts +180 -8
  83. package/dist/smart-dom-reader.d.ts +180 -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 +182 -8
  87. package/dist/theme-editor-preview.d.ts +182 -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 +181 -23
  91. package/dist/theme-editor.d.ts +181 -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-UOQOFAFY.js +17 -0
  98. package/dist/voice-runtime.cjs +17 -1
  99. package/dist/voice-runtime.d.cts +11650 -232
  100. package/dist/voice-runtime.d.ts +11650 -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 +221 -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 +852 -1536
  151. package/src/session.voice.test.ts +1170 -5
  152. package/src/styles/widget.css +58 -0
  153. package/src/theme-editor/state.ts +91 -91
  154. package/src/types.ts +198 -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 +670 -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 +981 -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
@@ -15,9 +15,11 @@ import type {
15
15
  HistoryViewOptions,
16
16
  HistoryViewHandle,
17
17
  } from "./history-view-entry";
18
+ import type { showHistoryConfirm } from "./components/history-confirm-dialog";
18
19
 
19
20
  export type HistoryViewModule = {
20
21
  createHistoryView: (options: HistoryViewOptions) => HistoryViewHandle;
22
+ showHistoryConfirm: typeof showHistoryConfirm;
21
23
  };
22
24
 
23
25
  // IIFE/CDN: sibling-URL chunk via the registered loader.
@@ -12,6 +12,9 @@
12
12
  */
13
13
 
14
14
  export { createHistoryView } from "./history-view-entry";
15
+ // The destructive-action confirm rides this chunk: every caller is already an
16
+ // async history action, so it costs the core bundle nothing.
17
+ export { showHistoryConfirm } from "./components/history-confirm-dialog";
15
18
  export {
16
19
  HISTORY_VIEW_COPY_DEFAULTS,
17
20
  resolveHistoryViewCopy,
package/src/index-core.ts CHANGED
@@ -653,6 +653,12 @@ export type {
653
653
  VoiceConfig,
654
654
  VoiceMetrics,
655
655
  VoicePlaybackEngine,
656
+ VoiceTranscriptMetadata,
657
+ VoiceDelegationRequest,
658
+ VoiceDelegationResult,
659
+ VoiceDelegationStatus,
660
+ VoiceDelegationFollowUp,
661
+ VoiceSessionBridge,
656
662
  PcmStreamPlayer,
657
663
  AgentWidgetVoiceStatusEvent,
658
664
  ReadAloudState,
@@ -45,25 +45,36 @@ const widgetScriptSrc: string | null =
45
45
  ? ((document.currentScript as HTMLScriptElement | null)?.src ?? null)
46
46
  : null;
47
47
 
48
- setWebMcpPolyfillLoader(() => {
49
- const chunkUrl = widgetScriptSrc?.replace(
50
- /index\.global\.js($|\?)/,
51
- "webmcp-polyfill.js$1",
52
- );
53
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
54
- return Promise.reject(
55
- new Error(
56
- "Could not derive the webmcp-polyfill.js URL from the widget script URL " +
57
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
58
- "rename index.global.js should install @mcp-b/webmcp-polyfill on the " +
59
- "page themselves before enabling config.webmcp.",
60
- ),
61
- );
62
- }
63
- // Runtime-only dynamic import; the specifier is a computed URL, so esbuild
64
- // leaves it untouched (and must not try to bundle it).
65
- return import(/* @vite-ignore */ chunkUrl);
66
- });
48
+ /**
49
+ * Loader for a lazy chunk published next to `index.global.js` (every
50
+ * `set*Loader` below uses it). Derives the chunk URL from this script's URL;
51
+ * self-hosted deployments that rename the bundle get an error naming the
52
+ * `remedy`.
53
+ */
54
+ const siblingChunk =
55
+ <T>(file: string, remedy = `host ${file} alongside it`) =>
56
+ (): Promise<T> => {
57
+ const chunkUrl = widgetScriptSrc?.replace(/index\.global\.js($|\?)/, `${file}$1`);
58
+ if (!chunkUrl || chunkUrl === widgetScriptSrc) {
59
+ return Promise.reject(
60
+ new Error(
61
+ `Could not derive the ${file} URL from the widget script URL ` +
62
+ `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
63
+ `rename index.global.js should ${remedy}.`,
64
+ ),
65
+ );
66
+ }
67
+ // Runtime-only dynamic import; the specifier is a computed URL, so esbuild
68
+ // leaves it untouched (and must not try to bundle it).
69
+ return import(/* @vite-ignore */ chunkUrl);
70
+ };
71
+
72
+ setWebMcpPolyfillLoader(
73
+ siblingChunk(
74
+ "webmcp-polyfill.js",
75
+ "install @mcp-b/webmcp-polyfill on the page themselves before enabling config.webmcp",
76
+ ),
77
+ );
67
78
 
68
79
  // ---------------------------------------------------------------------------
69
80
  // Deferred Markdown Parsers (marked + dompurify) loading.
@@ -77,22 +88,38 @@ setWebMcpPolyfillLoader(() => {
77
88
 
78
89
  import { setMarkdownParsersLoader } from "./markdown-parsers-loader";
79
90
 
80
- setMarkdownParsersLoader(() => {
81
- const chunkUrl = widgetScriptSrc?.replace(
82
- /index\.global\.js($|\?)/,
83
- "markdown-parsers.js$1",
84
- );
85
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
86
- return Promise.reject(
87
- new Error(
88
- "Could not derive the markdown-parsers.js URL from the widget script URL " +
89
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
90
- "rename index.global.js should host markdown-parsers.js alongside it.",
91
- ),
92
- );
93
- }
94
- return import(/* @vite-ignore */ chunkUrl);
95
- });
91
+ setMarkdownParsersLoader(siblingChunk("markdown-parsers.js"));
92
+
93
+ // Deferred SSE stream processor (`client-stream.ts`), built with
94
+ // `./client-stream` external. The client starts the fetch when a dispatch
95
+ // begins and the UI warms it alongside the markdown parsers.
96
+ import { setClientStreamLoader } from "./client-stream-loader";
97
+
98
+ setClientStreamLoader(siblingChunk("client-stream.js"));
99
+
100
+ // Deferred visitor-history REST (`client-history.ts`), built with
101
+ // `./client-history` external; fetched on the first history call.
102
+ import { setClientHistoryLoader } from "./client-history-loader";
103
+
104
+ setClientHistoryLoader(siblingChunk("client-history.js"));
105
+
106
+ // Deferred UI glue for opt-in / interaction-only features (`ui-extras-entry.ts`),
107
+ // built with `./ui-extras-entry` external; warmed when such a feature activates.
108
+ import { setUiExtrasLoader } from "./ui-extras-loader";
109
+
110
+ setUiExtrasLoader(siblingChunk("ui-extras.js"));
111
+ // Deferred session resolve paths (`session-actions.ts`: approvals,
112
+ // ask_user_question answers, WebMCP / suggest_replies resumes), built with
113
+ // `./session-actions` external. The session warms it when the agent pauses.
114
+ import { setSessionActionsLoader } from "./session-actions-loader";
115
+
116
+ setSessionActionsLoader(siblingChunk("session-actions.js"));
117
+ // Deferred visitor-history shell (`history-shell.ts`), built with
118
+ // `./history-shell` external. Fetched at mount only when
119
+ // `features.history.enabled`, or on the first history API call.
120
+ import { setHistoryShellLoader } from "./history-shell-loader";
121
+
122
+ setHistoryShellLoader(siblingChunk("history-shell.js"));
96
123
 
97
124
  // ---------------------------------------------------------------------------
98
125
  // Deferred Runtype TTS engine loading.
@@ -108,23 +135,12 @@ setMarkdownParsersLoader(() => {
108
135
 
109
136
  import { setRuntypeTtsLoader } from "./voice/runtype-tts-loader";
110
137
 
111
- setRuntypeTtsLoader(() => {
112
- const chunkUrl = widgetScriptSrc?.replace(
113
- /index\.global\.js($|\?)/,
114
- "runtype-tts.js$1",
115
- );
116
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
117
- return Promise.reject(
118
- new Error(
119
- "Could not derive the runtype-tts.js URL from the widget script URL " +
120
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
121
- "rename index.global.js should host runtype-tts.js alongside it, or set " +
122
- "textToSpeech.createEngine to supply a speech engine directly.",
123
- ),
124
- );
125
- }
126
- return import(/* @vite-ignore */ chunkUrl);
127
- });
138
+ setRuntypeTtsLoader(
139
+ siblingChunk(
140
+ "runtype-tts.js",
141
+ "host runtype-tts.js alongside it, or set textToSpeech.createEngine to supply a speech engine directly",
142
+ ),
143
+ );
128
144
 
129
145
  // ---------------------------------------------------------------------------
130
146
  // Deferred Context Mentions loading.
@@ -140,42 +156,11 @@ setRuntypeTtsLoader(() => {
140
156
  import { setContextMentionsLoader } from "./context-mentions-loader";
141
157
  import { setContextMentionsInlineLoader } from "./context-mentions-inline-loader";
142
158
 
143
- setContextMentionsLoader(() => {
144
- const chunkUrl = widgetScriptSrc?.replace(
145
- /index\.global\.js($|\?)/,
146
- "context-mentions.js$1",
147
- );
148
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
149
- return Promise.reject(
150
- new Error(
151
- "Could not derive the context-mentions.js URL from the widget script URL " +
152
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
153
- "rename index.global.js should host context-mentions.js alongside it.",
154
- ),
155
- );
156
- }
157
- return import(/* @vite-ignore */ chunkUrl);
158
- });
159
+ setContextMentionsLoader(siblingChunk("context-mentions.js"));
159
160
 
160
161
  // Sibling loader for the inline-mention contenteditable chunk, loaded on composer
161
162
  // mount when `contextMentions.display === "inline"`. Same sibling-URL scheme.
162
- setContextMentionsInlineLoader(() => {
163
- const chunkUrl = widgetScriptSrc?.replace(
164
- /index\.global\.js($|\?)/,
165
- "context-mentions-inline.js$1",
166
- );
167
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
168
- return Promise.reject(
169
- new Error(
170
- "Could not derive the context-mentions-inline.js URL from the widget " +
171
- `script URL (${widgetScriptSrc ?? "unavailable"}). Self-hosted ` +
172
- "deployments that rename index.global.js should host " +
173
- "context-mentions-inline.js alongside it.",
174
- ),
175
- );
176
- }
177
- return import(/* @vite-ignore */ chunkUrl);
178
- });
163
+ setContextMentionsInlineLoader(siblingChunk("context-mentions-inline.js"));
179
164
 
180
165
  // ---------------------------------------------------------------------------
181
166
  // Deferred history-view loading.
@@ -188,22 +173,7 @@ setContextMentionsInlineLoader(() => {
188
173
 
189
174
  import { setHistoryViewLoader } from "./history-view-loader";
190
175
 
191
- setHistoryViewLoader(() => {
192
- const chunkUrl = widgetScriptSrc?.replace(
193
- /index\.global\.js($|\?)/,
194
- "history-view.js$1",
195
- );
196
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
197
- return Promise.reject(
198
- new Error(
199
- "Could not derive the history-view.js URL from the widget script URL " +
200
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
201
- "rename index.global.js should host history-view.js alongside it.",
202
- ),
203
- );
204
- }
205
- return import(/* @vite-ignore */ chunkUrl);
206
- });
176
+ setHistoryViewLoader(siblingChunk("history-view.js"));
207
177
 
208
178
  // ---------------------------------------------------------------------------
209
179
  // Deferred stream-animations loading (wipe + glyph-cycle).
@@ -217,24 +187,12 @@ setHistoryViewLoader(() => {
217
187
 
218
188
  import { setAnimationsExtraLoader } from "./animations-extra-loader";
219
189
 
220
- setAnimationsExtraLoader(() => {
221
- const chunkUrl = widgetScriptSrc?.replace(
222
- /index\.global\.js($|\?)/,
223
- "animations-extra.js$1",
224
- );
225
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
226
- return Promise.reject(
227
- new Error(
228
- "Could not derive the animations-extra.js URL from the widget script URL " +
229
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
230
- "rename index.global.js should host animations-extra.js alongside it, " +
231
- "or register the animation plugins themselves via " +
232
- "registerStreamAnimationPlugin.",
233
- ),
234
- );
235
- }
236
- return import(/* @vite-ignore */ chunkUrl);
237
- });
190
+ setAnimationsExtraLoader(
191
+ siblingChunk(
192
+ "animations-extra.js",
193
+ "host animations-extra.js alongside it, or register the animation plugins themselves via registerStreamAnimationPlugin",
194
+ ),
195
+ );
238
196
 
239
197
  // ---------------------------------------------------------------------------
240
198
  // Deferred approval-ui loading.
@@ -247,22 +205,7 @@ setAnimationsExtraLoader(() => {
247
205
 
248
206
  import { setApprovalUiLoader } from "./approval-ui-loader";
249
207
 
250
- setApprovalUiLoader(() => {
251
- const chunkUrl = widgetScriptSrc?.replace(
252
- /index\.global\.js($|\?)/,
253
- "approval-ui.js$1",
254
- );
255
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
256
- return Promise.reject(
257
- new Error(
258
- "Could not derive the approval-ui.js URL from the widget script URL " +
259
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
260
- "rename index.global.js should host approval-ui.js alongside it.",
261
- ),
262
- );
263
- }
264
- return import(/* @vite-ignore */ chunkUrl);
265
- });
208
+ setApprovalUiLoader(siblingChunk("approval-ui.js"));
266
209
 
267
210
  // ---------------------------------------------------------------------------
268
211
  // Deferred voice-runtime loading.
@@ -276,22 +219,7 @@ setApprovalUiLoader(() => {
276
219
 
277
220
  import { setVoiceRuntimeLoader } from "./voice-runtime-loader";
278
221
 
279
- setVoiceRuntimeLoader(() => {
280
- const chunkUrl = widgetScriptSrc?.replace(
281
- /index\.global\.js($|\?)/,
282
- "voice-runtime.js$1",
283
- );
284
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
285
- return Promise.reject(
286
- new Error(
287
- "Could not derive the voice-runtime.js URL from the widget script URL " +
288
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
289
- "rename index.global.js should host voice-runtime.js alongside it.",
290
- ),
291
- );
292
- }
293
- return import(/* @vite-ignore */ chunkUrl);
294
- });
222
+ setVoiceRuntimeLoader(siblingChunk("voice-runtime.js"));
295
223
 
296
224
  // ---------------------------------------------------------------------------
297
225
  // Deferred artifacts-ui loading.
@@ -305,22 +233,7 @@ setVoiceRuntimeLoader(() => {
305
233
 
306
234
  import { setArtifactsUiLoader } from "./artifacts-ui-loader";
307
235
 
308
- setArtifactsUiLoader(() => {
309
- const chunkUrl = widgetScriptSrc?.replace(
310
- /index\.global\.js($|\?)/,
311
- "artifacts-ui.js$1",
312
- );
313
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
314
- return Promise.reject(
315
- new Error(
316
- "Could not derive the artifacts-ui.js URL from the widget script URL " +
317
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
318
- "rename index.global.js should host artifacts-ui.js alongside it.",
319
- ),
320
- );
321
- }
322
- return import(/* @vite-ignore */ chunkUrl);
323
- });
236
+ setArtifactsUiLoader(siblingChunk("artifacts-ui.js"));
324
237
 
325
238
  // ---------------------------------------------------------------------------
326
239
  // Deferred forms-ui loading.
@@ -333,22 +246,7 @@ setArtifactsUiLoader(() => {
333
246
 
334
247
  import { setFormsUiLoader } from "./forms-ui-loader";
335
248
 
336
- setFormsUiLoader(() => {
337
- const chunkUrl = widgetScriptSrc?.replace(
338
- /index\.global\.js($|\?)/,
339
- "forms-ui.js$1",
340
- );
341
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
342
- return Promise.reject(
343
- new Error(
344
- "Could not derive the forms-ui.js URL from the widget script URL " +
345
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
346
- "rename index.global.js should host forms-ui.js alongside it.",
347
- ),
348
- );
349
- }
350
- return import(/* @vite-ignore */ chunkUrl);
351
- });
249
+ setFormsUiLoader(siblingChunk("forms-ui.js"));
352
250
 
353
251
  // ---------------------------------------------------------------------------
354
252
  // Deferred extra-icons loading.
@@ -361,23 +259,12 @@ setFormsUiLoader(() => {
361
259
 
362
260
  import { setIconsExtraLoader } from "./icons-extra-loader";
363
261
 
364
- setIconsExtraLoader(() => {
365
- const chunkUrl = widgetScriptSrc?.replace(
366
- /index\.global\.js($|\?)/,
367
- "icons-extra.js$1",
368
- );
369
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
370
- return Promise.reject(
371
- new Error(
372
- "Could not derive the icons-extra.js URL from the widget script URL " +
373
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
374
- "rename index.global.js should host icons-extra.js alongside it, or " +
375
- "register the icons they use via registerIcons().",
376
- ),
377
- );
378
- }
379
- return import(/* @vite-ignore */ chunkUrl);
380
- });
262
+ setIconsExtraLoader(
263
+ siblingChunk(
264
+ "icons-extra.js",
265
+ "host icons-extra.js alongside it, or register the icons they use via registerIcons()",
266
+ ),
267
+ );
381
268
 
382
269
  // ---------------------------------------------------------------------------
383
270
  // Deferred WebMCP bridge runtime loading.
@@ -391,22 +278,7 @@ setIconsExtraLoader(() => {
391
278
 
392
279
  import { setWebMcpRuntimeLoader } from "./webmcp-runtime-loader";
393
280
 
394
- setWebMcpRuntimeLoader(() => {
395
- const chunkUrl = widgetScriptSrc?.replace(
396
- /index\.global\.js($|\?)/,
397
- "webmcp-runtime.js$1",
398
- );
399
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
400
- return Promise.reject(
401
- new Error(
402
- "Could not derive the webmcp-runtime.js URL from the widget script URL " +
403
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
404
- "rename index.global.js should host webmcp-runtime.js alongside it.",
405
- ),
406
- );
407
- }
408
- return import(/* @vite-ignore */ chunkUrl);
409
- });
281
+ setWebMcpRuntimeLoader(siblingChunk("webmcp-runtime.js"));
410
282
 
411
283
  // ---------------------------------------------------------------------------
412
284
  // Deferred session-reconnect loading.
@@ -420,22 +292,7 @@ setWebMcpRuntimeLoader(() => {
420
292
 
421
293
  import { setSessionReconnectLoader } from "./session-reconnect-loader";
422
294
 
423
- setSessionReconnectLoader(() => {
424
- const chunkUrl = widgetScriptSrc?.replace(
425
- /index\.global\.js($|\?)/,
426
- "session-reconnect.js$1",
427
- );
428
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
429
- return Promise.reject(
430
- new Error(
431
- "Could not derive the session-reconnect.js URL from the widget script URL " +
432
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
433
- "rename index.global.js should host session-reconnect.js alongside it.",
434
- ),
435
- );
436
- }
437
- return import(/* @vite-ignore */ chunkUrl);
438
- });
295
+ setSessionReconnectLoader(siblingChunk("session-reconnect.js"));
439
296
 
440
297
  // ---------------------------------------------------------------------------
441
298
  // Deferred event-stream-view loading.
@@ -447,19 +304,4 @@ setSessionReconnectLoader(() => {
447
304
 
448
305
  import { setEventStreamViewLoader } from "./event-stream-view-loader";
449
306
 
450
- setEventStreamViewLoader(() => {
451
- const chunkUrl = widgetScriptSrc?.replace(
452
- /index\.global\.js($|\?)/,
453
- "event-stream-view.js$1",
454
- );
455
- if (!chunkUrl || chunkUrl === widgetScriptSrc) {
456
- return Promise.reject(
457
- new Error(
458
- "Could not derive the event-stream-view.js URL from the widget script URL " +
459
- `(${widgetScriptSrc ?? "unavailable"}). Self-hosted deployments that ` +
460
- "rename index.global.js should host event-stream-view.js alongside it.",
461
- ),
462
- );
463
- }
464
- return import(/* @vite-ignore */ chunkUrl);
465
- });
307
+ setEventStreamViewLoader(siblingChunk("event-stream-view.js"));
package/src/index.ts CHANGED
@@ -23,6 +23,19 @@ import "./markdown-parsers-eager";
23
23
  // `renderLucideIcon` contract; the IIFE/CDN build lazy-loads `icons-extra.js`.
24
24
  import "./icons-extra-eager";
25
25
 
26
+ // Same for the SSE stream processor (lazy `client-stream.js` in the IIFE).
27
+ import "./client-stream-eager";
28
+ import "./client-history-eager";
29
+
30
+ // And the opt-in UI glue (lazy `ui-extras.js` in the IIFE).
31
+ import "./ui-extras-eager";
32
+ // Same for the session's approval / local-tool resolve paths
33
+ // (lazy `session-actions.js` in the IIFE).
34
+ import "./session-actions-eager";
35
+
36
+ // And the visitor-history shell (lazy `history-shell.js` in the IIFE).
37
+ import "./history-shell-eager";
38
+
26
39
  // Full public API (everything except the two dev-only helpers below).
27
40
  export * from "./index-core";
28
41
  export { default } from "./index-core";
package/src/install.ts CHANGED
@@ -422,13 +422,15 @@ declare global {
422
422
  document.head.appendChild(link);
423
423
  }
424
424
 
425
- // Also prefetch the markdown parsers chunk
426
- const markdownUrl = jsUrl.replace(/index\.global\.js($|\?)/, "markdown-parsers.js$1");
427
- if (markdownUrl !== jsUrl) {
425
+ // Also prefetch the chunks every conversation needs: the markdown
426
+ // parsers and the SSE stream processor.
427
+ for (const chunk of ["markdown-parsers.js", "client-stream.js"]) {
428
+ const chunkUrl = jsUrl.replace(/index\.global\.js($|\?)/, `${chunk}$1`);
429
+ if (chunkUrl === jsUrl) continue;
428
430
  const link2 = document.createElement("link");
429
431
  link2.rel = "prefetch";
430
432
  link2.as = "script";
431
- link2.href = markdownUrl;
433
+ link2.href = chunkUrl;
432
434
  document.head.appendChild(link2);
433
435
  }
434
436
  };
@@ -57,6 +57,7 @@ describe('createRuntypeHistoryProvider', () => {
57
57
  internals
58
58
  );
59
59
  const provider = createRuntypeHistoryProvider({
60
+ errors: { HistoryClientError, HistoryProviderError },
60
61
  client,
61
62
  getIdentityProofConfigured: () => Boolean(config.getIdentityProof),
62
63
  onActivationCommitted: (session) => {
@@ -11,23 +11,23 @@
11
11
  * Not public and not in any tsup entry or package export.
12
12
  */
13
13
 
14
- import { HistoryClientError, type AgentWidgetClient } from "../client";
14
+ import type { HistoryClientError, AgentWidgetClient } from "../client";
15
15
  import type { ClientSession, HistoryScope } from "../types";
16
16
  import {
17
17
  mapWireMessages,
18
18
  mergeWireMessagesById,
19
19
  } from "../utils/history-messages";
20
- import {
20
+ import type {
21
21
  HistoryProviderError,
22
- type HistoryConversationSummary,
23
- type HistoryDeleteAllOptions,
24
- type HistoryListOptions,
25
- type HistoryListResult,
26
- type HistoryPageOptions,
27
- type HistoryPageResult,
28
- type HistoryProvider,
29
- type HistoryProviderErrorCode,
30
- type PreparedHistoryActivation,
22
+ HistoryConversationSummary,
23
+ HistoryDeleteAllOptions,
24
+ HistoryListOptions,
25
+ HistoryListResult,
26
+ HistoryPageOptions,
27
+ HistoryPageResult,
28
+ HistoryProvider,
29
+ HistoryProviderErrorCode,
30
+ PreparedHistoryActivation,
31
31
  } from "./history-provider";
32
32
 
33
33
  export interface RuntypeHistoryProviderOptions {
@@ -41,8 +41,19 @@ export interface RuntypeHistoryProviderOptions {
41
41
  onActivationCommitted: (session: ClientSession) => void | Promise<void>;
42
42
  /** Live client rebuilds hand the provider its replacement. */
43
43
  getClient?: () => AgentWidgetClient;
44
+ /**
45
+ * The core bundle's error classes. Passed in (not imported) so a lazily
46
+ * loaded copy of this module still throws, and recognizes, the classes the
47
+ * rest of the widget checks with `instanceof`.
48
+ */
49
+ errors: HistoryErrorClasses;
44
50
  }
45
51
 
52
+ export type HistoryErrorClasses = {
53
+ HistoryClientError: typeof HistoryClientError;
54
+ HistoryProviderError: typeof HistoryProviderError;
55
+ };
56
+
46
57
  /** Client error code -> domain code. Anything unmapped is `unavailable`. */
47
58
  const ERROR_CODE_MAP = new Map<string, HistoryProviderErrorCode>([
48
59
  ["not_found", "not_found"],
@@ -78,7 +89,10 @@ const DOMAIN_MESSAGE = new Map<HistoryProviderErrorCode, string>([
78
89
  const domainMessage = (code: HistoryProviderErrorCode): string =>
79
90
  DOMAIN_MESSAGE.get(code) ?? "Conversation history is unavailable right now.";
80
91
 
81
- export function toHistoryProviderError(error: unknown): HistoryProviderError {
92
+ export function toHistoryProviderError(
93
+ error: unknown,
94
+ { HistoryClientError, HistoryProviderError }: HistoryErrorClasses
95
+ ): HistoryProviderError {
82
96
  if (error instanceof HistoryProviderError) return error;
83
97
  if (error instanceof HistoryClientError) {
84
98
  const code = ERROR_CODE_MAP.get(error.code) ?? "unavailable";
@@ -94,6 +108,7 @@ export function toHistoryProviderError(error: unknown): HistoryProviderError {
94
108
  export function createRuntypeHistoryProvider(
95
109
  options: RuntypeHistoryProviderOptions
96
110
  ): HistoryProvider {
111
+ const { HistoryProviderError } = options.errors;
97
112
  const client = (): AgentWidgetClient =>
98
113
  options.getClient?.() ?? options.client;
99
114
 
@@ -116,7 +131,7 @@ export function createRuntypeHistoryProvider(
116
131
  try {
117
132
  return await fn();
118
133
  } catch (error) {
119
- throw toHistoryProviderError(error);
134
+ throw toHistoryProviderError(error, options.errors);
120
135
  }
121
136
  };
122
137
 
@@ -1,17 +1,17 @@
1
1
  import { AgentWidgetPlugin } from "./types";
2
2
 
3
3
  class PluginRegistry {
4
- private plugins: Map<string, AgentWidgetPlugin> = new Map();
4
+ #plugins: Map<string, AgentWidgetPlugin> = new Map();
5
5
 
6
6
  /**
7
7
  * Register a plugin
8
8
  */
9
9
  register(plugin: AgentWidgetPlugin): void {
10
- if (this.plugins.has(plugin.id)) {
10
+ if (this.#plugins.has(plugin.id)) {
11
11
  console.warn(`Plugin "${plugin.id}" is already registered. Overwriting.`);
12
12
  }
13
13
 
14
- this.plugins.set(plugin.id, plugin);
14
+ this.#plugins.set(plugin.id, plugin);
15
15
  plugin.onRegister?.();
16
16
  }
17
17
 
@@ -19,10 +19,10 @@ class PluginRegistry {
19
19
  * Unregister a plugin
20
20
  */
21
21
  unregister(pluginId: string): void {
22
- const plugin = this.plugins.get(pluginId);
22
+ const plugin = this.#plugins.get(pluginId);
23
23
  if (plugin) {
24
24
  plugin.onUnregister?.();
25
- this.plugins.delete(pluginId);
25
+ this.#plugins.delete(pluginId);
26
26
  }
27
27
  }
28
28
 
@@ -30,7 +30,7 @@ class PluginRegistry {
30
30
  * Get all plugins sorted by priority
31
31
  */
32
32
  getAll(): AgentWidgetPlugin[] {
33
- return Array.from(this.plugins.values()).sort(
33
+ return Array.from(this.#plugins.values()).sort(
34
34
  (a, b) => (b.priority ?? 0) - (a.priority ?? 0)
35
35
  );
36
36
  }
@@ -61,8 +61,8 @@ class PluginRegistry {
61
61
  * Clear all plugins
62
62
  */
63
63
  clear(): void {
64
- this.plugins.forEach(plugin => plugin.onUnregister?.());
65
- this.plugins.clear();
64
+ this.#plugins.forEach(plugin => plugin.onUnregister?.());
65
+ this.#plugins.clear();
66
66
  }
67
67
  }
68
68