@runtypelabs/persona 4.29.0 → 4.29.2

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 (134) 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-B2HCRERn.js +9 -0
  13. package/dist/chunk-Bm2-bemv.js +1 -0
  14. package/dist/chunk-BvhTpG6k.js +1 -0
  15. package/dist/{chunk-DjOvgFsn.js → chunk-Car1mORT.js} +1 -1
  16. package/dist/chunk-D5B629Mj.js +1 -0
  17. package/dist/chunk-DO9_WSpy.js +1 -0
  18. package/dist/chunk-DTDHeUsG.js +1 -0
  19. package/dist/chunk-DjFpGFGA.js +1 -0
  20. package/dist/chunk-DrpuvY5W.js +1 -0
  21. package/dist/{chunk-dRBlrLd7.js → chunk-DtmtfIkd.js} +1 -1
  22. package/dist/client-history.js +1 -1
  23. package/dist/client-stream.js +1 -1
  24. package/dist/codegen.cjs +1 -1
  25. package/dist/codegen.js +1 -1
  26. package/dist/{composer-input-D3sB8_P_.d.cts → composer-input-C3Xh1Qzj.d.cts} +1 -1
  27. package/dist/{composer-input-D3sB8_P_.d.ts → composer-input-C3Xh1Qzj.d.ts} +1 -1
  28. package/dist/{context-mention-manager-D2qxE5op.d.cts → context-mention-manager-BsEiGObk.d.cts} +1 -1
  29. package/dist/{context-mention-manager-D2qxE5op.d.ts → context-mention-manager-BsEiGObk.d.ts} +1 -1
  30. package/dist/context-mentions-inline.d.cts +2 -2
  31. package/dist/context-mentions-inline.d.ts +2 -2
  32. package/dist/context-mentions.d.cts +3 -3
  33. package/dist/context-mentions.d.ts +3 -3
  34. package/dist/{defaults-Dsw66XqE.d.cts → defaults-DN-L67ak.d.cts} +1 -1
  35. package/dist/{defaults-Dsw66XqE.d.ts → defaults-DN-L67ak.d.ts} +1 -1
  36. package/dist/event-stream-view.d.cts +1 -1
  37. package/dist/event-stream-view.d.ts +1 -1
  38. package/dist/{fallback-speech-engine-DJpJcWAk.d.cts → fallback-speech-engine-Cph8FTux.d.cts} +1 -1
  39. package/dist/{fallback-speech-engine-DJpJcWAk.d.ts → fallback-speech-engine-Cph8FTux.d.ts} +1 -1
  40. package/dist/forms-ui.d.cts +2 -2
  41. package/dist/forms-ui.d.ts +2 -2
  42. package/dist/history-view.d.cts +1 -1
  43. package/dist/history-view.d.ts +1 -1
  44. package/dist/index.cjs +56 -56
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +6 -6
  47. package/dist/index.d.ts +6 -6
  48. package/dist/index.global.js +2 -3
  49. package/dist/index.global.js.map +1 -1
  50. package/dist/index.js +42 -42
  51. package/dist/index.js.map +1 -1
  52. package/dist/{markdown-parsers-loader-CCY7T4Up.d.cts → markdown-parsers-loader-C4Xze-Jw.d.cts} +1 -1
  53. package/dist/{markdown-parsers-loader-CCY7T4Up.d.ts → markdown-parsers-loader-C4Xze-Jw.d.ts} +1 -1
  54. package/dist/{preview-DKKpfTo7.d.cts → preview-m9QlqsZi.d.cts} +2 -2
  55. package/dist/{preview-DKKpfTo7.d.ts → preview-m9QlqsZi.d.ts} +2 -2
  56. package/dist/{session-DleMr9dZ.d.ts → session-BtvvmWnw.d.cts} +21 -9
  57. package/dist/{session-DleMr9dZ.d.cts → session-BtvvmWnw.d.ts} +21 -9
  58. package/dist/session-actions.js +1 -1
  59. package/dist/session-reconnect.cjs +1 -1
  60. package/dist/session-reconnect.d.cts +8 -2
  61. package/dist/session-reconnect.d.ts +8 -2
  62. package/dist/session-reconnect.js +1 -1
  63. package/dist/smart-dom-reader.d.cts +1 -1
  64. package/dist/smart-dom-reader.d.ts +1 -1
  65. package/dist/theme-editor-preview.cjs +62 -62
  66. package/dist/theme-editor-preview.d.cts +1 -1
  67. package/dist/theme-editor-preview.d.ts +1 -1
  68. package/dist/theme-editor-preview.js +41 -41
  69. package/dist/theme-editor.d.cts +2 -2
  70. package/dist/theme-editor.d.ts +2 -2
  71. package/dist/theme-reference.d.cts +2 -2
  72. package/dist/theme-reference.d.ts +2 -2
  73. package/dist/{types-oAZ1VReS.d.cts → types-DL-oBHE1.d.cts} +41 -3
  74. package/dist/{types-oAZ1VReS.d.ts → types-DL-oBHE1.d.ts} +41 -3
  75. package/dist/voice-client-tools.d.cts +1 -1
  76. package/dist/voice-client-tools.d.ts +1 -1
  77. package/dist/voice-runtime.cjs +3 -3
  78. package/dist/voice-runtime.d.cts +10 -4
  79. package/dist/voice-runtime.d.ts +10 -4
  80. package/dist/voice-runtime.js +5 -5
  81. package/dist/voice-worklet-player.d.cts +2 -2
  82. package/dist/voice-worklet-player.d.ts +2 -2
  83. package/dist/{webmcp-runtime-entry-Deg0NfmB.d.cts → webmcp-runtime-entry-T6SU_TlL.d.cts} +1 -1
  84. package/dist/{webmcp-runtime-entry-Deg0NfmB.d.ts → webmcp-runtime-entry-T6SU_TlL.d.ts} +1 -1
  85. package/dist/webmcp-runtime.d.cts +1 -1
  86. package/dist/webmcp-runtime.d.ts +1 -1
  87. package/dist/widget.css +1 -1
  88. package/package.json +1 -1
  89. package/src/client-approve.test.ts +17 -1
  90. package/src/client-resume.ts +15 -3
  91. package/src/client.interrupt.test.ts +21 -0
  92. package/src/client.ts +24 -4
  93. package/src/components/activity-row.ts +3 -2
  94. package/src/components/approval-actions.test.ts +8 -0
  95. package/src/components/approval-actions.ts +6 -2
  96. package/src/components/approval-bubble.test.ts +14 -0
  97. package/src/components/approval-bubble.ts +8 -1
  98. package/src/components/tool-bubble.ts +8 -5
  99. package/src/generated/runtype-openapi-contract.ts +7 -1
  100. package/src/resume-dedupe-local-only.test.ts +273 -0
  101. package/src/runtime/persist-state.test.ts +86 -0
  102. package/src/session-actions.ts +20 -6
  103. package/src/session-reconnect.ts +18 -1
  104. package/src/session.restored-browser-tools.test.ts +272 -0
  105. package/src/session.test.ts +23 -0
  106. package/src/session.ts +211 -46
  107. package/src/session.voice.test.ts +169 -0
  108. package/src/styles/widget.css +4 -2
  109. package/src/types.ts +37 -2
  110. package/src/ui.restored-browser-tools.test.ts +128 -0
  111. package/src/ui.scroll.test.ts +7 -2
  112. package/src/ui.stream-replay.test.ts +86 -0
  113. package/src/ui.streaming-coalescing.test.ts +183 -0
  114. package/src/ui.ts +152 -124
  115. package/src/ui.typing-indicator.test.ts +21 -0
  116. package/src/utils/formatting.test.ts +9 -1
  117. package/src/utils/formatting.ts +4 -0
  118. package/src/utils/local-only-message.ts +15 -0
  119. package/src/utils/message-fingerprint.test.ts +9 -0
  120. package/src/utils/message-fingerprint.ts +18 -5
  121. package/src/utils/morph.ts +10 -0
  122. package/src/utils/restored-browser-state.ts +50 -0
  123. package/src/utils/storage.ts +12 -1
  124. package/src/utils/voice-prior-tool-results.ts +37 -0
  125. package/src/voice/runtype-voice-provider.ts +13 -8
  126. package/src/voice/session-voice-wiring.ts +1 -2
  127. package/src/voice/voice-delegation.ts +10 -3
  128. package/src/voice/voice.test.ts +38 -2
  129. package/dist/chunk-B6zZsT6F.js +0 -1
  130. package/dist/chunk-CIVsNcrk.js +0 -1
  131. package/dist/chunk-CKdlNyzM.js +0 -9
  132. package/dist/chunk-DbhxjyOB.js +0 -4
  133. package/dist/chunk-DsdqLStH.js +0 -1
  134. package/dist/chunk-GIqbL2Eg.js +0 -1
@@ -0,0 +1,50 @@
1
+ import type { AgentWidgetApproval, AgentWidgetMessage, AgentWidgetToolCall } from "../types";
2
+ import { isWebMcpToolName } from "../webmcp-bridge";
3
+
4
+ export const BROWSER_TOOL_INTERRUPTION =
5
+ "The chat restarted and this browser tool was interrupted. Request a fresh proposal to try again.";
6
+
7
+ export function isBrowserLocalApproval(approval: AgentWidgetApproval): boolean {
8
+ return approval.toolType === "webmcp" && !approval.executionId;
9
+ }
10
+
11
+ /** History cannot restore a browser callback. Server continuations stay live. */
12
+ export function restoreBrowserToolState(message: AgentWidgetMessage): AgentWidgetMessage {
13
+ const approval = message.approval;
14
+ // Server approvals can also name webmcp tools. An execution id identifies
15
+ // their durable continuation; native browser gates have no execution id.
16
+ const interruptedApproval = approval?.status === "pending" && isBrowserLocalApproval(approval);
17
+ let hasBrowserTool = false;
18
+ const settle = (tool: AgentWidgetToolCall): AgentWidgetToolCall => {
19
+ if (!tool.name || !isWebMcpToolName(tool.name)) return tool;
20
+ hasBrowserTool = true;
21
+ // Older await frames used complete for the wire step before the browser
22
+ // had executed anything. A recorded outcome, however, remains historical.
23
+ const unfinished = tool.status !== "complete" ||
24
+ (message.agentMetadata?.awaitingLocalTool === true &&
25
+ tool.result === undefined && tool.success === undefined);
26
+ if (!unfinished) return tool;
27
+ return {
28
+ ...tool,
29
+ status: "complete",
30
+ interrupted: true,
31
+ success: false,
32
+ error: BROWSER_TOOL_INTERRUPTION,
33
+ approvalStatus: tool.approvalStatus === "pending" ? "timeout" : tool.approvalStatus,
34
+ // Retain recorded durations and paired timestamps. Never fabricate an
35
+ // end timestamp or derive a duration from the time spent off the page.
36
+ startedAt: tool.completedAt === undefined ? undefined : tool.startedAt,
37
+ };
38
+ };
39
+ const toolCall = message.toolCall ? settle(message.toolCall) : undefined;
40
+ const tools = message.tools?.map(settle);
41
+ return {
42
+ ...message,
43
+ streaming: hasBrowserTool || interruptedApproval ? false : message.streaming,
44
+ ...(interruptedApproval ? { approval: { ...approval, status: "timeout" as const, interrupted: true } } : {}),
45
+ ...(toolCall ? { toolCall } : {}),
46
+ ...(tools ? { tools } : {}),
47
+ ...(hasBrowserTool && message.agentMetadata?.awaitingLocalTool
48
+ ? { agentMetadata: { ...message.agentMetadata, awaitingLocalTool: false } } : {}),
49
+ };
50
+ }
@@ -30,8 +30,19 @@ const sanitizeArtifacts = (artifacts: PersonaArtifactRecord[]) =>
30
30
  status: "complete" as const
31
31
  }));
32
32
 
33
+ const DEFAULT_PERSIST_KEY_PREFIX = "persona-";
34
+
35
+ /**
36
+ * The widget's default transcript key, scoped by `persistState.keyPrefix` so
37
+ * two widgets on one origin with distinct prefixes keep separate transcripts.
38
+ * The default prefix yields the legacy `"persona-state"` key, so unprefixed
39
+ * widgets keep their stored conversation; prefixed widgets never adopt it.
40
+ */
41
+ export const transcriptStorageKey = (keyPrefix?: string): string =>
42
+ `${keyPrefix ?? DEFAULT_PERSIST_KEY_PREFIX}state`;
43
+
33
44
  export const createLocalStorageAdapter = (
34
- key = "persona-state"
45
+ key = transcriptStorageKey()
35
46
  ): AgentWidgetStorageAdapter => {
36
47
  const getStorage = () => {
37
48
  if (typeof window === "undefined" || !window.localStorage) {
@@ -0,0 +1,37 @@
1
+ import type { AgentWidgetMessage } from "../types";
2
+
3
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
4
+ typeof value === "object" && value !== null && !Array.isArray(value);
5
+
6
+ /**
7
+ * Tool rows for the page tools a voice server already ran before handing the
8
+ * turn to the chat (`delegation_started.input.priorToolResults`). Each row is
9
+ * a completed call carrying `clientToolAnswer`, so proxy/agent payloads replay
10
+ * it to the model as an assistant `toolCalls` + `tool` `toolResults` pair under
11
+ * the same `toolCallId`. Nothing marks it awaiting, so it never runs again.
12
+ * Malformed entries and repeats of a `toolCallId` are skipped.
13
+ */
14
+ export const voicePriorToolRows = (value: unknown, createdAt: string): AgentWidgetMessage[] => {
15
+ const seen = new Set<string>();
16
+ return (Array.isArray(value) ? value : []).flatMap((entry): AgentWidgetMessage[] => {
17
+ if (!isRecord(entry)) return [];
18
+ const { toolCallId, name } = entry;
19
+ if (typeof toolCallId !== "string" || !toolCallId || typeof name !== "string" || !name) return [];
20
+ if (seen.has(toolCallId)) return [];
21
+ seen.add(toolCallId);
22
+ const args = isRecord(entry.arguments) ? entry.arguments : {};
23
+ const result = entry.result ?? null;
24
+ return [
25
+ {
26
+ id: `voice-tool-${toolCallId}`,
27
+ role: "assistant",
28
+ variant: "tool",
29
+ content: "",
30
+ createdAt,
31
+ streaming: false,
32
+ toolCall: { id: toolCallId, name, status: "complete", args, result },
33
+ agentMetadata: { clientToolAnswer: { toolCallId, toolName: name, args, result } },
34
+ },
35
+ ];
36
+ });
37
+ };
@@ -99,7 +99,10 @@
99
99
  // sent), `failed`, or `timeout` (past `timeoutMs`, which bounds the gate too).
100
100
  // Then `delegation_completed{route:'direct', text}` for a delegation that never
101
101
  // started here writes the heard user turn and `text` into the chat. When the
102
- // server falls through, the delegation arrives as today's `delegation_started`.
102
+ // server falls through, the delegation arrives as today's `delegation_started`;
103
+ // its `input.priorToolResults` (page tools the server already ran; sent only
104
+ // with `prior_tool_results`, declared beside `client_tools`) ride along to the
105
+ // chat turn as completed calls, never run again here.
103
106
 
104
107
  import type {
105
108
  VoiceClientToolsSession,
@@ -519,17 +522,17 @@ export class RuntypeVoiceProvider implements VoiceProvider {
519
522
  * the URL, and these params are not secrets.
520
523
  */
521
524
  #voiceSocketUrl(host: string, agentId: string, attach?: URLSearchParams): string {
522
- const capabilities = ["partial_transcript", "context"];
525
+ let capabilities = "partial_transcript,context";
523
526
  if (this.bridge && this.config?.clientDelegation !== false) {
524
- capabilities.push("client_delegation", "delegation_update", "delegation_read_back", "delegation_stream");
525
- if (this.bridge.clientTools?.()) capabilities.push("client_tools");
527
+ capabilities += ",client_delegation,delegation_update,delegation_read_back,delegation_stream";
528
+ if (this.bridge.clientTools?.()) capabilities += ",client_tools,prior_tool_results";
526
529
  }
527
- if (attach) capabilities.unshift("attach");
530
+ if (attach) capabilities = `attach,${capabilities}`;
528
531
  const params = new URLSearchParams({
529
532
  voiceProtocol: VOICE_PROTOCOL,
530
533
  clientVersion: `persona/${VERSION}`,
531
534
  voiceCapabilities: FULL_DUPLEX_CAPABILITY,
532
- clientCapabilities: capabilities.join(","),
535
+ clientCapabilities: capabilities,
533
536
  });
534
537
  attach?.forEach((value, key) => params.set(key, value));
535
538
  return `${toWsBase(host)}/ws/agents/${encodeURIComponent(agentId)}/voice?${params}`;
@@ -877,9 +880,10 @@ export class RuntypeVoiceProvider implements VoiceProvider {
877
880
  this.#pendingContext = this.#buildContextText();
878
881
  }
879
882
  if (this.#clientDelegation && this.#capabilities.has("client_tools") && !this.#fastTier) {
883
+ // INVARIANT: #clientDelegation implies a bridge.
880
884
  this.#fastTier =
881
- this.bridge
882
- ?.clientTools?.()
885
+ this.bridge!
886
+ .clientTools?.()
883
887
  ?.open({
884
888
  send: (frame) => {
885
889
  const ws = this.#ws;
@@ -974,6 +978,7 @@ export class RuntypeVoiceProvider implements VoiceProvider {
974
978
  ? input.userUtteranceIds.filter((id: unknown): id is string => typeof id === "string")
975
979
  : [],
976
980
  messages: Array.isArray(input.messages) ? input.messages : [],
981
+ priorToolResults: input.priorToolResults,
977
982
  },
978
983
  generation,
979
984
  );
@@ -81,8 +81,7 @@ export const wireSessionVoice = (
81
81
  busy: () => p.busy(),
82
82
  parked: () => s.webMcpApprovalResolvers.size > 0,
83
83
  claim: (text, userUtteranceIds) => p.keyed?.claimUserTurn(text, userUtteranceIds) ?? null,
84
- send: (text, userMessageId) =>
85
- s.sendMessage(text, { viaVoice: true, voiceTurn: { userMessageId } }),
84
+ send: (text, voiceTurn) => s.sendMessage(text, { viaVoice: true, voiceTurn }),
86
85
  track: (capture) => {
87
86
  p.setDelegation(capture);
88
87
  },
@@ -45,8 +45,11 @@ export interface VoiceDelegationHost {
45
45
  parked(): boolean;
46
46
  /** The transcript bubble the request came from (see KeyedVoiceTranscript.claimUserTurn). */
47
47
  claim(userText: string, userUtteranceIds: string[]): string | null;
48
- /** sendMessage as a voice turn, submitting `userMessageId`'s bubble when given. */
49
- send(userText: string, userMessageId: string | undefined): Promise<void>;
48
+ /**
49
+ * sendMessage as a voice turn, submitting `userMessageId`'s bubble when
50
+ * given and recording `priorToolResults` as already-run tool calls.
51
+ */
52
+ send(userText: string, voiceTurn: { userMessageId?: string | null; priorToolResults?: unknown }): Promise<void>;
50
53
  /** Route the chat stream's assistant messages and failures into `capture` (or stop). */
51
54
  track(capture: VoiceDelegationCapture | null): void;
52
55
  /** Deny a pending approval (server gate or WebMCP) by its message id. */
@@ -240,6 +243,7 @@ export function createVoiceSessionBridge(host: VoiceDelegationHost): VoiceSessio
240
243
  userText,
241
244
  userUtteranceIds,
242
245
  stream,
246
+ priorToolResults,
243
247
  }: VoiceDelegationRequest): Promise<VoiceDelegationResult> {
244
248
  const live = parks.filter((park) => pendingOf(park).length);
245
249
  const pendingIds = live.flatMap(pendingOf);
@@ -306,7 +310,10 @@ export function createVoiceSessionBridge(host: VoiceDelegationHost): VoiceSessio
306
310
  active = capture;
307
311
  retrack();
308
312
  try {
309
- await host.send(userText, host.claim(userText, userUtteranceIds) ?? undefined);
313
+ await host.send(userText, {
314
+ userMessageId: host.claim(userText, userUtteranceIds),
315
+ priorToolResults,
316
+ });
310
317
  // Local tools and approvals may continue the turn past the first stream.
311
318
  await settled(capture);
312
319
  } catch {
@@ -1762,7 +1762,7 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
1762
1762
  );
1763
1763
  const results = (ws: MockWebSocket) => sentJson(ws).filter((f) => f.type === 'client_tool_result');
1764
1764
 
1765
- it('declares client_tools only when the bridge has WebMCP tools', async () => {
1765
+ it('declares client_tools and prior_tool_results only when the bridge has WebMCP tools', async () => {
1766
1766
  const { ws } = await startFastCall();
1767
1767
  expect(ws.url).toBe(
1768
1768
  voiceUrl('wss://api.example.com', 'a1', [
@@ -1772,12 +1772,15 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
1772
1772
  'delegation_read_back',
1773
1773
  'delegation_stream',
1774
1774
  'client_tools',
1775
+ 'prior_tool_results',
1775
1776
  ]),
1776
1777
  );
1777
1778
  const provider = new RuntypeVoiceProvider(baseConfig());
1778
1779
  provider.setSessionBridge({ ...makeBridge().bridge, clientTools: () => null });
1779
1780
  await provider.startListening();
1780
- expect(new URL(lastWs().url).searchParams.get('clientCapabilities')).not.toContain('client_tools');
1781
+ const declared = new URL(lastWs().url).searchParams.get('clientCapabilities');
1782
+ expect(declared).not.toContain('client_tools');
1783
+ expect(declared).not.toContain('prior_tool_results');
1781
1784
  });
1782
1785
 
1783
1786
  it('sends client_tools after session_config with full webmcp: names and the dispatch fields', async () => {
@@ -2002,6 +2005,39 @@ describe('RuntypeVoiceProvider (realtime streaming)', () => {
2002
2005
  ]);
2003
2006
  });
2004
2007
 
2008
+ it('hands a fall-through its priorToolResults without running them again on the page', async () => {
2009
+ const { ws, calls, executed, recorded, pending } = await startFastCall([...FAST_CAPS, 'prior_tool_results']);
2010
+ const prior = [
2011
+ { toolCallId: 'vtc_01', name: 'webmcp:jump_to_slide', arguments: { position: 5 }, result: { slideTitle: 'Pricing' } },
2012
+ ];
2013
+ heard(ws);
2014
+ toolCall(ws);
2015
+ await flush();
2016
+ expect(executed).toHaveLength(1);
2017
+ ws.triggerMessage(
2018
+ JSON.stringify({
2019
+ type: 'delegation_started',
2020
+ delegationId: 'd1',
2021
+ input: { text: 'Jump to the pricing slide', userUtteranceIds: ['u1'], messages: [], priorToolResults: prior },
2022
+ }),
2023
+ );
2024
+ await flush();
2025
+ expect(calls).toHaveLength(1);
2026
+ expect(calls[0].priorToolResults).toEqual(prior);
2027
+ pending[0]({ status: 'completed', text: 'You are on Pricing.' });
2028
+ await flush();
2029
+ directCompleted(ws);
2030
+ expect(executed).toHaveLength(1);
2031
+ expect(recorded).toEqual([]);
2032
+ });
2033
+
2034
+ it('leaves priorToolResults unset on a fall-through without them', async () => {
2035
+ const { ws, calls } = await startFastCall();
2036
+ started(ws, 'd1');
2037
+ await flush();
2038
+ expect(calls[0].priorToolResults).toBeUndefined();
2039
+ });
2040
+
2005
2041
  it('ignores a direct completion when client_tools was not negotiated', async () => {
2006
2042
  const { ws, recorded } = await startFastCall(ALL_CAPS);
2007
2043
  heard(ws);
@@ -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 +0,0 @@
1
- const e=`4.29.0`;export{e as t};
@@ -1,9 +0,0 @@
1
- import{t as e}from"./chunk-CIVsNcrk.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;#K;#q;#J;#Y;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=null,this.#H=/* @__PURE__ */ new Set,this.#U=null,this.#W=/* @__PURE__ */ new Map,this.#G=[],this.#K=[],this.#q=[],this.#J=[],this.#Y=[]}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.#Z(n,e,t):this.#X(n,e,t)}catch{}}}#X(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(()=>{})}#Z(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.#te(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.#Q(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.#Q(c,t.idleMs-(Date.now()-c.openedAt))},o.onerror=()=>{},o.onclose=()=>{this.#m===c&&this.#$()}}#Q(e,t){clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{this.#m===e&&this.#$()},Math.max(0,t))}#$(){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#ee(){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.#$(),null):(this.#m=null,clearTimeout(e.idleTimer),{ws:e.ws,live:e.state===`live`}):null}#te(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`),this.bridge.clientTools?.()&&i.push(`client_tools`)),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.#he(),this.#ie(l,c,s);let d=await this.#ee();if(s!==this.#d){d?.ws.close(1e3,`client ended call`);return}if(d){let{ws:e}=d;this.#e=e,this.#ne(e,s),d.live||e.send(`{"type":"start"}`),this.#ae(e),this.#be(`listening`);return}let f=new WebSocket(this.#te(o,r),[`runtype.bearer`,i]);f.binaryType=`arraybuffer`,this.#e=f,f.onopen=()=>{s===this.#d&&(this.#ae(f),this.#be(`listening`))},this.#ne(f,s)}catch(e){throw this.#ye(),this.#xe(e),this.#be(`error`),e}}#ne(e,t){e.onmessage=e=>this.#oe(e,t),e.onerror=()=>{t!==this.#d||this.#E||(this.#xe(/* @__PURE__ */ Error(`Voice connection failed`)),this.#be(`error`),this.#ye())},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.#re(n.reason,n.message);else{if(e.code!==1e3){let t=e.code?` (code ${e.code})`:``;this.#xe(/* @__PURE__ */ Error(`Voice connection closed${t}`)),this.#be(`error`)}else this.#be(`idle`);this.#ye()}}}#re(e,t){let n=i.includes(e)&&!this.#k;if(this.#ye(),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.#be(`idle`);else{if(i.includes(e))return this.#D=a,this.#xe(/* @__PURE__ */ Error(a)),this.#be(`error`);if(e===`error`)return this.#be(`error`);this.#D=e===`quota`&&t||r.get(e)||null,this.#be(`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.#ye(),this.#be(`idle`)}async disconnect(){this.#ye(),this.#be(`disconnected`),this.#G=[],this.#K=[],this.#q=[],this.#J=[],this.#Y=[]}stopPlayback(){this.#ve();let e=this.#e;e&&e.readyState===WebSocket.OPEN&&(this.#h&&(this.#_=Date.now()+2e3,e.send(`{"type":"cancel"}`)),this.#be(`listening`))}getInterruptionMode(){return`barge-in`}isBargeInActive(){return this.#l}onLevel(e){this.#n.push(e)}async deactivateBargeIn(){this.#ye(),this.#be(`idle`)}#ie(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.#ae(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)}#ae(e){for(let t of this.#o)e.send(t);this.#o=[],this.#s=0}#oe(e,t){if(t!==this.#d)return;if(e.data instanceof ArrayBuffer){this.#pe(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.#be(`listening`),this.#S.has(`context`)&&!this.#j&&(this.#j=!0,this.#M=this.#se()),this.#x&&this.#S.has(`client_tools`)&&!this.#V&&(this.#V=this.bridge?.clientTools?.()?.open({send:e=>{let n=this.#e;return t!==this.#d||n?.readyState!==WebSocket.OPEN?!1:(n.send(JSON.stringify(e)),!0)},cancelled:e=>this.#w.has(e)}).catch(()=>null)??null);break;case`client_tool_call`:{let e=String(n.delegationId);this.#V&&!this.#W.has(e)&&(this.#W.set(e,this.#U),this.#F.add(e)),this.#V?.then(e=>e?.call(n));break}case`transcript_update`:{let e=n.role===`assistant`?`assistant`:`user`,r=n.utteranceId??n.turnId;if(!r||e===`assistant`&&this.#me())break;let i=String(r);if(e===`user`)n.final===!0&&(this.#ce(t),this.#U={id:i,text:String(n.text??``)}),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.#Se(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.#ce(t),this.#H.add(e),this.#F.delete(e),this.#W.delete(e)&&this.#V?.then(t=>t?.abort(e));let r=n.input;this.#x&&r&&this.#fe(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 if(n.route===`direct`&&this.#V&&!this.#H.has(e)){let t=this.#W.get(e)??this.#U;this.#W.delete(e),this.#H.add(e),this.#F.add(e),this.bridge?.recordDirectTurn?.({delegationId:e,userText:t?.text??``,userUtteranceIds:t?[t.id]:[],assistantText:typeof n.text==`string`?n.text:``})}n.type===`delegation_completed`&&n.speak!==!1&&this.#F.has(e)&&!this.#I.delete(e)&&!this.#S.has(`delegation_read_back`)&&this.#ue(e),this.#g=n.type===`delegation_started`,!this.#u&&!this.#me()&&this.#be(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.#ue(e));break}case`delegation_cancelled`:this.#de(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.#de(String(n.delegationId));break;case`audio_clear`:this.#ve(),this.#_=0,this.#be(`listening`);break;case`transcript_interim`:this.#be(`listening`),this.#Se(`user`,n.text??``,!1);break;case`transcript_final`:{let e=n.role===`assistant`?`assistant`:`user`;this.#be(e===`user`?`processing`:`speaking`),this.#Se(e,n.text??``,!0);break}case`audio_end`:this.#c?this.#c.markStreamEnd():(this.#u=!1,this.#be(`listening`));break;case`metrics`:this.#Ce({llmMs:n.llm_ms,ttsMs:n.tts_ms,firstAudioMs:n.first_audio_ms,totalMs:n.total_ms});break;case`error`:this.#xe(Error(n.error||`Voice error`)),this.#be(`error`);break;case`session_end`:this.#E={reason:String(n.reason),...typeof n.message==`string`&&{message:n.message}}}}async#se(){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)}#ce(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#le(){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()}#ue(e){this.#R=!0,this.#L=e}#de(e,t=!1){this.#w.add(e),this.#L===e&&(this.#R=!1),this.#I.delete(e),this.#H.has(e)||this.#F.delete(e),this.#V?.then(t=>t?.abort(e)),this.bridge?.dropDelegation?.(e,t),this.#C.get(e)?.abort()}#fe(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.#le()).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.#le(),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)})})}#pe(e,t){if(t!==this.#d||!this.#c||this.#me())return;let n=s(e);n.length!==0&&(this.#u||(this.#u=!0,this.#be(`speaking`)),this.#he(),this.#c.enqueue(n),this.#h&&this.#ge(n.length))}#me(){return Date.now()<this.#_}#he(){if(this.#b||!this.#c)return;this.#b=!0;let e=this.#d;this.#c.onFinished(()=>{e===this.#d&&(this.#b=!1,this.#_e())})}#ge(e){let t=Date.now();this.#v=Math.max(t,this.#v)+e/48,clearTimeout(this.#y),this.#y=setTimeout(()=>this.#_e(),this.#v-t+300)}#_e(){this.#u=!1,this.#v=0,this.#e&&this.#e.readyState===WebSocket.OPEN&&this.#be(this.#g?`processing`:`listening`)}#ve(){this.#c?.flush(),this.#b=!1,this.#he(),this.#u=!1,this.#v=0,clearTimeout(this.#y)}#ye(){this.#d+=1,this.#l=!1,this.#u=!1,this.#$(),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.#V?.then(e=>e?.close()),this.#V=null,this.#H.clear(),this.#W.clear(),this.#U=null,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.#G.push(e)}onError(e){this.#K.push(e)}onStatusChange(e){this.#q.push(e)}onTranscript(e){this.#J.push(e)}onMetrics(e){this.#Y.push(e)}#be(e){this.#q.forEach(t=>t(e))}#xe(e){this.#K.forEach(t=>t(e))}#Se(e,t,n,r){this.#J.forEach(i=>i(e,t,n,r))}#Ce(e){this.#Y.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{clientTools:e.clientTools,recordDirectTurn:e.recordDirect,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)},clientTools:()=>i.getClient().getVoiceClientTools(),recordDirect:({delegationId:t,userText:n,userUtteranceIds:r,assistantText:a})=>{let o=e.keyed?.claimUserTurn(n,r),s=!1;i.messages=i.messages.map(e=>{if(e.id!==o||e.role!==`user`)return e;s=!0;let{voiceCaption:t,...n}=e;return{...n,viaVoice:!0}}),s?i.callbacks.onMessagesChanged([...i.messages]):n.trim()&&i.injectMessage({role:`user`,content:n.trim()});let c=a.trim();if(!c)return;let l=`voice-direct-${t}`;i.ttsSpokenMessageIds.add(l),i.injectMessage({id:l,role:`assistant`,content:c})},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};