@runtypelabs/persona 4.7.0 → 4.9.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 (185) hide show
  1. package/README.md +1 -0
  2. package/dist/animations/glyph-cycle.cjs +2 -2
  3. package/dist/animations/glyph-cycle.d.cts +1 -1
  4. package/dist/animations/glyph-cycle.d.ts +1 -1
  5. package/dist/animations/glyph-cycle.js +2 -2
  6. package/dist/animations/{types-CSmiKRVa.d.cts → types-4ROVJ1gA.d.cts} +85 -3
  7. package/dist/animations/{types-CSmiKRVa.d.ts → types-4ROVJ1gA.d.ts} +85 -3
  8. package/dist/animations/wipe.cjs +2 -2
  9. package/dist/animations/wipe.d.cts +1 -1
  10. package/dist/animations/wipe.d.ts +1 -1
  11. package/dist/chunk-5EIIHQLQ.js +1 -0
  12. package/dist/chunk-IO5VVUKP.js +3 -0
  13. package/dist/chunk-IPVK3KOM.js +1 -0
  14. package/dist/chunk-UPO4GUFC.js +1 -0
  15. package/dist/codegen.cjs +13 -13
  16. package/dist/codegen.js +14 -14
  17. package/dist/context-mentions-7S5KVUTG.js +169 -0
  18. package/dist/context-mentions-inline-TTCN7ZM2.js +4 -0
  19. package/dist/context-mentions-inline.cjs +4 -0
  20. package/dist/context-mentions-inline.d.cts +203 -0
  21. package/dist/context-mentions-inline.d.ts +203 -0
  22. package/dist/context-mentions-inline.js +4 -0
  23. package/dist/context-mentions.cjs +295 -0
  24. package/dist/context-mentions.d.cts +7025 -0
  25. package/dist/context-mentions.d.ts +7025 -0
  26. package/dist/context-mentions.js +295 -0
  27. package/dist/index.cjs +99 -68
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +1507 -182
  30. package/dist/index.d.ts +1507 -182
  31. package/dist/index.global.js +88 -56
  32. package/dist/index.global.js.map +1 -1
  33. package/dist/index.js +99 -68
  34. package/dist/index.js.map +1 -1
  35. package/dist/install.global.js +1 -1
  36. package/dist/install.global.js.map +1 -1
  37. package/dist/launcher.global.js +3 -2
  38. package/dist/launcher.global.js.map +1 -1
  39. package/dist/markdown-parsers.js +24 -24
  40. package/dist/plugin-kit.cjs +1 -1
  41. package/dist/plugin-kit.d.cts +17 -0
  42. package/dist/plugin-kit.d.ts +17 -0
  43. package/dist/plugin-kit.js +1 -1
  44. package/dist/runtype-tts-entry-UJAEF7NZ.js +1 -0
  45. package/dist/runtype-tts.js +1 -1
  46. package/dist/session-reconnect-JKIJBHS5.js +1 -0
  47. package/dist/smart-dom-reader.cjs +18 -17
  48. package/dist/smart-dom-reader.d.cts +1260 -16
  49. package/dist/smart-dom-reader.d.ts +1260 -16
  50. package/dist/smart-dom-reader.js +18 -17
  51. package/dist/testing.cjs +3 -3
  52. package/dist/testing.js +3 -3
  53. package/dist/theme-editor-preview.cjs +260 -58
  54. package/dist/theme-editor-preview.d.cts +1234 -15
  55. package/dist/theme-editor-preview.d.ts +1234 -15
  56. package/dist/theme-editor-preview.js +87 -58
  57. package/dist/theme-editor.cjs +10 -10
  58. package/dist/theme-editor.d.cts +1226 -15
  59. package/dist/theme-editor.d.ts +1226 -15
  60. package/dist/theme-editor.js +10 -10
  61. package/dist/theme-reference.cjs +1 -1
  62. package/dist/theme-reference.d.cts +76 -0
  63. package/dist/theme-reference.d.ts +76 -0
  64. package/dist/theme-reference.js +1 -1
  65. package/dist/voice-worklet-player.cjs +2 -2
  66. package/dist/voice-worklet-player.js +2 -2
  67. package/dist/webmcp-polyfill.js +2 -2
  68. package/dist/widget.css +1 -1
  69. package/package.json +16 -5
  70. package/src/artifacts-session.test.ts +178 -0
  71. package/src/client.test.ts +255 -1
  72. package/src/client.ts +157 -60
  73. package/src/components/artifact-card.test.ts +333 -0
  74. package/src/components/artifact-card.ts +75 -28
  75. package/src/components/artifact-inline.test.ts +1328 -0
  76. package/src/components/artifact-inline.ts +920 -0
  77. package/src/components/artifact-pane.test.ts +1042 -0
  78. package/src/components/artifact-pane.ts +440 -131
  79. package/src/components/artifact-preview.test.ts +1155 -0
  80. package/src/components/artifact-preview.ts +994 -0
  81. package/src/components/composer-parts.ts +3 -12
  82. package/src/components/context-mention-button.test.ts +70 -0
  83. package/src/components/context-mention-button.ts +82 -0
  84. package/src/components/context-mention-chip.ts +134 -0
  85. package/src/components/context-mention-menu.test.ts +508 -0
  86. package/src/components/context-mention-menu.ts +0 -0
  87. package/src/components/message-bubble.test.ts +175 -0
  88. package/src/components/message-bubble.ts +177 -19
  89. package/src/components/panel.ts +7 -10
  90. package/src/components/pill-composer-builder.test.ts +6 -2
  91. package/src/components/pill-composer-builder.ts +6 -6
  92. package/src/components/reasoning-bubble.ts +1 -13
  93. package/src/components/registry.ts +38 -3
  94. package/src/components/tool-bubble.ts +1 -13
  95. package/src/context-mentions-bundle.test.ts +163 -0
  96. package/src/context-mentions-entry.ts +185 -0
  97. package/src/context-mentions-inline-entry.test.ts +136 -0
  98. package/src/context-mentions-inline-entry.ts +226 -0
  99. package/src/context-mentions-inline-loader.test.ts +30 -0
  100. package/src/context-mentions-inline-loader.ts +36 -0
  101. package/src/context-mentions-inline.ts +15 -0
  102. package/src/context-mentions-loader.ts +32 -0
  103. package/src/context-mentions.ts +16 -0
  104. package/src/defaults.ts +1 -0
  105. package/src/generated/runtype-openapi-contract.ts +55 -3
  106. package/src/index-core.ts +46 -1
  107. package/src/index-global.ts +51 -0
  108. package/src/index.ts +8 -0
  109. package/src/markdown-parsers-loader.test.ts +158 -0
  110. package/src/markdown-parsers-loader.ts +83 -27
  111. package/src/plugin-kit.test.ts +40 -0
  112. package/src/plugin-kit.ts +39 -5
  113. package/src/runtime/host-layout.test.ts +163 -0
  114. package/src/runtime/host-layout.ts +110 -7
  115. package/src/runtime/init.ts +18 -61
  116. package/src/session.mentions.test.ts +175 -0
  117. package/src/session.test.ts +52 -4
  118. package/src/session.ts +197 -27
  119. package/src/smart-dom-reader.test.ts +129 -2
  120. package/src/smart-dom-reader.ts +127 -1
  121. package/src/styles/context-mention-menu-css.ts +176 -0
  122. package/src/styles/widget.css +1002 -152
  123. package/src/theme-editor/preview.ts +2 -0
  124. package/src/theme-editor/sections.test.ts +26 -1
  125. package/src/theme-editor/sections.ts +13 -5
  126. package/src/theme-reference.ts +2 -2
  127. package/src/tool-call-display-defaults.test.ts +1 -0
  128. package/src/types/theme.ts +79 -0
  129. package/src/types.ts +1041 -17
  130. package/src/ui.artifact-pane-gating.test.ts +636 -0
  131. package/src/ui.component-directive.test.ts +104 -0
  132. package/src/ui.composer-bar.test.ts +60 -2
  133. package/src/ui.detached-panel.test.ts +1049 -0
  134. package/src/ui.mention-submit.test.ts +235 -0
  135. package/src/ui.tool-display.test.ts +51 -0
  136. package/src/ui.ts +998 -159
  137. package/src/utils/artifact-custom-actions.ts +128 -0
  138. package/src/utils/artifact-display.test.ts +42 -0
  139. package/src/utils/artifact-display.ts +84 -0
  140. package/src/utils/artifact-file.test.ts +116 -0
  141. package/src/utils/artifact-file.ts +117 -0
  142. package/src/utils/artifact-gate.test.ts +112 -5
  143. package/src/utils/artifact-gate.ts +39 -14
  144. package/src/utils/artifact-loading-status.ts +55 -0
  145. package/src/utils/artifact-status-label.ts +190 -0
  146. package/src/utils/buttons.ts +7 -1
  147. package/src/utils/chunk-loader.test.ts +97 -0
  148. package/src/utils/chunk-loader.ts +88 -0
  149. package/src/utils/code-highlight.test.ts +186 -0
  150. package/src/utils/code-highlight.ts +400 -0
  151. package/src/utils/composer-contenteditable.test.ts +507 -0
  152. package/src/utils/composer-contenteditable.ts +626 -0
  153. package/src/utils/composer-document.test.ts +280 -0
  154. package/src/utils/composer-document.ts +293 -0
  155. package/src/utils/composer-history.test.ts +35 -7
  156. package/src/utils/composer-history.ts +30 -20
  157. package/src/utils/composer-input.ts +159 -0
  158. package/src/utils/context-mention-controller.test.ts +1215 -0
  159. package/src/utils/context-mention-controller.ts +1186 -0
  160. package/src/utils/context-mention-manager.test.ts +422 -0
  161. package/src/utils/context-mention-manager.ts +410 -0
  162. package/src/utils/context-mention-orchestrator.test.ts +538 -0
  163. package/src/utils/context-mention-orchestrator.ts +348 -0
  164. package/src/utils/icons.ts +2 -0
  165. package/src/utils/live-region.test.ts +108 -0
  166. package/src/utils/live-region.ts +94 -0
  167. package/src/utils/mention-channels.ts +63 -0
  168. package/src/utils/mention-llm-format.test.ts +91 -0
  169. package/src/utils/mention-llm-format.ts +79 -0
  170. package/src/utils/mention-matcher.test.ts +86 -0
  171. package/src/utils/mention-matcher.ts +221 -0
  172. package/src/utils/mention-token.ts +72 -0
  173. package/src/utils/mention-trigger.test.ts +155 -0
  174. package/src/utils/mention-trigger.ts +156 -0
  175. package/src/utils/roving-tablist.test.ts +152 -0
  176. package/src/utils/roving-tablist.ts +111 -0
  177. package/src/utils/spinner.ts +45 -0
  178. package/src/utils/theme.test.ts +76 -4
  179. package/src/utils/theme.ts +7 -0
  180. package/src/utils/tokens.ts +118 -11
  181. package/src/utils/tool-loading-animation.test.ts +32 -0
  182. package/src/utils/tool-loading-animation.ts +24 -0
  183. package/dist/chunk-DFBSCFYN.js +0 -1
  184. package/dist/runtype-tts-entry-HFUV2UF7.js +0 -1
  185. package/dist/session-reconnect-U77QFUR7.js +0 -1
@@ -157,6 +157,110 @@ describe("component directive bubble: listener preservation across morphs", () =
157
157
  controller.destroy();
158
158
  });
159
159
 
160
+ it("renders a bubbleChrome:false component bare (no persona-message-bubble ancestor) under default config", () => {
161
+ const mount = createMount();
162
+ const controller = createAgentExperience(mount, {
163
+ apiUrl: "https://api.example.com/chat",
164
+ launcher: { enabled: false },
165
+ parserType: "json",
166
+ enableComponentStreaming: true,
167
+ components: {},
168
+ } as unknown as Parameters<typeof createAgentExperience>[1]);
169
+
170
+ componentRegistry.register(
171
+ "BareCard",
172
+ ((props) => {
173
+ const el = document.createElement("div");
174
+ el.setAttribute("data-test-id", "bare-card");
175
+ el.textContent = String(props.label ?? "");
176
+ return el;
177
+ }) satisfies ComponentRenderer,
178
+ { bubbleChrome: false }
179
+ );
180
+
181
+ directiveMessage(controller, {
182
+ id: "bare-1",
183
+ rawContent: JSON.stringify({ component: "BareCard", props: { label: "hello" } }),
184
+ });
185
+
186
+ const card = mount.querySelector<HTMLElement>('[data-test-id="bare-card"]');
187
+ expect(card).not.toBeNull();
188
+ // No message-bubble chrome around the bare directive.
189
+ expect(card!.closest(".persona-message-bubble")).toBeNull();
190
+ // The bare stack wrapper is present instead.
191
+ expect(card!.closest('[data-persona-component-directive="true"]')).not.toBeNull();
192
+
193
+ controller.destroy();
194
+ });
195
+
196
+ it("wraps a component without bubbleChrome:false in the message bubble under default config", () => {
197
+ const mount = createMount();
198
+ const controller = createAgentExperience(mount, {
199
+ apiUrl: "https://api.example.com/chat",
200
+ launcher: { enabled: false },
201
+ parserType: "json",
202
+ enableComponentStreaming: true,
203
+ components: {},
204
+ } as unknown as Parameters<typeof createAgentExperience>[1]);
205
+
206
+ componentRegistry.register(
207
+ "ChromeCard",
208
+ ((props) => {
209
+ const el = document.createElement("div");
210
+ el.setAttribute("data-test-id", "chrome-card");
211
+ el.textContent = String(props.label ?? "");
212
+ return el;
213
+ }) satisfies ComponentRenderer
214
+ );
215
+
216
+ directiveMessage(controller, {
217
+ id: "chrome-1",
218
+ rawContent: JSON.stringify({ component: "ChromeCard", props: { label: "hello" } }),
219
+ });
220
+
221
+ const card = mount.querySelector<HTMLElement>('[data-test-id="chrome-card"]');
222
+ expect(card).not.toBeNull();
223
+ expect(card!.closest(".persona-message-bubble")).not.toBeNull();
224
+
225
+ controller.destroy();
226
+ });
227
+
228
+ it("unwraps every component when wrapComponentDirectiveInBubble is false", () => {
229
+ const mount = createMount();
230
+ const controller = createAgentExperience(mount, {
231
+ apiUrl: "https://api.example.com/chat",
232
+ launcher: { enabled: false },
233
+ parserType: "json",
234
+ enableComponentStreaming: true,
235
+ wrapComponentDirectiveInBubble: false,
236
+ components: {},
237
+ } as unknown as Parameters<typeof createAgentExperience>[1]);
238
+
239
+ // A component with default (chrome) options still renders bare when the
240
+ // global flag is off.
241
+ componentRegistry.register(
242
+ "ChromeCard",
243
+ ((props) => {
244
+ const el = document.createElement("div");
245
+ el.setAttribute("data-test-id", "chrome-card");
246
+ el.textContent = String(props.label ?? "");
247
+ return el;
248
+ }) satisfies ComponentRenderer
249
+ );
250
+
251
+ directiveMessage(controller, {
252
+ id: "off-1",
253
+ rawContent: JSON.stringify({ component: "ChromeCard", props: { label: "hello" } }),
254
+ });
255
+
256
+ const card = mount.querySelector<HTMLElement>('[data-test-id="chrome-card"]');
257
+ expect(card).not.toBeNull();
258
+ expect(card!.closest(".persona-message-bubble")).toBeNull();
259
+ expect(card!.closest('[data-persona-component-directive="true"]')).not.toBeNull();
260
+
261
+ controller.destroy();
262
+ });
263
+
160
264
  it("falls back to the standard render path when the directive component is not registered", () => {
161
265
  const mount = createMount();
162
266
  const controller = createAgentExperience(mount, {
@@ -1,11 +1,12 @@
1
1
  // @vitest-environment jsdom
2
2
 
3
- import { afterEach, describe, expect, it } from "vitest";
3
+ import { afterEach, describe, expect, it, vi } from "vitest";
4
4
 
5
5
  import { createAgentExperience } from "./ui";
6
6
 
7
7
  describe("createAgentExperience composer-bar mode", () => {
8
8
  afterEach(() => {
9
+ vi.unstubAllGlobals();
9
10
  document.body.innerHTML = "";
10
11
  // The widget's default localStorage adapter persists chat history
11
12
  // across createAgentExperience calls. Clear it so each test starts
@@ -329,18 +330,26 @@ describe("createAgentExperience composer-bar mode", () => {
329
330
  controller.destroy();
330
331
  });
331
332
 
332
- it("clicking the clear-chat button clears injected messages", () => {
333
+ it("clicking the clear-chat button clears messages and artifacts", () => {
334
+ vi.stubGlobal("matchMedia", () => ({ matches: false }));
333
335
  const mount = document.createElement("div");
334
336
  document.body.appendChild(mount);
335
337
 
336
338
  const controller = createAgentExperience(mount, {
337
339
  apiUrl: "https://api.example.com/chat",
338
340
  launcher: { mountMode: "composer-bar" },
341
+ features: { artifacts: { enabled: true } },
339
342
  });
340
343
 
341
344
  controller.injectAssistantMessage({ content: "hello there" });
342
345
  controller.injectUserMessage({ content: "ping" });
346
+ controller.upsertArtifact({
347
+ artifactType: "markdown",
348
+ title: "Generated analysis",
349
+ content: "# Revenue trend",
350
+ });
343
351
  expect(controller.getMessages().length).toBeGreaterThan(0);
352
+ expect(controller.getArtifacts()).toHaveLength(1);
344
353
 
345
354
  const clearChat = mount.querySelector<HTMLButtonElement>(
346
355
  "[aria-label='Clear chat'], [aria-label='Start over']"
@@ -349,6 +358,7 @@ describe("createAgentExperience composer-bar mode", () => {
349
358
  clearChat!.click();
350
359
 
351
360
  expect(controller.getMessages().length).toBe(0);
361
+ expect(controller.getArtifacts()).toHaveLength(0);
352
362
 
353
363
  controller.destroy();
354
364
  });
@@ -413,6 +423,54 @@ describe("createAgentExperience composer-bar mode", () => {
413
423
  controller.destroy();
414
424
  });
415
425
 
426
+ it("keeps the pill composer mounted when artifacts enable the split layout", () => {
427
+ const mount = document.createElement("div");
428
+ document.body.appendChild(mount);
429
+
430
+ const controller = createAgentExperience(mount, {
431
+ apiUrl: "https://api.example.com/chat",
432
+ launcher: { mountMode: "composer-bar" },
433
+ features: { artifacts: { enabled: true } },
434
+ });
435
+
436
+ const pillRoot = mount.querySelector<HTMLElement>(".persona-widget-pill-root");
437
+ const composerInput = pillRoot?.querySelector<HTMLTextAreaElement>(
438
+ "[data-persona-composer-input]"
439
+ );
440
+ expect(pillRoot).not.toBeNull();
441
+ expect(composerInput).not.toBeNull();
442
+ expect(composerInput!.placeholder).toBeTruthy();
443
+
444
+ controller.open();
445
+ expect(pillRoot!.dataset.state).toBe("expanded");
446
+ expect(composerInput!.isConnected).toBe(true);
447
+
448
+ controller.destroy();
449
+ });
450
+
451
+ it("renders configured suggestion chips in the composer-bar footer", () => {
452
+ const mount = document.createElement("div");
453
+ document.body.appendChild(mount);
454
+
455
+ const controller = createAgentExperience(mount, {
456
+ apiUrl: "https://api.example.com/chat",
457
+ launcher: { mountMode: "composer-bar" },
458
+ suggestionChips: ["Revenue trend", "Channel mix"],
459
+ });
460
+
461
+ const pillRoot = mount.querySelector<HTMLElement>(".persona-widget-pill-root");
462
+ const suggestions = pillRoot?.querySelector<HTMLElement>(
463
+ "[data-persona-composer-suggestions]"
464
+ );
465
+ expect(suggestions?.querySelectorAll("button")).toHaveLength(2);
466
+
467
+ controller.open();
468
+ expect(pillRoot!.dataset.state).toBe("expanded");
469
+ expect(suggestions!.isConnected).toBe(true);
470
+
471
+ controller.destroy();
472
+ });
473
+
416
474
  it("hides the container when collapsed and shows it (display:flex) when expanded", () => {
417
475
  const mount = document.createElement("div");
418
476
  document.body.appendChild(mount);