@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.
- package/dist/animations/glyph-cycle.d.cts +1 -1
- package/dist/animations/glyph-cycle.d.ts +1 -1
- package/dist/animations/{types-Db61aI9J.d.cts → types-BwKTZhg9.d.cts} +14 -0
- package/dist/animations/{types-Db61aI9J.d.ts → types-BwKTZhg9.d.ts} +14 -0
- package/dist/animations/wipe.d.cts +1 -1
- package/dist/animations/wipe.d.ts +1 -1
- package/dist/animations-extra.d.cts +14 -0
- package/dist/animations-extra.d.ts +14 -0
- package/dist/approval-ui-QAKWNFNM.js +1 -0
- package/dist/approval-ui.cjs +2 -2
- package/dist/approval-ui.d.cts +180 -8
- package/dist/approval-ui.d.ts +180 -8
- package/dist/approval-ui.js +2 -2
- package/dist/{artifacts-ui-IGB5YKLO.js → artifacts-ui-NJGMM27I.js} +1 -1
- package/dist/artifacts-ui.cjs +4 -4
- package/dist/artifacts-ui.d.cts +180 -8
- package/dist/artifacts-ui.d.ts +180 -8
- package/dist/artifacts-ui.js +5 -5
- package/dist/chunk-2ANTRKTV.js +1 -0
- package/dist/chunk-4HPTPUC6.js +1 -0
- package/dist/chunk-6V3MNEKB.js +1 -0
- package/dist/chunk-HGUCGM3K.js +9 -0
- package/dist/chunk-IO5VVUKP.js +3 -0
- package/dist/chunk-J4J3Y2P2.js +1 -0
- package/dist/chunk-K6HKIP5K.js +1 -0
- package/dist/chunk-K7NA7G7J.js +1 -0
- package/dist/chunk-MXUTS3LB.js +1 -0
- package/dist/chunk-PDPVORUF.js +1 -0
- package/dist/chunk-QPPJUSZH.js +1 -0
- package/dist/chunk-QRKGQPU7.js +1 -0
- package/dist/chunk-S6PBWE75.js +1 -0
- package/dist/chunk-T7QM7YMF.js +1 -0
- package/dist/chunk-TR2H475E.js +1 -0
- package/dist/chunk-UPO4GUFC.js +1 -0
- package/dist/chunk-ZC66NAIR.js +1 -0
- package/dist/client-history-YPEG45Q4.js +1 -0
- package/dist/client-history.js +1 -0
- package/dist/client-stream-42FOI3EC.js +4 -0
- package/dist/client-stream.js +5 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/context-mentions-E7HJYWO6.js +161 -0
- package/dist/{context-mentions-inline-I2RDEBAK.js → context-mentions-inline-QVESLW55.js} +1 -1
- package/dist/context-mentions.cjs +7 -7
- package/dist/context-mentions.d.cts +180 -8
- package/dist/context-mentions.d.ts +180 -8
- package/dist/context-mentions.js +8 -8
- package/dist/event-stream-view-FOIJHFQO.js +1 -0
- package/dist/event-stream-view.cjs +1 -1
- package/dist/event-stream-view.d.cts +183 -31
- package/dist/event-stream-view.d.ts +183 -31
- package/dist/event-stream-view.js +1 -1
- package/dist/forms-ui.d.cts +221 -667
- package/dist/forms-ui.d.ts +221 -667
- package/dist/history-shell-QDQ44PSE.js +3 -0
- package/dist/history-shell.js +3 -0
- package/dist/{history-view-BD6OXLNA.js → history-view-NCFBI5GR.js} +2 -2
- package/dist/history-view.cjs +2 -2
- package/dist/history-view.d.cts +35 -1
- package/dist/history-view.d.ts +35 -1
- package/dist/history-view.js +2 -2
- package/dist/index.cjs +80 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +227 -738
- package/dist/index.d.ts +227 -738
- package/dist/index.global.js +3 -215
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +81 -75
- 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 -67
- package/dist/launcher.global.js.map +1 -1
- package/dist/markdown-parsers.js +22 -22
- package/dist/runtype-tts-entry-NFBVWR7N.js +1 -0
- package/dist/runtype-tts.js +1 -1
- package/dist/session-actions-ISSKSI66.js +1 -0
- package/dist/session-actions.js +1 -0
- package/dist/session-reconnect.d.cts +180 -8
- package/dist/session-reconnect.d.ts +180 -8
- package/dist/smart-dom-reader.cjs +13 -13
- package/dist/smart-dom-reader.d.cts +180 -8
- package/dist/smart-dom-reader.d.ts +180 -8
- package/dist/smart-dom-reader.js +11 -11
- package/dist/theme-editor-preview.cjs +116 -98
- package/dist/theme-editor-preview.d.cts +182 -8
- package/dist/theme-editor-preview.d.ts +182 -8
- package/dist/theme-editor-preview.js +49 -54
- package/dist/theme-editor.cjs +2 -2
- package/dist/theme-editor.d.cts +181 -23
- package/dist/theme-editor.d.ts +181 -23
- package/dist/theme-editor.js +2 -2
- package/dist/theme-reference.d.cts +14 -0
- package/dist/theme-reference.d.ts +14 -0
- package/dist/ui-extras-entry-WAYFKVNW.js +3 -0
- package/dist/ui-extras.js +72 -0
- package/dist/voice-runtime-UOQOFAFY.js +17 -0
- package/dist/voice-runtime.cjs +17 -1
- package/dist/voice-runtime.d.cts +11650 -232
- package/dist/voice-runtime.d.ts +11650 -232
- package/dist/voice-runtime.js +17 -1
- package/dist/voice-worklet-player.cjs +19 -4
- package/dist/voice-worklet-player.d.cts +9 -10
- package/dist/voice-worklet-player.d.ts +9 -10
- package/dist/voice-worklet-player.js +19 -4
- package/dist/webmcp-polyfill.js +1 -1
- package/dist/webmcp-runtime-V6ZWW3PI.js +6 -0
- package/dist/webmcp-runtime.cjs +2 -2
- package/dist/webmcp-runtime.d.cts +1 -33
- package/dist/webmcp-runtime.d.ts +1 -33
- package/dist/webmcp-runtime.js +2 -2
- package/dist/widget.css +1 -1
- package/package.json +11 -5
- package/src/approval-paused-tool-settle.test.ts +221 -0
- package/src/client-approve.test.ts +311 -0
- package/src/client-history-eager.ts +9 -0
- package/src/client-history-loader.ts +23 -0
- package/src/client-history.ts +579 -0
- package/src/client-resume.ts +177 -0
- package/src/client-stream-eager.ts +12 -0
- package/src/client-stream-loader.ts +25 -0
- package/src/client-stream.ts +1880 -0
- package/src/client.test.ts +31 -1
- package/src/client.ts +293 -2607
- package/src/components/approval-actions.test.ts +27 -0
- package/src/components/approval-actions.ts +27 -3
- package/src/components/message-bubble.test.ts +19 -0
- package/src/components/message-bubble.ts +2 -0
- package/src/components/registry.ts +6 -6
- package/src/components/tool-bubble.test.ts +9 -0
- package/src/components/tool-bubble.ts +1 -0
- package/src/history-shell-bundle.test.ts +54 -0
- package/src/history-shell-eager.ts +12 -0
- package/src/history-shell-loader.ts +27 -0
- package/src/history-shell.ts +2362 -0
- package/src/history-view-loader.ts +2 -0
- package/src/history-view.ts +3 -0
- package/src/index-core.ts +6 -0
- package/src/index-global.ts +90 -248
- package/src/index.ts +13 -0
- package/src/install.ts +6 -4
- package/src/internal/runtype-history-provider.test.ts +1 -0
- package/src/internal/runtype-history-provider.ts +28 -13
- package/src/plugins/registry.ts +8 -8
- package/src/session-actions-chunk.test.ts +55 -0
- package/src/session-actions-eager.ts +11 -0
- package/src/session-actions-loader.ts +37 -0
- package/src/session-actions.ts +909 -0
- package/src/session-history.test.ts +3 -1
- package/src/session.ts +852 -1536
- package/src/session.voice.test.ts +1170 -5
- package/src/styles/widget.css +58 -0
- package/src/theme-editor/state.ts +91 -91
- package/src/types.ts +198 -5
- package/src/ui-ask-user-sheet.ts +382 -0
- package/src/ui-extras-eager.ts +10 -0
- package/src/ui-extras-entry.ts +9 -0
- package/src/ui-extras-loader.ts +26 -0
- package/src/ui.artifact-rail-resize.test.ts +2 -1
- package/src/ui.ask-user-chunk.test.ts +93 -0
- package/src/ui.history-chunk.test.ts +2 -1
- package/src/ui.history-config-provider.test.ts +2 -1
- package/src/ui.history-confirm-fallback.test.ts +142 -0
- package/src/ui.history-controller.test.ts +2 -1
- package/src/ui.history-lifecycle.test.ts +2 -1
- package/src/ui.history-render-hooks.test.ts +2 -1
- package/src/ui.history-shell.test.ts +2 -1
- package/src/ui.rail-overlay.test.ts +2 -1
- package/src/ui.rail-resize.test.ts +2 -1
- package/src/ui.rail-trigger-pending.test.ts +2 -1
- package/src/ui.ts +340 -2770
- package/src/utils/attachment-manager.ts +67 -67
- package/src/utils/constants.ts +3 -0
- package/src/utils/context-mention-controller.ts +323 -323
- package/src/utils/context-mention-manager.ts +40 -40
- package/src/utils/context-mention-orchestrator.ts +28 -0
- package/src/utils/event-stream-buffer.ts +50 -50
- package/src/utils/event-stream-store.ts +43 -43
- package/src/utils/throughput-tracker.ts +34 -34
- package/src/utils/virtual-scroller.ts +67 -67
- package/src/utils/visitor-store.test.ts +50 -0
- package/src/utils/visitor-store.ts +23 -5
- package/src/voice/__fixtures__/voice-wire/README.md +1 -0
- package/src/voice/__fixtures__/voice-wire/client/cancel.json +3 -0
- package/src/voice/__fixtures__/voice-wire/client/context.json +4 -0
- package/src/voice/__fixtures__/voice-wire/client/delegation_result.json +6 -0
- package/src/voice/__fixtures__/voice-wire/client/delegation_update.json +6 -0
- package/src/voice/__fixtures__/voice-wire/client/ping.json +3 -0
- package/src/voice/__fixtures__/voice-wire/client/playback_progress.json +5 -0
- package/src/voice/__fixtures__/voice-wire/client/start.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/artifact.json +11 -0
- package/src/voice/__fixtures__/voice-wire/server/attached.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/audio_clear.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/audio_end.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_cancelled.json +5 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_completed.json +8 -0
- package/src/voice/__fixtures__/voice-wire/server/delegation_started.json +15 -0
- package/src/voice/__fixtures__/voice-wire/server/error.json +6 -0
- package/src/voice/__fixtures__/voice-wire/server/metrics.json +10 -0
- package/src/voice/__fixtures__/voice-wire/server/pong.json +3 -0
- package/src/voice/__fixtures__/voice-wire/server/session_config.json +16 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_final.json +7 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_interim.json +4 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_partial.json +6 -0
- package/src/voice/__fixtures__/voice-wire/server/transcript_update.json +10 -0
- package/src/voice/__fixtures__/voice-wire/server/warning.json +5 -0
- package/src/voice/audio-playback-manager.test.ts +57 -0
- package/src/voice/audio-playback-manager.ts +120 -98
- package/src/voice/browser-voice-provider.ts +37 -37
- package/src/voice/fallback-speech-engine.ts +22 -16
- package/src/voice/keyed-voice-transcript.ts +314 -0
- package/src/voice/mic-state-styles.ts +182 -0
- package/src/voice/read-aloud-controller.ts +46 -44
- package/src/voice/runtype-speech-engine.ts +35 -33
- package/src/voice/runtype-voice-provider.ts +670 -189
- package/src/voice/session-voice-wiring.ts +266 -0
- package/src/voice/voice-delegation.test.ts +71 -0
- package/src/voice/voice-delegation.ts +364 -0
- package/src/voice/voice-turn-tracker.ts +6 -6
- package/src/voice/voice.test.ts +981 -8
- package/src/voice/worklet-playback-engine.test.ts +81 -0
- package/src/voice/worklet-playback-engine.ts +21 -3
- package/src/voice-runtime-loader.ts +4 -1
- package/src/voice-runtime.ts +7 -0
- package/src/webmcp-runtime-entry.ts +41 -39
- package/dist/approval-ui-3NMYNXBD.js +0 -1
- package/dist/chunk-5EIIHQLQ.js +0 -1
- package/dist/chunk-7CO4T5KB.js +0 -1
- package/dist/chunk-EFJBUH5F.js +0 -1
- package/dist/chunk-R2TMIMDI.js +0 -3
- package/dist/chunk-UTVLOTWB.js +0 -9
- package/dist/context-mentions-45MODWOY.js +0 -161
- package/dist/event-stream-view-GL3ADRY2.js +0 -1
- package/dist/runtype-tts-entry-UJAEF7NZ.js +0 -1
- package/dist/voice-runtime-7DA7MJH4.js +0 -1
- package/dist/webmcp-runtime-JI7T4QYF.js +0 -6
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createChunkLoader } from "./utils/chunk-loader";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Loader indirection for the `ui-extras` chunk (`ui-extras-entry.ts`): UI glue
|
|
5
|
+
* for opt-in or interaction-only features. The ESM/CJS fallback imports
|
|
6
|
+
* `./ui-extras-entry` directly (inlined by `--splitting false`); the IIFE/CDN
|
|
7
|
+
* build marks it external and registers a loader for the sibling
|
|
8
|
+
* `ui-extras.js` chunk (see `index-global.ts`).
|
|
9
|
+
*/
|
|
10
|
+
export type UiExtrasModule = typeof import("./ui-extras-entry");
|
|
11
|
+
|
|
12
|
+
const { setLoader, load, provide, getSync } = createChunkLoader<UiExtrasModule>({
|
|
13
|
+
fallbackImport: () => import("./ui-extras-entry"),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/** Override how the chunk is fetched (the IIFE build registers a sibling-URL loader). */
|
|
17
|
+
export const setUiExtrasLoader = setLoader;
|
|
18
|
+
|
|
19
|
+
/** Load the chunk. Memoized; retries after rejection. */
|
|
20
|
+
export const loadUiExtras = load;
|
|
21
|
+
|
|
22
|
+
/** Eagerly supply the module (`ui-extras-eager.ts`: npm builds and tests). */
|
|
23
|
+
export const provideUiExtras = provide;
|
|
24
|
+
|
|
25
|
+
/** Synchronous access once loaded/provided; null before that. */
|
|
26
|
+
export const getUiExtrasSync = getSync;
|
|
@@ -11,6 +11,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
|
|
|
11
11
|
|
|
12
12
|
import { createAgentExperience } from "./ui";
|
|
13
13
|
import { createHistoryView } from "./components/history-view";
|
|
14
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
14
15
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
15
16
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
16
17
|
import {
|
|
@@ -162,7 +163,7 @@ const dragArtifact = (mount: HTMLElement, dx: number) => {
|
|
|
162
163
|
describe("history rail beside a resizable artifact split", () => {
|
|
163
164
|
beforeEach(() => {
|
|
164
165
|
window.scrollTo = vi.fn();
|
|
165
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
166
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
166
167
|
});
|
|
167
168
|
|
|
168
169
|
afterEach(() => {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { describe, it, expect, vi } from "vitest";
|
|
3
|
+
|
|
4
|
+
// Simulate the IIFE/CDN path: the ui-extras chunk is not provided up front and
|
|
5
|
+
// each test controls when its load resolves.
|
|
6
|
+
const chunk = vi.hoisted(() => {
|
|
7
|
+
const click = vi.fn();
|
|
8
|
+
const keydown = vi.fn();
|
|
9
|
+
let release: () => void = () => {};
|
|
10
|
+
let promise: Promise<unknown> = Promise.resolve();
|
|
11
|
+
const reset = () => {
|
|
12
|
+
click.mockClear();
|
|
13
|
+
keydown.mockClear();
|
|
14
|
+
promise = new Promise((resolve) => {
|
|
15
|
+
release = () =>
|
|
16
|
+
resolve({
|
|
17
|
+
createAskUserSheetHandlers: () => ({ click, keydown }),
|
|
18
|
+
createContextMentionOrchestrator: () => null,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
return { click, keydown, reset, release: () => release(), load: () => promise };
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
vi.mock("./ui-extras-loader", () => ({
|
|
26
|
+
getUiExtrasSync: () => null,
|
|
27
|
+
loadUiExtras: () => chunk.load(),
|
|
28
|
+
setUiExtrasLoader: () => {},
|
|
29
|
+
provideUiExtras: () => {},
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
import { createAgentExperience } from "./ui";
|
|
33
|
+
|
|
34
|
+
const mountWithSheet = () => {
|
|
35
|
+
const mount = document.createElement("div");
|
|
36
|
+
document.body.appendChild(mount);
|
|
37
|
+
const controller = createAgentExperience(mount, {
|
|
38
|
+
apiUrl: "https://api.example.com/chat",
|
|
39
|
+
launcher: { enabled: false },
|
|
40
|
+
});
|
|
41
|
+
const overlay = mount.querySelector<HTMLElement>("[data-persona-composer-overlay]")!;
|
|
42
|
+
const sheet = document.createElement("div");
|
|
43
|
+
sheet.setAttribute("data-persona-ask-sheet-for", "tool-1");
|
|
44
|
+
const pill = document.createElement("button");
|
|
45
|
+
pill.setAttribute("data-ask-user-action", "pick");
|
|
46
|
+
sheet.appendChild(pill);
|
|
47
|
+
overlay.appendChild(sheet);
|
|
48
|
+
return { controller, sheet, pill };
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
52
|
+
|
|
53
|
+
describe("ask-user sheet events waiting on the lazy chunk", () => {
|
|
54
|
+
it("handles only the first of repeated early clicks", async () => {
|
|
55
|
+
chunk.reset();
|
|
56
|
+
const { controller, pill } = mountWithSheet();
|
|
57
|
+
pill.click();
|
|
58
|
+
pill.click();
|
|
59
|
+
chunk.release();
|
|
60
|
+
await flush();
|
|
61
|
+
expect(chunk.click).toHaveBeenCalledTimes(1);
|
|
62
|
+
controller.destroy();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it("typing in the free-text input does not block the Enter that submits", async () => {
|
|
66
|
+
chunk.reset();
|
|
67
|
+
const { controller, sheet } = mountWithSheet();
|
|
68
|
+
const input = document.createElement("input");
|
|
69
|
+
input.setAttribute("data-ask-free-text-input", "true");
|
|
70
|
+
sheet.appendChild(input);
|
|
71
|
+
const key = (k: string) =>
|
|
72
|
+
input.dispatchEvent(new KeyboardEvent("keydown", { key: k, bubbles: true }));
|
|
73
|
+
key("h");
|
|
74
|
+
key("i");
|
|
75
|
+
key("Enter");
|
|
76
|
+
chunk.release();
|
|
77
|
+
await flush();
|
|
78
|
+
expect(chunk.keydown).toHaveBeenCalledTimes(1);
|
|
79
|
+
expect((chunk.keydown.mock.calls[0][0] as KeyboardEvent).key).toBe("Enter");
|
|
80
|
+
controller.destroy();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("drops a queued click whose sheet was removed before the chunk loaded", async () => {
|
|
84
|
+
chunk.reset();
|
|
85
|
+
const { controller, sheet, pill } = mountWithSheet();
|
|
86
|
+
pill.click();
|
|
87
|
+
sheet.remove();
|
|
88
|
+
chunk.release();
|
|
89
|
+
await flush();
|
|
90
|
+
expect(chunk.click).not.toHaveBeenCalled();
|
|
91
|
+
controller.destroy();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -10,6 +10,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
10
10
|
|
|
11
11
|
import { createAgentExperience } from "./ui";
|
|
12
12
|
import { createHistoryView } from "./components/history-view";
|
|
13
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
13
14
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
14
15
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
15
16
|
import { createDemoHistoryProvider } from "./internal/demo-history-provider";
|
|
@@ -63,7 +64,7 @@ describe("history lazy chunk", () => {
|
|
|
63
64
|
expect(body.hasAttribute("inert")).toBe(false);
|
|
64
65
|
|
|
65
66
|
// A dropped fetch must not disable the feature for the session.
|
|
66
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
67
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
67
68
|
mount.querySelector<HTMLButtonElement>("[data-persona-history-toggle]")!.click();
|
|
68
69
|
await flush();
|
|
69
70
|
expect(mount.querySelector(".persona-history-view")).not.toBeNull();
|
|
@@ -11,6 +11,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
11
11
|
|
|
12
12
|
import { createAgentExperience } from "./ui";
|
|
13
13
|
import { createHistoryView } from "./components/history-view";
|
|
14
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
14
15
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
15
16
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
16
17
|
import {
|
|
@@ -118,7 +119,7 @@ describe("features.history.provider", () => {
|
|
|
118
119
|
window.scrollTo = vi.fn();
|
|
119
120
|
// No registry override: this suite exercises the public config path only.
|
|
120
121
|
setHistoryProviderFactory(null);
|
|
121
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
122
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
122
123
|
});
|
|
123
124
|
|
|
124
125
|
afterEach(() => {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Version skew on the CDN: a fresh `index.global.js` paired with a cached
|
|
5
|
+
* `history-view.js` that predates the `showHistoryConfirm` export. Own file
|
|
6
|
+
* because `loadHistoryView` memoizes the resolved module per module graph.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
10
|
+
|
|
11
|
+
import { createAgentExperience } from "./ui";
|
|
12
|
+
import { createHistoryView } from "./components/history-view";
|
|
13
|
+
import { setHistoryViewLoader } from "./history-view-loader";
|
|
14
|
+
import type { HistoryViewOptions } from "./history-view-entry";
|
|
15
|
+
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
16
|
+
import {
|
|
17
|
+
createDemoHistoryProvider,
|
|
18
|
+
type DemoHistoryConversationSeed,
|
|
19
|
+
} from "./internal/demo-history-provider";
|
|
20
|
+
|
|
21
|
+
const SEEDS: DemoHistoryConversationSeed[] = [
|
|
22
|
+
{
|
|
23
|
+
id: "conv-a",
|
|
24
|
+
title: "Order status",
|
|
25
|
+
targetId: null,
|
|
26
|
+
messages: [{ id: "a1", role: "user", content: "where is my order" }],
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const flush = async (times = 12) => {
|
|
31
|
+
for (let i = 0; i < times; i += 1) {
|
|
32
|
+
// eslint-disable-next-line no-await-in-loop
|
|
33
|
+
await Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type HistoryViewModule = Awaited<
|
|
38
|
+
ReturnType<Parameters<typeof setHistoryViewLoader>[0]>
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
describe("history confirm with a stale chunk", () => {
|
|
42
|
+
let controller: ReturnType<typeof createAgentExperience> | null = null;
|
|
43
|
+
let mount: HTMLElement | null = null;
|
|
44
|
+
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
window.scrollTo = vi.fn();
|
|
47
|
+
setHistoryProviderFactory(() =>
|
|
48
|
+
createDemoHistoryProvider({ conversations: SEEDS })
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(() => {
|
|
53
|
+
setHistoryProviderFactory(null);
|
|
54
|
+
controller?.destroy();
|
|
55
|
+
controller = null;
|
|
56
|
+
mount?.remove();
|
|
57
|
+
mount = null;
|
|
58
|
+
document.body.innerHTML = "";
|
|
59
|
+
vi.restoreAllMocks();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Runs first: a resolved chunk is memoized for the rest of the module graph,
|
|
63
|
+
// so the rejecting loader only takes effect before any successful load.
|
|
64
|
+
it("falls back to the native confirm when the chunk fails to load", async () => {
|
|
65
|
+
setHistoryViewLoader(async () => {
|
|
66
|
+
throw new Error("chunk fetch failed");
|
|
67
|
+
});
|
|
68
|
+
mount = document.createElement("div");
|
|
69
|
+
document.body.appendChild(mount);
|
|
70
|
+
controller = createAgentExperience(mount, {
|
|
71
|
+
apiUrl: "https://api.example.com/chat",
|
|
72
|
+
launcher: { enabled: false },
|
|
73
|
+
persistState: false,
|
|
74
|
+
features: { history: { enabled: true } },
|
|
75
|
+
} as unknown as Parameters<typeof createAgentExperience>[1]);
|
|
76
|
+
await controller.openConversation("conv-a");
|
|
77
|
+
await flush();
|
|
78
|
+
|
|
79
|
+
// The title-menu delete needs no history view: it goes straight to the
|
|
80
|
+
// confirm, whose chunk load rejects.
|
|
81
|
+
const deleteFromTitleMenu = () =>
|
|
82
|
+
mount!
|
|
83
|
+
.querySelector('[data-persona-theme-zone="header"]')!
|
|
84
|
+
.dispatchEvent(
|
|
85
|
+
new CustomEvent("persona:title-menu-builtin", {
|
|
86
|
+
bubbles: true,
|
|
87
|
+
detail: { actionId: "delete" },
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
const listIds = async () =>
|
|
91
|
+
(await controller!.listConversations({ limit: 10 })).items.map(
|
|
92
|
+
(item) => item.id
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const confirmSpy = vi.spyOn(window, "confirm").mockReturnValue(false);
|
|
96
|
+
deleteFromTitleMenu();
|
|
97
|
+
await flush();
|
|
98
|
+
expect(confirmSpy).toHaveBeenCalledTimes(1);
|
|
99
|
+
expect(await listIds()).toContain("conv-a");
|
|
100
|
+
|
|
101
|
+
confirmSpy.mockReturnValue(true);
|
|
102
|
+
deleteFromTitleMenu();
|
|
103
|
+
await flush();
|
|
104
|
+
expect(confirmSpy).toHaveBeenCalledTimes(2);
|
|
105
|
+
expect(await listIds()).not.toContain("conv-a");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("falls back to the native confirm when the chunk lacks showHistoryConfirm", async () => {
|
|
109
|
+
let viewOptions: HistoryViewOptions | null = null;
|
|
110
|
+
// Older chunk shape: no showHistoryConfirm export.
|
|
111
|
+
setHistoryViewLoader(
|
|
112
|
+
async () =>
|
|
113
|
+
({
|
|
114
|
+
createHistoryView: (options: HistoryViewOptions) => {
|
|
115
|
+
viewOptions = options;
|
|
116
|
+
return createHistoryView(options);
|
|
117
|
+
},
|
|
118
|
+
}) as unknown as HistoryViewModule
|
|
119
|
+
);
|
|
120
|
+
mount = document.createElement("div");
|
|
121
|
+
document.body.appendChild(mount);
|
|
122
|
+
controller = createAgentExperience(mount, {
|
|
123
|
+
apiUrl: "https://api.example.com/chat",
|
|
124
|
+
launcher: { enabled: false },
|
|
125
|
+
persistState: false,
|
|
126
|
+
features: { history: { enabled: true } },
|
|
127
|
+
} as unknown as Parameters<typeof createAgentExperience>[1]);
|
|
128
|
+
|
|
129
|
+
mount.querySelector<HTMLButtonElement>("[data-persona-history-toggle]")!.click();
|
|
130
|
+
await flush();
|
|
131
|
+
expect(viewOptions).not.toBeNull();
|
|
132
|
+
const requestClear = viewOptions!.onRequestClearHistory!;
|
|
133
|
+
|
|
134
|
+
const confirmSpy = vi.spyOn(window, "confirm").mockReturnValue(false);
|
|
135
|
+
await expect(requestClear()).resolves.toBe("cancelled");
|
|
136
|
+
expect(confirmSpy).toHaveBeenCalledTimes(1);
|
|
137
|
+
|
|
138
|
+
confirmSpy.mockReturnValue(true);
|
|
139
|
+
await expect(requestClear()).resolves.toBe("cleared");
|
|
140
|
+
expect(confirmSpy).toHaveBeenCalledTimes(2);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -13,6 +13,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
13
13
|
import { createAgentExperience } from "./ui";
|
|
14
14
|
import { initAgentWidget } from "./runtime/init";
|
|
15
15
|
import { createHistoryView } from "./components/history-view";
|
|
16
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
16
17
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
17
18
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
18
19
|
import {
|
|
@@ -87,7 +88,7 @@ const setup = (
|
|
|
87
88
|
describe("history controller API", () => {
|
|
88
89
|
beforeEach(() => {
|
|
89
90
|
window.scrollTo = vi.fn();
|
|
90
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
91
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
91
92
|
});
|
|
92
93
|
|
|
93
94
|
afterEach(() => {
|
|
@@ -52,6 +52,7 @@ vi.mock("./utils/visitor-store", async (importOriginal) => {
|
|
|
52
52
|
|
|
53
53
|
import { createAgentExperience } from "./ui";
|
|
54
54
|
import { createHistoryView } from "./components/history-view";
|
|
55
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
55
56
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
56
57
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
57
58
|
import { createDemoHistoryProvider } from "./internal/demo-history-provider";
|
|
@@ -109,7 +110,7 @@ const mount = (config: Record<string, unknown>) => {
|
|
|
109
110
|
describe("history controller lifecycle", () => {
|
|
110
111
|
beforeEach(() => {
|
|
111
112
|
window.scrollTo = vi.fn();
|
|
112
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
113
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
113
114
|
installFetch();
|
|
114
115
|
});
|
|
115
116
|
|
|
@@ -11,6 +11,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
11
11
|
|
|
12
12
|
import { createAgentExperience } from "./ui";
|
|
13
13
|
import { createHistoryView } from "./components/history-view";
|
|
14
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
14
15
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
15
16
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
16
17
|
import {
|
|
@@ -127,7 +128,7 @@ const fullViewPlugin = (
|
|
|
127
128
|
describe("history render hooks", () => {
|
|
128
129
|
beforeEach(() => {
|
|
129
130
|
window.scrollTo = vi.fn();
|
|
130
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
131
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
131
132
|
});
|
|
132
133
|
|
|
133
134
|
afterEach(() => {
|
|
@@ -13,6 +13,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
13
13
|
|
|
14
14
|
import { createAgentExperience } from "./ui";
|
|
15
15
|
import { createHistoryView } from "./components/history-view";
|
|
16
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
16
17
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
17
18
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
18
19
|
import {
|
|
@@ -169,7 +170,7 @@ describe("history shell", () => {
|
|
|
169
170
|
beforeEach(() => {
|
|
170
171
|
window.scrollTo = vi.fn();
|
|
171
172
|
// The loader's production path is a sibling-URL / external-subpath import.
|
|
172
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
173
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
173
174
|
});
|
|
174
175
|
|
|
175
176
|
afterEach(() => {
|
|
@@ -12,6 +12,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
12
12
|
|
|
13
13
|
import { createAgentExperience } from "./ui";
|
|
14
14
|
import { createHistoryView } from "./components/history-view";
|
|
15
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
15
16
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
16
17
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
17
18
|
import {
|
|
@@ -53,7 +54,7 @@ const wait = (ms: number) =>
|
|
|
53
54
|
/** Past the 300ms pointer-out grace. */
|
|
54
55
|
const GRACE = 380;
|
|
55
56
|
|
|
56
|
-
const loadHistoryChunk = vi.fn(async () => ({ createHistoryView }));
|
|
57
|
+
const loadHistoryChunk = vi.fn(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
57
58
|
|
|
58
59
|
const setup = (
|
|
59
60
|
options: {
|
|
@@ -10,6 +10,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
10
10
|
|
|
11
11
|
import { createAgentExperience } from "./ui";
|
|
12
12
|
import { createHistoryView } from "./components/history-view";
|
|
13
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
13
14
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
14
15
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
15
16
|
import {
|
|
@@ -103,7 +104,7 @@ const drag = (handle: HTMLElement, dx: number, opts?: { hold?: boolean }) => {
|
|
|
103
104
|
describe("rail resize handle", () => {
|
|
104
105
|
beforeEach(() => {
|
|
105
106
|
window.scrollTo = vi.fn();
|
|
106
|
-
setHistoryViewLoader(async () => ({ createHistoryView }));
|
|
107
|
+
setHistoryViewLoader(async () => ({ createHistoryView, showHistoryConfirm }));
|
|
107
108
|
});
|
|
108
109
|
|
|
109
110
|
afterEach(() => {
|
|
@@ -13,6 +13,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
13
13
|
|
|
14
14
|
import { createAgentExperience } from "./ui";
|
|
15
15
|
import { createHistoryView } from "./components/history-view";
|
|
16
|
+
import { showHistoryConfirm } from "./components/history-confirm-dialog";
|
|
16
17
|
import { setHistoryViewLoader } from "./history-view-loader";
|
|
17
18
|
import { setHistoryProviderFactory } from "./internal/history-provider-registry";
|
|
18
19
|
import { createDemoHistoryProvider } from "./internal/demo-history-provider";
|
|
@@ -103,7 +104,7 @@ describe("rail trigger during a docking open", () => {
|
|
|
103
104
|
setHistoryViewLoader(
|
|
104
105
|
() =>
|
|
105
106
|
new Promise((resolve) => {
|
|
106
|
-
release = () => resolve({ createHistoryView });
|
|
107
|
+
release = () => resolve({ createHistoryView, showHistoryConfirm });
|
|
107
108
|
})
|
|
108
109
|
);
|
|
109
110
|
const { controller: ctl } = setup();
|