@runtypelabs/persona 4.7.0 → 4.8.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.
- package/dist/animations/glyph-cycle.cjs +2 -2
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/glyph-cycle.js +2 -2
- package/dist/animations/{types-CSmiKRVa.d.cts → types-BsZtXPKK.d.cts} +43 -3
- package/dist/animations/{types-CSmiKRVa.d.ts → types-BsZtXPKK.d.ts} +43 -3
- package/dist/animations/wipe.cjs +2 -2
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/chunk-5EIIHQLQ.js +1 -0
- package/dist/codegen.cjs +12 -12
- package/dist/codegen.js +14 -14
- package/dist/index.cjs +91 -68
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +877 -172
- package/dist/index.d.ts +877 -172
- package/dist/index.global.js +81 -57
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +91 -68
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/launcher.global.js +3 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers.js +24 -24
- package/dist/plugin-kit.cjs +1 -1
- package/dist/plugin-kit.js +1 -1
- package/dist/runtype-tts-entry-UJAEF7NZ.js +1 -0
- package/dist/runtype-tts.js +1 -1
- package/dist/session-reconnect-JKIJBHS5.js +1 -0
- package/dist/smart-dom-reader.cjs +17 -17
- package/dist/smart-dom-reader.d.cts +753 -15
- package/dist/smart-dom-reader.d.ts +753 -15
- package/dist/smart-dom-reader.js +17 -17
- package/dist/testing.cjs +3 -3
- package/dist/testing.js +3 -3
- package/dist/theme-editor-preview.cjs +81 -58
- package/dist/theme-editor-preview.d.cts +761 -15
- package/dist/theme-editor-preview.d.ts +761 -15
- package/dist/theme-editor-preview.js +81 -58
- package/dist/theme-editor.cjs +6 -6
- package/dist/theme-editor.d.cts +753 -15
- package/dist/theme-editor.d.ts +753 -15
- package/dist/theme-editor.js +10 -10
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +74 -0
- package/dist/theme-reference.d.ts +74 -0
- package/dist/theme-reference.js +1 -1
- package/dist/voice-worklet-player.cjs +2 -2
- package/dist/voice-worklet-player.js +2 -2
- package/dist/webmcp-polyfill.js +2 -2
- package/dist/widget.css +1 -1
- package/package.json +2 -3
- package/src/artifacts-session.test.ts +178 -0
- package/src/client.test.ts +186 -1
- package/src/client.ts +92 -9
- package/src/components/artifact-card.test.ts +333 -0
- package/src/components/artifact-card.ts +75 -28
- package/src/components/artifact-inline.test.ts +1328 -0
- package/src/components/artifact-inline.ts +920 -0
- package/src/components/artifact-pane.test.ts +1042 -0
- package/src/components/artifact-pane.ts +440 -131
- package/src/components/artifact-preview.test.ts +1155 -0
- package/src/components/artifact-preview.ts +994 -0
- package/src/components/pill-composer-builder.test.ts +6 -2
- package/src/components/pill-composer-builder.ts +6 -6
- package/src/components/reasoning-bubble.ts +1 -13
- package/src/components/registry.ts +38 -3
- package/src/components/tool-bubble.ts +1 -13
- package/src/defaults.ts +1 -0
- package/src/generated/runtype-openapi-contract.ts +55 -3
- package/src/index-core.ts +20 -1
- package/src/index.ts +8 -0
- package/src/markdown-parsers-loader.test.ts +158 -0
- package/src/markdown-parsers-loader.ts +74 -9
- package/src/runtime/host-layout.test.ts +163 -0
- package/src/runtime/host-layout.ts +110 -7
- package/src/runtime/init.ts +18 -61
- package/src/session.ts +76 -22
- package/src/styles/widget.css +773 -26
- package/src/theme-editor/preview.ts +2 -0
- package/src/theme-editor/sections.test.ts +26 -1
- package/src/theme-editor/sections.ts +10 -2
- package/src/theme-reference.ts +2 -2
- package/src/tool-call-display-defaults.test.ts +1 -0
- package/src/types/theme.ts +77 -0
- package/src/types.ts +516 -17
- package/src/ui.artifact-pane-gating.test.ts +636 -0
- package/src/ui.component-directive.test.ts +104 -0
- package/src/ui.composer-bar.test.ts +60 -2
- package/src/ui.detached-panel.test.ts +1049 -0
- package/src/ui.tool-display.test.ts +51 -0
- package/src/ui.ts +698 -109
- package/src/utils/artifact-custom-actions.ts +128 -0
- package/src/utils/artifact-display.test.ts +42 -0
- package/src/utils/artifact-display.ts +84 -0
- package/src/utils/artifact-file.test.ts +116 -0
- package/src/utils/artifact-file.ts +117 -0
- package/src/utils/artifact-gate.test.ts +112 -5
- package/src/utils/artifact-gate.ts +39 -14
- package/src/utils/artifact-loading-status.ts +55 -0
- package/src/utils/artifact-status-label.ts +190 -0
- package/src/utils/buttons.ts +7 -1
- package/src/utils/code-highlight.test.ts +186 -0
- package/src/utils/code-highlight.ts +400 -0
- package/src/utils/icons.ts +2 -0
- package/src/utils/roving-tablist.test.ts +152 -0
- package/src/utils/roving-tablist.ts +111 -0
- package/src/utils/spinner.ts +45 -0
- package/src/utils/theme.test.ts +48 -0
- package/src/utils/theme.ts +7 -0
- package/src/utils/tokens.ts +91 -0
- package/src/utils/tool-loading-animation.test.ts +32 -0
- package/src/utils/tool-loading-animation.ts +24 -0
- package/dist/chunk-DFBSCFYN.js +0 -1
- package/dist/runtype-tts-entry-HFUV2UF7.js +0 -1
- 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
|
|
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);
|