@runtypelabs/persona 4.21.1 → 4.22.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 (77) hide show
  1. package/dist/{approval-ui-RNNBR5R3.js → approval-ui-K7R5Q5OC.js} +1 -1
  2. package/dist/approval-ui.cjs +2 -2
  3. package/dist/approval-ui.d.cts +73 -2
  4. package/dist/approval-ui.d.ts +73 -2
  5. package/dist/approval-ui.js +2 -2
  6. package/dist/artifacts-ui-F4N6VMKF.js +7 -0
  7. package/dist/artifacts-ui.cjs +1 -1
  8. package/dist/artifacts-ui.d.cts +73 -2
  9. package/dist/artifacts-ui.d.ts +73 -2
  10. package/dist/artifacts-ui.js +1 -1
  11. package/dist/chunk-NQLDCJAP.js +4 -0
  12. package/dist/codegen.cjs +1 -1
  13. package/dist/codegen.js +1 -1
  14. package/dist/context-mentions.d.cts +73 -2
  15. package/dist/context-mentions.d.ts +73 -2
  16. package/dist/event-stream-view-FKWDY3UB.js +1 -0
  17. package/dist/event-stream-view.cjs +1 -1
  18. package/dist/event-stream-view.d.cts +73 -2
  19. package/dist/event-stream-view.d.ts +73 -2
  20. package/dist/event-stream-view.js +1 -1
  21. package/dist/forms-ui.d.cts +73 -2
  22. package/dist/forms-ui.d.ts +73 -2
  23. package/dist/index.cjs +63 -63
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +136 -5
  26. package/dist/index.d.ts +136 -5
  27. package/dist/index.global.js +48 -48
  28. package/dist/index.global.js.map +1 -1
  29. package/dist/index.js +64 -64
  30. package/dist/index.js.map +1 -1
  31. package/dist/launcher.global.js +2 -2
  32. package/dist/launcher.global.js.map +1 -1
  33. package/dist/session-reconnect.d.cts +73 -2
  34. package/dist/session-reconnect.d.ts +73 -2
  35. package/dist/smart-dom-reader.d.cts +73 -2
  36. package/dist/smart-dom-reader.d.ts +73 -2
  37. package/dist/theme-editor-preview.cjs +64 -64
  38. package/dist/theme-editor-preview.d.cts +73 -2
  39. package/dist/theme-editor-preview.d.ts +73 -2
  40. package/dist/theme-editor-preview.js +45 -45
  41. package/dist/theme-editor.cjs +4 -4
  42. package/dist/theme-editor.d.cts +73 -2
  43. package/dist/theme-editor.d.ts +73 -2
  44. package/dist/theme-editor.js +2 -2
  45. package/dist/theme-reference.cjs +1 -1
  46. package/dist/theme-reference.d.cts +65 -1
  47. package/dist/theme-reference.d.ts +65 -1
  48. package/dist/theme-reference.js +1 -1
  49. package/dist/webmcp-polyfill.js +1 -4
  50. package/dist/webmcp-runtime-JI7T4QYF.js +6 -0
  51. package/dist/webmcp-runtime.cjs +2 -2
  52. package/dist/webmcp-runtime.d.cts +34 -2
  53. package/dist/webmcp-runtime.d.ts +34 -2
  54. package/dist/webmcp-runtime.js +2 -2
  55. package/package.json +2 -2
  56. package/src/components/artifact-preview.ts +5 -0
  57. package/src/components/event-stream-badge-theming.test.ts +159 -0
  58. package/src/components/event-stream-view.ts +50 -20
  59. package/src/generated/runtype-openapi-contract.ts +8 -0
  60. package/src/index-core.ts +2 -0
  61. package/src/runtime/init.registry.test.ts +56 -0
  62. package/src/runtime/init.ts +17 -0
  63. package/src/types/theme.ts +41 -1
  64. package/src/types.ts +38 -1
  65. package/src/ui.reasoning-display.test.ts +136 -2
  66. package/src/ui.ts +41 -10
  67. package/src/utils/__snapshots__/tokens-parity.test.ts.snap +1740 -0
  68. package/src/utils/formatting.ts +22 -0
  69. package/src/utils/theme.ts +16 -0
  70. package/src/utils/tokens.ts +59 -0
  71. package/src/webmcp-bridge.test.ts +132 -23
  72. package/src/webmcp-bridge.ts +26 -2
  73. package/src/webmcp-runtime-entry.ts +71 -11
  74. package/dist/artifacts-ui-J6AKUGTS.js +0 -7
  75. package/dist/chunk-HBE7LFNT.js +0 -4
  76. package/dist/event-stream-view-73NWKWVQ.js +0 -1
  77. package/dist/webmcp-runtime-P3CHZRHF.js +0 -6
@@ -52,6 +52,28 @@ export const describeReasonStatus = (reasoning: AgentWidgetReasoning) => {
52
52
  return "";
53
53
  };
54
54
 
55
+ /** Defaults for `features.reasoningDisplay.shortThinkThreshold`. */
56
+ export const DEFAULT_SHORT_THINK_DURATION_MS = 15_000;
57
+ export const DEFAULT_SHORT_THINK_CHARS = 1_200;
58
+
59
+ /**
60
+ * A completed reasoning trace is short when its duration is under the
61
+ * threshold, or (with no reported duration) its streamed text is under the
62
+ * character threshold. Duration is preferred when available.
63
+ */
64
+ export const isShortReasoning = (
65
+ reasoning: AgentWidgetReasoning,
66
+ threshold?: { durationMs?: number; chars?: number }
67
+ ): boolean => {
68
+ const durationThreshold = threshold?.durationMs ?? DEFAULT_SHORT_THINK_DURATION_MS;
69
+ const charsThreshold = threshold?.chars ?? DEFAULT_SHORT_THINK_CHARS;
70
+ if (typeof reasoning.durationMs === "number") {
71
+ return reasoning.durationMs < durationThreshold;
72
+ }
73
+ const chars = (reasoning.chunks ?? []).join("").length;
74
+ return chars < charsThreshold;
75
+ };
76
+
55
77
  export const formatToolDuration = (tool: AgentWidgetToolCall) => {
56
78
  const durationMs =
57
79
  typeof tool.duration === "number"
@@ -128,6 +128,22 @@ const DARK_COMPONENTS: DeepPartial<PersonaTheme> = {
128
128
  foreground: 'palette.colors.primary.300',
129
129
  },
130
130
  },
131
+ // Event-stream badge chips flip to a 900-tone fill with a 300-tone text
132
+ // (primary is the inverted dark ramp, so 800/200 lands the same way).
133
+ // The light defaults are 100-tone fills that read as glowing swatches on
134
+ // a dark panel; every pair here keeps >=4.5:1 text contrast (locked by
135
+ // event-stream-badge-theming.test.ts).
136
+ eventStream: {
137
+ badge: {
138
+ flow: { background: 'palette.colors.success.900', foreground: 'palette.colors.success.300' },
139
+ step: { background: 'palette.colors.primary.800', foreground: 'palette.colors.primary.200' },
140
+ reasoning: { background: 'palette.colors.warning.900', foreground: 'palette.colors.warning.300' },
141
+ tool: { background: 'palette.colors.purple.900', foreground: 'palette.colors.purple.300' },
142
+ agent: { background: 'palette.colors.teal.900', foreground: 'palette.colors.teal.300' },
143
+ error: { background: 'palette.colors.error.900', foreground: 'palette.colors.error.300' },
144
+ default: { background: 'palette.colors.gray.800', foreground: 'palette.colors.gray.300' },
145
+ },
146
+ },
131
147
  history: {
132
148
  // error-400: the light-surface error-600 red lands ~3:1 on dark
133
149
  // surfaces, under the 4.5:1 AA floor for the 14px destructive labels.
@@ -128,6 +128,32 @@ export const DEFAULT_PALETTE = {
128
128
  900: '#1e3a8a',
129
129
  950: '#172554',
130
130
  },
131
+ purple: {
132
+ 50: '#faf5ff',
133
+ 100: '#f3e8ff',
134
+ 200: '#e9d5ff',
135
+ 300: '#d8b4fe',
136
+ 400: '#c084fc',
137
+ 500: '#a855f7',
138
+ 600: '#9333ea',
139
+ 700: '#7e22ce',
140
+ 800: '#6b21a8',
141
+ 900: '#581c87',
142
+ 950: '#3b0764',
143
+ },
144
+ teal: {
145
+ 50: '#f0fdfa',
146
+ 100: '#ccfbf1',
147
+ 200: '#99f6e4',
148
+ 300: '#5eead4',
149
+ 400: '#2dd4bf',
150
+ 500: '#14b8a6',
151
+ 600: '#0d9488',
152
+ 700: '#0f766e',
153
+ 800: '#115e59',
154
+ 900: '#134e4a',
155
+ 950: '#042f2e',
156
+ },
131
157
  },
132
158
  spacing,
133
159
  typography: {
@@ -472,6 +498,20 @@ export const DEFAULT_COMPONENTS: ComponentTokens = {
472
498
  border: 'palette.colors.gray.200',
473
499
  },
474
500
  },
501
+ // Event-stream badge chips: 100-tone fill / dark text per family. tool/agent
502
+ // keep their pre-token literals (#6b21a8 / #115e59), which sit at the 800
503
+ // step of the canonical purple/teal ramps.
504
+ eventStream: {
505
+ badge: {
506
+ flow: { background: 'palette.colors.success.100', foreground: 'palette.colors.success.700' },
507
+ step: { background: 'palette.colors.primary.100', foreground: 'palette.colors.primary.700' },
508
+ reasoning: { background: 'palette.colors.warning.100', foreground: 'palette.colors.warning.700' },
509
+ tool: { background: 'palette.colors.purple.100', foreground: 'palette.colors.purple.800' },
510
+ agent: { background: 'palette.colors.teal.100', foreground: 'palette.colors.teal.800' },
511
+ error: { background: 'palette.colors.error.100', foreground: 'palette.colors.error.700' },
512
+ default: { background: 'palette.colors.gray.100', foreground: 'palette.colors.gray.600' },
513
+ },
514
+ },
475
515
  scrollToBottom: {
476
516
  background: 'components.button.primary.background',
477
517
  foreground: 'components.button.primary.foreground',
@@ -1085,6 +1125,25 @@ export function themeToCssVariables(theme: PersonaTheme): Record<string, string>
1085
1125
  ['scroll-to-bottom-gap', 'components-scrollToBottom-gap', '=0.5rem'],
1086
1126
  ['scroll-to-bottom-font-size', 'components-scrollToBottom-fontSize', 'palette-typography-fontSize-sm', '=0.875rem'],
1087
1127
  ['scroll-to-bottom-icon-size', 'components-scrollToBottom-iconSize', '=14px'],
1128
+ // Event-stream badge chips. Materialized in every theme (light defaults in
1129
+ // DEFAULT_COMPONENTS, dark pairs in the built-in dark layer), so the
1130
+ // chip's inline var() refs always resolve inside a themed root and
1131
+ // re-resolve on scheme toggles; the literal terminals only cover unthemed
1132
+ // direct mounts.
1133
+ ['event-badge-flow-bg', 'components-eventStream-badge-flow-background', '=#dcfce7'],
1134
+ ['event-badge-flow-fg', 'components-eventStream-badge-flow-foreground', '=#15803d'],
1135
+ ['event-badge-step-bg', 'components-eventStream-badge-step-background', '=#f5f5f5'],
1136
+ ['event-badge-step-fg', 'components-eventStream-badge-step-foreground', '=#0a0a0a'],
1137
+ ['event-badge-reasoning-bg', 'components-eventStream-badge-reasoning-background', '=#fef9c3'],
1138
+ ['event-badge-reasoning-fg', 'components-eventStream-badge-reasoning-foreground', '=#a16207'],
1139
+ ['event-badge-tool-bg', 'components-eventStream-badge-tool-background', '=#f3e8ff'],
1140
+ ['event-badge-tool-fg', 'components-eventStream-badge-tool-foreground', '=#6b21a8'],
1141
+ ['event-badge-agent-bg', 'components-eventStream-badge-agent-background', '=#ccfbf1'],
1142
+ ['event-badge-agent-fg', 'components-eventStream-badge-agent-foreground', '=#115e59'],
1143
+ ['event-badge-error-bg', 'components-eventStream-badge-error-background', '=#fee2e2'],
1144
+ ['event-badge-error-fg', 'components-eventStream-badge-error-foreground', '=#b91c1c'],
1145
+ ['event-badge-default-bg', 'components-eventStream-badge-default-background', '=#f3f4f6'],
1146
+ ['event-badge-default-fg', 'components-eventStream-badge-default-foreground', '=#4b5563'],
1088
1147
  ['tool-bubble-shadow', 'components-toolBubble-shadow', '=0 5px 15px rgba(15, 23, 42, 0.08)'],
1089
1148
  ['reasoning-bubble-shadow', 'components-reasoningBubble-shadow', '=0 5px 15px rgba(15, 23, 42, 0.08)'],
1090
1149
  ['composer-shadow', 'components-composer-shadow', '=none'],
@@ -11,7 +11,8 @@ import type {
11
11
  // calls `initializeWebMCPPolyfill()` (idempotent install of document.modelContext).
12
12
  // We stub the install as a no-op and provide `document.modelContext` ourselves,
13
13
  // modeling the strict producer-preview surface the bridge consumes:
14
- // - getTools(): async; inputSchema is a JSON string; NO annotations
14
+ // - getTools(): async; inputSchema in either generation (see
15
+ // `registry.schemaShape`); annotations only when the tool declared them
15
16
  // - executeTool(info, argsJson, { signal }): async; validates+runs execute(),
16
17
  // returns JSON.stringify(rawResult) or null; honors the abort signal.
17
18
  // ---------------------------------------------------------------------------
@@ -45,21 +46,46 @@ type MockTool = {
45
46
  description?: string;
46
47
  inputSchema?: object;
47
48
  title?: string;
49
+ annotations?: Record<string, unknown>;
48
50
  execute: (args: Record<string, unknown>, client: MockClient) => unknown;
49
51
  };
50
52
 
51
- const registry: { tools: MockTool[] } = { tools: [] };
53
+ /**
54
+ * Which generation of the WebMCP `inputSchema` contract the fake emits.
55
+ *
56
+ * `"object"` is what `@mcp-b/webmcp-polyfill` v5 and Chrome 154+ return after
57
+ * `webmcp#241`; `"string"` is the serialized form Chrome 149-153 and 154's
58
+ * same-document tools still emit. Both are live in the field, so the snapshot
59
+ * tests run against both -- pinning this fake to one generation is exactly how
60
+ * the v5 bump landed green while every real dispatch 400'd.
61
+ */
62
+ type SchemaShape = "object" | "string";
63
+
64
+ const registry: { tools: MockTool[]; schemaShape: SchemaShape } = {
65
+ tools: [],
66
+ schemaShape: "object",
67
+ };
52
68
 
53
69
  /** A fake `document.modelContext` exposing the strict consumer surface. */
54
70
  const makeModelContext = () => ({
55
71
  async getTools() {
56
- // Mirrors the real polyfill's getRegisteredToolInfos(): `title` is always
57
- // present, "" when the tool didn't declare one; annotations are absent.
72
+ // Mirrors the real polyfill's getTools(): `title` is always present, ""
73
+ // when the tool didn't declare one; annotations are absent. v5 OMITS
74
+ // `inputSchema` for a tool that registered none, where v4 always emitted a
75
+ // `{"type":"object"}` string.
58
76
  return registry.tools.map((t) => ({
59
77
  name: t.name,
60
78
  description: t.description ?? `mock ${t.name}`,
61
- inputSchema: JSON.stringify(t.inputSchema ?? { type: "object" }),
79
+ ...(t.inputSchema === undefined
80
+ ? {}
81
+ : {
82
+ inputSchema:
83
+ registry.schemaShape === "object"
84
+ ? t.inputSchema
85
+ : JSON.stringify(t.inputSchema),
86
+ }),
62
87
  title: t.title ?? "",
88
+ ...(t.annotations === undefined ? {} : { annotations: t.annotations }),
63
89
  }));
64
90
  },
65
91
  async executeTool(
@@ -110,6 +136,7 @@ beforeEach(() => {
110
136
  vi.clearAllMocks();
111
137
  polyfillMock.initThrows = false;
112
138
  registry.tools = [];
139
+ registry.schemaShape = "object";
113
140
  // location is read by snapshotForDispatch; document.modelContext is the
114
141
  // consumer surface. Both are absent in the Node test environment.
115
142
  vi.stubGlobal("location", { origin: "https://example.test" });
@@ -166,29 +193,111 @@ describe("WebMcpBridge.snapshotForDispatch", () => {
166
193
  expect(bridge.isOperational()).toBe(false);
167
194
  });
168
195
 
169
- it("ships only the JSON-serializable surface (name, description, schema, origin)", async () => {
196
+ // Both `inputSchema` generations must produce the same wire tool: the object
197
+ // form (webmcp#241 / polyfill v5 / Chrome 154+) and the serialized string
198
+ // Chrome 149-153 still emits.
199
+ it.each(["object", "string"] as const)(
200
+ "ships only the JSON-serializable surface (name, description, schema, origin) [%s inputSchema]",
201
+ async (schemaShape) => {
202
+ registry.schemaShape = schemaShape;
203
+ registry.tools = [
204
+ fakeTool({
205
+ name: "search",
206
+ description: "search the shop",
207
+ inputSchema: { type: "object", properties: { q: { type: "string" } } },
208
+ }),
209
+ ];
210
+ const bridge = new WebMcpBridge({ enabled: true });
211
+ const snap = await bridge.snapshotForDispatch();
212
+ expect(snap).toHaveLength(1);
213
+ const tool = snap[0]!;
214
+ expect(tool.name).toBe("search");
215
+ expect(tool.description).toBe("search the shop");
216
+ expect(tool.parametersSchema).toEqual({
217
+ type: "object",
218
+ properties: { q: { type: "string" } },
219
+ });
220
+ expect(tool.origin).toBe("webmcp");
221
+ expect(tool.pageOrigin).toBe("https://example.test");
222
+ expect((tool as unknown as { execute?: unknown }).execute).toBeUndefined();
223
+ // Now that the registry was read, the bridge reports operational.
224
+ expect(bridge.isOperational()).toBe(true);
225
+ },
226
+ );
227
+
228
+ // `parametersSchema` is required by the server's InlineClientToolSchema, and
229
+ // one entry missing it fails the whole DispatchRequestSchema union: a tool
230
+ // with no usable schema must degrade to "takes no arguments", never to an
231
+ // omitted key that 400s the turn.
232
+ it("always sends a parametersSchema, even when the tool declared none", async () => {
233
+ registry.tools = [fakeTool({ name: "ping" })];
234
+ const snap = await new WebMcpBridge({ enabled: true }).snapshotForDispatch();
235
+ expect(snap[0]!.parametersSchema).toEqual({ type: "object", properties: {} });
236
+ });
237
+
238
+ it("forwards annotations and hoists untrustedContentHint to the top level", async () => {
170
239
  registry.tools = [
171
240
  fakeTool({
172
- name: "search",
173
- description: "search the shop",
174
- inputSchema: { type: "object", properties: { q: { type: "string" } } },
241
+ name: "get_reviews",
242
+ annotations: { readOnlyHint: true, untrustedContentHint: true },
175
243
  }),
176
244
  ];
177
- const bridge = new WebMcpBridge({ enabled: true });
178
- const snap = await bridge.snapshotForDispatch();
179
- expect(snap).toHaveLength(1);
180
- const tool = snap[0]!;
181
- expect(tool.name).toBe("search");
182
- expect(tool.description).toBe("search the shop");
183
- expect(tool.parametersSchema).toEqual({
184
- type: "object",
185
- properties: { q: { type: "string" } },
245
+ const snap = await new WebMcpBridge({ enabled: true }).snapshotForDispatch();
246
+ expect(snap[0]!.annotations).toEqual({
247
+ readOnlyHint: true,
248
+ untrustedContentHint: true,
186
249
  });
187
- expect(tool.origin).toBe("webmcp");
188
- expect(tool.pageOrigin).toBe("https://example.test");
189
- expect((tool as unknown as { execute?: unknown }).execute).toBeUndefined();
190
- // Now that the registry was read, the bridge reports operational.
191
- expect(bridge.isOperational()).toBe(true);
250
+ // The server acts on the top-level field, not the nested metadata copy.
251
+ expect(snap[0]!.untrustedContentHint).toBe(true);
252
+ });
253
+
254
+ it("omits annotations and the top-level hint when the tool declared none", async () => {
255
+ registry.tools = [fakeTool({ name: "search" })];
256
+ const snap = await new WebMcpBridge({ enabled: true }).snapshotForDispatch();
257
+ expect(snap[0]!).not.toHaveProperty("annotations");
258
+ expect(snap[0]!).not.toHaveProperty("untrustedContentHint");
259
+ });
260
+
261
+ it("does not hoist untrustedContentHint: false, and drops unknown annotation keys", async () => {
262
+ registry.tools = [
263
+ fakeTool({
264
+ name: "add_to_cart",
265
+ annotations: {
266
+ readOnlyHint: false,
267
+ untrustedContentHint: false,
268
+ destructiveHint: true, // MCP-only today; not in the WebMCP dict
269
+ evil: () => "not JSON",
270
+ },
271
+ }),
272
+ ];
273
+ const snap = await new WebMcpBridge({ enabled: true }).snapshotForDispatch();
274
+ expect(snap[0]!.annotations).toEqual({
275
+ readOnlyHint: false,
276
+ untrustedContentHint: false,
277
+ });
278
+ expect(snap[0]!).not.toHaveProperty("untrustedContentHint");
279
+ });
280
+
281
+ it.each([
282
+ ["unparseable string", "{not json"],
283
+ ["non-object JSON string", '"just a string"'],
284
+ ["JSON array string", "[1,2,3]"],
285
+ ["array object", [1, 2, 3]],
286
+ ["null", null],
287
+ ])("falls back to an empty schema for %s", async (_label, inputSchema) => {
288
+ registry.tools = [fakeTool({ name: "odd" })];
289
+ // Bypass the fake's shape switch: these are malformed values a page or a
290
+ // future runtime could hand us, not either sanctioned generation.
291
+ vi.stubGlobal("document", {
292
+ modelContext: {
293
+ ...makeModelContext(),
294
+ async getTools() {
295
+ return [{ name: "odd", description: "odd", inputSchema, title: "" }];
296
+ },
297
+ },
298
+ });
299
+ const snap = await new WebMcpBridge({ enabled: true }).snapshotForDispatch();
300
+ expect(snap[0]!.parametersSchema).toEqual({ type: "object", properties: {} });
192
301
  });
193
302
 
194
303
  it("applies client-side allowlist glob (`search_*`)", async () => {
@@ -49,8 +49,22 @@ export const WEBMCP_TOOL_PREFIX = "webmcp:";
49
49
  export interface ModelContextToolInfo {
50
50
  name: string;
51
51
  description: string;
52
- /** JSON-encoded JSON Schema for the tool's input. */
53
- inputSchema?: string;
52
+ /**
53
+ * JSON Schema for the tool's input, in EITHER generation of the WebMCP
54
+ * contract. Never read it raw: `normalizeInputSchema` in
55
+ * `webmcp-runtime-entry.ts` collapses both shapes to the object the wire
56
+ * needs.
57
+ *
58
+ * `webmcp#241` changed this from a JSON-encoded string to a JSON Schema
59
+ * object. `@mcp-b/webmcp-polyfill` made the switch in v5, and Chrome ships it
60
+ * from 154.0.8013 (cross-document tools first) -- but Chrome 149-153, most of
61
+ * the Origin Trial population, and 154's same-document tools still emit the
62
+ * string. Both are live in the field, so we accept both.
63
+ *
64
+ * Absent when the tool registered no schema: v5 omits the member, where v4
65
+ * always emitted a `{"type":"object"}` string.
66
+ */
67
+ inputSchema?: object | string;
54
68
  /**
55
69
  * Display title declared on the tool (`ToolDescriptor.title` in the WebMCP
56
70
  * spec). The polyfill returns `""` when the tool didn't declare one. Note:
@@ -59,6 +73,16 @@ export interface ModelContextToolInfo {
59
73
  * channel available to us.
60
74
  */
61
75
  title?: string;
76
+ /**
77
+ * WebMCP `Tool.annotations`. Returned by `getTools()` since
78
+ * `@mcp-b/webmcp-polyfill` v5 (and by Chrome's native implementation);
79
+ * absent on v4 and whenever the tool declared none -- the spec omits the
80
+ * member rather than emitting an empty object.
81
+ */
82
+ annotations?: {
83
+ readOnlyHint?: boolean;
84
+ untrustedContentHint?: boolean;
85
+ };
62
86
  }
63
87
 
64
88
  export interface ModelContextCoreLike {
@@ -131,14 +131,21 @@ export class WebMcpBridge {
131
131
  return infos
132
132
  .filter((info) => this.passesClientAllowlist(info.name))
133
133
  .map<ClientToolDefinition>((info) => {
134
+ const annotations = pickAnnotations(info.annotations);
134
135
  const def: ClientToolDefinition = {
135
136
  name: info.name,
136
137
  description: info.description,
138
+ parametersSchema: normalizeInputSchema(info.inputSchema),
137
139
  origin: "webmcp",
138
140
  ...(pageOrigin ? { pageOrigin } : {}),
141
+ ...(annotations ? { annotations } : {}),
142
+ // Hoisted because the server acts on the TOP-LEVEL field
143
+ // (`InlineClientToolSchema.untrustedContentHint` gates output
144
+ // spotlighting); the nested `annotations` object is metadata only.
145
+ ...(annotations?.untrustedContentHint === true
146
+ ? { untrustedContentHint: true }
147
+ : {}),
139
148
  };
140
- const schema = parseSchema(info.inputSchema);
141
- if (schema) def.parametersSchema = schema;
142
149
  return def;
143
150
  });
144
151
  }
@@ -404,19 +411,72 @@ const matchesGlob = (name: string, pattern: string): boolean => {
404
411
  };
405
412
 
406
413
  /**
407
- * Parse the JSON-string `inputSchema` from `getTools()` back into an object for
408
- * `parametersSchema`. Returns `undefined` for a missing or unparseable schema
409
- * (the server can still accept a tool with no declared parameters).
414
+ * A tool that declared no usable schema. Sent rather than omitted: see below.
410
415
  */
411
- const parseSchema = (raw: string | undefined): object | undefined => {
412
- if (raw === undefined || raw === "") return undefined;
416
+ const EMPTY_INPUT_SCHEMA = { type: "object", properties: {} } as const;
417
+
418
+ /**
419
+ * `getTools()`'s `inputSchema`, in either generation, as the JSON Schema object
420
+ * `dispatch.clientTools[].parametersSchema` carries.
421
+ *
422
+ * TWO shapes are live in the field. `webmcp#241` replaced the serialized JSON
423
+ * string with a JSON Schema object; `@mcp-b/webmcp-polyfill` adopted that in v5
424
+ * and Chrome ships it from 154.0.8013 (cross-document tools first), while
425
+ * Chrome 149-153 -- most of the Origin Trial population -- and 154's
426
+ * same-document tools still emit the string. So: branch on `typeof`, and guard
427
+ * the parse of the string arm. Assuming one shape is a silent failure here and
428
+ * a loud one at dispatch, which is how the object generation shipped past us
429
+ * (`JSON.parse(object)` throws, every schema was dropped, every turn 400'd).
430
+ *
431
+ * ALWAYS returns an object. `parametersSchema` is required by the server's
432
+ * `InlineClientToolSchema`, and one entry missing it fails the whole top-level
433
+ * `DispatchRequestSchema` union -- 400-ing the entire turn rather than dropping
434
+ * the one tool, with an `INVALID_UNION` at path `""` that names nothing. A tool
435
+ * with no schema, or an unparseable one, degrades to "takes no arguments"
436
+ * instead of taking the conversation down with it.
437
+ */
438
+ /**
439
+ * Copy the WebMCP annotation hints onto the wire, dropping anything else.
440
+ *
441
+ * `getTools()` returns `annotations` since `@mcp-b/webmcp-polyfill` v5 (absent
442
+ * on v4 and when the tool declared none). Only the spec's two boolean hints are
443
+ * forwarded -- annotations are page-authored, so an explicit copy keeps
444
+ * functions/junk off the dispatch payload. Returns `undefined` when nothing
445
+ * usable remains so the member is omitted, matching the spec's own
446
+ * omit-when-empty behavior.
447
+ */
448
+ const pickAnnotations = (
449
+ raw: ModelContextToolInfo["annotations"],
450
+ ): ClientToolDefinition["annotations"] | undefined => {
451
+ if (!raw || typeof raw !== "object") return undefined;
452
+ const picked = {
453
+ ...(typeof raw.readOnlyHint === "boolean"
454
+ ? { readOnlyHint: raw.readOnlyHint }
455
+ : {}),
456
+ ...(typeof raw.untrustedContentHint === "boolean"
457
+ ? { untrustedContentHint: raw.untrustedContentHint }
458
+ : {}),
459
+ };
460
+ return Object.keys(picked).length > 0 ? picked : undefined;
461
+ };
462
+
463
+ const normalizeInputSchema = (raw: object | string | undefined): object => {
464
+ if (raw === undefined || raw === "") return { ...EMPTY_INPUT_SCHEMA };
465
+
466
+ // Object generation (webmcp#241): pass through as-is. Arrays are `typeof
467
+ // "object"` but are not JSON Schema objects, so they fall through.
468
+ if (typeof raw === "object") {
469
+ return raw !== null && !Array.isArray(raw) ? raw : { ...EMPTY_INPUT_SCHEMA };
470
+ }
471
+
472
+ // String generation: guarded parse.
413
473
  try {
414
- const parsed = JSON.parse(raw);
415
- return parsed !== null && typeof parsed === "object"
474
+ const parsed: unknown = JSON.parse(raw);
475
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)
416
476
  ? (parsed as object)
417
- : undefined;
477
+ : { ...EMPTY_INPUT_SCHEMA };
418
478
  } catch {
419
- return undefined;
479
+ return { ...EMPTY_INPUT_SCHEMA };
420
480
  }
421
481
  };
422
482
 
@@ -1,7 +0,0 @@
1
- import{c as Qe,d as et,e as tt,f as nt,g as ot,h as rt,i as st,q as V,r as ge,s as Te,t as lt,v as ct,w as dt}from"./chunk-NIKYKSNZ.js";import{a as ye}from"./chunk-7NQ4ZTHF.js";import{a as m,b as at,d as it}from"./chunk-76IELU7F.js";function oe(e){let t=String(e).split(/[\\/]/);return t[t.length-1]??""}function ft(e){let t=oe(e),n=t.lastIndexOf(".");return n<=0?"":t.slice(n+1).toLowerCase()}function ke(e){if(typeof e!="string")return"";let t=e.indexOf(`
2
- `);if(t===-1||!e.slice(0,t).startsWith("```"))return e;let r=e.slice(t+1),o=r.lastIndexOf(`
3
- `);return(o===-1?r:r.slice(0,o)).split("`\u200B``").join("```")}function fe(e){let t=ft(e.path);if(t)return t==="html"||t==="htm"?"html":t==="svg"?"svg":t==="md"||t==="mdx"?"markdown":"other";let n=(e.mimeType||"").toLowerCase();return n.includes("html")?"html":n.includes("svg")?"svg":n.includes("markdown")?"markdown":"other"}function ce(e){switch(fe(e)){case"html":return"HTML";case"svg":return"SVG";case"markdown":return"Markdown";default:{let t=ft(e.path);return t?t.toUpperCase():"File"}}}function Se(e){let t=e.markdown??"";return e.file?{filename:oe(e.file.path)||"artifact",mime:e.file.mimeType||"application/octet-stream",content:ke(t)}:{filename:`${e.title||"artifact"}.md`,mime:"text/markdown",content:t}}function Ee(e){let t=new Blob([e.content],{type:e.mime}),n=URL.createObjectURL(t),r=document.createElement("a");r.href=n,r.download=e.filename,r.click(),URL.revokeObjectURL(n)}var Pe="persona-artifact-custom-action-btn";function be(e,t){let n=t?.documentChrome??!1,r;if(typeof e.icon=="function"){if(e.showLabel){let o="persona-label-btn persona-label-btn--sm "+Pe+(n?" persona-artifact-doc-copy-btn":"");r=m("button",o)}else{let o="persona-icon-btn "+Pe+(n?" persona-artifact-doc-icon-btn":"");r=m("button",o)}r.type="button",r.setAttribute("aria-label",e.label),r.title=e.label;try{let o=e.icon();o&&r.appendChild(o)}catch{}if(e.showLabel){let o=m("span");o.textContent=e.label,r.appendChild(o)}}else e.showLabel||!e.icon?r=ge({icon:e.icon,label:e.label,className:Pe+(n?" persona-artifact-doc-copy-btn":"")}):r=V({icon:e.icon,label:e.label,className:Pe+(n?" persona-artifact-doc-icon-btn":"")});return t?.onClick&&r.addEventListener("click",t.onClick),r}function ve(e){if(!e)return null;let t={artifactId:e.id,title:e.title??"",artifactType:e.artifactType};return e.artifactType==="markdown"?(t.markdown=e.markdown??"",e.file&&(t.file=e.file)):t.jsonPayload=JSON.stringify({component:e.component,props:e.props},null,2),t}var Ne="http://www.w3.org/2000/svg";function pt(e){let t=document.createElementNS(Ne,"svg");t.setAttribute("class",it("persona-spinner",e)),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false");let n=document.createElementNS(Ne,"circle");n.setAttribute("class","persona-spinner-track"),n.setAttribute("cx","12"),n.setAttribute("cy","12"),n.setAttribute("r","9");let r=document.createElementNS(Ne,"circle");return r.setAttribute("class","persona-spinner-arc"),r.setAttribute("cx","12"),r.setAttribute("cy","12"),r.setAttribute("r","9"),t.appendChild(n),t.appendChild(r),t}function ut(e,t,n){let r=n?.loadingAnimation??"shimmer",o=n?.loadingAnimationDuration??2e3;if(r==="none"){e.textContent=t;return}if(r==="pulse"){e.setAttribute("data-preserve-animation","true"),e.classList.add("persona-tool-loading-pulse"),e.style.setProperty("--persona-tool-anim-duration",`${o}ms`),e.textContent=t;return}e.setAttribute("data-preserve-animation","true"),e.classList.add(`persona-tool-loading-${r}`),e.style.setProperty("--persona-tool-anim-duration",`${o}ms`),r==="shimmer-color"&&(n?.loadingAnimationColor&&e.style.setProperty("--persona-tool-anim-color",n.loadingAnimationColor),n?.loadingAnimationSecondaryColor&&e.style.setProperty("--persona-tool-anim-secondary-color",n.loadingAnimationSecondaryColor)),ct(e,t,0)}var Ve="persona-artifact-status-label",mt="persona-artifact-status-detail",yt="data-artifact-status-label",ze=new Map,gt=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();function he(e){e&&ze.delete(e)}function Ot(e){let t=e.artifactType==="markdown"?e.file:void 0;return t?ce(t):e.artifactType==="component"?"Component":"Document"}function we(e,t,n){let r=Ot(e),o=`Generating ${r.toLowerCase()}...`,s=t?.statusLabel;if(typeof s=="string")return{label:s};if(typeof s!="function")return{label:o};let i=e.id,l=ze.get(i);e.status!=="complete"&&l===void 0&&(l=gt(),ze.set(i,l));let A=l===void 0?0:Math.max(0,gt()-l),h=e.artifactType==="component",f=!h&&typeof e.markdown=="string"?e.markdown:"",p=h?0:f.length,u=h||f===""?0:f.split(`
4
- `).length,c=e.artifactType==="markdown"?e.file:void 0,y={artifactId:i,artifactType:e.artifactType,title:e.title,typeLabel:r,file:c,chars:p,lines:u,elapsedMs:A,content:()=>h?"":f,surface:n};try{let g=s(y);return typeof g=="string"?{label:g}:g&&typeof g=="object"&&typeof g.label=="string"?{label:g.label,detail:typeof g.detail=="string"?g.detail:void 0}:{label:o}}catch{return{label:o}}}function Ft(e){e.className=Ve,e.removeAttribute("data-preserve-animation"),e.style.removeProperty("--persona-tool-anim-duration"),e.style.removeProperty("--persona-tool-anim-color"),e.style.removeProperty("--persona-tool-anim-secondary-color"),e.replaceChildren()}function pe(e,t,n){let r=e.querySelector(`:scope > .${Ve}`);r||(r=m("span",Ve),e.appendChild(r)),r.getAttribute(yt)!==t.label&&(Ft(r),ut(r,t.label,n),r.setAttribute(yt,t.label));let o=e.querySelector(`:scope > .${mt}`),s=t.detail;s?(o||(o=m("span",mt),e.appendChild(o)),o.textContent!==s&&(o.textContent=s)):o&&o.remove()}var _t={keyword:"persona-code-token-keyword",string:"persona-code-token-string",comment:"persona-code-token-comment",number:"persona-code-token-number",tag:"persona-code-token-tag",attr:"persona-code-token-attr",property:"persona-code-token-property"},Dt=15e4,Me={html:"html",htm:"html",xhtml:"html",xml:"html",svg:"html",css:"css",js:"js",jsx:"js",mjs:"js",cjs:"js",ts:"js",tsx:"js",mts:"js",cts:"js",javascript:"js",typescript:"js",ecmascript:"js",json:"json",jsonc:"json",json5:"json"};function jt(e,t){let n=(e||"").trim().toLowerCase();if(n&&Me[n])return Me[n];if(t){let r=t.lastIndexOf(".");if(r>=0){let o=t.slice(r+1).toLowerCase();if(Me[o])return Me[o]}}return null}function Re(e,t){let n=[],r=0,o=0,s=i=>{i>o&&n.push({type:"plain",value:e.slice(o,i)})};for(;r<e.length;){let i=!1;for(let l of t){l.re.lastIndex=r;let A=l.re.exec(e);if(A&&A.index===r&&A[0].length>0){s(r);let h=l.map?l.map(A[0]):l.type;n.push({type:h,value:A[0]}),r+=A[0].length,o=r,i=!0;break}}i||(r+=1)}return s(e.length),n}var Nt=new Set(["abstract","any","as","async","await","boolean","break","case","catch","class","const","continue","debugger","declare","default","delete","do","else","enum","export","extends","false","finally","for","from","function","get","if","implements","import","in","instanceof","interface","keyof","let","namespace","never","new","null","number","object","of","private","protected","public","readonly","return","satisfies","set","static","string","super","switch","symbol","this","throw","true","try","type","typeof","undefined","unknown","var","void","while","yield"]),Vt=[{type:"comment",re:/\/\/[^\n]*/y},{type:"comment",re:/\/\*[\s\S]*?\*\//y},{type:"string",re:/`(?:\\[\s\S]|[^\\`])*`/y},{type:"string",re:/"(?:\\.|[^"\\\n])*"/y},{type:"string",re:/'(?:\\.|[^'\\\n])*'/y},{type:"number",re:/0[xX][0-9a-fA-F]+|(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/y},{type:"plain",re:/[A-Za-z_$][\w$]*/y,map:e=>Nt.has(e)?"keyword":"plain"}];function bt(e){return Re(e,Vt)}var zt=[{type:"string",re:/"(?:\\.|[^"\\])*"/y},{type:"number",re:/-?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/y},{type:"plain",re:/[A-Za-z_]\w*/y,map:e=>e==="true"||e==="false"||e==="null"?"keyword":"plain"}];function Wt(e){let t=Re(e,zt);for(let n=0;n<t.length;n+=1){if(t[n].type!=="string")continue;let r=n+1;for(;r<t.length&&t[r].value.trim()==="";)r+=1;let o=t[r];o&&o.value.replace(/^\s*/,"").startsWith(":")&&(t[n].type="property")}return t}var Ut=[{type:"comment",re:/\/\*[\s\S]*?\*\//y},{type:"string",re:/"(?:\\.|[^"\\\n])*"/y},{type:"string",re:/'(?:\\.|[^'\\\n])*'/y},{type:"keyword",re:/@[A-Za-z-]+/y},{type:"number",re:/#[0-9a-fA-F]{3,8}\b/y},{type:"number",re:/-?(?:\d+\.?\d*|\.\d+)(?:[a-z%]+)?/y},{type:"plain",re:/[A-Za-z_-][\w-]*/y}];function ht(e){let t=Re(e,Ut),n="";for(let r=0;r<t.length;r+=1){let o=t[r];if(o.type==="plain"&&/^[A-Za-z_-][\w-]*$/.test(o.value)){let i=r+1;for(;i<t.length&&t[i].value.trim()==="";)i+=1;let l=t[i];l&&l.value.replace(/^\s*/,"").startsWith(":")&&(n===""||n==="{"||n==="}"||n===";"||n===",")&&(o.type="property")}let s=o.value.replace(/\s+$/,"");s&&(n=s[s.length-1])}return t}var $t=[{type:"tag",re:/<\/?\s*[A-Za-z][\w:-]*/y},{type:"string",re:/"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/y},{type:"attr",re:/[A-Za-z_:@][\w:.-]*(?=\s*=)/y},{type:"attr",re:/[A-Za-z_:@][\w:.-]*/y},{type:"tag",re:/\/?>/y}];function qt(e){let t=[],n=(s,i)=>{i&&t.push({type:s,value:i})},r=e.length,o=0;for(;o<r;){if(e.startsWith("<!--",o)){let i=e.indexOf("-->",o+4),l=i===-1?r:i+3;n("comment",e.slice(o,l)),o=l;continue}if(e[o]==="<"&&e[o+1]==="!"){let i=e.indexOf(">",o),l=i===-1?r:i+1;n("tag",e.slice(o,l)),o=l;continue}if(e[o]==="<"&&/[A-Za-z/]/.test(e[o+1]||"")){let i=e.indexOf(">",o),l=i===-1?r:i+1,A=e.slice(o,l);for(let f of Re(A,$t))t.push(f);o=l;let h=/^<\s*(script|style)\b/i.exec(A);if(h&&!/\/>\s*$/.test(A)){let f=h[1].toLowerCase(),u=new RegExp("</\\s*"+f+"\\s*>","i").exec(e.slice(o)),c=u?o+u.index:r,y=e.slice(o,c),g=f==="script"?bt(y):ht(y);for(let S of g)t.push(S);o=c}continue}let s=e.indexOf("<",o);if(s===o)n("plain",e[o]),o+=1;else{let i=s===-1?r:s;n("plain",e.slice(o,i)),o=i}}return t}function Gt(e,t){switch(t){case"html":return qt(e);case"css":return ht(e);case"js":return bt(e);case"json":return Wt(e)}}function Kt(e){let t=at(),n=m("span","persona-code-line"),r=(o,s)=>{if(!s)return;let i=_t[o];if(i){let l=m("span",i);l.textContent=s,n.appendChild(l)}else n.appendChild(document.createTextNode(s))};for(let o of e){let s=o.value.split(`
5
- `);for(let i=0;i<s.length;i+=1)i>0&&(t.appendChild(n),t.appendChild(document.createTextNode(`
6
- `)),n=m("span","persona-code-line")),r(o.type,s[i])}return n.childNodes.length>0?t.appendChild(n):t.lastChild||t.appendChild(n),t}function wt(e,t,n){let r=e.length<=Dt?jt(t,n):null,o=r?Gt(e,r):[{type:"plain",value:e}];return Kt(o)}var At=null,vt=e=>{At=e.componentRegistry},Ct=()=>At;function He(e){if(!e)return"";if(e.artifactType==="markdown"){let t=e.markdown??"";return e.file?ke(t):t}return JSON.stringify({component:e.component,props:e.props},null,2)}var We=!1;function Zt(e){return"persona-artifact-vt-"+((e||"artifact").replace(/[^A-Za-z0-9_-]/g,"-").replace(/^-+/,"")||"artifact")}function xt(e,t,n,r){let o=typeof document<"u"?document.startViewTransition:void 0,s=!1;try{s=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{s=!1}if(t!=="auto"||!e||typeof o!="function"||We||s){r();return}We=!0;let i=Zt(n);e.style.setProperty("view-transition-name",i);let l=()=>{We=!1,e.style.removeProperty("view-transition-name")};try{o.call(document,()=>{r()}).finished.then(l,l)}catch{l(),r()}}var Jt="persona-font-mono persona-text-xs persona-whitespace-pre-wrap persona-break-words persona-text-persona-primary",Xt="persona-text-sm persona-leading-relaxed persona-markdown-bubble";function Yt(e){let t=m("div","persona-rounded-lg persona-border persona-border-persona-border persona-p-3 persona-text-persona-primary"),n=m("div","persona-font-semibold persona-text-sm persona-mb-2");n.textContent=e.component?`Component: ${e.component}`:"Component";let r=m("pre","persona-font-mono persona-text-xs persona-whitespace-pre-wrap persona-overflow-x-auto");return r.textContent=JSON.stringify(e.props??{},null,2),t.appendChild(n),t.appendChild(r),t}function Qt(e){if(e===!1)return{enabled:!1,delayMs:0,minVisibleMs:0,timeoutMs:0,injectReadySignal:!1,label:"Starting preview...",labelDelayMs:2e3};let t=e&&typeof e=="object"?e:void 0;return{enabled:!0,delayMs:t?.delayMs??200,minVisibleMs:t?.minVisibleMs??300,timeoutMs:t?.timeoutMs??8e3,injectReadySignal:t?.injectReadySignal!==!1,label:t?.label===!1?!1:t?.label??"Starting preview...",labelDelayMs:t?.labelDelayMs??2e3,renderIndicator:t?.renderIndicator}}var en=220;function tn(){try{if(typeof crypto<"u"&&crypto.getRandomValues){let e=new Uint32Array(2);return crypto.getRandomValues(e),e[0].toString(36)+e[1].toString(36)}}catch{}return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}function nn(e){return`
7
- <script>(function(){var d=false;var t=`+JSON.stringify(e)+";function r(){if(d)return;d=true;try{parent.postMessage({persona:'artifact-preview-ready',token:t},'*');}catch(e){}}function s(){if(typeof requestAnimationFrame==='function'){requestAnimationFrame(function(){requestAnimationFrame(r);});}setTimeout(r,150);}if(document.readyState==='complete'){s();}else{window.addEventListener('load',s);}})();</script>"}function on(e,t,n){let r=m("div","persona-artifact-frame-loading");if(n.renderIndicator)try{let i=n.renderIndicator({artifactId:e,config:t});if(i)return r.appendChild(i),{el:r,revealLabel:()=>{}}}catch{}let o=m("div","persona-artifact-frame-loading-indicator");o.appendChild(pt());let s=null;return n.label!==!1&&(s=m("div","persona-artifact-frame-loading-text"),s.textContent=n.label,o.appendChild(s)),r.appendChild(o),{el:r,revealLabel:()=>{s&&s.classList.add("persona-artifact-frame-loading-text--visible")}}}function rn(e,t,n,r,o,s){let i=null,l=0,A=!1,h=new Set,f=()=>{h.forEach(x=>clearTimeout(x)),h.clear()},p=(x,P)=>{let $=setTimeout(()=>{h.delete($),x()},P);h.add($)},u=()=>{i&&i.parentElement&&i.remove(),i=null},c=()=>{if(i||A)return;let x=on(o,s,r);i=x.el,e.appendChild(i),l=Date.now(),r.label!==!1&&p(x.revealLabel,r.labelDelayMs)},y=()=>{i&&(i.classList.add("persona-artifact-frame-loading--out"),p(u,en))},g=()=>{n!==null?typeof window<"u"&&window.removeEventListener("message",I):t.removeEventListener("load",L)},S=()=>{if(A||(A=!0,g(),f(),!i))return;let x=Math.max(0,r.minVisibleMs-(Date.now()-l));x>0?p(y,x):y()};function I(x){if(n===null)return;let P=x.data;!P||P.persona!=="artifact-preview-ready"||P.token!==n||x.source===t.contentWindow&&S()}function L(){let x=P=>{typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>P()):setTimeout(P,0)};x(()=>x(()=>S()))}return p(c,r.delayMs),p(S,r.timeoutMs),n!==null?typeof window<"u"&&window.addEventListener("message",I):t.addEventListener("load",L),()=>{A=!0,f(),g(),u()}}function Ie(e,t){let{config:n}=t,r=t.registry??Ct()??dt,o=t.bodyLayout,s=n.markdown?nt(n.markdown):null,i=rt(n.sanitize),l=e,A=!1,h=d=>{let M=tt()!==null;s&&!M&&!A&&(A=!0,Qe(()=>Z(l)));let O=s?s(d):ot(d);return s&&M&&i?i(O):O},f=m("div","persona-artifact-preview-body"),p=null,u=null,c=null,y=()=>{c&&(c(),c=null),p=null,u=null},g=null,S=null,I=null,L=!1,x=()=>{g=null,S=null,I=null,L=!1},P=null,$=null,J=()=>{P=null,$=null},re=40,Y=0,ie=d=>typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>d()):setTimeout(d,0),_=d=>d.scrollHeight-d.clientHeight-d.scrollTop<=re,K=d=>{if(!o)return;let M=d.scrollHeight-d.clientHeight>1,O=d.scrollHeight-d.clientHeight-d.scrollTop;d.classList.toggle("persona-artifact-fade-top",o.fadeTop&&M&&d.scrollTop>1),d.classList.toggle("persona-artifact-fade-bottom",o.fadeBottom&&M&&O>1)},D=d=>{Y||(Y=ie(()=>{Y=0,d.scrollTop=d.scrollHeight,K(d)}))},z=(d,M,O,b)=>{let T=!!o,F=O.id+"|"+(T?"w":"p");if(!g||I!==F||g.parentElement!==f){y(),J(),f.replaceChildren();let w=m("pre",Jt+" persona-code-pre"),H=m("code","persona-code");if(w.appendChild(H),T){let j=m("div","persona-artifact-source-window");if(j.appendChild(w),f.appendChild(j),!(o?.overflow==="clip")&&typeof j.addEventListener=="function"){let X=()=>j.scrollHeight-j.clientHeight>1;j.addEventListener("scroll",()=>{_(j)&&(L=!1),K(j)},{passive:!0}),j.addEventListener("wheel",ee=>{X()&&ee.deltaY<0&&(L=!0)},{passive:!0}),j.addEventListener("touchmove",()=>{X()&&(L=!0)},{passive:!0})}g=j}else f.appendChild(w),g=w;S=H,I=F}let k=T?g:null;k&&(k.classList.toggle("persona-artifact-source-window--fixed",b),k.classList.toggle("persona-artifact-source-window--clip",b&&o?.overflow==="clip"));let R=k?_(k):!0;if(S.replaceChildren(wt(d,M?.language,M?.path)),k){let w=O.status!=="complete";b&&w&&o?.followOutput&&!L&&R?D(k):w||(L=!1),K(k)}},W=d=>{y(),x(),J(),f.replaceChildren();let M=m("div",Xt);M.innerHTML=h(d),f.appendChild(M)},Q=d=>{let M=d.id,O=n.features?.artifacts,b=we(d,O,"status-body");if(P&&$===M&&P.parentElement===f){let k=P.querySelector(".persona-artifact-status-view-text");k&&pe(k,b,O);return}y(),x(),f.replaceChildren();let T=m("div","persona-artifact-status-view"),F=m("div","persona-artifact-status-view-text");pe(F,b,O),T.appendChild(F),f.appendChild(T),P=T,$=M},Z=d=>{l=d;let M=t.resolveViewMode?.(d)??o?.viewMode??"rendered",O=d.artifactType==="markdown"?d.file:void 0,b=d.status!=="complete";b||he(d.id);let T=b?o?.streamingHeight:o?.completeHeight,F=!!o&&typeof T=="number";if(o?.streamingView==="status"&&b){Q(d);return}if(O){let R=ke(d.markdown??""),w=fe(O),H=n.features?.artifacts?.filePreview?.enabled!==!1;if(!b&&M==="rendered"&&H&&(w==="html"||w==="svg")){let ue=d.id+"\0"+R;if(p&&u===ue&&p.parentElement===f)return;x(),J(),y(),f.replaceChildren();let X=n.features?.artifacts?.filePreview,ee=X?.iframeSandbox??"allow-scripts";!X?.dangerouslyAllowSameOrigin&&ee.includes("allow-same-origin")&&(console.warn("[AgentWidget] Stripped allow-same-origin from filePreview.iframeSandbox: it lets artifact content run with the page origin. Set filePreview.dangerouslyAllowSameOrigin to keep it."),ee=ee.split(/\s+/).filter(B=>B&&B!=="allow-same-origin").join(" "));let me=Qt(X?.loading),U=m("div","persona-artifact-frame"),te=m("iframe","persona-artifact-iframe");te.setAttribute("sandbox",ee),te.setAttribute("data-artifact-id",d.id);let Ae=null;me.enabled&&me.injectReadySignal?(Ae=tn(),te.srcdoc=R+nn(Ae)):te.srcdoc=R,U.appendChild(te),f.appendChild(U),me.enabled&&(c=rn(U,te,Ae,me,d.id,n)),p=U,u=ue;return}if(y(),!b&&w==="markdown"&&M==="rendered"){W(R);return}z(R,{language:O.language,path:O.path},d,F);return}if(d.artifactType==="markdown"){if(M==="source"){y(),z(d.markdown??"",void 0,d,F);return}W(d.markdown??"");return}y(),x(),J(),f.replaceChildren();let k=d.component?r.get(d.component):void 0;if(k){let w={message:{id:d.id,role:"assistant",content:"",createdAt:new Date().toISOString()},config:n,updateProps:()=>{}};try{let H=k(d.props??{},w);if(H){f.appendChild(H);return}}catch{}}f.appendChild(Yt(d))};return Z(e),{el:f,update(d){Z(d)},destroy(){y()}}}import{Check as an,ChevronDown as sn,Maximize as ln,Minimize as cn}from"lucide";function Lt(e,t){let n=t.orientation??"horizontal",r=n==="vertical"?"ArrowUp":"ArrowLeft",o=n==="vertical"?"ArrowDown":"ArrowRight";e.setAttribute("role","tablist");let s=[],i=!1,l=p=>{typeof p.scrollIntoView=="function"&&p.scrollIntoView({block:"nearest",inline:"nearest"})},A=p=>{let u=p;return s.findIndex(c=>c===u||c.contains(u))},h=p=>{let u=A(p.target);if(u<0)return;let c=u;if(p.key===o)c=Math.min(u+1,s.length-1);else if(p.key===r)c=Math.max(u-1,0);else if(p.key==="Home")c=0;else if(p.key==="End")c=s.length-1;else return;p.preventDefault(),c!==u&&t.onSelect(c)},f=p=>{let u=A(p.target);u>=0&&l(s[u])};return e.addEventListener("keydown",h),e.addEventListener("focusin",f),{beforeRender(){i=typeof document<"u"&&e.contains(document.activeElement)},render(p,u){if(s=p,p.forEach((c,y)=>{c.setAttribute("role","tab");let g=y===u;c.setAttribute("aria-selected",g?"true":"false"),c.tabIndex=g||u<0&&y===0?0:-1}),i){let c=(u>=0?p[u]:void 0)??p[0];c&&typeof c.focus=="function"&&(l(c),c.focus())}},destroy(){e.removeEventListener("keydown",h),e.removeEventListener("focusin",f)}}}function Tt(e,t){let n=e.features?.artifacts?.layout,o=(n?.toolbarPreset??"default")==="document",s=n?.toolbarTitle??"Artifacts",i=n?.closeButtonLabel??"Close",l=n?.panePadding?.trim(),A=n?.tabFadeSize?.trim(),h=a=>({start:a===!1?!1:typeof a=="object"&&a?a.start!==!1:!0,end:a===!1?!1:typeof a=="object"&&a?a.end!==!1:!0}),{start:f,end:p}=h(n?.tabFade),u=typeof document<"u"?m("div","persona-artifact-backdrop persona-fixed persona-inset-0 persona-z-[55] persona-bg-black/30 persona-hidden md:persona-hidden"):null,c=()=>{u?.classList.add("persona-hidden"),y.classList.remove("persona-artifact-drawer-open"),K?.closeMenu()};u&&u.addEventListener("click",()=>{c(),t.onDismiss?.()});let y=m("aside","persona-artifact-pane persona-flex persona-flex-col persona-min-h-0 persona-min-w-0 persona-bg-persona-surface persona-text-persona-primary persona-border-l persona-border-persona-border");y.setAttribute("data-persona-theme-zone","artifact-pane"),o&&y.classList.add("persona-artifact-pane-document");let g=m("div","persona-artifact-toolbar persona-flex persona-items-center persona-justify-between persona-gap-2 persona-px-2 persona-py-2 persona-border-b persona-border-persona-border persona-shrink-0");g.setAttribute("data-persona-theme-zone","artifact-toolbar"),o&&g.classList.add("persona-artifact-toolbar-document");let S=m("span","persona-text-xs persona-font-medium persona-truncate");S.textContent=s;let I=V({icon:"x",label:i});I.addEventListener("click",()=>{c(),t.onDismiss?.()});let L="rendered",x=Te({items:[{id:"rendered",icon:"eye",label:"Rendered view",className:o?"persona-artifact-doc-icon-btn persona-artifact-view-btn":void 0},{id:"source",icon:"code-xml",label:"Source",className:o?"persona-artifact-doc-icon-btn persona-artifact-code-btn":void 0}],selectedId:"rendered",className:"persona-artifact-toggle-group persona-shrink-0",onSelect:a=>{L=a==="source"?"source":"rendered",Le()}}),P=m("div","persona-flex persona-items-center persona-gap-1 persona-shrink-0"),$=n?.documentToolbarShowCopyLabel===!0,J=n?.documentToolbarShowCopyChevron===!0,re=n?.documentToolbarCopyMenuItems,Y=!!(J&&re&&re.length>0),ie=null,_,K=null;if(o&&($||J)&&!Y){if(_=$?ge({icon:"copy",label:"Copy",iconSize:14,className:"persona-artifact-doc-copy-btn"}):V({icon:"copy",label:"Copy",className:"persona-artifact-doc-copy-btn"}),J){let a=ye(sn,14,"currentColor",2);a&&_.appendChild(a)}}else o&&Y?(K=lt({label:"Copy",icon:"copy",iconSize:14,iconOnly:!$,primaryClassName:"persona-artifact-doc-copy-btn",chevronLabel:"More copy options",chevronClassName:"persona-artifact-doc-copy-menu-chevron persona-artifact-doc-icon-btn",menuItems:(re??[]).map(a=>({id:a.id,label:a.label})),position:"bottom-right",portal:()=>y.closest("[data-persona-root]")??document.body,onSelect:a=>{k(a)}}),ie=K.element,_=K.primaryButton):o?_=V({icon:"copy",label:"Copy",className:"persona-artifact-doc-icon-btn"}):(_=V({icon:"copy",label:"Copy"}),n?.showCopyButton!==!0&&_.classList.add("persona-hidden"));let D=o?V({icon:"refresh-cw",label:"Refresh",className:"persona-artifact-doc-icon-btn"}):V({icon:"refresh-cw",label:"Refresh"});n?.onDocumentToolbarRefresh||D.classList.add("persona-hidden");let z=o?V({icon:"x",label:i,className:"persona-artifact-doc-icon-btn"}):V({icon:"x",label:i}),W=V({icon:"maximize",label:"Expand artifacts panel",className:"persona-artifact-expand-btn"+(o?" persona-artifact-doc-icon-btn":""),onClick:()=>t.onToggleExpand?.()});n?.showExpandToggle!==!0&&W.classList.add("persona-hidden");let Q=m("div","persona-flex persona-items-center persona-gap-1 persona-shrink-0 persona-artifact-toolbar-custom-actions"),Z=e.features?.artifacts?.toolbarActions??[],d=()=>{let a=B.find(ae=>ae.id===q)??B[B.length-1],C=a?.id??null,v=a?.artifactType==="markdown"?a.markdown??"":"",E=a?JSON.stringify({component:a.component,props:a.props},null,2):"",{filename:N,mime:G,content:se}=Se({title:a?.title,markdown:a?.markdown??"",file:a?.file});return{markdown:v,jsonPayload:E,id:C,file:a?.file,suggestedFilename:N,mime:G,content:se}},M=()=>{let{suggestedFilename:a,mime:C,content:v}=d();v&&Ee({filename:a,mime:C,content:v})},O=a=>{let{id:C,...v}=d();return{actionId:a,artifactId:C,...v}},b=async()=>{let a=B.find(C=>C.id===q)??B[B.length-1];try{return await navigator.clipboard.writeText(He(a)),!0}catch{return!1}},T=null,F=()=>{T?.();let a=_.querySelector("svg"),C=Number(a?.getAttribute("width"))||16,v=ye(an,C,"currentColor",2);if(!a||!v)return;a.replaceWith(v);let E=_.querySelector("span");E&&(E.textContent="Copied");let N=setTimeout(()=>T?.(),2e3);T=()=>{clearTimeout(N),v.replaceWith(a),E&&(E.textContent="Copy"),T=null}};_.addEventListener("click",async()=>{let a=n?.onDocumentToolbarCopyMenuSelect;if(a&&Y){try{if(await a(O("primary"))===!1){await b()&&F();return}F()}catch{}return}await b()&&F()});async function k(a){let C=n?.onDocumentToolbarCopyMenuSelect;try{if(C&&await C(O(a))!==!1)return;if(a==="download"){M();return}let{markdown:v,jsonPayload:E}=d();a==="markdown"||a==="md"?await navigator.clipboard.writeText(v):a==="json"||a==="source"?await navigator.clipboard.writeText(E):await navigator.clipboard.writeText(v||E),F()}catch{}}D.addEventListener("click",async()=>{try{await n?.onDocumentToolbarRefresh?.()}catch{}Le()}),z.addEventListener("click",()=>{c(),t.onDismiss?.()});let R=m("span","persona-min-w-0 persona-flex-1 persona-text-xs persona-font-medium persona-text-persona-primary persona-truncate persona-text-center md:persona-text-left");if(o)g.replaceChildren(),ie?P.append(ie,D,z):P.append(_,D,z),P.insertBefore(Q,z),P.insertBefore(W,z),g.append(x.element,R,P);else{let a=m("div","persona-flex persona-items-center persona-gap-1 persona-shrink-0");a.append(_,Q,W,I),g.appendChild(S),g.appendChild(a)}l&&(g.style.paddingLeft=l,g.style.paddingRight=l);let w=m("div","persona-artifact-list persona-shrink-0 persona-flex persona-gap-1 persona-overflow-x-auto persona-p-2 persona-border-b persona-border-persona-border");A&&w.style.setProperty("--persona-artifact-tab-fade-size",A);let H=e.features?.artifacts?.renderTabBar,j=m("div","persona-artifact-tab-custom persona-shrink-0 persona-border-b persona-border-persona-border persona-hidden"),ue=Lt(w,{onSelect:a=>t.onSelect(B[a].id)}),X=a=>{let C=a.scrollWidth-a.clientWidth,v=C>1,E=Math.abs(a.scrollLeft);a.classList.toggle("persona-artifact-tab-fade-start",f&&v&&E>1),a.classList.toggle("persona-artifact-tab-fade-end",p&&v&&E<C-1)},ee=0,me=()=>{if(ee)return;let a=()=>{ee=0,X(w)};ee=typeof requestAnimationFrame=="function"?requestAnimationFrame(a):setTimeout(a,0)};w.addEventListener("scroll",()=>me(),{passive:!0}),typeof ResizeObserver<"u"&&new ResizeObserver(()=>X(w)).observe(w);let U=m("div","persona-artifact-content persona-flex-1 persona-min-h-0 persona-overflow-y-auto persona-p-3"),te=()=>{U.scrollLeft=0},Ae=()=>{typeof requestAnimationFrame=="function"?requestAnimationFrame(te):setTimeout(te,0)};if(l){for(let a of[w,j])a.style.paddingLeft=l,a.style.paddingRight=l;U.style.padding=l}y.appendChild(g),y.appendChild(w),y.appendChild(j),y.appendChild(U);let B=[],q=null,Oe=!1,Ue=!1,Fe=!0,_e=!1,$e=null,De="",ne=null,xe=!1,Bt=a=>a.artifactType==="markdown"&&!!a.file||o?L:"rendered",qe=a=>{o||(a&&!xe?(g.insertBefore(x.element,S),xe=!0):!a&&xe&&(x.element.remove(),xe=!1))},Ge=()=>q&&B.find(a=>a.id===q)||B[B.length-1],Ke=()=>{let a=ve(Ge());if(!a){Q.replaceChildren();return}let C=Z.filter(v=>v.visible===void 0||v.visible(a)).map(v=>be(v,{documentChrome:o,onClick:()=>{let E=ve(Ge());if(E)try{Promise.resolve(v.onClick(E)).catch(()=>{})}catch{}}}));Q.replaceChildren(...C)},Le=()=>{Ke();let a=o&&B.length<=1,C=!!H;if(w.classList.toggle("persona-hidden",a||C),j.classList.toggle("persona-hidden",a||!C),C&&H){let N=B.map(G=>G.id).join("|")+" "+(q??"");if(N!==De){De=N;let G=H({records:B,selectedId:q,onSelect:t.onSelect});j.firstElementChild!==G&&j.replaceChildren(G)}}else{ue.beforeRender(),w.replaceChildren();let N=[],G=-1;for(let[se,ae]of B.entries()){let le=m("button","persona-artifact-tab persona-shrink-0 persona-rounded-lg persona-px-2 persona-py-1 persona-text-xs persona-border persona-border-transparent persona-text-persona-primary");le.type="button";let je=ae.artifactType==="markdown"?ae.file:void 0,Xe=je?oe(je.path):ae.title||ae.id.slice(0,8),Ye=je?.path||ae.title||Xe;le.textContent=Xe,le.title=Ye,le.setAttribute("aria-label",Ye),ae.id===q&&(le.classList.add("persona-bg-persona-container","persona-border-persona-border"),G=se),le.addEventListener("click",()=>t.onSelect(ae.id)),w.appendChild(le),N.push(le)}if(ue.render(N,G),G>=0&&q!==$e){$e=q;let se=N[G];typeof se.scrollIntoView=="function"&&se.scrollIntoView({block:"nearest",inline:"nearest"})}X(w)}let v=q&&B.find(N=>N.id===q)||B[B.length-1];if(!v){U.replaceChildren(),ne?.destroy(),ne=null,qe(!1);return}let E=v.artifactType==="markdown"?v.file:void 0;if(qe(!!E&&fe(E)!=="other"),o){let N=E?ce(E):v.artifactType==="markdown"?"MD":v.component??"Component",G=(v.title||"Document").trim(),se=E?oe(E.path):G.replace(/\s*·\s*MD\s*$/i,"").trim()||"Document";R.textContent=`${se} \xB7 ${N}`}else S.textContent=E?oe(E.path):s;ne?(ne.el.parentElement!==U&&U.replaceChildren(ne.el),ne.update(v)):(ne=Ie(v,{config:e,resolveViewMode:Bt}),U.replaceChildren(ne.el)),U.classList.toggle("persona-artifact-content-flush",!!U.querySelector(".persona-code-pre"))},Ze=()=>{let a=B.length>0;if(y.classList.toggle("persona-hidden",!a),u){let E=((typeof y.closest=="function"?y.closest("[data-persona-root]"):null)?.classList.contains("persona-artifact-narrow-host")??!1)||typeof window<"u"&&window.matchMedia("(max-width: 640px)").matches;a&&E&&Oe?(u.classList.remove("persona-hidden"),y.classList.add("persona-artifact-drawer-open")):(u.classList.add("persona-hidden"),y.classList.remove("persona-artifact-drawer-open"))}},Je=()=>{_e=!1,Le(),Ze()};return{element:y,backdrop:u,update(a){let C=a.selectedId??a.artifacts[a.artifacts.length-1]?.id??null,v=C!==q;B=a.artifacts,q=C,B.length>0&&(Oe=!0),_e=!0,Fe&&Je(),v&&te()},setMobileOpen(a){Oe=a,!a&&u?(u.classList.add("persona-hidden"),y.classList.remove("persona-artifact-drawer-open")):Ze()},setExpanded(a){a!==Ue&&(Ue=a,Ae());let C=ye(a?cn:ln,16,"currentColor",2);C&&W.replaceChildren(C);let v=a?"Collapse artifacts panel":"Expand artifacts panel";W.setAttribute("aria-label",v),W.title=v},setExpandToggleVisible(a){W.classList.toggle("persona-hidden",!a)},setCopyButtonVisible(a){o||_.classList.toggle("persona-hidden",!a)},setRefreshButtonVisible(a){D.classList.toggle("persona-hidden",!a)},setCustomActions(a){Z=a,Ke()},setTabFade(a){let C=h(a);C.start===f&&C.end===p||(f=C.start,p=C.end,X(w))},setRenderTabBar(a){a!==H&&(H=a,De="",Le())},setVisible(a){a!==Fe&&(Fe=a,a&&_e&&Je())},destroy(){ne?.destroy(),ne=null}}}import{FileText as dn}from"lucide";function kt(e,t){let n=e.file&&typeof e.file=="object"&&!Array.isArray(e.file)?e.file:void 0,r=typeof e.title=="string"&&e.title?e.title:"Untitled artifact",o=n?oe(n.path):r,s=typeof e.artifactId=="string"?e.artifactId:"",i=e.status==="streaming"?"streaming":"complete",l=typeof e.artifactType=="string"?e.artifactType:"markdown",A=e.presentation&&typeof e.presentation=="object"&&!Array.isArray(e.presentation)?e.presentation:void 0,h=n?ce(n):l==="component"?"Component":"Document",f=document.createElement("div");f.className="persona-artifact-card persona-flex persona-w-full persona-max-w-full persona-items-center persona-gap-3 persona-px-4 persona-py-3",f.tabIndex=0,f.setAttribute("role","button"),f.setAttribute("aria-label",`Open ${o} in artifact panel`),s&&f.setAttribute("data-open-artifact",s);let p=document.createElement("div");p.className="persona-flex persona-h-10 persona-w-10 persona-flex-shrink-0 persona-items-center persona-justify-center persona-rounded-lg",p.style.border="1px solid var(--persona-border, #e5e7eb)",p.style.color="var(--persona-muted, #9ca3af)",p.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>';let u=document.createElement("div");u.className="persona-min-w-0 persona-flex-1 persona-flex persona-flex-col persona-gap-0.5";let c=document.createElement("div");c.className="persona-truncate persona-text-sm persona-font-medium",c.style.color="var(--persona-text, #1f2937)",c.textContent=o;let y=document.createElement("div");if(y.className="persona-text-xs persona-flex persona-items-center persona-gap-1.5",y.style.color="var(--persona-muted, #9ca3af)",i==="streaming"){let g=t?.config?.features?.artifacts,S={id:s,artifactType:l==="component"?"component":"markdown",title:r,status:"streaming",...typeof e.markdown=="string"?{markdown:e.markdown}:{},...n?{file:n}:{},...A?{presentation:A}:{}},I=we(S,g,"card");pe(y,I,g)}else s&&he(s),y.textContent=h;if(u.append(c,y),f.append(p,u),i==="complete"){let g=t?.config?.features?.artifacts?.cardActions;if(g&&g.length>0){let I={artifactId:s||null,title:o,artifactType:l,markdown:typeof e.markdown=="string"?e.markdown:void 0,file:n};for(let L of g)try{if(L.visible===void 0||L.visible(I)){let x=be(L);x.setAttribute("data-artifact-custom-action",L.id),x.className=`${x.className} persona-flex-shrink-0`,f.append(x)}}catch{}}let S=ge({label:"Download",className:"persona-flex-shrink-0"});S.title=`Download ${o}`,S.setAttribute("data-download-artifact",s),f.append(S)}return f}var Be=(e,t)=>{let n=t?.config?.features?.artifacts?.renderCard;if(n){let r=typeof e.title=="string"&&e.title?e.title:"Untitled artifact",o=typeof e.artifactId=="string"?e.artifactId:"",s=e.status==="streaming"?"streaming":"complete",i=typeof e.artifactType=="string"?e.artifactType:"markdown",l=n({artifact:{artifactId:o,title:r,artifactType:i,status:s},config:t.config,defaultRenderer:()=>kt(e,t)});if(l)return l}return kt(e,t)};var de=new WeakMap;function Rt(e,t,n){if(t.length===0)return;let r=new Map(t.map(o=>[o.id,o]));e.querySelectorAll("[data-artifact-inline]").forEach(o=>{let s=de.get(o);if(!s)return;let i=r.get(o.getAttribute("data-artifact-inline")??"");i&&s(i,n)})}function Ht(e){return de.has(e)}function fn(e){let t=typeof e.artifactId=="string"?e.artifactId:"",n=typeof e.title=="string"&&e.title?e.title:void 0,r=e.status==="streaming"?"streaming":"complete",o=e.presentation&&typeof e.presentation=="object"&&!Array.isArray(e.presentation)?e.presentation:void 0;if(e.artifactType==="component"){let i=e.componentProps,l=i&&typeof i=="object"&&!Array.isArray(i)?i:{};return{id:t,artifactType:"component",title:n,status:r,component:typeof e.component=="string"?e.component:"",props:l,...o?{presentation:o}:{}}}let s=e.file&&typeof e.file=="object"&&!Array.isArray(e.file)?e.file:void 0;return{id:t,artifactType:"markdown",title:n,status:r,markdown:typeof e.markdown=="string"?e.markdown:"",...s?{file:s}:{},...o?{presentation:o}:{}}}function St(e){let t=e.artifactType==="markdown"?e.file:void 0,n=t?oe(t.path):e.title&&e.title.trim()?e.title:"Untitled artifact",r=t?ce(t):e.artifactType==="component"?"Component":"Document";return{title:n,typeLabel:r}}function pn(e){let t={artifactId:e.id,title:e.title??"",status:e.status,artifactType:e.artifactType};return e.artifactType==="markdown"&&(typeof e.markdown=="string"&&(t.markdown=e.markdown),e.file&&(t.file=e.file)),t}var Et=180,un=240,mn=.8,yn=300,gn=500,bn="cubic-bezier(0.2, 0, 0, 1)",Pt=240,hn=.35;function wn(e,t,n){let{swap:r,onSettled:o}=n,s=!1;try{s=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}catch{s=!1}if(!t||!e.isConnected||s||typeof e.animate!="function"){r(),o();return}e.style.height=`${t}px`,e.style.overflow="hidden";let i=[];for(let l of Array.from(e.children))l instanceof HTMLElement&&i.push(l.animate([{opacity:1},{opacity:0}],{duration:Et,easing:"ease-out",fill:"forwards"}));window.setTimeout(()=>{for(let I of i)I.cancel();r();let l=()=>{e.style.removeProperty("height"),e.style.removeProperty("overflow")};if(!e.isConnected){l(),o();return}e.style.height="auto";let A=e.getBoundingClientRect().height;if(e.style.height=`${t}px`,!A||Math.abs(A-t)<1){l(),o();return}let h=Math.abs(t-A),f=Math.round(Math.min(gn,Math.max(yn,un+h*mn))),p=Math.round(f*hn),u=e.firstElementChild instanceof HTMLElement?e.firstElementChild:null,c=u?u.animate([{opacity:0},{opacity:1}],{duration:Pt,delay:p,easing:"ease-out",fill:"backwards"}):null,y=e.animate([{height:`${t}px`},{height:`${A}px`}],{duration:f,easing:bn});e.style.height=`${A}px`;let g=!1,S=()=>{g||(g=!0,l(),o())};Promise.allSettled([y.finished,c?.finished].filter(Boolean)).then(S),window.setTimeout(S,Math.max(f,p+Pt)+120)},Et)}function An(e){let t=e?.inlineChrome;if(t===!1)return{chromeEnabled:!1,showCopy:!1,showExpand:!1,showViewToggle:!1};let n=typeof t=="object"?t:void 0;return{chromeEnabled:!0,showCopy:n?.showCopy!==!1,showExpand:n?.showExpand!==!1,showViewToggle:n?.showViewToggle!==!1}}var Ce="--persona-artifact-inline-body-height";function vn(e){let t=e?.inlineBody,n=t?.streamingView==="status"?"status":"source",r=t?.viewMode==="source"?"source":"rendered",o=320,s=320,i=t?.height;typeof i=="number"||i==="auto"?(o=i,s=i):i&&typeof i=="object"&&(o=i.streaming??320,s=i.complete??320);let l=t?.overflow==="clip"?"clip":"scroll",A=l==="clip"?!1:t?.followOutput!==!1,h,f,p=t?.fadeMask;p===!0?(h=!0,f=!0):p===!1?(h=!1,f=!1):p&&typeof p=="object"?(h=p.top===!0,f=p.bottom===!0):l==="clip"?(h=!1,f=!0):(h=!0,f=!0);let u=t?.transition==="none"?"none":"auto",c=t?.completeDisplay==="card"?"card":"inline";return{streamingView:n,viewMode:r,streamingHeight:o,completeHeight:s,followOutput:A,overflow:l,fadeTop:h,fadeBottom:f,transition:u,completeDisplay:c}}function Mt(e,t){let n=fn(e),r=t.config?.features?.artifacts,{chromeEnabled:o,showCopy:s,showExpand:i,showViewToggle:l}=An(r),A=r?.inlineActions??[],h=vn(r),f=h.completeDisplay==="card",p=null,u=n,c=m("div","persona-artifact-inline persona-w-full persona-max-w-full");c.setAttribute("data-persona-theme-zone","artifact-inline"),n.id&&c.setAttribute("data-artifact-inline",n.id);let y=b=>Be(pn(b),t),g=null,S=b=>{g?.destroy(),g=null,c.classList.add("persona-artifact-inline--card"),c.style.removeProperty(Ce),c.replaceChildren(y(b)),de.set(c,T=>{c.replaceChildren(y(T))})};if(f&&n.status==="complete")return S(n),c;let I=Ie(n,{config:t.config,bodyLayout:h,resolveViewMode:()=>p??h.viewMode});g=I;let L=m("div","persona-artifact-inline-body");L.appendChild(I.el);let x=b=>{let T=b.status!=="complete",F=T?h.streamingHeight:h.completeHeight,k=typeof F=="number";k?c.style.setProperty(Ce,`${F}px`):c.style.removeProperty(Ce);let R=!!I.el.querySelector(".persona-code-pre"),w=!!I.el.querySelector("iframe, .persona-artifact-source-window--fixed, .persona-artifact-status-view");L.classList.toggle("persona-artifact-content-flush",R),L.classList.toggle("persona-artifact-inline-body--sized",k&&w),L.classList.toggle("persona-artifact-inline-body--cap",!T&&!w&&typeof h.completeHeight=="number")},P=n.status,$=(b,T)=>{P!=="complete"&&b.status==="complete"?(typeof h.completeHeight=="number"?c.style.setProperty(Ce,`${h.completeHeight}px`):c.style.removeProperty(Ce),xt(L,T?.suppressTransition?"none":h.transition,b.id,()=>{I.update(b),x(b)})):I.update(b),x(b),P=b.status};x(n);let J=h.overflow==="clip"&&i&&!!n.id;if(J&&(L.setAttribute("data-expand-artifact-inline",n.id),L.setAttribute("role","button"),L.setAttribute("tabindex","0"),L.classList.add("persona-cursor-pointer"),L.setAttribute("aria-label",`Open ${St(n).title} in panel`)),!o)return c.appendChild(L),de.set(c,$),c;let re=m("div","persona-artifact-inline-chrome");re.setAttribute("data-persona-theme-zone","artifact-inline-chrome");let Y=m("div","persona-artifact-inline-chrome-lead"),ie=m("span","persona-flex persona-items-center persona-flex-shrink-0"),_=ye(dn,16,"currentColor",2);_&&ie.appendChild(_);let K=m("span","persona-artifact-inline-title persona-truncate persona-min-w-0"),D=m("span","persona-artifact-inline-type");Y.append(ie,K,D);let z=m("div","persona-artifact-inline-chrome-actions"),W=m("span","persona-flex persona-items-center persona-gap-1"),Q=()=>p??h.viewMode,Z=l?Te({items:[{id:"rendered",icon:"eye",label:"Rendered view",className:"persona-artifact-doc-icon-btn persona-artifact-view-btn"},{id:"source",icon:"code-xml",label:"Source",className:"persona-artifact-doc-icon-btn persona-artifact-code-btn"}],selectedId:Q(),className:"persona-artifact-toggle-group persona-flex-shrink-0",onSelect:b=>{let T=b==="source"?"source":"rendered";T!==Q()&&(p=T,I.update(u),x(u))}}):null,d=s?V({icon:"copy",label:"Copy",className:"persona-artifact-doc-icon-btn persona-flex-shrink-0"}):null;d&&n.id&&d.setAttribute("data-copy-artifact",n.id);let M=i?V({icon:"maximize",label:"Open in panel",className:"persona-artifact-doc-icon-btn persona-flex-shrink-0"}):null;M&&n.id&&M.setAttribute("data-expand-artifact-inline",n.id),z.appendChild(W),Z&&z.appendChild(Z.element),d&&z.appendChild(d),M&&z.appendChild(M),re.append(Y,z),c.append(re,L);let O=b=>{let{title:T,typeLabel:F}=St(b);K.textContent=T,K.title=T,J&&L.setAttribute("aria-label",`Open ${T} in panel`);let k=b.status!=="complete";if(k){D.classList.contains("persona-artifact-inline-status")||(D.className="persona-artifact-inline-status",D.removeAttribute("data-preserve-animation"),D.replaceChildren());let R=we(b,r,"inline-chrome");pe(D,R,r)}else he(b.id),D.className="persona-artifact-inline-type",D.removeAttribute("data-preserve-animation"),D.replaceChildren(),D.textContent=F;if(d&&d.classList.toggle("persona-hidden",k),Z){let R=b.artifactType==="markdown"?b.file:void 0,w=!1;if(!k&&R&&h.viewMode!=="source"){let H=fe(R);H==="markdown"?w=!0:(H==="html"||H==="svg")&&(w=r?.filePreview?.enabled!==!1)}Z.element.classList.toggle("persona-hidden",!w),Z.setSelected(Q())}if(W.replaceChildren(),!k&&A.length>0){let R=ve(b);if(R)for(let w of A)try{if(w.visible===void 0||w.visible(R)){let H=be(w,{documentChrome:!0});H.setAttribute("data-artifact-custom-action",w.id),H.classList.add("persona-flex-shrink-0"),W.appendChild(H)}}catch{}}};return O(n),de.set(c,(b,T)=>{if(f&&P!=="complete"&&b.status==="complete"){let F=c.isConnected?c.getBoundingClientRect().height:0;P="complete";let k=b,R=!1,w=H=>{k=H,R=!0};de.set(c,w),wn(c,F,{swap:()=>{S(k),R=!1,de.set(c,w)},onSettled:()=>{R?S(k):de.set(c,H=>{c.replaceChildren(y(H))})}});return}(b.status!=="complete"||b.id!==u.id)&&(p=null),u=b,$(b,T),O(b)}),c}var It=(e,t)=>{let n=t?.config?.features?.artifacts?.renderInline;if(n){let r=typeof e.title=="string"&&e.title?e.title:"Untitled artifact",o=typeof e.artifactId=="string"?e.artifactId:"",s=e.status==="streaming"?"streaming":"complete",i=typeof e.artifactType=="string"?e.artifactType:"markdown",l=n({artifact:{artifactId:o,title:r,artifactType:i,status:s},config:t.config,defaultRenderer:()=>Mt(e,t)});if(l)return l}return Mt(e,t)};export{Be as PersonaArtifactCard,It as PersonaArtifactInline,et as __provideMarkdownParsers,st as __setIconsExtraLoader,He as artifactCopyText,Tt as createArtifactPane,Se as downloadInfoFor,Ht as hasLiveInlineArtifactBlock,vt as initArtifactsUi,Ee as triggerArtifactDownload,Rt as updateInlineArtifactBlocks};
@@ -1,4 +0,0 @@
1
- var c="webmcp:",g=new Map,A=t=>{g.clear();for(let r of t){let e=r.title?.trim();e&&g.set(r.name,e)}},w=t=>g.get(h(t)),u=null;function R(t){if(t.length===0)return"0:empty";let r=t.map(e=>[e.name,e.description??"",e.parametersSchema?JSON.stringify(e.parametersSchema):"",e.origin??"",e.annotations?JSON.stringify(e.annotations):""].join("")).sort();return`${t.length}:${m(r.join(""))}`}function p(t,r){let e=3735928559^r,n=1103547991^r;for(let o=0;o<t.length;o++){let s=t.charCodeAt(o);e=Math.imul(e^s,2654435761),n=Math.imul(n^s,1597334677)}return e=Math.imul(e^e>>>16,2246822507),e^=Math.imul(n^n>>>13,3266489909),n=Math.imul(n^n>>>16,2246822507),n^=Math.imul(e^e>>>13,3266489909),4294967296*(2097151&n)+(e>>>0)}function m(t){let r=p(t,0).toString(36),e=p(t,2654435761).toString(36);return`${r}.${e}`}var h=t=>t.startsWith(c)?t.slice(c.length):t,D=t=>t.startsWith(c),E=()=>u?u():import("@mcp-b/webmcp-polyfill");import{parse as T,STR as y,OBJ as M}from"partial-json";var d=t=>t.replace(/\\n/g,`
2
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"),_=t=>{if(t===null)return"null";if(t===void 0)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t,null,2)}catch{return String(t)}},W=t=>{let r=t.completedAt??Date.now(),e=t.startedAt??r,o=(t.durationMs!==void 0?t.durationMs:Math.max(0,r-e))/1e3;return o<.1?"Thought for <0.1 seconds":`Thought for ${o>=10?Math.round(o).toString():o.toFixed(1).replace(/\.0$/,"")} seconds`},F=t=>t.status==="complete"?W(t):t.status==="pending"?"Waiting":"",P=t=>{let e=(typeof t.duration=="number"?t.duration:typeof t.durationMs=="number"?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now())))/1e3;return e<.1?"Used tool for <0.1 seconds":`Used tool for ${e>=10?Math.round(e).toString():e.toFixed(1).replace(/\.0$/,"")} seconds`};var C=t=>t.status==="complete"?P(t):"Using tool...",x=t=>{let r=t/1e3;return r<.1?"<0.1s":r>=10?`${Math.round(r)}s`:`${r.toFixed(1).replace(/\.0$/,"")}s`},S=t=>{let r=typeof t.duration=="number"?t.duration:typeof t.durationMs=="number"?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now()));return x(r)},$=t=>{let r=t.durationMs!==void 0?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now()));return x(r)},I=(t,r,e)=>{if(!r)return e;let n=t.name?.trim()||"tool",o=S(t);return r.replace(/\{toolName\}/g,n).replace(/\{duration\}/g,o)},N=(t,r)=>{let e=t.replace(/\{toolName\}/g,r),n=[],o=/\*\*(.+?)\*\*|\*(.+?)\*|~(.+?)~/g,s=0,i;for(;(i=o.exec(e))!==null;)i.index>s&&l(n,e.slice(s,i.index),[]),i[1]!==void 0?l(n,i[1],["bold"]):i[2]!==void 0?l(n,i[2],["italic"]):i[3]!==void 0&&l(n,i[3],["dim"]),s=i.index+i[0].length;return s<e.length&&l(n,e.slice(s),[]),n},l=(t,r,e)=>{let n=r.split("{duration}");for(let o=0;o<n.length;o++)n[o]&&t.push({text:n[o],styles:e}),o<n.length-1&&t.push({text:"{duration}",styles:e,isDuration:!0})},b=()=>{let t=null,r=0,e=n=>{let o=/"text"\s*:\s*"((?:[^"\\]|\\.|")*?)"/,s=n.match(o);if(s&&s[1])try{return s[1].replace(/\\n/g,`
3
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}catch{return s[1]}let i=/"text"\s*:\s*"((?:[^"\\]|\\.)*)/,a=n.match(i);if(a&&a[1])try{return a[1].replace(/\\n/g,`
4
- `).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}catch{return a[1]}return null};return{getExtractedText:()=>t,processChunk:async n=>{if(n.length<=r)return t!==null?{text:t,raw:n}:null;let o=n.trim();if(!o.startsWith("{")&&!o.startsWith("["))return null;let s=e(n);return s!==null&&(t=s),r=n.length,t!==null?{text:t,raw:n}:null},close:async()=>{}}},L=t=>{try{let r=JSON.parse(t);if(r&&typeof r=="object"&&typeof r.text=="string")return r.text}catch{return null}return null},O=()=>{let t={processChunk:r=>null,getExtractedText:()=>null};return t.__isPlainTextParser=!0,t},j=()=>{let t=b();return{processChunk:async r=>{let e=r.trim();return!e.startsWith("{")&&!e.startsWith("[")?null:t.processChunk(r)},getExtractedText:t.getExtractedText.bind(t),close:t.close?.bind(t)}},U=()=>{let t=null,r=0;return{getExtractedText:()=>t,processChunk:e=>{let n=e.trim();if(!n.startsWith("{")&&!n.startsWith("["))return null;if(e.length<=r)return t!==null||t===""?{text:t||"",raw:e}:null;try{let o=T(e,y|M);o&&typeof o=="object"&&(o.component&&typeof o.component=="string"?t=typeof o.text=="string"?d(o.text):"":o.type==="init"&&o.form?t="":typeof o.text=="string"&&(t=d(o.text)))}catch{}return r=e.length,t!==null?{text:t,raw:e}:null},close:()=>{}}};var B=()=>{let t=null;return{processChunk:r=>{if(!r.trim().startsWith("<"))return null;let n=r.match(/<text[^>]*>([\s\S]*?)<\/text>/);return n&&n[1]?(t=n[1],{text:t,raw:r}):null},getExtractedText:()=>t}};export{c as a,A as b,w as c,R as d,D as e,E as f,_ as g,F as h,C as i,x as j,S as k,$ as l,I as m,N as n,L as o,O as p,j as q,U as r,B as s};