@runtypelabs/persona 4.28.2 → 4.29.1

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 (145) hide show
  1. package/dist/animations/glyph-cycle.d.cts +1 -1
  2. package/dist/animations/glyph-cycle.d.ts +1 -1
  3. package/dist/animations/wipe.d.cts +1 -1
  4. package/dist/animations/wipe.d.ts +1 -1
  5. package/dist/approval-ui.cjs +3 -3
  6. package/dist/approval-ui.d.cts +1 -1
  7. package/dist/approval-ui.d.ts +1 -1
  8. package/dist/approval-ui.js +3 -3
  9. package/dist/artifacts-ui.d.cts +2 -2
  10. package/dist/artifacts-ui.d.ts +2 -2
  11. package/dist/chunk-B1-_pp-Y.js +4 -0
  12. package/dist/{chunk-DrYAfpvk.js → chunk-BcLIgi1h.js} +1 -1
  13. package/dist/chunk-BkW8s3fj.js +2 -0
  14. package/dist/chunk-Bm2-bemv.js +1 -0
  15. package/dist/chunk-BvhTpG6k.js +1 -0
  16. package/dist/chunk-Csks3Qw1.js +1 -0
  17. package/dist/chunk-D5B629Mj.js +1 -0
  18. package/dist/chunk-DGlFKA0r.js +9 -0
  19. package/dist/chunk-DO9_WSpy.js +1 -0
  20. package/dist/chunk-DTDHeUsG.js +1 -0
  21. package/dist/chunk-DjFpGFGA.js +1 -0
  22. package/dist/{chunk-dRBlrLd7.js → chunk-DtmtfIkd.js} +1 -1
  23. package/dist/chunk-lA5CJCgK.js +1 -0
  24. package/dist/client-history.js +1 -1
  25. package/dist/client-stream.js +1 -1
  26. package/dist/codegen.cjs +1 -1
  27. package/dist/codegen.js +1 -1
  28. package/dist/{composer-input-C39npJaz.d.cts → composer-input-B0P4OtNi.d.cts} +1 -1
  29. package/dist/{composer-input-C39npJaz.d.ts → composer-input-B0P4OtNi.d.ts} +1 -1
  30. package/dist/{context-mention-manager-DLCB1l9E.d.cts → context-mention-manager-DmLI_RM6.d.cts} +1 -1
  31. package/dist/{context-mention-manager-DLCB1l9E.d.ts → context-mention-manager-DmLI_RM6.d.ts} +1 -1
  32. package/dist/context-mentions-inline.d.cts +2 -2
  33. package/dist/context-mentions-inline.d.ts +2 -2
  34. package/dist/context-mentions.d.cts +3 -3
  35. package/dist/context-mentions.d.ts +3 -3
  36. package/dist/{defaults-DiAgWHXy.d.cts → defaults-DVo1wbZs.d.cts} +1 -1
  37. package/dist/{defaults-DiAgWHXy.d.ts → defaults-DVo1wbZs.d.ts} +1 -1
  38. package/dist/event-stream-view.d.cts +1 -1
  39. package/dist/event-stream-view.d.ts +1 -1
  40. package/dist/{fallback-speech-engine-C5_PUZjH.d.cts → fallback-speech-engine-BMnlmKnY.d.cts} +1 -1
  41. package/dist/{fallback-speech-engine-C5_PUZjH.d.ts → fallback-speech-engine-BMnlmKnY.d.ts} +1 -1
  42. package/dist/forms-ui.d.cts +2 -2
  43. package/dist/forms-ui.d.ts +2 -2
  44. package/dist/history-view.d.cts +1 -1
  45. package/dist/history-view.d.ts +1 -1
  46. package/dist/index.cjs +50 -49
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +7 -7
  49. package/dist/index.d.ts +7 -7
  50. package/dist/index.global.js +2 -3
  51. package/dist/index.global.js.map +1 -1
  52. package/dist/index.js +38 -37
  53. package/dist/index.js.map +1 -1
  54. package/dist/{markdown-parsers-loader-BBdyIEU7.d.cts → markdown-parsers-loader-CeovcyYf.d.cts} +1 -1
  55. package/dist/{markdown-parsers-loader-BBdyIEU7.d.ts → markdown-parsers-loader-CeovcyYf.d.ts} +1 -1
  56. package/dist/{preview-Chjb0bmI.d.cts → preview-Bkb4UrQC.d.cts} +2 -2
  57. package/dist/{preview-Chjb0bmI.d.ts → preview-Bkb4UrQC.d.ts} +2 -2
  58. package/dist/session-actions.js +1 -1
  59. package/dist/{session-a_qIp4xp.d.ts → session-iLyKipoM.d.cts} +28 -10
  60. package/dist/{session-a_qIp4xp.d.cts → session-iLyKipoM.d.ts} +28 -10
  61. package/dist/session-reconnect.cjs +1 -1
  62. package/dist/session-reconnect.d.cts +8 -2
  63. package/dist/session-reconnect.d.ts +8 -2
  64. package/dist/session-reconnect.js +1 -1
  65. package/dist/smart-dom-reader.d.cts +1 -1
  66. package/dist/smart-dom-reader.d.ts +1 -1
  67. package/dist/theme-editor-preview.cjs +61 -60
  68. package/dist/theme-editor-preview.d.cts +1 -1
  69. package/dist/theme-editor-preview.d.ts +1 -1
  70. package/dist/theme-editor-preview.js +40 -40
  71. package/dist/theme-editor.d.cts +2 -2
  72. package/dist/theme-editor.d.ts +2 -2
  73. package/dist/theme-reference.d.cts +2 -2
  74. package/dist/theme-reference.d.ts +2 -2
  75. package/dist/{types-BdO1jNRm.d.cts → types-BuDirJkQ.d.cts} +200 -23
  76. package/dist/{types-BdO1jNRm.d.ts → types-BuDirJkQ.d.ts} +200 -23
  77. package/dist/voice-client-tools.cjs +1 -0
  78. package/dist/voice-client-tools.d.cts +13 -0
  79. package/dist/voice-client-tools.d.ts +13 -0
  80. package/dist/voice-client-tools.js +1 -0
  81. package/dist/voice-runtime.cjs +3 -3
  82. package/dist/voice-runtime.d.cts +15 -5
  83. package/dist/voice-runtime.d.ts +15 -5
  84. package/dist/voice-runtime.js +5 -5
  85. package/dist/voice-worklet-player.d.cts +2 -2
  86. package/dist/voice-worklet-player.d.ts +2 -2
  87. package/dist/{webmcp-runtime-entry-B6bpVWSa.d.ts → webmcp-runtime-entry-CXLjRt1k.d.cts} +26 -5
  88. package/dist/{webmcp-runtime-entry-B6bpVWSa.d.cts → webmcp-runtime-entry-CXLjRt1k.d.ts} +26 -5
  89. package/dist/webmcp-runtime.cjs +2 -1
  90. package/dist/webmcp-runtime.d.cts +1 -1
  91. package/dist/webmcp-runtime.d.ts +1 -1
  92. package/dist/webmcp-runtime.js +2 -1
  93. package/dist/widget.css +1 -1
  94. package/package.json +6 -1
  95. package/src/client-approve.test.ts +17 -1
  96. package/src/client-resume.ts +15 -3
  97. package/src/client.interrupt.test.ts +21 -0
  98. package/src/client.ts +61 -4
  99. package/src/client.voice-tools.test.ts +65 -0
  100. package/src/components/activity-row.ts +3 -2
  101. package/src/components/approval-actions.test.ts +8 -0
  102. package/src/components/approval-actions.ts +6 -2
  103. package/src/components/approval-bubble.test.ts +14 -0
  104. package/src/components/approval-bubble.ts +8 -1
  105. package/src/components/tool-bubble.ts +8 -5
  106. package/src/generated/runtype-openapi-contract.ts +39 -1
  107. package/src/index-core.ts +11 -0
  108. package/src/index-global.ts +6 -0
  109. package/src/resume-dedupe-local-only.test.ts +273 -0
  110. package/src/runtime/persist-state.test.ts +86 -0
  111. package/src/session-actions.ts +20 -6
  112. package/src/session-reconnect.ts +18 -1
  113. package/src/session.restored-browser-tools.test.ts +272 -0
  114. package/src/session.test.ts +26 -0
  115. package/src/session.ts +185 -31
  116. package/src/session.voice.test.ts +212 -0
  117. package/src/styles/widget.css +4 -2
  118. package/src/types.ts +178 -22
  119. package/src/ui.restored-browser-tools.test.ts +128 -0
  120. package/src/ui.ts +32 -18
  121. package/src/utils/formatting.test.ts +9 -1
  122. package/src/utils/formatting.ts +4 -0
  123. package/src/utils/local-only-message.ts +15 -0
  124. package/src/utils/restored-browser-state.ts +50 -0
  125. package/src/utils/storage.ts +12 -1
  126. package/src/utils/voice-prior-tool-results.ts +37 -0
  127. package/src/voice/runtype-voice-provider.ts +94 -7
  128. package/src/voice/session-voice-wiring.ts +27 -3
  129. package/src/voice/voice-client-tools-session.ts +116 -0
  130. package/src/voice/voice-delegation.ts +19 -3
  131. package/src/voice/voice.test.ts +396 -0
  132. package/src/voice-client-tools-bundle.test.ts +37 -0
  133. package/src/voice-client-tools-loader.ts +24 -0
  134. package/src/voice-client-tools.ts +9 -0
  135. package/src/webmcp-bridge.test.ts +152 -1
  136. package/src/webmcp-bridge.ts +5 -6
  137. package/src/webmcp-polyfill.integration.test.ts +5 -1
  138. package/src/webmcp-runtime-entry.ts +151 -26
  139. package/dist/chunk-B6zZsT6F.js +0 -1
  140. package/dist/chunk-CztSjKHK.js +0 -9
  141. package/dist/chunk-DbhxjyOB.js +0 -4
  142. package/dist/chunk-DsdqLStH.js +0 -1
  143. package/dist/chunk-GIqbL2Eg.js +0 -1
  144. package/dist/chunk-HUOUif-P.js +0 -1
  145. package/dist/chunk-UlcxdHef.js +0 -1
@@ -25,8 +25,10 @@
25
25
  * not replace an existing context. v5's initializeWebMCPPolyfill() and v6's
26
26
  * installWebMCP() are both accepted by custom loaders.
27
27
  *
28
- * Every call passes one confirm gate before execution, regardless of
29
- * annotations.readOnlyHint. v6 callbacks also receive an invocation signal.
28
+ * Every chat-path call passes one confirm gate before execution, regardless of
29
+ * annotations.readOnlyHint. The one exception is a voice fast-tier
30
+ * `client_tool_call`, which skips the gate only for a tool whose registry entry
31
+ * declares `readOnlyHint: true`. v6 callbacks also receive an invocation signal.
30
32
  */
31
33
 
32
34
  import type { ClientToolDefinition } from "./types";
@@ -74,10 +76,7 @@ export interface ModelContextToolInfo {
74
76
  * absent on v4 and whenever the tool declared none -- the spec omits the
75
77
  * member rather than emitting an empty object.
76
78
  */
77
- annotations?: {
78
- readOnlyHint?: boolean;
79
- untrustedContentHint?: boolean;
80
- };
79
+ annotations?: ClientToolDefinition["annotations"];
81
80
  }
82
81
 
83
82
  export interface ModelContextCoreLike {
@@ -129,7 +129,11 @@ describe.each([
129
129
  type: "object",
130
130
  properties: { query: { type: "string" } },
131
131
  },
132
- annotations: { readOnlyHint: true, untrustedContentHint: true },
132
+ annotations: {
133
+ readOnlyHint: true,
134
+ untrustedContentHint: true,
135
+ ...(legacy ? {} : { consequentialHint: false, debugging: false }),
136
+ },
133
137
  untrustedContentHint: true,
134
138
  }),
135
139
  ]);
@@ -16,6 +16,7 @@
16
16
  import type {
17
17
  AgentWidgetWebMcpConfig,
18
18
  ClientToolDefinition,
19
+ VoiceClientToolOutcome,
19
20
  WebMcpConfirmHandler,
20
21
  WebMcpConfirmInfo,
21
22
  WebMcpToolResult,
@@ -38,6 +39,22 @@ export interface WebMcpBridgeDeps {
38
39
 
39
40
  const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
40
41
 
42
+ /**
43
+ * One run of a page tool, before it is shaped for `/resume` (`executeToolCall`)
44
+ * or for a voice `client_tool_result` (`executeVoiceToolCall`). `message` is
45
+ * the exact text the `/resume` error result has always carried.
46
+ */
47
+ type ToolRunFailureReason = "stale" | "denied" | "failed" | "timeout" | "aborted";
48
+ type ToolRunOutcome =
49
+ | { ok: true; raw: string | null }
50
+ | { ok: false; reason: ToolRunFailureReason; message: string };
51
+
52
+ const runFailure = (reason: ToolRunFailureReason, message: string): ToolRunOutcome => ({
53
+ ok: false,
54
+ reason,
55
+ message,
56
+ });
57
+
41
58
  // Local copies of the wire-prefix helpers: pure, and duplicating them keeps
42
59
  // this chunk free of any value edge into core webmcp-bridge state.
43
60
  const WEBMCP_TOOL_PREFIX = "webmcp:";
@@ -177,11 +194,77 @@ export class WebMcpBridge {
177
194
  args: unknown,
178
195
  signal?: AbortSignal,
179
196
  ): Promise<WebMcpToolResult> {
197
+ const outcome = await this.#run(wireToolName, args, signal, false);
198
+ return outcome.ok
199
+ ? normalizeSerializedResult(outcome.raw)
200
+ : errorResult(outcome.message);
201
+ }
202
+
203
+ /**
204
+ * Execute a page tool the voice server picked for a delegation
205
+ * (`client_tool_call`) and return its `client_tool_result` outcome.
206
+ *
207
+ * Same registry lookup, allowlist, abort points and timeout as
208
+ * `executeToolCall`, with one difference: when `autoConfirmReadOnly` is set,
209
+ * a tool whose LIVE registry entry declares `annotations.readOnlyHint ===
210
+ * true` skips the confirm gate. Every other tool still shows it, and a
211
+ * decline answers `denied`. A tool missing from the registry or excluded by
212
+ * the allowlist answers `stale` (the server's snapshot is out of date).
213
+ * `signal` aborting (the caller's deadline, a hang-up) answers `failed`;
214
+ * the caller decides whether that was its timeout.
215
+ */
216
+ public async executeVoiceToolCall(
217
+ wireToolName: string,
218
+ args: unknown,
219
+ options: { signal?: AbortSignal; autoConfirmReadOnly?: boolean } = {},
220
+ ): Promise<VoiceClientToolOutcome> {
221
+ const outcome = await this.#run(
222
+ wireToolName,
223
+ args,
224
+ options.signal,
225
+ options.autoConfirmReadOnly === true,
226
+ );
227
+ if (!outcome.ok) {
228
+ return {
229
+ status: outcome.reason === "aborted" ? "failed" : outcome.reason,
230
+ error: { message: outcome.message },
231
+ };
232
+ }
233
+ return voiceOutcomeFromRaw(outcome.raw);
234
+ }
235
+
236
+ /**
237
+ * Call `listener` whenever the page's tool registry changes (the WebMCP
238
+ * `toolchange` event on `document.modelContext`). Returns an unsubscribe.
239
+ * A registry without the event never calls it: callers then keep the
240
+ * snapshot they took first.
241
+ */
242
+ public watchToolChanges(listener: () => void): () => void {
243
+ let stopped = false;
244
+ let target: EventTarget | null = null;
245
+ void this.#ensureReady().then(() => {
246
+ if (stopped || this.config.enabled !== true) return;
247
+ const mc = this.#getModelContext() as unknown as Partial<EventTarget> | null;
248
+ if (!mc || typeof mc.addEventListener !== "function") return;
249
+ target = mc as EventTarget;
250
+ target.addEventListener("toolchange", listener);
251
+ });
252
+ return () => {
253
+ stopped = true;
254
+ target?.removeEventListener("toolchange", listener);
255
+ target = null;
256
+ };
257
+ }
258
+
259
+ async #run(
260
+ wireToolName: string,
261
+ args: unknown,
262
+ signal: AbortSignal | undefined,
263
+ autoConfirmReadOnly: boolean,
264
+ ): Promise<ToolRunOutcome> {
180
265
  await this.#ensureReady();
181
266
  if (this.config.enabled !== true) {
182
- return errorResult(
183
- "WebMCP is not enabled on this widget.",
184
- );
267
+ return runFailure("failed", "WebMCP is not enabled on this widget.");
185
268
  }
186
269
 
187
270
  const mc = this.#getModelContext();
@@ -193,7 +276,8 @@ export class WebMcpBridge {
193
276
  const present =
194
277
  typeof document !== "undefined" &&
195
278
  Boolean((document as Document & { modelContext?: unknown }).modelContext);
196
- return errorResult(
279
+ return runFailure(
280
+ "failed",
197
281
  present
198
282
  ? "WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill)."
199
283
  : "WebMCP bridge is not operational on this page (document.modelContext not available).",
@@ -207,13 +291,14 @@ export class WebMcpBridge {
207
291
  infos = (await mc.getTools()).filter(isLocalTool);
208
292
  } catch (err) {
209
293
  const message = err instanceof Error ? err.message : String(err);
210
- return errorResult(`Failed to read WebMCP registry: ${message}`);
294
+ return runFailure("failed", `Failed to read WebMCP registry: ${message}`);
211
295
  }
212
296
  this.#deps.recordToolDisplayTitles(infos);
213
297
  const info = infos.find((candidate) => candidate.name === bareName);
214
298
 
215
299
  if (!info) {
216
- return errorResult(
300
+ return runFailure(
301
+ "stale",
217
302
  `WebMCP tool not registered on this page: ${bareName}`,
218
303
  );
219
304
  }
@@ -225,7 +310,8 @@ export class WebMcpBridge {
225
310
  // tool. The server is the trust boundary; this is a defense-in-depth
226
311
  // convenience check to keep us symmetric with the snapshot.
227
312
  if (!this.#passesClientAllowlist(bareName)) {
228
- return errorResult(
313
+ return runFailure(
314
+ "stale",
229
315
  `WebMCP tool not allowed by client allowlist: ${bareName}`,
230
316
  );
231
317
  }
@@ -233,28 +319,33 @@ export class WebMcpBridge {
233
319
  // Bail before the confirm renders: a late approval after cancel() would
234
320
  // otherwise fire a host-page side effect with no matching /resume.
235
321
  if (signal?.aborted) {
236
- return errorResult("Aborted by cancel()");
322
+ return runFailure("aborted", "Aborted by cancel()");
237
323
  }
238
324
 
239
- // Confirm-by-default gate. Every `webmcp:*` call routes through here,
240
- // regardless of `annotations.readOnlyHint`.
325
+ // Confirm-by-default gate. Every chat-path `webmcp:*` call routes through
326
+ // here regardless of `annotations.readOnlyHint`; only a voice fast-tier
327
+ // call (`autoConfirmReadOnly`) of a tool the registry marks read-only skips it.
241
328
  const displayTitle = this.#deps.getToolDisplayTitle(bareName);
329
+ const annotations = pickAnnotations(info.annotations);
242
330
  const gateInfo: WebMcpConfirmInfo = {
243
331
  toolName: bareName,
244
332
  args,
245
333
  description: info.description,
334
+ ...(annotations ? { annotations } : {}),
246
335
  ...(displayTitle ? { title: displayTitle } : {}),
336
+ ...(signal ? { signal } : {}),
247
337
  reason: "gate",
248
338
  };
249
- if (!(await this.#requestConfirm(gateInfo))) {
250
- return errorResult("User declined the tool call.");
339
+ const skipGate = autoConfirmReadOnly && annotations?.readOnlyHint === true;
340
+ if (!skipGate && !(await this.#requestConfirm(gateInfo))) {
341
+ return runFailure("denied", "User declined the tool call.");
251
342
  }
252
343
 
253
344
  // The await above may have parked us long enough for cancel() to fire.
254
345
  // Bail before invoking `execute()` so we don't fire a side effect that
255
346
  // the server can no longer accept a `/resume` for.
256
347
  if (signal?.aborted) {
257
- return errorResult("Aborted by cancel()");
348
+ return runFailure("aborted", "Aborted by cancel()");
258
349
  }
259
350
 
260
351
  // Drive both the 30s timeout and the caller's `signal` through a single
@@ -278,18 +369,19 @@ export class WebMcpBridge {
278
369
  const raw = await mc.executeTool(info, createCompatibleToolInput(args), {
279
370
  signal: controller.signal,
280
371
  });
281
- return normalizeSerializedResult(raw);
372
+ return { ok: true, raw };
282
373
  } catch (err) {
283
374
  if (timedOut) {
284
- return errorResult(
375
+ return runFailure(
376
+ "timeout",
285
377
  `WebMCP tool '${bareName}' timed out after ${this.#timeoutMs}ms`,
286
378
  );
287
379
  }
288
380
  if (signal?.aborted) {
289
- return errorResult("Aborted by cancel()");
381
+ return runFailure("aborted", "Aborted by cancel()");
290
382
  }
291
383
  const message = err instanceof Error ? err.message : String(err);
292
- return errorResult(message);
384
+ return runFailure("failed", message);
293
385
  } finally {
294
386
  clearTimeout(timer);
295
387
  if (signal) signal.removeEventListener("abort", onAbort);
@@ -442,7 +534,7 @@ const EMPTY_INPUT_SCHEMA = { type: "object", properties: {} } as const;
442
534
  * Copy the WebMCP annotation hints onto the wire, dropping anything else.
443
535
  *
444
536
  * `getTools()` returns `annotations` since `@mcp-b/webmcp-polyfill` v5 (absent
445
- * on v4 and when the tool declared none). Only the spec's two boolean hints are
537
+ * on v4 and when the tool declared none). Only supported boolean hints are
446
538
  * forwarded -- annotations are page-authored, so an explicit copy keeps
447
539
  * functions/junk off the dispatch payload. Returns `undefined` when nothing
448
540
  * usable remains so the member is omitted, matching the spec's own
@@ -452,14 +544,14 @@ const pickAnnotations = (
452
544
  raw: ModelContextToolInfo["annotations"],
453
545
  ): ClientToolDefinition["annotations"] | undefined => {
454
546
  if (!raw || typeof raw !== "object") return undefined;
455
- const picked = {
456
- ...(typeof raw.readOnlyHint === "boolean"
457
- ? { readOnlyHint: raw.readOnlyHint }
458
- : {}),
459
- ...(typeof raw.untrustedContentHint === "boolean"
460
- ? { untrustedContentHint: raw.untrustedContentHint }
461
- : {}),
462
- };
547
+ const picked: NonNullable<ClientToolDefinition["annotations"]> = {};
548
+ for (const key of [
549
+ "readOnlyHint", "destructiveHint", "consequentialHint", "untrustedContentHint",
550
+ "idempotentHint", "openWorldHint", "debugging",
551
+ ] as const) {
552
+ const value = raw[key];
553
+ if (typeof value === "boolean") picked[key] = value;
554
+ }
463
555
  return Object.keys(picked).length > 0 ? picked : undefined;
464
556
  };
465
557
 
@@ -544,6 +636,39 @@ const errorResult = (message: string): WebMcpToolResult => ({
544
636
  content: [{ type: "text", text: message }],
545
637
  });
546
638
 
639
+ const textOfContent = (content: unknown): string =>
640
+ Array.isArray(content)
641
+ ? content
642
+ .map((block: unknown) =>
643
+ block && typeof block === "object" && typeof (block as { text?: unknown }).text === "string"
644
+ ? (block as { text: string }).text
645
+ : "",
646
+ )
647
+ .filter(Boolean)
648
+ .join("\n")
649
+ : "";
650
+
651
+ /**
652
+ * A page tool's serialized return as a voice `client_tool_result`: the tool's
653
+ * own JSON value (not the MCP content wrapper `/resume` gets), so the server
654
+ * can template a readout from its fields. A tool that returned an MCP error
655
+ * (`isError: true`) is `failed`, with its text as the message.
656
+ */
657
+ const voiceOutcomeFromRaw = (raw: string | null): VoiceClientToolOutcome => {
658
+ if (raw === null || raw === undefined) return { status: "completed" };
659
+ let parsed: unknown;
660
+ try {
661
+ parsed = JSON.parse(raw);
662
+ } catch {
663
+ return { status: "completed", result: raw };
664
+ }
665
+ if (parsed !== null && typeof parsed === "object" && (parsed as { isError?: unknown }).isError === true) {
666
+ const message = textOfContent((parsed as { content?: unknown }).content);
667
+ return { status: "failed", error: { message: message || "The page tool reported an error." } };
668
+ }
669
+ return parsed === undefined ? { status: "completed" } : { status: "completed", result: parsed };
670
+ };
671
+
547
672
  /**
548
673
  * Fallback confirm UI: `window.confirm()`. Production deployments should wire
549
674
  * `config.webmcp.onConfirm` to a handler matched to their UX (e.g. an inline
@@ -1 +0,0 @@
1
- const e=[1e3,2e3,4e3,8e3,8e3];function t(t){let n=0,r=null,i=null,a=!1,o=()=>{if(i&&=(clearTimeout(i),null),r){let e=r;r=null,e()}},s=()=>{let e=t.getStatus();(e===`resuming`||e===`paused`)&&o()},c=()=>{(typeof document>`u`||document.visibilityState!==`hidden`)&&s()},l=()=>{s()},u=()=>{a||=(typeof document<`u`&&document.addEventListener(`visibilitychange`,c),typeof window<`u`&&window.addEventListener(`online`,l),!0)},d=()=>{a&&=(typeof document<`u`&&document.removeEventListener(`visibilitychange`,c),typeof window<`u`&&window.removeEventListener(`online`,l),!1)},f=e=>new Promise(t=>{r=t,i=setTimeout(()=>{i=null,r=null,t()},e)}),p=()=>{let e=t.getResumable();t.clearResumable(),t.setReconnecting(!1),n=0,d(),t.setAbortController(null);let r=!1;for(let e of t.getMessages())e.streaming&&(e.streaming=!1,r=!0);let i=t.buildErrorContent(`Connection lost and the response could not be resumed.`);i?t.appendMessage({id:`reconnect-failed-${e?.executionId??t.nextSequence()}`,role:`assistant`,content:i,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:t.nextSequence()}):r&&t.notifyMessagesChanged(),t.setStreaming(!1),t.setStatus(`idle`),t.onError(/* @__PURE__ */ Error(`Durable session reconnect failed.`))},m=async()=>{let r=t.config.reconnect?.backoffMs??e,i=t.config.reconnect?.maxAttempts??r.length,a=t.config.reconnectStream;if(!a)t.setReconnecting(!1);else{for(;t.getResumable()&&n<i;){n+=1,t.setStatus(`resuming`);let e=t.getResumable(),o=e.lastEventId,s=new AbortController;t.setAbortController(s),t.emitReconnect({phase:`resuming`,handle:e,attempt:n});let c=null;try{let t=await a({executionId:e.executionId,after:e.lastEventId,signal:s.signal});t&&t.ok&&t.body&&(c=t.body)}catch{c=null}if(s.signal.aborted)return;if(c){let r=t.getMessages().find(t=>t.id===e.assistantMessageId)?.content,i=typeof r==`string`?r:``;try{await t.resumeConnect(c,e.assistantMessageId,i)}catch{}if(s.signal.aborted)return;if(!t.getResumable()){t.setReconnecting(!1),n=0,d(),t.emitReconnect({phase:`resumed`,handle:e});return}t.getResumable().lastEventId!==o&&(n=0)}if(t.getResumable()&&n<i&&(t.setStatus(`paused`),await f(r[Math.min(n-1,r.length-1)]??1e3),s.signal.aborted))return}t.getResumable()&&p()}};return{begin(){n=0,u(),m()},teardown(){i&&=(clearTimeout(i),null),r=null,n=0,d()},wake:o}}export{t as createReconnectController};
@@ -1,9 +0,0 @@
1
- import{t as e}from"./chunk-UlcxdHef.js";import{t}from"./chunk-DqbzUVEI.js";const n=16e3,r=/* @__PURE__ */ new Map([[`idle_timeout`,`Voice call ended after a quiet period.`],[`max_duration`,`This voice call reached its time limit.`],[`provider_ended`,`The voice session ended.`],[`quota`,`Voice is unavailable right now.`],[`auth_expired`,`Voice session expired. Tap the mic to reconnect.`]]),i=[`provider_error`,`server_restart`],a=`Voice connection lost.`;function o(e,t){let n=t.slice(0,4e3).trim(),r=8e3-(n?n.length+2:0)-20,i=[];for(let t of e.slice(-12).reverse()){let e=t.content.replace(/\s+/g,` `).trim();if(!e)continue;e.length>2e3&&(e=`${e.slice(0,1999)}…`);let n=`${t.role===`user`?`User`:`Assistant`}: ${e}`;if(n.length+1>r)break;r-=n.length+1,i.unshift(n)}let a=i.length>0?[`Conversation so far:\n${i.join(`
2
- `)}`]:[];return n&&a.push(n),a.join(`
3
-
4
- `)}function s(e){return e.byteLength>=44&&new DataView(e).getUint32(0,!1)===1380533830?new Uint8Array(e,44):new Uint8Array(e)}function c(e){let t=e.replace(/\/+$/,``);return/^wss?:\/\//i.test(t)?t:/^https?:\/\//i.test(t)?t.replace(/^http/i,`ws`):`${typeof window<`u`&&window.location?.protocol===`https:`?`wss:`:`ws:`}//${t}`}function l(e){return c(e).replace(/^ws/i,`http`)}function u(e){return typeof e!=`number`||!Number.isFinite(e)?3e4:Math.min(6e5,Math.max(3e4,Math.round(e)))}var d=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x;#S;#C;#w;#T;#E;#D;#O;#k;#A;#j;#M;#N;#P;#F;#I;#L;#R;#z;#B;#V;#H;#U;#W;#G;constructor(e){this.config=e,this.type=`runtype`,this.#e=null,this.#t=null,this.#n=[],this.#r=null,this.#i=null,this.#a=null,this.#o=[],this.#s=0,this.#c=null,this.#l=!1,this.#u=!1,this.#d=0,this.#f=!1,this.#p=-1/0,this.#m=null,this.#h=!1,this.#g=!1,this.#_=0,this.#v=0,this.#b=!1,this.bridge=null,this.#x=!1,this.#S=/* @__PURE__ */ new Set,this.#C=/* @__PURE__ */ new Map,this.#w=/* @__PURE__ */ new Set,this.#E=null,this.#D=null,this.#k=!1,this.#A=!1,this.#j=!1,this.#M=null,this.#N=null,this.#P=Promise.resolve(),this.#F=/* @__PURE__ */ new Set,this.#I=/* @__PURE__ */ new Set,this.#L=null,this.#R=!1,this.#z=/* @__PURE__ */ new Set,this.#B=/* @__PURE__ */ new Set,this.#V=[],this.#H=[],this.#U=[],this.#W=[],this.#G=[]}async connect(){}setSessionBridge(e){this.bridge=e}prewarm(){if(this.#l||this.#m)return;let e=this.config?.agentId,t=this.config?.clientToken,n=this.config?.host;if(!e||!t||!n)return;let r=Date.now();if(!(r-this.#p<3e4)){this.#p=r;try{this.config?.prewarmMode===`attach`?this.#q(n,e,t):this.#K(n,e,t)}catch{}}}#K(e,t,n){if(typeof fetch!=`function`)return;let r=`${l(e)}/v1/client/agents/${encodeURIComponent(t)}/voice/prewarm`;fetch(r,{method:`POST`,headers:{Authorization:`Bearer ${n}`},keepalive:!0}).catch(()=>{})}#q(e,t,n){let r=new URLSearchParams,i=this.config?.attachIdleMs,a=u(i);i!==void 0&&r.set(`attachIdleMs`,String(a));let o=new WebSocket(this.#Z(e,t,r),[`runtype.bearer`,`runtype.attach`,n]);o.binaryType=`arraybuffer`;let s=()=>{},c={ws:o,state:`connecting`,ready:new Promise(e=>{s=e}),settle:s,openedAt:0,idleTimer:void 0};this.#m=c,o.onopen=()=>{this.#m===c&&(c.state=o.protocol===`runtype.attach`?`attached`:`live`,c.openedAt=Date.now(),this.#J(c,a),c.state===`attached`&&o.send(`{"type":"ping"}`),c.settle())},o.onmessage=e=>{if(this.#m!==c||typeof e.data!=`string`)return;let t;try{t=JSON.parse(e.data)}catch{return}t.type===`attached`&&typeof t.idleMs==`number`&&this.#J(c,t.idleMs-(Date.now()-c.openedAt))},o.onerror=()=>{},o.onclose=()=>{this.#m===c&&this.#Y()}}#J(e,t){clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{this.#m===e&&this.#Y()},Math.max(0,t))}#Y(){let e=this.#m;if(!e)return;this.#m=null,clearTimeout(e.idleTimer);let{ws:t}=e;if(t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,e.settle(),t.readyState===WebSocket.CONNECTING||t.readyState===WebSocket.OPEN)try{t.close(1e3,`prewarm released`)}catch{}}async#X(){let e=this.#m;if(!e)return null;if(e.state===`connecting`){let t;await Promise.race([e.ready,new Promise(e=>{t=setTimeout(e,5e3)})]),clearTimeout(t)}return this.#m===e?e.state===`connecting`||e.ws.readyState!==WebSocket.OPEN?(this.#Y(),null):(this.#m=null,clearTimeout(e.idleTimer),{ws:e.ws,live:e.state===`live`}):null}#Z(t,n,r){let i=[`partial_transcript`,`context`];this.bridge&&this.config?.clientDelegation!==!1&&i.push(`client_delegation`,`delegation_update`,`delegation_read_back`,`delegation_stream`),r&&i.unshift(`attach`);let a=new URLSearchParams({voiceProtocol:`runtype-browser-v1`,clientVersion:`persona/${e}`,voiceCapabilities:`full-duplex-v1`,clientCapabilities:i.join(`,`)});return r?.forEach((e,t)=>a.set(t,e)),`${c(t)}/ws/agents/${encodeURIComponent(n)}/voice?${a}`}async startListening(){if(this.#l)return;let e=this.#A;e||(this.#k=!1,this.#D=null),this.#A=!1;let r=this.config?.agentId,i=this.config?.clientToken,o=this.config?.host;if(!r)throw Error(`Runtype voice requires an agentId`);if(!i)throw Error(`Runtype voice requires a clientToken`);if(!o)throw Error(`Runtype voice requires a host (or widget apiUrl)`);let s=++this.#d;this.#f=!1,this.#l=!0;try{let c=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:n,channelCount:1,echoCancellation:!0}});if(s!==this.#d){c.getTracks().forEach(e=>e.stop());return}this.#r=c;let l=new(window.AudioContext||window.webkitAudioContext)({sampleRate:n});if(this.#t=l,l.state===`suspended`){if(await Promise.race([l.resume().catch(()=>{}),new Promise(t=>setTimeout(t,e?500:1e3))]),s!==this.#d)return;if(l.state!==`running`)throw Error(e?this.#D=`${a} Tap the mic to reconnect.`:`Audio blocked until a tap`)}let u=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new t(24e3);if(s!==this.#d){u.destroy(),c.getTracks().forEach(e=>e.stop()),l.close().catch(()=>{});return}this.#c=u,this.#de(),this.#ee(l,c,s);let d=await this.#X();if(s!==this.#d){d?.ws.close(1e3,`client ended call`);return}if(d){let{ws:e}=d;this.#e=e,this.#Q(e,s),d.live||e.send(`{"type":"start"}`),this.#te(e),this.#ge(`listening`);return}let f=new WebSocket(this.#Z(o,r),[`runtype.bearer`,i]);f.binaryType=`arraybuffer`,this.#e=f,f.onopen=()=>{s===this.#d&&(this.#te(f),this.#ge(`listening`))},this.#Q(f,s)}catch(e){throw this.#he(),this.#_e(e),this.#ge(`error`),e}}#Q(e,t){e.onmessage=e=>this.#ne(e,t),e.onerror=()=>{t!==this.#d||this.#E||(this.#_e(/* @__PURE__ */ Error(`Voice connection failed`)),this.#ge(`error`),this.#he())},e.onclose=e=>{if(this.#f){this.#f=!1;return}if(t!==this.#d)return;let n=this.#E??(e.code===4408?{reason:`idle_timeout`}:null);if(n)this.#$(n.reason,n.message);else{if(e.code!==1e3){let t=e.code?` (code ${e.code})`:``;this.#_e(/* @__PURE__ */ Error(`Voice connection closed${t}`)),this.#ge(`error`)}else this.#ge(`idle`);this.#he()}}}#$(e,t){let n=i.includes(e)&&!this.#k;if(this.#he(),n)this.#k=!0,this.#l=!0,this.#D=e===`provider_error`?`${a} Reconnecting…`:`Reconnecting…`,this.#O=setTimeout(()=>{this.#l=!1,this.#A=!0,this.startListening().catch(()=>{})},1e3+Math.random()*1e3),this.#ge(`idle`);else{if(i.includes(e))return this.#D=a,this.#_e(/* @__PURE__ */ Error(a)),this.#ge(`error`);if(e===`error`)return this.#ge(`error`);this.#D=e===`quota`&&t||r.get(e)||null,this.#ge(`idle`)}}takeNotice(){let e=this.#D;return this.#D=null,e}getDisclosure(){let e=this.config?.disclosureText;return this.#l&&this.#h&&e!==!1?e||`You're talking to an AI assistant. Voice is processed by OpenAI.`:null}async stopListening(){this.#he(),this.#ge(`idle`)}async disconnect(){this.#he(),this.#ge(`disconnected`),this.#V=[],this.#H=[],this.#U=[],this.#W=[],this.#G=[]}stopPlayback(){this.#me();let e=this.#e;e&&e.readyState===WebSocket.OPEN&&(this.#h&&(this.#_=Date.now()+2e3,e.send(`{"type":"cancel"}`)),this.#ge(`listening`))}getInterruptionMode(){return`barge-in`}isBargeInActive(){return this.#l}onLevel(e){this.#n.push(e)}async deactivateBargeIn(){this.#he(),this.#ge(`idle`)}#ee(e,t,n){let r=e.createMediaStreamSource(t);this.#i=r;let i=e.createScriptProcessor(4096,1,1);this.#a=i,i.onaudioprocess=e=>{if(n!==this.#d)return;let t=this.#e,r=t?.readyState===WebSocket.OPEN;if(t&&!r&&t.readyState!==WebSocket.CONNECTING)return;let i=e.inputBuffer.getChannelData(0),a=new Int16Array(i.length),o=0;for(let e=0;e<i.length;e++){let t=Math.max(-1,Math.min(1,i[e]));o+=t*t,a[e]=t<0?t*32768:t*32767}if(t&&r)this.#te(t),t.send(a.buffer);else for(this.#o.push(a.buffer),this.#s+=a.byteLength;this.#s>256e3;)this.#s-=this.#o.shift().byteLength;if(this.#n.length>0){let e=Math.sqrt(o/i.length),t=Math.max(0,Math.min(1,e*4));for(let e of this.#n)e(t)}},r.connect(i),i.connect(e.destination)}#te(e){for(let t of this.#o)e.send(t);this.#o=[],this.#s=0}#ne(e,t){if(t!==this.#d)return;if(e.data instanceof ArrayBuffer){this.#le(e.data,t);return}let n;try{n=JSON.parse(e.data)}catch{return}switch(n.type){case`session_config`:n.speechMode&&(this.#h=n.speechMode===`speech_to_speech`,this.#c?.setContinuousMode?.(this.#h)),Array.isArray(n.capabilities)&&(this.#S=new Set(n.capabilities)),typeof n.callId==`string`&&(this.#T=n.callId),this.#x=this.#h&&this.#S.has(`client_delegation`)&&!!this.bridge,this.#h&&!this.#u&&this.#ge(`listening`),this.#S.has(`context`)&&!this.#j&&(this.#j=!0,this.#M=this.#re());break;case`transcript_update`:{let e=n.role===`assistant`?`assistant`:`user`,r=n.utteranceId??n.turnId;if(!r||e===`assistant`&&this.#ue())break;let i=String(r);if(e===`user`)n.final===!0&&this.#ie(t),this.#R=!1;else{if(this.#S.has(`delegation_read_back`)){let e=n.delegationId;(typeof e==`string`&&this.#F.has(e)&&!this.#z.has(i)||this.#R&&!this.#z.has(i))&&(this.#B.add(i),this.#R=!1)}else this.#R&&!this.#z.has(i)&&(this.#B.add(i),this.#R=!1);if(this.#z.add(i),this.#B.has(i))break}this.#ve(e,n.text??``,n.final===!0,{turnId:i,...typeof n.startMs==`number`&&{startMs:n.startMs},...typeof n.endMs==`number`&&{endMs:n.endMs},...this.#x&&{caption:!0}});break}case`delegation_started`:case`delegation_completed`:{let e=String(n.delegationId??n.turnId);if(n.type===`delegation_started`){this.#ie(t);let r=n.input;this.#x&&r&&this.#ce(e,{delegationId:e,userText:String(r.text??``),userUtteranceIds:Array.isArray(r.userUtteranceIds)?r.userUtteranceIds.filter(e=>typeof e==`string`):[],messages:Array.isArray(r.messages)?r.messages:[]},t)}else n.speak!==!1&&this.#F.has(e)&&!this.#I.delete(e)&&!this.#S.has(`delegation_read_back`)&&this.#oe(e);this.#g=n.type===`delegation_started`,!this.#u&&!this.#ue()&&this.#ge(this.#g?`processing`:`listening`);break}case`delegation_progress`:{let e=String(n.delegationId);this.#F.has(e)&&!this.#I.has(e)&&!this.#w.has(e)&&(this.#I.add(e),this.#oe(e));break}case`delegation_cancelled`:this.#se(String(n.delegationId),n.reason!==`session_ending`&&n.reason!==`provider_cancelled`);break;case`warning`:console.warn(`[Persona voice] ${n.code}: ${n.message??``}`,this.#T??``),n.delegationId&&(n.code===`UNKNOWN_DELEGATION`||n.code===`LATE_RESULT_LIMIT`)&&this.#se(String(n.delegationId));break;case`audio_clear`:this.#me(),this.#_=0,this.#ge(`listening`);break;case`transcript_interim`:this.#ge(`listening`),this.#ve(`user`,n.text??``,!1);break;case`transcript_final`:{let e=n.role===`assistant`?`assistant`:`user`;this.#ge(e===`user`?`processing`:`speaking`),this.#ve(e,n.text??``,!0);break}case`audio_end`:this.#c?this.#c.markStreamEnd():(this.#u=!1,this.#ge(`listening`));break;case`metrics`:this.#ye({llmMs:n.llm_ms,ttsMs:n.tts_ms,firstAudioMs:n.first_audio_ms,totalMs:n.total_ms});break;case`error`:this.#_e(Error(n.error||`Voice error`)),this.#ge(`error`);break;case`session_end`:this.#E={reason:String(n.reason),...typeof n.message==`string`&&{message:n.message}}}}async#re(){let e=this.bridge?.getHistory()??[],t=``;try{let e=this.config?.callContext;t=String((typeof e==`function`?await e():e)??``)}catch{}return o(e,t)}#ie(e){let t=this.#M;if(!t)return;this.#M=null;let n=!1,r=t.then(t=>{let r=this.#e;!n&&t&&e===this.#d&&r?.readyState===WebSocket.OPEN&&r.send(JSON.stringify({type:`context`,text:t}))});this.#N={done:r,drop:()=>n=!0}}async#ae(){let e=this.#N;if(!e)return;let t,n=await Promise.race([e.done.then(()=>!1),new Promise(e=>{t=setTimeout(()=>e(!0),2e3)})]);clearTimeout(t),n&&e.drop()}#oe(e){this.#R=!0,this.#L=e}#se(e,t=!1){this.#w.add(e),this.#L===e&&(this.#R=!1),this.#I.delete(e),this.bridge?.dropDelegation?.(e,t),this.#C.get(e)?.abort()}#ce(e,t,n){let r=this.bridge,i=({type:t,...r})=>{let i=this.#e;return n!==this.#d||i?.readyState!==WebSocket.OPEN||this.#w.has(e)?!1:(i.send(JSON.stringify({type:t,delegationId:e,...r})),!0)},a=(e,t,n,r=0)=>i({type:e,status:t,text:n,...r>0&&{streamedChars:r}});this.#P=this.#P.then(async()=>{if(n!==this.#d||this.#w.has(e))return;let o=null,s=this.#S.has(`delegation_stream`)&&this.#S.has(`delegation_read_back`),c=t=>{o=(o??this.#ae()).then(()=>{i({type:`delegation_delta`,text:t})&&this.#F.add(e)})},l=await r.runDelegatedTurn(s?{...t,stream:c}:t).catch(()=>({status:`failed`,text:``}));await this.#ae(),await o;let u=s?l.streamedChars??0:0,d=!!l.followUp,f=d&&this.#S.has(`delegation_update`);if(!a(f?`delegation_update`:`delegation_result`,d&&!f?`completed`:l.status,l.text,u)||(l.status!==`failed`&&l.inChat!==!1&&this.#F.add(e),!l.followUp))return;let p=new AbortController;this.#C.set(e,p),l.followUp({signal:p.signal,approvalTimeoutMs:this.config?.approvalTimeoutMs&&Math.min(this.config.approvalTimeoutMs,54e4),readBack:f,onUpdate:e=>a(`delegation_update`,`pending_approval`,e)}).then(t=>{this.#C.delete(e),f&&t&&!p.signal.aborted&&a(`delegation_result`,t.status,t.text)})})}#le(e,t){if(t!==this.#d||!this.#c||this.#ue())return;let n=s(e);n.length!==0&&(this.#u||(this.#u=!0,this.#ge(`speaking`)),this.#de(),this.#c.enqueue(n),this.#h&&this.#fe(n.length))}#ue(){return Date.now()<this.#_}#de(){if(this.#b||!this.#c)return;this.#b=!0;let e=this.#d;this.#c.onFinished(()=>{e===this.#d&&(this.#b=!1,this.#pe())})}#fe(e){let t=Date.now();this.#v=Math.max(t,this.#v)+e/48,clearTimeout(this.#y),this.#y=setTimeout(()=>this.#pe(),this.#v-t+300)}#pe(){this.#u=!1,this.#v=0,this.#e&&this.#e.readyState===WebSocket.OPEN&&this.#ge(this.#g?`processing`:`listening`)}#me(){this.#c?.flush(),this.#b=!1,this.#de(),this.#u=!1,this.#v=0,clearTimeout(this.#y)}#he(){this.#d+=1,this.#l=!1,this.#u=!1,this.#Y(),this.#h=!1,this.#g=!1,this.#x=!1,this.#S=/* @__PURE__ */ new Set;for(let e of this.#C.values())e.abort();if(this.#C.clear(),this.#w.clear(),this.#T=void 0,this.#E=null,clearTimeout(this.#O),this.#j=!1,this.#M=null,this.#N=null,this.#P=Promise.resolve(),this.#F.clear(),this.#I.clear(),this.#L=null,this.#R=!1,this.#z.clear(),this.#B.clear(),this.#b=!1,this.#_=0,this.#v=0,clearTimeout(this.#y),this.#o=[],this.#s=0,this.#a&&=(this.#a.onaudioprocess=null,this.#a.disconnect(),null),this.#i&&=(this.#i.disconnect(),null),this.#r&&=(this.#r.getTracks().forEach(e=>e.stop()),null),this.#t&&=(this.#t.close().catch(()=>{}),null),this.#c&&=(this.#c.destroy(),null),this.#e){this.#f=!0;try{this.#e.close(1e3,`client ended call`)}catch{}this.#e=null}}onResult(e){this.#V.push(e)}onError(e){this.#H.push(e)}onStatusChange(e){this.#U.push(e)}onTranscript(e){this.#W.push(e)}onMetrics(e){this.#G.push(e)}#ge(e){this.#U.forEach(t=>t(e))}#_e(e){this.#H.forEach(t=>t(e))}#ve(e,t,n,r){this.#W.forEach(i=>i(e,t,n,r))}#ye(e){this.#G.forEach(t=>t(e))}},f=class{#e;#t;#n;#r;#i;#a;constructor(e={}){this.config=e,this.type=`browser`,this.#e=null,this.#t=[],this.#n=[],this.#r=[],this.#i=!1,this.#a=typeof window<`u`?window:void 0}async connect(){this.#r.forEach(e=>e(`connected`))}async startListening(){try{if(this.#i)throw Error(`Already listening`);if(!this.#a)throw Error(`Window object not available`);let e=this.#a.SpeechRecognition||this.#a.webkitSpeechRecognition;if(!e)throw Error(`Browser speech recognition not supported`);this.#e=new e,this.#e.lang=this.config?.language||`en-US`,this.#e.continuous=this.config?.continuous||!1,this.#e.interimResults=!0,this.#e.onresult=e=>{let t=Array.from(e.results).map(e=>e[0]).map(e=>e.transcript).join(``),n=e.results[e.results.length-1].isFinal;this.#t.forEach(e=>e({text:t,confidence:n?.8:.5,provider:`browser`})),n&&!this.config?.continuous&&this.stopListening()},this.#e.onerror=e=>{this.#n.forEach(t=>t(Error(e.error))),this.#r.forEach(e=>e(`error`))},this.#e.onstart=()=>{this.#i=!0,this.#r.forEach(e=>e(`listening`))},this.#e.onend=()=>{this.#i=!1,this.#r.forEach(e=>e(`idle`))},this.#e.start()}catch(e){throw this.#n.forEach(t=>t(e)),this.#r.forEach(e=>e(`error`)),e}}async stopListening(){this.#e&&=(this.#e.stop(),null),this.#i=!1,this.#r.forEach(e=>e(`idle`))}onResult(e){this.#t.push(e)}onError(e){this.#n.push(e)}onStatusChange(e){this.#r.push(e)}async disconnect(){await this.stopListening(),this.#r.forEach(e=>e(`disconnected`))}static isSupported(){return`SpeechRecognition`in window||`webkitSpeechRecognition`in window}};function p(e){switch(e.type){case`runtype`:if(!e.runtype)throw Error(`Runtype voice provider requires configuration`);return new d(e.runtype);case`browser`:if(!f.isSupported())throw Error(`Browser speech recognition not supported`);return new f(e.browser||{});case`custom`:{let t=e.custom;if(!t)throw Error("Custom voice provider requires a `custom` provider instance or factory");let n=typeof t==`function`?t():t;if(!n||typeof n.startListening!=`function`)throw Error("Custom voice provider `custom` must be a VoiceProvider (or a factory returning one)");return n}default:throw Error(`Unknown voice provider type: ${e.type}`)}}function m(e){if(e?.type===`custom`&&e.custom)return p({type:`custom`,custom:e.custom});if(e?.type===`runtype`&&e.runtype)return p({type:`runtype`,runtype:e.runtype});if(f.isSupported())return p({type:`browser`,browser:e?.browser||{language:`en-US`}});throw Error(`No supported voice providers available`)}function h(e){try{return m(e),!0}catch{return!1}}const g=e=>e.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,``);var _=class{constructor(e){this.host=e,this.turns=/* @__PURE__ */ new Map,this.latestId=null,this.cancelled=/* @__PURE__ */ new Set}apply(e,t,n,r,i,a){let o=this.host;t=t.trim();let s=this.turns.get(r);if(s||(s={},this.turns.set(r,s),this.latestId=r),e===`user`){s.userFinal=n;let e=s.userId?o.find(s.userId):void 0;if(e){let r=s.userStartMs===void 0&&i!==void 0;r&&(s.userStartMs=i),o.upsert({...e,content:t,voiceProcessing:!n,...r&&this.placeBefore(this.startedAfter(i))})}else{s.userStartMs=i;let e=s.assistantId?o.find(s.assistantId):void 0;s.userId=o.inject({role:`user`,content:t,streaming:!1,voiceProcessing:!n,voiceCaption:a,...this.placeBefore(this.startedAfter(i)??e)}).id}}else if(!this.cancelled.has(r)){s.assistantFinal=n;let e=s.assistantId?o.find(s.assistantId):void 0;if(e){let r=s.assistantStartMs===void 0&&i!==void 0;r&&(s.assistantStartMs=i),o.upsert({...e,content:t,streaming:!n,voiceProcessing:!n,...r&&this.placeBefore(this.startedAfter(i))})}else t&&(s.assistantStartMs=i,s.assistantId=o.inject({role:`assistant`,content:t,streaming:!n,voiceProcessing:!n,voiceCaption:a,...this.placeBefore(this.startedAfter(i))}).id);n&&s.assistantId&&o.markSpoken(s.assistantId)}this.sync()}claimUserTurn(e,t=[]){let n=t[t.length-1];for(let e of t)e!==n&&(this.turns.has(e)||this.turns.set(e,{}),this.turns.get(e).claimed=!0);let r;if(n){if(r=this.turns.get(n),r||(r={},this.turns.set(n,r)),r.claimed)return null;(!r.userId||!this.host.find(r.userId))&&(r.userFinal=!0,r.userId=this.host.inject({role:`user`,content:e.trim()}).id)}else{let t=g(e),n=[...this.turns.values()].reverse().flatMap(e=>{let t=e.userId&&!e.claimed?this.host.find(e.userId):void 0;return t?[{turn:e,text:g(t.content)}]:[]}).filter(({text:e})=>e&&t);r=(n.find(({text:e})=>e===t)??n.find(({text:e})=>e.startsWith(t)||t.startsWith(e)))?.turn}return r?(r.claimed=!0,r.userId):null}cancel(){let e=this.inFlight();if(e.length===0){let t=this.awaiting();if(!t)return;e=[t]}for(let t of e)this.cancelled.add(t);this.closeReplies(e),this.sync()}fail(e){let t=this.awaiting(),n=this.inFlight();if(!t&&n.length===0)return;for(let e of n)this.turns.get(e).assistantFinal=!0;this.closeReplies(n);let r=this.host.inject({role:`assistant`,content:e,streaming:!1,voiceProcessing:!1}),i=t?this.turns.get(t):void 0;i&&(i.assistantId=r.id,i.assistantFinal=!0),this.sync()}settle(){if(this.turns.size===0)return;let e=this.pending(),t=/* @__PURE__ */ new Set;for(let e of this.turns.values())e.userId&&t.add(e.userId),e.assistantId&&(t.add(e.assistantId),this.host.markSpoken(e.assistantId));this.turns.clear(),this.latestId=null,this.host.settle(t),e&&this.host.setStreaming(!1)}startedAfter(e){if(e===void 0)return;let t;for(let n of this.turns.values())for(let[r,i]of[[n.userId,n.userStartMs],[n.assistantId,n.assistantStartMs]])r&&i!==void 0&&i>e&&(!t||i<t.start)&&(t={start:i,id:r});return t&&this.host.find(t.id)}placeBefore(e){if(!e)return;let t=e.sequence??0,n=t-1;for(let r of this.turns.values())for(let i of[r.userId,r.assistantId]){let r=i?this.host.find(i):void 0,a=r?.sequence;r?.createdAt===e.createdAt&&a!==void 0&&a>n&&a<t&&(n=a)}return{createdAt:e.createdAt,sequence:(n+t)/2}}closeReplies(e){let t=/* @__PURE__ */ new Set;for(let n of e){let e=this.turns.get(n)?.assistantId;e&&(t.add(e),this.host.markSpoken(e))}t.size>0&&this.host.settle(t)}inFlight(){let e=[];for(let[t,n]of this.turns)n.assistantId&&!n.assistantFinal&&!this.cancelled.has(t)&&e.push(t);return e}awaiting(){let e=this.latestId;if(!e)return null;let t=this.turns.get(e);return t?.userFinal&&!t.assistantId&&!t.claimed&&!this.cancelled.has(e)?e:null}pending(){return this.awaiting()!==null||this.inFlight().length>0}sync(){this.host.setStreaming(this.pending())}};const v=/* @__PURE__ */ new Set(/* @__PURE__ */ `mr,mrs,ms,dr,prof,sr,jr,st,mt,vs,etc,approx,inc,ltd,co,corp,no,nos,fig,ft,dept,est,min,max,e.g,i.e,a.m,p.m,u.s,u.k`.split(`,`)),y=/([.!?]+|[,;:])(["'”’)\]*_]*)(\s+)|\n\s*/g;function b(e){let t=/(\S+)$/.exec(e)?.[1];if(!t)return!1;let n=t.replace(/^[("'“‘[*_]+/,``).toLowerCase();if(v.has(n)||/^[a-z](?:\.[a-z])*$/.test(n))return!0;if(/^\d+$/.test(t)){let n=e.length-t.length;return n===0||/\n\s*$/.test(e.slice(0,n))}return!1}function*x(e,t){let n=new RegExp(y.source,`g`);for(let r=n.exec(e);r;r=n.exec(e)){let n=r[1];if(!e.slice(0,r.index+(n?.length??0)).trim()||n!==void 0&&(/^[,;:]$/.test(n)&&!t||n===`.`&&b(e.slice(0,r.index))))continue;let i=r.index+r[0].length;i<e.length&&(yield i)}}function S(e,t){let n=e.slice(0,t),r=0;for(let e of n.matchAll(/\s+/g))n.slice(0,e.index).trim()&&(r=e.index+e[0].length);return r}function C(e){let t=0;for(let n of x(e.slice(0,220),!0))t=n;if(t)return t;let n=S(e,220);if(n)return n;let r=e.charCodeAt(219);return r>=55296&&r<=56319?219:220}var w=class{#e=``;#t=!0;push(e){return this.#e+=e,this.#n()}flush(){let e=this.#n(),t=this.#e;if(this.#e=``,t.trim()){for(let n=0;n<t.length;){let r=t.slice(n),i=r.length>220?C(r):r.length;e.push(r.slice(0,i)),n+=i}this.#t=!1}return e}idle(){let e=this.#e;if(!e.trim()||!/(?:[.!?…]["'”’)\]*_]*|\n)\s*$/.test(e))return[];this.#e=``,this.#t=!1;let t=[];for(let n=0;n<e.length;){let r=e.slice(n),i=r.length>220?C(r):r.length;t.push(r.slice(0,i)),n+=i}return t}#n(){let e=[];for(let t=this.#r();t>0;t=this.#r())e.push(this.#e.slice(0,t)),this.#e=this.#e.slice(t),this.#t=!1;return e}#r(){let e=this.#e;if(!e.trim())return 0;let t=x(e,this.#t).next().value??0;if(t&&t<=220)return t;let n=/[.!?]["'”’)\]*_]*$/.test(e);if(this.#t&&!n){let t=e.match(/\S+\s+/g)?.length??0;if(e.trim().length>=30||t>=6){let t=S(e,220);if(t)return t}}return e.length>220?C(e):0}};const T=(e,t)=>{let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n+=1;return n},E=`no|nope|never ?mind|decline(?: it| that)?|cancel(?: it| that| this)?(?: (?:the|my|that|this) (?:[a-z]+ )?(?:order|request))?|don'?t (?:do|place) (?:it|that|the (?:[a-z]+ )?order)`,D=RegExp(`^(?:${E})(?: (?:${E}))?(?: thanks| thank you)?$`),O=e=>D.test(e.toLowerCase().replace(/[^a-z' ]+/g,` `).replace(/\s+/g,` `).trim()),k=()=>new Promise(e=>setTimeout(e,50)),A=(e,t)=>e.length>t?`${e.slice(0,t-1).trimEnd()}…`:e,j=e=>e.replace(/^webmcp:/,``).replace(/([a-z\d])([A-Z])/g,`$1 $2`).replace(/[_\-.]+/g,` `).trim().toLowerCase();function M(e,t=0){if(e==null||e===``)return``;if(typeof e!=`object`)return String(e);if(t>2)return``;if(Array.isArray(e))return e.map(e=>M(e,t+1)).filter(Boolean).join(`, `);let n=e,r=n.quantity??n.qty??n.count,i=n.name??n.item??n.product??n.title;return r!=null&&i!=null&&typeof i!=`object`?`${r} ${i}`:Object.entries(n).filter(([e])=>!e.startsWith(`_`)).map(([e,n])=>{let r=M(n,t+1);return r&&(t?`${j(e)} ${r}`:`${j(e)}: ${r}`)}).filter(Boolean).join(t?`, `:`; `)}function N(e){let t=e.length>1?`These actions need the user's approval in the chat before they happen:`:`This action needs the user's approval in the chat before it happens:`,n=1e3-t.length-119-2;return`${t}\n${e.map(t=>{let r=[j(t.toolName)];t.description&&r.push(`(${A(t.description.trim(),160)})`);let i=M(t.parameters);return i&&r.push(`with ${i}`),t.reason&&r.push(`because: ${A(t.reason.trim(),160)}`),A(`- ${r.join(` `)}`,Math.floor(n/e.length)-1)}).join(`
5
- `)}\n\nBriefly tell the user what you're about to do and ask them to approve or decline it in the chat. Don't claim it's done.`}const P=e=>e.variant===`approval`&&e.approval?.status===`pending`;function F(e){let t=null,n=null,r=()=>e.track(t??n),i=[],a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Map,s=(e,t)=>{a.set(e,[...a.get(e)??[],t]),a.size>32&&a.delete(a.keys().next().value)},c=t=>e.messages().find(e=>e.id===t),l=e=>e.approvals.filter(e=>c(e)?.approval?.status===`pending`),u=e=>j(c(e)?.approval?.toolName??``),d=(t,n,r)=>{t.outcome={status:n,text:r};for(let n of l(t))e.decide(n)},f=t=>t.flatMap(t=>e.messages().find(e=>e.id===t)??[]).filter(e=>!e.variant&&e.content.trim()).map(e=>e.content.trim()).join(`
6
-
7
- `),p=async t=>{do await k();while(e.busy()&&!(t&&(e.parked()||t.failed)))};return{getHistory:()=>{let t=e.messages().filter(e=>(e.role===`user`||e.role===`assistant`)&&!e.variant&&!e.voiceProcessing&&!e.streaming&&e.content),n=!1,r=[];for(let e=t.length-1;e>=0;--e){let i=t[e];if(i.role===`user`)n=!1;else if(!i.voiceCaption)n=!0;else if(n)continue;r.unshift({role:i.role,content:i.content})}return r},dropDelegation(t,n){o.set(t,!!n),o.size>32&&o.delete(o.keys().next().value);let r=n&&i.find(e=>e.delegationId===t);r&&!r.outcome&&d(r,`timeout`,``);for(let n of a.get(t)??[])n.stopStream?.(),n.dropped=!0,n.ids.length&&e.unspoken(n.ids)},async runDelegatedTurn({delegationId:m,userText:h,userUtteranceIds:g,stream:_}){let v=i.filter(e=>l(e).length),y=v.flatMap(l);if(y.length===1&&O(h)){let e=u(y[0]);return d(v[0],`denied`,``),{status:`denied`,text:`Okay, I cancelled the ${e} request. Nothing was done.`,inChat:!1}}let b=e.parked()&&e.messages().every(e=>!P(e)||y.includes(e.id));e.busy()&&!b&&await p();let x=new Set(e.messages().map(e=>e.id)),S=()=>e.messages().filter(e=>!x.has(e.id)&&e.variant===`approval`),C={ids:[],failed:!1},E=_?new w:null,D=``,A=``,M=!1,F=e=>{for(let t of e)A+=t,_(t)},I;E&&(C.onUpdate=()=>{if(M)return;let e=f(C.ids);if(!e.startsWith(D)){M=!0,clearTimeout(I);return}if(e.length===D.length)return;let t=e.slice(D.length);D=e,F(E.push(t)),clearTimeout(I),I=setTimeout(()=>{M||F(E.idle())},200)},C.stopStream=()=>{clearTimeout(I),M=!0,C.onUpdate=void 0}),s(m,C),t=C,r();try{await e.send(h,e.claim(h,g)??void 0),await p(C)}catch{C.failed=!0}finally{t=null,r()}E&&(C.onUpdate?.(),clearTimeout(I),M||F(E.flush()),C.onUpdate=void 0,C.stopStream=void 0);let L=e=>{let t=T(A,e);return t>0?{streamedChars:t}:{}},R=C.ids.flatMap(t=>e.messages().find(e=>e.id===t)??[]),z=f(C.ids),B=C.failed?[]:S().filter(P),V=new Set(B.map(e=>j(e.approval.toolName)));for(let t of v){if(t.outcome)continue;for(let n of l(t).filter(e=>V.has(u(e))))t.replaced.add(n),e.decide(n);let n=u(t.approvals[0]);(t.approvals.every(e=>t.replaced.has(e))||b&&t.approvals.every(e=>c(e)?.approval?.status===`denied`))&&(t.outcome={status:`cancelled`,text:`The earlier ${n} request was replaced by the new one; it was not done.`})}if(B.length){let c=new Set(B.map(e=>e.id)),p={delegationId:m,approvals:[...c],at:Date.now(),replaced:/* @__PURE__ */ new Set};return i.push(p),o.get(m)&&d(p,`timeout`,``),z=`${z}\n\n${N(B.map(e=>e.approval))}`.trim(),{status:`pending_approval`,text:z,...L(z),followUp:async({signal:o,approvalTimeoutMs:h=3e5,readBack:g=!0,onUpdate:_})=>{let v={ids:[],failed:!1};a.delete(m),s(m,v);let y=()=>S().filter(e=>c.has(e.id)||v.ids.includes(e.id)),b=()=>S().filter(e=>P(e)&&!c.has(e.id)&&!i.some(t=>t.approvals.includes(e.id))&&(v.ids.includes(e.id)||e.approval?.toolType===`webmcp`&&n===v)),x=()=>{n=v,r()};g&&x();try{for(;!o.aborted&&!p.outcome&&(t||e.busy()||y().some(P));){g&&n!==v&&!l(p).length&&x();let t=b();if(t.length){for(let e of t)c.add(e.id),p.approvals.push(e.id);p.at=Date.now(),_?.(N(t.map(e=>e.approval)))}if(Date.now()-p.at>=h&&l(p).length&&(!e.busy()||e.parked())){d(p,`timeout`,`That ${u(p.approvals[0])} request expired, so nothing was done.`);break}await k()}}finally{n===v&&(n=null,r()),i.splice(i.indexOf(p),1)}if(o.aborted)return null;if(p.outcome)return p.outcome;if(v.failed)return{status:`failed`,text:`The ${u(p.approvals[0])} request didn't complete.`};let C=y(),w=e=>C.filter(e).map(e=>j(e.approval.toolName)).join(`, `),T=C.some(e=>e.approval?.status===`approved`),E=w(e=>e.approval?.status===`denied`&&!p.replaced.has(e.id)),D=w(e=>p.replaced.has(e.id)),O=w(e=>e.approval?.status===`timeout`),A=[T?f(v.ids):``,E&&`The user declined the ${E} request in the chat, so ${T?`that part was not done`:`nothing was done`}.`,D&&`The earlier ${D} request was replaced by the new one; it was not done.`,O&&`The ${O} request timed out, so it was not done.`].filter(Boolean).join(`
8
-
9
- `);return{status:T?`completed`:E?`denied`:D?`cancelled`:O?`timeout`:`completed`,text:A}}}}return!C.failed&&e.parked()||R.some(e=>e.agentMetadata?.awaitingLocalTool&&!e.agentMetadata.askUserQuestionAnswered&&!e.toolCall?.name?.startsWith(`webmcp:`))?(z=`${z}\n\nI need your answer in the chat before I can continue.`.trim(),{status:C.failed?`failed`:`completed`,text:z,...L(z)}):{status:!C.failed&&z?`completed`:`failed`,text:z,...L(z)}}}}const I=(e,t,n,r)=>{let i=e.session;try{e.keyed=n?new n({find:e=>i.messages.find(t=>t.id===e),inject:e=>i.injectMessage(e),upsert:e=>i.upsertMessage(e),settle:e=>{i.messages=i.messages.map(t=>e.has(t.id)?{...t,streaming:!1,voiceProcessing:!1}:t),i.callbacks.onMessagesChanged([...i.messages])},setStreaming:t=>{(t||!e.busy())&&e.setStreaming(t)},markSpoken:e=>{i.ttsSpokenMessageIds.add(e)}}):null,r&&t.setSessionBridge&&t.setSessionBridge(r({messages:()=>i.messages,busy:()=>e.busy(),parked:()=>i.webMcpApprovalResolvers.size>0,claim:(t,n)=>e.keyed?.claimUserTurn(t,n)??null,send:(e,t)=>i.sendMessage(e,{viaVoice:!0,voiceTurn:{userMessageId:t}}),track:t=>{e.setDelegation(t)},unspoken:e=>{for(let t of e)i.ttsSpokenMessageIds.delete(t);i.streaming||i.speakLatestAssistantMessage(e)},decide:e=>{if(i.webMcpApprovalResolvers.has(e))return i.resolveWebMcpApproval(e,`denied`);let t=i.messages.find(t=>t.id===e)?.approval;t?.status===`pending`&&i.resolveApproval(t,`denied`)}}));let a=e.generation(),o=()=>e.provider()===t&&a===e.generation(),s=(i.config.voiceRecognition??{}).processingErrorText??`Voice processing failed. Please try again.`;t.onResult(e=>{o()&&e.provider!==`runtype`&&e.text&&e.text.trim()&&i.sendMessage(e.text,{viaVoice:!0})}),t.onTranscript&&t.onTranscript((t,n,r,a)=>{if(o()){if(a?.turnId)e.keyed?.apply(t,n,r,a.turnId,a.startMs,a.caption);else if(t===`user`)e.pendingUser?i.upsertMessage({id:e.pendingUser,role:`user`,content:n,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,voiceProcessing:!r}):e.pendingUser=i.injectMessage({role:`user`,content:n,streaming:!1,voiceProcessing:!r}).id,r&&(e.turns().start(a?.turnId),e.pendingUser=null,e.pendingAssistant=i.injectMessage({role:`assistant`,content:``,streaming:!0,voiceProcessing:!0}).id,e.setStreaming(!0));else{if(!e.turns().accepts(a?.turnId))return;e.pendingAssistant?i.upsertMessage({id:e.pendingAssistant,role:`assistant`,content:n,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!r,voiceProcessing:!r}):e.pendingAssistant=i.injectMessage({role:`assistant`,content:n,streaming:!r,voiceProcessing:!r}).id,r&&(e.pendingAssistant&&i.ttsSpokenMessageIds.add(e.pendingAssistant),e.setStreaming(!1),e.pendingAssistant=null)}}}),t.onLevel&&t.onLevel(t=>{o()&&e.setLevel(Number.isFinite(t)?Math.max(0,Math.min(1,t)):0)}),t.onMetrics&&t.onMetrics(e=>{o()&&i.config.voiceRecognition?.onMetrics?.(e)}),t.onError(t=>{o()&&(console.error(`Voice error:`,t),e.pendingAssistant&&=(i.upsertMessage({id:e.pendingAssistant,role:`assistant`,content:s,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,voiceProcessing:!1}),e.setStreaming(!1),e.pendingUser=null,null),e.keyed?.fail(s))}),t.onStatusChange(t=>{o()&&(e.setStatus(t),(t===`listening`||t===`idle`||t===`disconnected`)&&e.settlePending(t!==`listening`),(t===`idle`||t===`disconnected`)&&e.keyed?.settle(),i.callbacks.onVoiceStatusChanged?.(t))}),t.connect()}catch(e){console.error(`Failed to setup voice:`,e)}},L=e=>{let t=t=>{if(e.original)return;let n=e.config().voiceRecognition??{};e.original={backgroundColor:t.style.backgroundColor,color:t.style.color,borderColor:t.style.borderColor,iconName:n.iconName??`mic`,iconSize:parseFloat(n.iconSize??``)||e.iconFallbackPx}},n=(t,n,r)=>{let i=t.querySelector(`svg`);i&&i.remove();let a=e.original?.iconSize??(parseFloat(e.config().voiceRecognition?.iconSize??``)||e.iconFallbackPx),o=e.renderIcon(n,a,r,1.5);o&&t.appendChild(o)},r=e=>{e.classList.remove(`persona-voice-recording`,`persona-voice-processing`,`persona-voice-speaking`)};return{recording:()=>{let n=e.mic();if(!n)return;t(n);let i=e.config().voiceRecognition??{},a=i.recordingBackgroundColor,o=i.recordingIconColor,s=i.recordingBorderColor;if(r(n),n.classList.add(`persona-voice-recording`),e.setMicState(`recording`),n.style.backgroundColor=a??`var(--persona-voice-recording-bg, #ef4444)`,n.style.color=o??`var(--persona-voice-recording-indicator, #ffffff)`,o){let e=n.querySelector(`svg`);e&&e.setAttribute(`stroke`,o)}s&&(n.style.borderColor=s),n.setAttribute(`aria-label`,`Stop voice recognition`)},processing:()=>{let i=e.mic();if(!i)return;t(i);let a=e.config().voiceRecognition??{},o=e.session().getVoiceInterruptionMode(),s=e.original,c=a.processingIconName??`loader`,l=a.processingIconColor??s?.color??``,u=a.processingBackgroundColor??s?.backgroundColor??``,d=a.processingBorderColor??s?.borderColor??``;r(i),i.classList.add(`persona-voice-processing`),e.setMicState(`processing`),i.style.backgroundColor=u,i.style.borderColor=d;let f=l||`currentColor`;i.style.color=f,n(i,c,f),i.setAttribute(`aria-label`,`Processing voice input`),o===`none`&&(i.style.cursor=`default`)},speaking:()=>{let i=e.mic();if(!i)return;t(i);let a=e.config().voiceRecognition??{},o=e.session().getVoiceInterruptionMode(),s=e.original,c=o===`cancel`?`square`:o===`barge-in`?`mic`:`volume-2`,l=a.speakingIconName??c,u=a.speakingIconColor??(o===`barge-in`?a.recordingIconColor??s?.color??``:s?.color??``),d=a.speakingBackgroundColor??(o===`barge-in`?a.recordingBackgroundColor??`var(--persona-voice-recording-bg, #ef4444)`:s?.backgroundColor??``),f=a.speakingBorderColor??(o===`barge-in`?a.recordingBorderColor??``:s?.borderColor??``);r(i),i.classList.add(`persona-voice-speaking`),e.setMicState(`speaking`),i.style.backgroundColor=d,i.style.borderColor=f;let p=u||`currentColor`;i.style.color=p,n(i,l,p);let m=o===`cancel`?`Stop playback and re-record`:o===`barge-in`?`Speak to interrupt`:`Agent is speaking`;i.setAttribute(`aria-label`,m),o===`none`&&(i.style.cursor=`default`),o===`barge-in`&&i.classList.add(`persona-voice-recording`)},reset:()=>{let t=e.mic();if(!t)return;r(t),e.setMicState(`idle`);let i=e.original;i&&(t.style.backgroundColor=i.backgroundColor??``,t.style.color=i.color??``,t.style.borderColor=i.borderColor??``,n(t,i.iconName,i.color||`currentColor`),e.original=null),t.style.cursor=``,t.setAttribute(`aria-label`,`Start voice recognition`)}}};export{f as BrowserVoiceProvider,_ as KeyedVoiceTranscript,d as RuntypeVoiceProvider,m as createBestAvailableVoiceProvider,L as createMicStateStyles,p as createVoiceProvider,F as createVoiceSessionBridge,h as isVoiceSupported,I as wireSessionVoice};
@@ -1,4 +0,0 @@
1
- import{l as e,v as t}from"./chunk-dRBlrLd7.js";import{a as n,i as r,t as i}from"./chunk-CPdEltCR.js";import"./chunk-Bb41bKyp.js";async function a(e,t,n){let r={"Content-Type":`application/json`,...e.headers};e.getHeaders&&Object.assign(r,await e.getHeaders());let i={executionId:t.executionId,approvalId:t.approvalId,decision:n,streamResponse:!0},a=(t,n)=>fetch(`${e.clientApiBase()}${t}`,{method:`POST`,headers:r,body:JSON.stringify({...n,...i})}),o=`/v1/agents/${t.agentId}/approve`;if(!e.isClientTokenMode())return a(o);let{sessionId:s}=await e.initSession(),c=await a(`/v1/client/approve`,{sessionId:s});if(c.status===404){let e=await c.clone().json().catch(()=>null);if(!e||e.error===`Not Found`)return a(o)}return c}async function o(e,t,r,i){let a=e.isClientTokenMode(),o=a?e.getClientApiUrl(`resume`):`${e.config.apiUrl?.replace(/\/+$/,``)||`https://api.runtype.com`}/resume`,s,c=null;if(a){let t=await e.initSession();s=t.sessionId,t.durableRecovery?.enabled===!0&&(c=await e.readVisitorToken())}let l={"Content-Type":`application/json`,...c?{"X-Visitor-Token":c}:{},...e.headers};e.getHeaders&&Object.assign(l,await e.getHeaders());let u={executionId:t,toolOutputs:r,streamResponse:i?.streamResponse??!0,...i?.after?{after:i.after}:{}};if(s&&(u.sessionId=s),a&&s){let t=[...n(e.config),...await(await e.getWebMcpBridge())?.snapshotForDispatch()??[]],{response:r,commit:a}=await e.sendWithClientToolsDiff(s,t,t=>{let n={...u,...t};return e.debug&&console.debug(`[AgentWidgetClient] client token resume`,n),fetch(o,{method:`POST`,headers:l,body:JSON.stringify(n),signal:i?.signal})},{emptyMeansReplace:!0});return r.ok&&a(),r}return fetch(o,{method:`POST`,headers:l,body:JSON.stringify(u),signal:i?.signal})}function s(e){let t=e.toLowerCase(),n={"application/pdf":`pdf`,"application/json":`json`,"application/zip":`zip`,"text/plain":`txt`,"text/csv":`csv`,"text/markdown":`md`}[t];if(n)return`attachment.${n}`;let r=t.indexOf(`/`);if(r>0){let e=t.slice(r+1).split(`;`)[0]?.trim()??``;if(e&&e!==`octet-stream`&&/^[a-z0-9.+-]+$/i.test(e))return`attachment.${e}`}return`attachment`}const c=e=>e.startsWith(`{`)||e.startsWith(`[`)||e.startsWith(`<`);function l(t,n){if(!t)return n;let r=t.trim(),i=n.trim();if(r.length===0)return n;if(i.length===0)return t;let a=c(r);if(!c(i))return t;if(!a||i===r||i.startsWith(r))return n;let o=e(t);return e(n)!==null&&o===null?n:t}async function u(e,t,n,r,i,a,o){if(!e.parseSSEEvent)return!1;try{let s=await e.parseSSEEvent(t);if(s===null)return!1;let c=e=>{let t={id:`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,variant:`assistant`,sequence:a(),...e!==void 0&&{partId:e}};return r.current=t,i(t),t},l=e=>r.current?r.current:c(e);if(s.text!==void 0){s.partId!==void 0&&o.current!==null&&s.partId!==o.current&&(r.current&&(r.current.streaming=!1,i(r.current)),c(s.partId)),s.partId!==void 0&&(o.current=s.partId);let e=l(s.partId);s.partId!==void 0&&!e.partId&&(e.partId=s.partId),e.content+=s.text,i(e)}return s.done&&(r.current&&(r.current.streaming=!1,i(r.current)),o.current=null,n({type:`status`,status:`idle`})),s.error&&(o.current=null,n({type:`error`,error:Error(s.error)})),!0}catch(e){return typeof console<`u`&&console.error(`[AgentWidget] parseSSEEvent error:`,e),!1}}async function d(n,a,o,c,d){let f=a.getReader(),ee=new TextDecoder,p=``,m=Date.now(),te=0,h=()=>m+te++,g=e=>{let t=e.reasoning?{...e.reasoning,chunks:[...e.reasoning.chunks]}:void 0,n=e.toolCall?{...e.toolCall,chunks:e.toolCall.chunks?[...e.toolCall.chunks]:void 0}:void 0,r=e.tools?e.tools.map(e=>({...e,chunks:e.chunks?[...e.chunks]:void 0})):void 0;return{...e,reasoning:t,toolCall:n,tools:r}},ne=e=>{if(e.role!==`assistant`||e.variant)return!0;let t=Array.isArray(e.contentParts)&&e.contentParts.length>0,n=typeof e.rawContent==`string`&&e.rawContent.trim()!==``;return typeof e.content==`string`&&e.content.trim()!==``||t||n||!!e.stopReason},_=e=>{ne(e)&&o({type:`message`,message:g(e)})},v=null,y=null,b={current:null},re={current:null},x=null,S=``,C=/* @__PURE__ */ new Map,w=/* @__PURE__ */ new Map,T=/* @__PURE__ */ new Map,E=/* @__PURE__ */ new Map,D=/* @__PURE__ */ new Map,O=c,k=!1,A=()=>{if(v)return v;let e,t=``,n=x;return!k&&O?(e=O,k=!0,t=d??``):e=O&&n?`${O}_${n}`:`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,v={id:e,role:`assistant`,content:t,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,sequence:h()},_(v),v},j=e=>{let t=E.get(e);if(t)return t;let n={id:`reason-${e}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,variant:`reasoning`,sequence:h(),reasoning:{id:e,status:`streaming`,chunks:[]}};return E.set(e,n),_(n),n},M=/* @__PURE__ */ new Set,N=/* @__PURE__ */ new Map,P=/* @__PURE__ */ new Set,F=/* @__PURE__ */ new Map,I=e=>{if(!e)return!1;let t=e.replace(/_+/g,`_`).replace(/^_|_$/g,``);return t===`emit_artifact_markdown`||t===`emit_artifact_component`},L=e=>{let t=D.get(e);if(t)return t;let n={id:`tool-${e}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,variant:`tool`,sequence:h(),toolCall:{id:e,status:`pending`}};return D.set(e,n),_(n),n},R=e=>{if(typeof e==`number`&&Number.isFinite(e))return e;if(typeof e==`string`){let t=Number(e);if(!Number.isNaN(t)&&Number.isFinite(t))return t;let n=Date.parse(e);if(!Number.isNaN(n))return n}return Date.now()},z=e=>{if(typeof e==`string`)return e;if(e==null)return``;try{return JSON.stringify(e)}catch{return String(e)}},B=/* @__PURE__ */ new Map,V=/* @__PURE__ */ new Map,ie=(t,n)=>{let r=z(n),i=l(V.get(t.id),r);t.rawContent=i;let a=B.get(t.id),o=e=>{let n=t.content??``;e.trim()!==``&&(n.trim().length===0||e.startsWith(n)||e.trimStart().startsWith(n.trim()))&&(t.content=e)},s=()=>{if(a){let e=a.close?.();e instanceof Promise&&e.catch(()=>{})}B.delete(t.id),V.delete(t.id),t.streaming=!1,_(t)};if(!a){o(r),s();return}let c=e(i);if(c!==null&&c.trim()!==``){o(c),s();return}let u=e=>{let t=typeof e==`string`?e:e?.text??null;if(t!==null&&t.trim()!==``)return t;let n=a.getExtractedText();return n!==null&&n.trim()!==``?n:r},d;try{d=a.processChunk(i)}catch{o(r),s();return}d instanceof Promise?d.then(e=>{o(u(e)),s()}).catch(()=>{o(r),s()}):(o(u(d)),s())},H=null,U=(e,t,r,i)=>{e.rawContent=t,B.has(e.id)||B.set(e.id,n.createStreamParser());let a=B.get(e.id),o=t.trim().startsWith(`{`)||t.trim().startsWith(`[`);if(o&&V.set(e.id,t),a.__isPlainTextParser===!0){e.content=i===void 0?e.content+r:t,V.delete(e.id),B.delete(e.id),e.rawContent=void 0,_(e);return}let s=a.processChunk(t);if(s instanceof Promise)s.then(n=>{let a=typeof n==`string`?n:n?.text??null;a!==null&&a.trim()!==``?(e.content=a,_(e)):!o&&!t.trim().startsWith(`<`)&&(e.content=i===void 0?e.content+r:t,V.delete(e.id),B.delete(e.id),e.rawContent=void 0,_(e))}).catch(()=>{e.content=i===void 0?e.content+r:t,V.delete(e.id),B.delete(e.id),e.rawContent=void 0,_(e)});else{let n=typeof s==`string`?s:s?.text??null;n!==null&&n.trim()!==``?(e.content=n,_(e)):!o&&!t.trim().startsWith(`<`)&&(e.content=i===void 0?e.content+r:t,V.delete(e.id),B.delete(e.id),e.rawContent=void 0,_(e))}},W=(t,n)=>{let r=n??t.content;if(r==null||r===``){t.streaming=!1,_(t);return}let i=V.get(t.id)??z(r);t.rawContent=i;let a=B.get(t.id),o=null,s=!1;if(a&&(o=a.getExtractedText(),o===null&&(o=e(i)),o===null)){let e=a.processChunk(i);e instanceof Promise?(s=!0,e.then(e=>{let n=typeof e==`string`?e:e?.text??null;n!==null&&(t.content=n,t.streaming=!1,B.delete(t.id),V.delete(t.id),_(t))}).catch(()=>{})):o=typeof e==`string`?e:e?.text??null}if(!s){o!==null&&o.trim()!==``?t.content=o:V.has(t.id)||(t.content=z(r));let e=B.get(t.id);if(e){let n=e.close?.();n instanceof Promise&&n.catch(()=>{}),B.delete(t.id)}V.delete(t.id),t.streaming=!1,_(t)}},G=(e,t,n)=>{let r=w.get(e);if(r)return r;let i={id:`nested-${t}-${e}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,sequence:h(),...n?{variant:n}:{},...n===`reasoning`?{reasoning:{id:e,status:`streaming`,chunks:[]}}:{},agentMetadata:{parentToolId:t}};return w.set(e,i),_(i),i},K=[],q,J=/* @__PURE__ */ new Map,Y=0,X=`agent`,Z=!1,Q=null,$=null,ae=n.config().iterationDisplay??`separate`;for(q=()=>{for(let e=0;e<K.length;e++){let a=K[e];if(!Z&&X!==`flow`&&typeof a.stepType==`string`&&(X=`flow`),a.type===`reasoning_start`){let e=typeof a.id==`string`?a.id:null,t=typeof a.parentToolCallId==`string`&&a.parentToolCallId?a.parentToolCallId:null;if(e&&t){C.set(e,t),G(e,t,`reasoning`);continue}let n=a.id,r=j(n);r.reasoning=r.reasoning??{id:n,status:`streaming`,chunks:[]},r.reasoning.startedAt=r.reasoning.startedAt??Date.now(),r.reasoning.completedAt=void 0,r.reasoning.durationMs=void 0,(a.scope===`loop`||a.scope===`turn`)&&(r.reasoning.scope=a.scope),r.streaming=!0,r.reasoning.status=`streaming`,_(r)}else if(a.type===`reasoning_delta`){let e=typeof a.id==`string`?a.id:null;if(e&&C.has(e)&&w.has(e)){let t=w.get(e),n=a.delta;n&&t.reasoning&&(t.reasoning.chunks.push(String(n)),_(t));continue}let t=a.id,n=j(t);n.reasoning=n.reasoning??{id:t,status:`streaming`,chunks:[]},n.reasoning.startedAt=n.reasoning.startedAt??Date.now(),a.delta&&n.reasoning.chunks.push(a.delta),n.reasoning.status=`streaming`,n.streaming=!0,_(n)}else if(a.type===`reasoning_complete`){let e=typeof a.id==`string`?a.id:null;if(e&&C.has(e)&&w.has(e)){let t=w.get(e);if(t.reasoning){let e=typeof a.text==`string`?a.text:``;e&&t.reasoning.chunks.length===0&&t.reasoning.chunks.push(e),t.reasoning.status=`complete`,t.streaming=!1,_(t)}C.delete(e),w.delete(e);continue}let t=a.id,n=typeof a.text==`string`?a.text:``;!E.get(t)&&(n||a.scope===`loop`)&&j(t);let r=E.get(t);if(r?.reasoning){(a.scope===`loop`||a.scope===`turn`)&&(r.reasoning.scope=a.scope),n&&r.reasoning.chunks.length===0&&r.reasoning.chunks.push(n),r.reasoning.status=`complete`,r.reasoning.completedAt=Date.now();let e=r.reasoning.startedAt??Date.now();r.reasoning.durationMs=Math.max(0,(r.reasoning.completedAt??Date.now())-e),r.streaming=!1,_(r)}}else if(a.type===`tool_start`){v&&=(v.streaming=!1,_(v),null),typeof a.iteration==`number`&&(Y=a.iteration);let e=a.toolCallId,t=a.toolName;if(I(t)){M.add(e);continue}let n=L(e),r=n.toolCall??{id:e,status:`pending`};r.name=t??r.name,r.status=`running`,r.success=void 0,r.error=void 0,r.duration=void 0,a.parameters!==void 0&&(r.args=a.parameters),r.startedAt=r.startedAt??R(a.startedAt),r.completedAt=void 0,r.durationMs=void 0,n.toolCall=r,n.streaming=!0,a.executionId&&(n.agentMetadata={executionId:a.executionId,iteration:a.iteration}),_(n)}else if(a.type===`tool_output_delta`){let e=a.toolCallId;if(M.has(e))continue;let t=L(e),n=t.toolCall??{id:e,status:`running`};n.startedAt=n.startedAt??Date.now();let r=a.delta;r&&(n.chunks=n.chunks??[],n.chunks.push(String(r))),n.status=`running`,t.toolCall=n,t.streaming=!0,a.executionId&&(t.agentMetadata=t.agentMetadata??{executionId:a.executionId,iteration:Y}),_(t)}else if(a.type===`tool_complete`){let e=a.toolCallId;if(M.has(e)){M.delete(e);continue}let t=L(e),n=t.toolCall??{id:e,status:`running`};n.status=`complete`,a.result!==void 0&&(n.result=a.result),n.name=a.toolName??n.name,n.success=a.success,n.error=a.error,n.completedAt=Date.now();let r=a.executionTime;if(typeof r==`number`)n.durationMs=r,n.duration=r;else{let e=n.startedAt??Date.now();n.durationMs=Math.max(0,(n.completedAt??Date.now())-e)}t.toolCall=n,t.streaming=!1,a.executionId&&(t.agentMetadata=t.agentMetadata??{executionId:a.executionId,iteration:a.iteration??Y}),_(t)}else if(a.type===`await`&&a.toolName){let e=typeof a.toolCallId==`string`&&a.toolCallId.length>0?a.toolCallId:void 0,n=e??a.toolId??`local-${h()}`,r=L(n),i=a.toolName,o=a.origin===`webmcp`&&!t(i)?`webmcp:${i}`:i,s=t(o),c=r.toolCall??{id:n,status:`pending`};c.name=o,c.args=a.parameters,c.status=s?`running`:`complete`,c.chunks=c.chunks??[],c.startedAt=c.startedAt??R(a.awaitedAt),s?(c.completedAt=void 0,c.duration=void 0,c.durationMs=void 0):c.completedAt=c.completedAt??c.startedAt,r.toolCall=c,r.streaming=!1,r.agentMetadata={...r.agentMetadata,executionId:a.executionId??r.agentMetadata?.executionId,awaitingLocalTool:!0,...e?{webMcpToolCallId:e}:{}},_(r)}else if(a.type===`text_start`){let e=typeof a.id==`string`?a.id:null,t=typeof a.parentToolCallId==`string`&&a.parentToolCallId?a.parentToolCallId:null;if(e&&t){C.set(e,t);continue}let n=v;n&&(X===`flow`?(W(n),H=n):(n.streaming=!1,_(n)),v=null),x=typeof a.id==`string`?a.id:x,S=``}else if(a.type===`text_delta`){let e=typeof a.id==`string`?a.id:null,t=e?C.get(e):void 0;if(e&&t){let n=typeof a.delta==`string`?a.delta:``,r=(T.get(e)??``)+n;if(T.set(e,r),r.trim()===``)continue;let i=G(e,t);i.agentMetadata={...i.agentMetadata,executionId:a.executionId,parentToolId:t},U(i,r,n,void 0);continue}if(x=typeof a.id==`string`?a.id:x,X===`flow`){let e=typeof a.delta==`string`?a.delta:``;if(S+=e,S.trim()===``)continue;let t=A();t.agentMetadata={executionId:a.executionId,iteration:Y},U(t,S,e,void 0),y=t;continue}let n=typeof a.delta==`string`?a.delta:``;S+=n;let r=A();r.agentMetadata={executionId:a.executionId,iteration:Y,turnId:Q??void 0,agentName:$?.agentName},U(r,S,n,void 0),y=r}else if(a.type===`text_complete`){let e=typeof a.id==`string`?a.id:null;if(e&&C.has(e)){let t=w.get(e);t&&W(t),C.delete(e),T.delete(e),w.delete(e);continue}let t=v;t&&(X===`flow`?(W(t),H=t):((t.content??``)===``&&typeof a.text==`string`&&(t.content=a.text),t.streaming=!1,_(t)),v=null),x=null,S=``}else if(a.type===`step_complete`){if(a.stepType===`tool`)continue;if(a.success===!1){let e=a.error||`Step failed`;o({type:`error`,error:Error(e)});let t=v;t&&t.streaming&&(t.streaming=!1,_(t)),o({type:`status`,status:`idle`});continue}{let e=H;H=null;let t=a.stopReason,n=(a.result&&typeof a.result==`object`?a.result:null)?.response;if(e)t&&(e.stopReason=t),n==null?e.streaming!==!1&&(B.delete(e.id),V.delete(e.id),e.streaming=!1,_(e)):ie(e,n);else{let e=n!=null&&n!==``;if(e||t&&t!==`end_turn`&&t!==`unknown`){let r=A();t&&(r.stopReason=t),e?W(r,n):(r.streaming=!1,_(r))}}continue}}else if(a.type===`execution_start`)X=a.kind===`flow`?`flow`:`agent`,Z=!0,X===`agent`&&($={executionId:a.executionId,agentId:a.agentId??`virtual`,agentName:a.agentName??``});else if(a.type===`turn_start`){let e=typeof a.iteration==`number`?a.iteration:Y;if(e!==Y){if(ae===`separate`&&e>1){let e=v;e&&(e.streaming=!1,_(e),v=null)}Y=e}Q=typeof a.id==`string`?a.id:null,y=null}else if(a.type===`tool_input_delta`){let e=a.toolCallId;if(e){let t=D.get(e);t?.toolCall&&(t.toolCall.chunks=t.toolCall.chunks??[],t.toolCall.chunks.push(a.delta??``),_(t))}}else if(a.type===`tool_input_complete`){if(M.has(a.toolCallId))continue;let e=L(a.toolCallId),t=e.toolCall;t.args=a.parameters,t.name=a.toolName??t.name,_(e)}else if(a.type===`turn_complete`){let e=a.stopReason,t=v??y;if(e&&t!==null){let n=a.id;(!n||t.agentMetadata?.turnId===n)&&(t.stopReason=e,_(t))}Q===a.id&&(Q=null)}else if(a.type===`media_start`){let e=String(a.id);J.set(e,{mediaType:typeof a.mediaType==`string`?a.mediaType:void 0,toolCallId:a.toolCallId,parts:[]})}else if(a.type===`media_delta`){let e=J.get(String(a.id));e&&typeof a.delta==`string`&&e.parts.push(a.delta)}else if(a.type===`media_complete`){let e=String(a.id),t=J.get(e);J.delete(e);let n=(typeof a.mediaType==`string`?a.mediaType:void 0)??t?.mediaType??`application/octet-stream`,r=typeof a.data==`string`?a.data:void 0,i=typeof a.url==`string`?a.url:t&&t.parts.length>0?t.parts.join(``):void 0,o=null;if(r)o={type:`media`,data:r,mediaType:n};else if(i){let e=n.toLowerCase();o={type:e===`image`||e.startsWith(`image/`)?`image-url`:`file-url`,url:i,mediaType:n}}let c=a.toolCallId??t?.toolCallId,l=o?[o]:[],u=[];for(let e of l){if(!e||typeof e!=`object`)continue;let t=e,n=typeof t.type==`string`?t.type:void 0,r=typeof t.mediaType==`string`?t.mediaType.toLowerCase():``,i=null,a=``;if(n===`media`){let e=typeof t.data==`string`?t.data:void 0;if(!e)continue;a=r.length>0?r:`application/octet-stream`,i=`data:${a};base64,${e}`}else if(n===`image-url`){let e=typeof t.url==`string`?t.url:void 0;if(!e)continue;a=r,i=e}else if(n===`file-url`){let e=typeof t.url==`string`?t.url:void 0;if(!e)continue;a=r,i=e}else continue;if(i){if(n===`image-url`||a.startsWith(`image/`))u.push({type:`image`,image:i,...a.includes(`/`)?{mimeType:a}:{}});else if(a.startsWith(`audio/`))u.push({type:`audio`,audio:i,mimeType:a});else if(a.startsWith(`video/`))u.push({type:`video`,video:i,mimeType:a});else{let e=a||`application/octet-stream`;u.push({type:`file`,data:i,mimeType:e,filename:s(e)})}}}if(u.length>0){let e=h(),t=c,n={id:`agent-media-${typeof t==`string`&&t.length>0?`${t}-${e}`:String(e)}`,role:`assistant`,content:``,contentParts:u,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e,agentMetadata:{executionId:a.executionId,iteration:Y}};_(n);let r=v;r&&(r.streaming=!1,_(r)),v=null,b.current=null}}else if(a.type===`execution_complete`){let e=v;e&&(a.kind===`flow`&&e.streaming!==!1?W(e):(e.streaming=!1,_(e)),v=null),x=null,S=``,H=null,o({type:`status`,status:`idle`,terminal:!0})}else if(a.type===`execution_error`){let e=typeof a.error==`string`?a.error:a.error?.message??`Execution error`;o({type:`error`,error:Error(e)})}else if(a.type!==`ping`){if(a.type===`approval_start`){let e=a.approvalId??`approval-${h()}`,t={id:`approval-${e}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,variant:`approval`,sequence:h(),approval:{id:e,status:`pending`,agentId:$?.agentId??`virtual`,executionId:a.executionId??$?.executionId??``,toolName:a.toolName??``,toolType:a.toolType,description:a.description??`Execute ${a.toolName??`tool`}`,...typeof a.reason==`string`&&a.reason?{reason:a.reason}:{},parameters:a.parameters,...typeof a.toolCallId==`string`&&a.toolCallId?{toolCallId:a.toolCallId}:{}}};_(t)}else if(a.type===`approval_complete`){let e=a.approvalId;if(e){let t={id:`approval-${e}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,variant:`approval`,sequence:h(),approval:{id:e,status:a.decision??`approved`,agentId:$?.agentId??`virtual`,executionId:a.executionId??$?.executionId??``,toolName:``,description:``,resolvedAt:Date.now()}};_(t)}}else if(a.type===`artifact_start`||a.type===`artifact_delta`||a.type===`artifact_update`||a.type===`artifact_complete`){if(a.type===`artifact_start`){let e=a.artifactType,t=String(a.id),s=typeof a.title==`string`?a.title:void 0,c=a.file,l;if(c&&typeof c==`object`&&!Array.isArray(c)&&typeof c.path==`string`&&typeof c.mimeType==`string`&&(l={path:c.path,mimeType:c.mimeType,...typeof c.language==`string`?{language:c.language}:{}}),o({type:`artifact_start`,id:t,artifactType:e,title:s,component:typeof a.component==`string`?a.component:void 0,...l?{file:l}:{}}),F.set(t,{markdown:``,title:s,file:l}),!P.has(t)){P.add(t);let o=r(n.config().features?.artifacts,{artifactType:e,...l?{file:l}:{}}),c=typeof a.component==`string`?a.component:void 0,u={id:`artifact-ref-${t}`,role:`assistant`,content:``,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!0,sequence:h(),rawContent:i(o,{artifactId:t,title:s,artifactType:e,status:`streaming`,...l?{file:l}:{},...c?{component:c}:{}})};N.set(t,u),_(u)}}else if(a.type===`artifact_delta`){let e=String(a.id),t=typeof a.delta==`string`?a.delta:String(a.delta??``);o({type:`artifact_delta`,id:e,artDelta:t});let n=F.get(e);n&&(n.markdown+=t)}else if(a.type===`artifact_update`){let e=a.props&&typeof a.props==`object`&&!Array.isArray(a.props)?a.props:{};o({type:`artifact_update`,id:String(a.id),props:e,component:typeof a.component==`string`?a.component:void 0});let t=F.get(String(a.id));t&&(t.props={...t.props??{},...e})}else if(a.type===`artifact_complete`){let e=String(a.id);o({type:`artifact_complete`,id:e});let t=N.get(e);if(t){t.streaming=!1;try{let n=JSON.parse(t.rawContent??`{}`);if(n.props){n.props.status=`complete`;let t=F.get(e);t?.markdown&&(n.props.markdown=t.markdown),t?.file&&(n.props.file=t.file),n.component===`PersonaArtifactInline`&&t?.props&&Object.keys(t.props).length>0&&(n.props.componentProps=t.props)}t.rawContent=JSON.stringify(n)}catch{}F.delete(e),_(t),N.delete(e)}}}else if(a.type===`error`&&a.recoverable===!1&&a.error!=null&&a.error!==``){let e=typeof a.error==`string`?a.error:a.error?.message==null?`Execution error`:String(a.error.message);o({type:`error`,error:Error(e)});let t=v;t&&t.streaming&&(t.streaming=!1,_(t)),o({type:`status`,status:`idle`})}}}K.length=0};;){let{done:e,value:t}=await f.read();if(e)break;p+=ee.decode(t,{stream:!0});let r=p.split(`
2
-
3
- `);p=r.pop()??``;for(let e of r){let t=e.split(`
4
- `),r=`message`,i=``,a=null;for(let e of t)e.startsWith(`event:`)?r=e.replace(`event:`,``).trim():e.startsWith(`data:`)?i+=e.replace(`data:`,``).trim():e.startsWith(`id:`)&&(a=e.slice(3).trim());let s=()=>{a!==null&&a!==``&&o({type:`cursor`,id:a})};if(!i){s();continue}let c;try{c=JSON.parse(i)}catch(e){o({type:`error`,error:e instanceof Error?e:/* @__PURE__ */ Error(`Failed to parse chat stream payload`)});continue}let l=typeof c==`object`&&c&&!Array.isArray(c)?c:null,d=r===`message`?typeof l?.type==`string`?l.type:`message`:r;if(n.onSSEEvent?.(d,c),n.parseSSEEvent){b.current=v;let e=await u(n,c,o,b,_,h,re);if(b.current&&b.current!==v&&(v=b.current),e){s();continue}}l&&(K.push({...l,type:d}),q()),s()}}q()}export{l as preferFinalStructuredContent,a as resolveApproval,o as resumeFlow,d as streamResponse};
@@ -1 +0,0 @@
1
- import{o as e}from"./chunk-CfNME4R9.js";const t=e=>({isError:!0,content:[{type:`text`,text:e}]}),n=(e,t=`WebMCP tool execution failed.`)=>e instanceof Error&&e.message?e.message:typeof e==`string`&&e?e:t;async function r(e,t,n,r){let i=`approval-${t.id}`,a=`approval-error-${t.id}`,o={};e.s.approvalTokens.set(i,o);let s={...t,status:n,resolvedAt:Date.now()},c=e.s.messages.find(e=>e.id===i),l={id:i,role:`assistant`,content:``,createdAt:c?.createdAt??(/* @__PURE__ */ new Date()).toISOString(),...c?.sequence===void 0?{}:{sequence:c.sequence},streaming:!1,variant:`approval`,approval:s};e.s.upsertMessage(l),e.s.abortController?.abort(),e.s.abortController=new AbortController,e.setStreaming(!0);let u=e.s.config.approval,d=u&&typeof u==`object`?u.onDecision:void 0;try{let c;if(c=d?await d({approvalId:t.id,executionId:t.executionId,agentId:t.agentId,toolName:t.toolName},n,r):await e.s.client.resolveApproval({agentId:t.agentId,executionId:t.executionId,approvalId:t.id},n),c){let r=null;if(c instanceof Response){if(!c.ok){let n=await c.json().catch(()=>null),r=n?.message??n?.error??`Approval request failed: ${c.status}`,u=n?.code===`APPROVAL_ALREADY_RESOLVED`||c.status===404&&/no paused execution/i.test(String(n?.error)),d=e.s.messages.find(e=>e.id===i);throw e.s.approvalTokens.get(i)===o&&d?.approval?.resolvedAt===s.resolvedAt&&(e.s.upsertMessage({...l,approval:u?{...s,status:`timeout`}:t}),u&&e.settleApprovalPausedToolCall(i),e.s.upsertMessage({id:a,role:`assistant`,content:r,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e.nextSequence()})),Error(r)}r=c.body}else c instanceof ReadableStream&&(r=c);e.s.approvalTokens.get(i)===o&&e.s.messages.some(e=>e.id===a)&&(e.s.messages=e.s.messages.filter(e=>e.id!==a),e.s.callbacks.onMessagesChanged([...e.s.messages])),r?await e.s.connectStream(r,{allowReentry:!0}):(n===`denied`&&(e.settleApprovalPausedToolCall(i),e.appendMessage({id:`denial-${t.id}`,role:`assistant`,content:`Tool execution was denied by user.`,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e.nextSequence()})),e.setStreaming(!1),e.s.abortController=null)}else e.setStreaming(!1),e.s.abortController=null}catch(t){let n=t instanceof Error&&(t.name===`AbortError`||t.message.includes(`aborted`)||t.message.includes(`abort`));e.setStreaming(!1),e.s.abortController=null,n||e.s.callbacks.onError?.(t instanceof Error?t:Error(String(t)))}finally{e.s.approvalTokens.get(i)===o&&e.s.approvalTokens.delete(i)}}async function i(e,t,n){if(e.s.messages.find(e=>e.id===t.id)?.agentMetadata?.askUserQuestionAnswered===!0)return;let r=t.agentMetadata?.executionId,i=t.toolCall?.name;if(!r||!i){e.s.callbacks.onError?.(/* @__PURE__ */ Error(`resolveAskUserQuestion: message is missing executionId or toolCall.name`));return}let a=typeof n==`string`?void 0:n;if(a===void 0&&typeof n==`string`){let e=t.toolCall?.args,r=Array.isArray(e?.questions)?e.questions:[];if(r.length===1){let e=typeof r[0]?.question==`string`?r[0].question:``;e&&(a={[e]:n})}}e.s.markAskUserQuestionResolved(t,a),e.s.abortController?.abort(),e.s.abortController=new AbortController,e.setStreaming(!0);let o=t.toolCall.id,s=t.toolCall?.args,c=Array.isArray(s?.questions)?s.questions:[];if(c.length===0){let t=typeof n==`string`?n:Object.entries(n).map(([e,t])=>`${e}: ${Array.isArray(t)?t.join(`, `):t}`).join(` | `);e.appendMessage({id:`ask-user-answer-${o}`,role:`user`,content:t,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e.nextSequence()})}else{let t=a??{};c.forEach((n,r)=>{let i=typeof n?.question==`string`?n.question:``;if(!i)return;let a=t[i],s=Array.isArray(a)?a.join(`, `):typeof a==`string`?a:``;e.appendMessage({id:`ask-user-q-${o}-${r}`,role:`assistant`,content:i,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e.nextSequence()}),e.appendMessage({id:`ask-user-a-${o}-${r}`,role:`user`,content:s||`*Skipped*`,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,sequence:e.nextSequence()})})}try{let t=await e.s.client.resumeFlow(r,{[i]:n},{after:e.resumeAfter(r)});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`Resume failed: ${t.status}`)}t.body?await e.s.connectStream(t.body,{allowReentry:!0}):(e.setStreaming(!1),e.s.abortController=null)}catch(t){let n=t instanceof Error&&(t.name===`AbortError`||t.message.includes(`aborted`)||t.message.includes(`abort`));e.setStreaming(!1),e.s.abortController=null,n||e.s.callbacks.onError?.(t instanceof Error?t:Error(String(t)))}}function a(e,t){let n=[e.s.messages.find(e=>e.id===t.id)?.toolCall?.startedAt,t.toolCall?.startedAt];for(let e of n)if(typeof e==`number`&&Number.isFinite(e))return e;return Date.now()}function o(e,t){return t.toolCall?.name===`suggest_replies`&&(e.s.messages.find(e=>e.id===t.id)??t).agentMetadata?.suggestRepliesResolved===!0}function s(e,t){let n=a(e,t);return e.s.upsertMessage({...t,streaming:!0,agentMetadata:{...t.agentMetadata,awaitingLocalTool:!1},toolCall:t.toolCall?{...t.toolCall,status:`running`,startedAt:n,completedAt:void 0,duration:void 0,durationMs:void 0}:t.toolCall}),n}function c(e,t,n,r,i=Date.now(),a){e.s.messages.some(e=>e.id===t.id)&&e.s.upsertMessage({...t,streaming:!1,agentMetadata:{...t.agentMetadata,awaitingLocalTool:!1,...a},toolCall:t.toolCall?{...t.toolCall,status:`complete`,result:n,startedAt:r,completedAt:i,duration:void 0,durationMs:Math.max(0,i-r)}:t.toolCall})}async function l(r,i,a){let l=[],u=new AbortController;r.s.webMcpResolveControllers.add(u),r.setStreaming(!0);let d=async a=>{let d=a.toolCall?.name,f=a.toolCall?.id;if(!d||!f)return null;let p=`${i}:${f}`;if(r.s.webMcpInflightKeys.has(p)||r.s.webMcpResolvedKeys.has(p)||o(r,a))return null;r.s.webMcpInflightKeys.add(p),l.push(p);let m=s(r,a),h=a.agentMetadata?.webMcpToolCallId??d;if(d===`suggest_replies`)return{dedupeKey:p,resumeKey:h,output:e(),toolMessage:a,startedAt:m,completedAt:Date.now()};let g=r.s.client.executeWebMcpToolCall(d,a.toolCall?.args,u.signal),_;if(!g)_={isError:!0,content:[{type:`text`,text:`WebMCP not enabled on this widget.`}]};else try{_=await g}catch(e){let i=e instanceof Error&&(e.name===`AbortError`||e.message.includes(`aborted`)||e.message.includes(`abort`));return i||r.s.callbacks.onError?.(e instanceof Error?e:Error(String(e))),c(r,a,t(i?`Aborted by cancel()`:n(e)),m),r.s.webMcpInflightKeys.delete(p),null}return u.signal.aborted?(c(r,a,t(`Aborted by cancel()`),m),r.s.webMcpInflightKeys.delete(p),null):{dedupeKey:p,resumeKey:h,output:_,toolMessage:a,startedAt:m,completedAt:Date.now()}},f;if(r.s.config.webmcp?.execution===`sequential`){f=[];for(let e of a)f.push(await d(e))}else f=await Promise.all(a.map(d));let p=[];try{if(p=f.filter(e=>e!==null),p.length===0)return;let e={};for(let t of p)e[t.resumeKey]=t.output;let t=await r.s.client.resumeFlow(i,e,{signal:u.signal,after:r.resumeAfter(i)});if(!t.ok){let e=await t.json().catch(()=>null);throw Error(e?.error??`Resume failed: ${t.status}`)}let n=p[0].dedupeKey;for(let e of p){r.s.webMcpResolvedKeys.add(e.dedupeKey);let t=e.toolMessage.toolCall?.name,i=e.toolMessage.agentMetadata?.webMcpToolCallId;c(r,e.toolMessage,e.output,e.startedAt,e.completedAt,{...t===`suggest_replies`?{suggestRepliesResolved:!0}:{},...t&&i?{clientToolAnswer:{toolCallId:i,toolName:t,args:e.toolMessage.toolCall?.args,result:e.output,batch:n}}:{}})}t.body&&await r.s.connectStream(t.body,{allowReentry:!0})}catch(e){if(!(e instanceof Error&&(e.name===`AbortError`||e.message.includes(`aborted`)||e.message.includes(`abort`))))r.s.callbacks.onError?.(e instanceof Error?e:Error(String(e)));else for(let e of p)c(r,e.toolMessage,t(`Aborted by cancel()`),e.startedAt)}finally{for(let e of l)r.s.webMcpInflightKeys.delete(e);r.s.webMcpResolveControllers.delete(u),r.s.webMcpResolveControllers.size===0&&!r.s.abortController&&r.setStreaming(!1)}}async function u(e,t){let n=t.agentMetadata?.executionId,r=t.toolCall?.name,i=t.toolCall?.id;if(!n){e.s.callbacks.onError?.(/* @__PURE__ */ Error(`WebMCP await missing executionId: dispatch left paused.`));return}if(!r)return;if(!i){let t=`${n}:__no_tool_id__:${r}`;if(e.s.webMcpInflightKeys.has(t)||e.s.webMcpResolvedKeys.has(t))return;e.s.webMcpInflightKeys.add(t);try{await d(e,n,r,{isError:!0,content:[{type:`text`,text:`WebMCP await missing toolCall.id: cannot execute the page tool.`}]}),e.s.webMcpResolvedKeys.add(t)}catch(t){e.s.callbacks.onError?.(t instanceof Error?t:Error(String(t)))}finally{e.s.webMcpInflightKeys.delete(t)}return}let a=`${n}:${i}`;if(!(e.s.webMcpInflightKeys.has(a)||e.s.webMcpResolvedKeys.has(a)||o(e,t)))return l(e,n,[t])}async function d(e,t,n,r,i){let a=await e.s.client.resumeFlow(t,{[n]:r},{signal:i?.signal,after:e.resumeAfter(t)});if(!a.ok){let e=await a.json().catch(()=>null);throw Error(e?.error??`Resume failed: ${a.status}`)}i?.onHttpOk?.(),a.body?await e.s.connectStream(a.body,{allowReentry:!0}):e.s.webMcpResolveControllers.size===0&&(e.setStreaming(!1),e.s.abortController=null)}export{r as resolveApproval,i as resolveAskUserQuestion,u as resolveWebMcpToolCall,l as resolveWebMcpToolCallBatch};
@@ -1 +0,0 @@
1
- import{t as e}from"./chunk-BtTP1Wgi.js";import{t}from"./chunk-D5BxWOFB.js";import{d as n,h as r}from"./chunk-dRBlrLd7.js";import{r as i,t as a}from"./chunk-CQw6A6rt.js";import{Ban as o,ChevronDown as s,ChevronUp as c,ShieldAlert as l,ShieldCheck as u,ShieldX as d}from"lucide";let f=()=>void 0;const p=e=>{f=e.webMcpToolTitle},m=e=>f(e),h=e=>{let t=(e.startsWith(`webmcp:`)?e.slice(r.length):e).replace(/([a-z0-9])([A-Z])/g,`$1 $2`).split(/[_\-\s.]+/).filter(Boolean);if(t.length===0)return e;let n=t.join(` `).toLowerCase();return n.charAt(0).toUpperCase()+n.slice(1)},g=e=>e?.approval===!1?void 0:e?.approval,_=(e,t,n)=>{let r=g(n)?.detailsDisplay??`collapsed`;return t.get(e)??r===`expanded`},v=(t,n,r)=>{let i=g(r);t.setAttribute(`aria-expanded`,n?`true`:`false`);let a=t.querySelector(`[data-approval-details-label]`);a&&(a.textContent=n?i?.hideDetailsLabel??`Hide details`:i?.showDetailsLabel??`Show details`);let o=t.querySelector(`[data-approval-details-chevron]`);if(o){o.innerHTML=``;let t=e(n?c:s,14,`currentColor`,2);t&&o.appendChild(t)}},y=(e,t,n,r=/* @__PURE__ */ new Map)=>{let i=t.querySelector(`button[data-bubble-type="approval"]`),a=t.querySelector(`[data-approval-details]`);if(!i||!a)return;let o=_(e,r,n);v(i,o,n),a.style.display=o?``:`none`},b=(r,i,a=/* @__PURE__ */ new Map)=>{let o=r.approval,s=i?.approval===!1?void 0:i?.approval,c=o?.status===`pending`,f=t(`div`,[`persona-approval-bubble`,`persona-w-full`,`persona-rounded-2xl`,`persona-border`,`persona-shadow-sm`,`persona-overflow-hidden`].join(` `));if(f.id=`bubble-${r.id}`,f.setAttribute(`data-message-id`,r.id),f.style.backgroundColor=s?.backgroundColor??`var(--persona-approval-bg)`,f.style.borderColor=s?.borderColor??`var(--persona-approval-border)`,f.style.boxShadow=s?.shadow===void 0?`var(--persona-approval-shadow)`:s.shadow.trim()===``?`none`:s.shadow,!o)return f;let p=t(`div`,`persona-flex persona-items-start persona-gap-3 persona-px-4 persona-py-3`),g=t(`div`,`persona-flex-shrink-0 persona-mt-0.5`);g.setAttribute(`data-approval-icon`,`true`);let y=o.status===`denied`?d:o.status===`timeout`?l:u,b=o.status===`approved`?`var(--persona-feedback-success, var(--persona-palette-colors-success-600))`:o.status===`denied`?`var(--persona-feedback-error, var(--persona-palette-colors-error-600))`:o.status===`timeout`?`var(--persona-feedback-warning, var(--persona-palette-colors-warning-600))`:s?.titleColor??`currentColor`,x=e(y,20,b,2);x&&g.appendChild(x);let S=t(`div`,`persona-flex-1 persona-min-w-0`),C=t(`div`,`persona-flex persona-items-center persona-gap-2`),w=t(`span`,`persona-text-sm persona-font-medium persona-text-persona-primary`);if(s?.titleColor&&(w.style.color=s.titleColor),w.textContent=s?.title??`Approval Required`,C.appendChild(w),!c){let e=t(`span`,`persona-inline-flex persona-items-center persona-px-2 persona-py-0.5 persona-rounded-full persona-text-xs persona-font-medium`);e.setAttribute(`data-approval-status`,o.status),o.status===`approved`?(e.style.backgroundColor=`var(--persona-palette-colors-success-100)`,e.style.color=`var(--persona-palette-colors-success-700)`,e.textContent=`Approved`):o.status===`denied`?(e.style.backgroundColor=`var(--persona-palette-colors-error-100)`,e.style.color=`var(--persona-palette-colors-error-700)`,e.textContent=`Denied`):o.status===`timeout`&&(e.style.backgroundColor=`var(--persona-palette-colors-warning-100)`,e.style.color=`var(--persona-palette-colors-warning-700)`,e.textContent=`Timeout`),C.appendChild(e)}S.appendChild(C);let T=o.toolType===`webmcp`||o.toolName.startsWith(`webmcp:`)?m(o.toolName):void 0,E=s?.formatDescription?.({toolName:o.toolName,toolType:o.toolType,description:o.description,parameters:o.parameters,...T?{displayTitle:T}:{},...o.reason?{reason:o.reason}:{}}),D=!o.toolName,O=E||(D?o.description:`The assistant wants to use “${T??h(o.toolName)}”.`),k=t(`p`,`persona-text-sm persona-mt-0.5 persona-text-persona-muted`);if(k.setAttribute(`data-approval-summary`,`true`),s?.descriptionColor&&(k.style.color=s.descriptionColor),k.textContent=O,S.appendChild(k),o.reason){let e=t(`p`,`persona-text-sm persona-mt-1 persona-text-persona-muted`);e.setAttribute(`data-approval-reason`,`true`),s?.reasonColor?e.style.color=s.reasonColor:s?.descriptionColor&&(e.style.color=s.descriptionColor);let n=t(`span`,`persona-font-medium`);n.textContent=`${s?.reasonLabel??`Agent's stated reason:`} `,e.appendChild(n),e.appendChild(document.createTextNode(o.reason)),S.appendChild(e)}let A=s?.detailsDisplay??`collapsed`,j=!!o.description&&!D,M=j||!!o.parameters;if(A!==`hidden`&&M){let e=_(r.id,a,i),c=t(`button`,`persona-inline-flex persona-items-center persona-gap-1 persona-mt-1 persona-p-0 persona-border-none persona-bg-transparent persona-text-xs persona-font-medium persona-cursor-pointer persona-text-persona-muted`);c.type=`button`,c.setAttribute(`data-expand-header`,`true`),c.setAttribute(`data-bubble-type`,`approval`),s?.descriptionColor&&(c.style.color=s.descriptionColor);let l=t(`span`);l.setAttribute(`data-approval-details-label`,`true`);let u=t(`span`,`persona-inline-flex persona-items-center`);u.setAttribute(`data-approval-details-chevron`,`true`),c.append(l,u),v(c,e,i),S.appendChild(c);let d=t(`div`);if(d.setAttribute(`data-approval-details`,`true`),d.style.display=e?``:`none`,j){let e=t(`p`,`persona-text-sm persona-mt-1 persona-text-persona-muted`);s?.descriptionColor&&(e.style.color=s.descriptionColor),e.textContent=o.description,d.appendChild(e)}if(o.parameters){let e=t(`pre`,`persona-mt-2 persona-text-xs persona-p-2 persona-rounded persona-overflow-x-auto persona-max-h-32 persona-bg-persona-container persona-text-persona-primary`);s?.parameterBackgroundColor&&(e.style.backgroundColor=s.parameterBackgroundColor),s?.parameterTextColor&&(e.style.color=s.parameterTextColor),e.style.fontSize=`0.75rem`,e.style.lineHeight=`1rem`,e.textContent=n(o.parameters),d.appendChild(e)}S.appendChild(d)}if(c){let n=t(`div`,`persona-flex persona-gap-2 persona-mt-2`);n.setAttribute(`data-approval-buttons`,`true`);let r=t(`button`,`persona-inline-flex persona-items-center persona-px-3 persona-py-1.5 persona-rounded-md persona-text-xs persona-font-medium persona-border-none persona-cursor-pointer`);r.type=`button`,r.style.backgroundColor=s?.approveButtonColor??`var(--persona-approval-approve-bg)`,r.style.color=s?.approveButtonTextColor??`var(--persona-button-primary-fg)`,r.setAttribute(`data-approval-action`,`approve`);let i=e(u,14,s?.approveButtonTextColor??`var(--persona-button-primary-fg)`,2);i&&(i.style.marginRight=`4px`,r.appendChild(i));let a=document.createTextNode(s?.approveLabel??`Approve`);r.appendChild(a);let o=t(`button`,`persona-inline-flex persona-items-center persona-px-3 persona-py-1.5 persona-rounded-md persona-text-xs persona-font-medium persona-cursor-pointer`);o.type=`button`,o.style.backgroundColor=s?.denyButtonColor??`transparent`,o.style.color=s?.denyButtonTextColor??`var(--persona-feedback-error, var(--persona-palette-colors-error-600))`,o.style.border=`1px solid ${s?.denyButtonTextColor?s.denyButtonTextColor:`var(--persona-palette-colors-error-200)`}`,o.setAttribute(`data-approval-action`,`deny`);let c=e(d,14,s?.denyButtonTextColor??`var(--persona-feedback-error, var(--persona-palette-colors-error-600))`,2);c&&(c.style.marginRight=`4px`,o.appendChild(c));let l=document.createTextNode(s?.denyLabel??`Deny`);o.appendChild(l),n.append(r,o),S.appendChild(n)}return p.append(g,S),f.appendChild(p),f},x=()=>({keyHandlers:/* @__PURE__ */ new Map,popovers:/* @__PURE__ */ new Map,pendingOrder:[],latestPendingApprovalId:null}),S=(e,t)=>{let n=e.keyHandlers.get(t);n&&(document.removeEventListener(`keydown`,n),e.keyHandlers.delete(t));let r=e.popovers.get(t);r&&(r.destroy(),e.popovers.delete(t))},C=(e,t)=>{S(e,t);let n=e.pendingOrder.indexOf(t);n!==-1&&e.pendingOrder.splice(n,1),e.latestPendingApprovalId===t&&(e.latestPendingApprovalId=e.pendingOrder.length?e.pendingOrder[e.pendingOrder.length-1]:null)},w=e=>e?.approval===!1?void 0:e?.approval,T=(e,t,n)=>{let r=n?.detailsDisplay??`collapsed`;return t.get(e)??r===`expanded`},E=e=>{let n=t(`span`,`persona-approval-kbd`);return n.textContent=e,n},D=(e,n)=>{let r=t(`span`,`persona-approval-title`);n?.titleColor&&(r.style.color=n.titleColor);let i=e.toolType===`webmcp`||e.toolName.startsWith(`webmcp:`)?m(e.toolName):void 0,a=n?.formatDescription?.({toolName:e.toolName,toolType:e.toolType,description:e.description??``,parameters:e.parameters,...i?{displayTitle:i}:{},...e.reason?{reason:e.reason}:{}});if(a)return r.textContent=a,r;let o=i??h(e.toolName),s=e.toolType&&e.toolType!==`webmcp`?e.toolType:null;r.append(`The assistant wants to use `);let c=document.createElement(`strong`);if(c.textContent=o,r.appendChild(c),s){r.append(` from `);let e=document.createElement(`strong`);e.textContent=s,r.appendChild(e)}return r},O=n=>{let r=t(`div`,`persona-approval-resolved`),i=e(o,15,`currentColor`,2);i&&r.appendChild(i);let a=t(`span`,`persona-approval-resolved-name`);return a.textContent=n.toolName?h(n.toolName):`Tool`,r.append(a,document.createTextNode(n.status===`timeout`?` timed out`:` denied`)),r},k=(r,i,o,c,l,d,f,p,m=!1)=>{let h=t(`div`,`persona-approval-card persona-shadow-sm`);h.id=`bubble-${o.id}`,h.setAttribute(`data-message-id`,o.id),h.setAttribute(`data-bubble-type`,`approval`),l?.backgroundColor&&(h.style.background=l.backgroundColor),l?.borderColor&&(h.style.borderColor=l.borderColor),l?.shadow!==void 0&&(h.style.boxShadow=l.shadow.trim()===``?`none`:l.shadow);let g=l?.detailsDisplay??`collapsed`,_=!!c.description&&g!==`hidden`,v=c.parameters!=null&&g!==`hidden`&&!m,y=_||v,b=y&&T(o.id,i,l),x=l?.showDetailsLabel??`Show details`,S=l?.hideDetailsLabel??`Hide details`,w=t(`button`,`persona-approval-head`);w.type=`button`,y?(w.setAttribute(`data-action`,`toggle-params`),w.setAttribute(`aria-expanded`,b?`true`:`false`),w.setAttribute(`aria-label`,b?S:x)):w.setAttribute(`data-static`,`true`);let O=t(`span`,`persona-approval-logo`),k=e(u,16,`currentColor`,2);k&&O.appendChild(k),w.appendChild(O);let A=D(c,l);if(y){let n=t(`span`,`persona-approval-toggle`);n.setAttribute(`aria-hidden`,`true`);let r=e(s,14,`currentColor`,2);r&&n.appendChild(r),A.append(` `),A.appendChild(n)}w.appendChild(A),h.appendChild(w);let j=t(`div`,`persona-approval-body`);if(y){let e=t(`div`,`persona-approval-details`);if(e.setAttribute(`data-role`,`params`),e.hidden=!b,_){let n=t(`p`,`persona-approval-desc`);l?.descriptionColor&&(n.style.color=l.descriptionColor),n.textContent=c.description,e.appendChild(n)}if(v){let r=t(`pre`,`persona-approval-params`);l?.parameterBackgroundColor&&(r.style.background=l.parameterBackgroundColor),l?.parameterTextColor&&(r.style.color=l.parameterTextColor),r.textContent=n(c.parameters),e.appendChild(r)}j.appendChild(e)}if(m){let e=t(`div`,`persona-approval-call`);e.setAttribute(`data-role`,`raw-call`);let r=t(`code`,`persona-approval-tool-name`);if(r.textContent=c.toolName,e.appendChild(r),c.parameters!=null){let r=t(`pre`,`persona-approval-params`);l?.parameterBackgroundColor&&(r.style.background=l.parameterBackgroundColor),l?.parameterTextColor&&(r.style.color=l.parameterTextColor),r.textContent=n(c.parameters),e.appendChild(r)}j.appendChild(e)}if(c.reason){let e=t(`p`,`persona-approval-reason`);l?.reasonColor?e.style.color=l.reasonColor:l?.descriptionColor&&(e.style.color=l.descriptionColor);let n=t(`span`,`persona-approval-reason-label`);n.textContent=`${l?.reasonLabel??`Agent's stated reason:`} `,e.append(n,document.createTextNode(c.reason)),j.appendChild(e)}let M=t(`div`,`persona-approval-actions`),N=null,P=e=>{l?.approveButtonColor&&(e.style.background=l.approveButtonColor),l?.approveButtonTextColor&&(e.style.color=l.approveButtonTextColor)},F=t(`button`,`persona-approval-deny`);if(F.type=`button`,F.setAttribute(`data-action`,`deny`),l?.denyButtonColor&&(F.style.background=l.denyButtonColor),l?.denyButtonTextColor&&(F.style.color=l.denyButtonTextColor),F.append(l?.denyLabel??`Deny`),p){let n=t(`div`,`persona-approval-split`),i=t(`button`,`persona-approval-primary`);i.type=`button`,i.setAttribute(`data-action`,`always`),P(i),i.append(l?.approveLabel??`Always allow`,E(`⏎`));let c=t(`button`,`persona-approval-caret`);c.type=`button`,c.setAttribute(`data-action`,`toggle-menu`),c.setAttribute(`aria-label`,`More options`),P(c);let u=e(s,15,`currentColor`,2);u&&c.appendChild(u),n.append(i,c),M.append(n,F),F.append(E(`Esc`));let f=t(`div`,`persona-approval-menu`),p=t(`button`,`persona-approval-menu-item`);p.type=`button`,p.append(`Allow once`,E(`⌘⏎`)),f.appendChild(p),N=a({anchor:n,content:f,placement:`bottom-start`,matchAnchorWidth:!0}),r.popovers.set(o.id,N),p.addEventListener(`click`,()=>{C(r,o.id),d()})}else{let e=t(`button`,`persona-approval-primary persona-approval-primary--solo`);e.type=`button`,e.setAttribute(`data-action`,`allow`),P(e),e.append(l?.approveLabel??`Allow`),M.append(e,F)}return j.appendChild(M),h.appendChild(j),h.addEventListener(`click`,e=>{let t=e.target instanceof Element?e.target.closest(`[data-action]`):null;if(!t)return;let n=t.getAttribute(`data-action`);if(n===`toggle-params`){let e=h.querySelector(`[data-role="params"]`);if(e){let t=!!e.hidden;e.hidden=!t,w.setAttribute(`aria-expanded`,t?`true`:`false`),w.setAttribute(`aria-label`,t?S:x),i.set(o.id,t)}}else n===`toggle-menu`?N?.toggle():n===`always`?(C(r,o.id),d({remember:!0})):n===`allow`?(C(r,o.id),d()):n===`deny`&&(C(r,o.id),f())}),h},A=(e=/* @__PURE__ */ new Map)=>{let t=x();return{plugin:{id:`persona-built-in-approval`,renderApproval:({message:n,approve:r,deny:a,config:o})=>{let s=n?.approval;if(!s)return null;let c=w(o);if(s.status!==`pending`){if(C(t,n.id),s.status===`approved`){let e=document.createElement(`div`);return e.style.display=`none`,e}return O(s)}S(t,n.id);let l=!!o?.clientToken,u=c?.enableAlwaysAllow===!0,d=k(t,e,n,s,c,r,a,u,l);if(u){t.pendingOrder.includes(n.id)||t.pendingOrder.push(n.id),t.latestPendingApprovalId=t.pendingOrder[t.pendingOrder.length-1];let e=e=>{i(e)||n.id===t.latestPendingApprovalId&&(e.key===`Escape`||e.key===`Enter`)&&(e.preventDefault(),e.stopImmediatePropagation(),C(t,n.id),e.key===`Escape`?a():e.metaKey||e.ctrlKey?r():r({remember:!0}))};t.keyHandlers.set(n.id,e),document.addEventListener(`keydown`,e)}return d}},teardown:()=>{for(let e of[...t.keyHandlers.keys(),...t.popovers.keys()])C(t,e);t.latestPendingApprovalId=null}}};export{b as createApprovalBubble,A as createBuiltInApprovalPlugin,h as humanizeToolName,p as initApprovalUi,y as updateApprovalDetailsUI};
@@ -1 +0,0 @@
1
- const e=e=>e.startsWith(`webmcp:`)?e.slice(7):e,t={warn(e,...t){typeof console<`u`&&typeof console.warn==`function`&&console.warn(`[Persona/WebMCP] ${e}`,...t)}};var n=class{#e;#t;#n=!1;#r=null;#i=!1;#a;constructor(e,t){this.config=e,this.#a=t,this.#e=e.onConfirm??null,this.#t=3e4}setConfirmHandler(e){this.#e=e}isOperational(){return this.config.enabled!==!0||!this.#n?!1:this.#c()!==null}async snapshotForDispatch(){if(await this.#o(),this.config.enabled!==!0)return[];let e=this.#c();if(!e)return[];let n;try{n=(await e.getTools()).filter(f)}catch(e){return t.warn(`getTools() threw: shipping an empty WebMCP snapshot.`,e),[]}this.#a.recordToolDisplayTitles(n);let r=typeof location<`u`?location.origin:``;return n.filter(e=>this.#u(e.name)).map(e=>{let t=a(e.annotations);return{name:e.name,description:e.description,parametersSchema:o(e.inputSchema),origin:`webmcp`,...r?{pageOrigin:r}:{},...t?{annotations:t}:{},...t?.untrustedContentHint===!0?{untrustedContentHint:!0}:{}}})}async executeToolCall(t,n,r){if(await this.#o(),this.config.enabled!==!0)return l(`WebMCP is not enabled on this widget.`);let i=this.#c();if(!i){let e=typeof document<`u`&&!!document.modelContext;return l(e?`WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill).`:`WebMCP bridge is not operational on this page (document.modelContext not available).`)}let a=e(t),o;try{o=(await i.getTools()).filter(f)}catch(e){let t=e instanceof Error?e.message:String(e);return l(`Failed to read WebMCP registry: ${t}`)}this.#a.recordToolDisplayTitles(o);let u=o.find(e=>e.name===a);if(!u)return l(`WebMCP tool not registered on this page: ${a}`);if(!this.#u(a))return l(`WebMCP tool not allowed by client allowlist: ${a}`);if(r?.aborted)return l(`Aborted by cancel()`);let d=this.#a.getToolDisplayTitle(a),p={toolName:a,args:n,description:u.description,...d?{title:d}:{},reason:`gate`};if(!await this.#l(p))return l(`User declined the tool call.`);if(r?.aborted)return l(`Aborted by cancel()`);let m=new AbortController,h=!1,g=setTimeout(()=>{h=!0,m.abort()},this.#t),_=()=>m.abort();r&&(r.aborted?m.abort():r.addEventListener(`abort`,_,{once:!0}));try{let e=await i.executeTool(u,c(n),{signal:m.signal});return s(e)}catch(e){if(h)return l(`WebMCP tool '${a}' timed out after ${this.#t}ms`);if(r?.aborted)return l(`Aborted by cancel()`);let t=e instanceof Error?e.message:String(e);return l(t)}finally{clearTimeout(g),r&&r.removeEventListener(`abort`,_)}}#o(){return this.config.enabled===!0?(this.#r||=this.#s(),this.#r):Promise.resolve()}async#s(){try{if(this.#c()){this.#n=!0;return}let e=await this.#a.loadPolyfill();`initializeWebMCPPolyfill`in e?e.initializeWebMCPPolyfill():e.installWebMCP(),this.#n=!0}catch(e){t.warn(`Failed to load @mcp-b/webmcp-polyfill: WebMCP consumption disabled.`,e),this.#n=!1}}#c(){if(typeof document>`u`)return null;let e=document.modelContext;if(!e||typeof e!=`object`)return null;let n=e;return typeof n.getTools!=`function`||typeof n.executeTool!=`function`?(this.#i||(this.#i=!0,t.warn(`document.modelContext is present but does not expose getTools()/executeTool(): WebMCP consumption is disabled. Another (incompatible or older) WebMCP polyfill likely installed document.modelContext before Persona. Remove it, or use a polyfill implementing the strict standard surface (e.g. @mcp-b/webmcp-polyfill).`)),null):e}async#l(e){let n=this.#e??u;try{return await n(e)}catch(n){return t.warn(`Confirm handler threw for WebMCP tool '${e.toolName}'; declining.`,n),!1}}#u(e){let t=this.config.allowlist;return!t||t.length===0||t.some(t=>r(e,t))}};const r=(e,t)=>{if(t===`*`)return!0;let n=t.replace(/[.+?^${}()|[\]\\]/g,`\\$&`);return RegExp(`^`+n.replace(/\*/g,`.*`)+`$`).test(e)},i={type:`object`,properties:{}},a=e=>{if(!e||typeof e!=`object`)return;let t={...typeof e.readOnlyHint==`boolean`?{readOnlyHint:e.readOnlyHint}:{},...typeof e.untrustedContentHint==`boolean`?{untrustedContentHint:e.untrustedContentHint}:{}};return Object.keys(t).length>0?t:void 0},o=e=>{if(e===void 0||e===``)return{...i};if(typeof e==`object`)return e!==null&&!Array.isArray(e)?e:{...i};try{let t=JSON.parse(e);return typeof t==`object`&&t&&!Array.isArray(t)?t:{...i}}catch{return{...i}}},s=e=>{if(e==null)return{content:[{type:`text`,text:``}]};let t;try{t=JSON.parse(e)}catch{return{content:[{type:`text`,text:e}]}}return typeof t==`object`&&t&&Array.isArray(t.content)?t:{content:[{type:`text`,text:typeof t==`string`?t:p(t)}]}},c=e=>{let t;try{t=JSON.stringify(e)??`{}`}catch{t=`{}`}let n=JSON.parse(t);if(typeof n!=`object`||!n)throw TypeError(`WebMCP tool arguments must be an object or array.`);return Object.defineProperty(n,Symbol.toPrimitive,{value:()=>t}),n},l=e=>({isError:!0,content:[{type:`text`,text:e}]}),u=async e=>{if(typeof window>`u`||typeof window.confirm!=`function`)return!1;let t=d(e.args),n=`Allow the AI to call ${e.toolName}`+(t?`\n\nArguments:\n${t}`:``)+(e.description?`\n\n${e.description}`:``);return window.confirm(n)},d=e=>{if(e==null)return``;try{let t=JSON.stringify(e,null,2);return t.length>500?t.slice(0,500)+`…`:t}catch{return String(e)}},f=e=>(e.window===void 0||typeof window<`u`&&e.window===window)&&(e.origin===void 0||typeof location<`u`&&e.origin===location.origin),p=e=>{if(e===void 0)return``;try{return JSON.stringify(e)}catch{return String(e)}};export{n as WebMcpBridge};
@@ -1 +0,0 @@
1
- const e=`4.28.2`;export{e as t};