@runtypelabs/persona 4.28.2 → 4.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) 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.d.cts +1 -1
  6. package/dist/approval-ui.d.ts +1 -1
  7. package/dist/artifacts-ui.d.cts +2 -2
  8. package/dist/artifacts-ui.d.ts +2 -2
  9. package/dist/chunk-BkW8s3fj.js +2 -0
  10. package/dist/chunk-CIVsNcrk.js +1 -0
  11. package/dist/chunk-CKdlNyzM.js +9 -0
  12. package/dist/{chunk-DrYAfpvk.js → chunk-DjOvgFsn.js} +1 -1
  13. package/dist/chunk-lA5CJCgK.js +1 -0
  14. package/dist/client-history.js +1 -1
  15. package/dist/codegen.cjs +1 -1
  16. package/dist/codegen.js +1 -1
  17. package/dist/{composer-input-C39npJaz.d.cts → composer-input-D3sB8_P_.d.cts} +1 -1
  18. package/dist/{composer-input-C39npJaz.d.ts → composer-input-D3sB8_P_.d.ts} +1 -1
  19. package/dist/{context-mention-manager-DLCB1l9E.d.cts → context-mention-manager-D2qxE5op.d.cts} +1 -1
  20. package/dist/{context-mention-manager-DLCB1l9E.d.ts → context-mention-manager-D2qxE5op.d.ts} +1 -1
  21. package/dist/context-mentions-inline.d.cts +2 -2
  22. package/dist/context-mentions-inline.d.ts +2 -2
  23. package/dist/context-mentions.d.cts +3 -3
  24. package/dist/context-mentions.d.ts +3 -3
  25. package/dist/{defaults-DiAgWHXy.d.cts → defaults-Dsw66XqE.d.cts} +1 -1
  26. package/dist/{defaults-DiAgWHXy.d.ts → defaults-Dsw66XqE.d.ts} +1 -1
  27. package/dist/event-stream-view.d.cts +1 -1
  28. package/dist/event-stream-view.d.ts +1 -1
  29. package/dist/{fallback-speech-engine-C5_PUZjH.d.cts → fallback-speech-engine-DJpJcWAk.d.cts} +1 -1
  30. package/dist/{fallback-speech-engine-C5_PUZjH.d.ts → fallback-speech-engine-DJpJcWAk.d.ts} +1 -1
  31. package/dist/forms-ui.d.cts +2 -2
  32. package/dist/forms-ui.d.ts +2 -2
  33. package/dist/history-view.d.cts +1 -1
  34. package/dist/history-view.d.ts +1 -1
  35. package/dist/index.cjs +45 -44
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +7 -7
  38. package/dist/index.d.ts +7 -7
  39. package/dist/index.global.js +1 -1
  40. package/dist/index.global.js.map +1 -1
  41. package/dist/index.js +34 -33
  42. package/dist/index.js.map +1 -1
  43. package/dist/{markdown-parsers-loader-BBdyIEU7.d.cts → markdown-parsers-loader-CCY7T4Up.d.cts} +1 -1
  44. package/dist/{markdown-parsers-loader-BBdyIEU7.d.ts → markdown-parsers-loader-CCY7T4Up.d.ts} +1 -1
  45. package/dist/{preview-Chjb0bmI.d.cts → preview-DKKpfTo7.d.cts} +2 -2
  46. package/dist/{preview-Chjb0bmI.d.ts → preview-DKKpfTo7.d.ts} +2 -2
  47. package/dist/{session-a_qIp4xp.d.ts → session-DleMr9dZ.d.cts} +13 -7
  48. package/dist/{session-a_qIp4xp.d.cts → session-DleMr9dZ.d.ts} +13 -7
  49. package/dist/session-reconnect.d.cts +2 -2
  50. package/dist/session-reconnect.d.ts +2 -2
  51. package/dist/smart-dom-reader.d.cts +1 -1
  52. package/dist/smart-dom-reader.d.ts +1 -1
  53. package/dist/theme-editor-preview.cjs +41 -40
  54. package/dist/theme-editor-preview.d.cts +1 -1
  55. package/dist/theme-editor-preview.d.ts +1 -1
  56. package/dist/theme-editor-preview.js +20 -20
  57. package/dist/theme-editor.d.cts +2 -2
  58. package/dist/theme-editor.d.ts +2 -2
  59. package/dist/theme-reference.d.cts +2 -2
  60. package/dist/theme-reference.d.ts +2 -2
  61. package/dist/{types-BdO1jNRm.d.cts → types-oAZ1VReS.d.cts} +166 -21
  62. package/dist/{types-BdO1jNRm.d.ts → types-oAZ1VReS.d.ts} +166 -21
  63. package/dist/voice-client-tools.cjs +1 -0
  64. package/dist/voice-client-tools.d.cts +13 -0
  65. package/dist/voice-client-tools.d.ts +13 -0
  66. package/dist/voice-client-tools.js +1 -0
  67. package/dist/voice-runtime.cjs +3 -3
  68. package/dist/voice-runtime.d.cts +7 -3
  69. package/dist/voice-runtime.d.ts +7 -3
  70. package/dist/voice-runtime.js +4 -4
  71. package/dist/voice-worklet-player.d.cts +2 -2
  72. package/dist/voice-worklet-player.d.ts +2 -2
  73. package/dist/{webmcp-runtime-entry-B6bpVWSa.d.ts → webmcp-runtime-entry-Deg0NfmB.d.cts} +26 -5
  74. package/dist/{webmcp-runtime-entry-B6bpVWSa.d.cts → webmcp-runtime-entry-Deg0NfmB.d.ts} +26 -5
  75. package/dist/webmcp-runtime.cjs +2 -1
  76. package/dist/webmcp-runtime.d.cts +1 -1
  77. package/dist/webmcp-runtime.d.ts +1 -1
  78. package/dist/webmcp-runtime.js +2 -1
  79. package/package.json +6 -1
  80. package/src/client.ts +37 -0
  81. package/src/client.voice-tools.test.ts +65 -0
  82. package/src/generated/runtype-openapi-contract.ts +38 -0
  83. package/src/index-core.ts +11 -0
  84. package/src/index-global.ts +6 -0
  85. package/src/session.test.ts +26 -0
  86. package/src/session.ts +8 -1
  87. package/src/session.voice.test.ts +43 -0
  88. package/src/types.ts +141 -20
  89. package/src/voice/runtype-voice-provider.ts +85 -3
  90. package/src/voice/session-voice-wiring.ts +26 -1
  91. package/src/voice/voice-client-tools-session.ts +116 -0
  92. package/src/voice/voice-delegation.ts +9 -0
  93. package/src/voice/voice.test.ts +360 -0
  94. package/src/voice-client-tools-bundle.test.ts +37 -0
  95. package/src/voice-client-tools-loader.ts +24 -0
  96. package/src/voice-client-tools.ts +9 -0
  97. package/src/webmcp-bridge.test.ts +152 -1
  98. package/src/webmcp-bridge.ts +5 -6
  99. package/src/webmcp-polyfill.integration.test.ts +5 -1
  100. package/src/webmcp-runtime-entry.ts +151 -26
  101. package/dist/chunk-CztSjKHK.js +0 -9
  102. package/dist/chunk-HUOUif-P.js +0 -1
  103. package/dist/chunk-UlcxdHef.js +0 -1
@@ -1778,6 +1778,7 @@ type RuntypeExecutionStreamEvent = ({
1778
1778
  finalOutput?: string;
1779
1779
  iterations?: number;
1780
1780
  kind: "agent" | "flow";
1781
+ outcome?: "completed" | "error" | "aborted";
1781
1782
  seq: number;
1782
1783
  stepErrorCount?: number;
1783
1784
  stopReason?: string;
@@ -1803,6 +1804,7 @@ type RuntypeExecutionStreamEvent = ({
1803
1804
  executionId: string;
1804
1805
  finalOutput?: string;
1805
1806
  kind: "agent" | "flow";
1807
+ outcome?: "completed" | "error" | "aborted";
1806
1808
  seq: number;
1807
1809
  stopReason?: string;
1808
1810
  type: "execution_error";
@@ -2122,6 +2124,15 @@ type RuntypeExecutionStreamEvent = ({
2122
2124
  seq: number;
2123
2125
  type: "state_delta";
2124
2126
  }) | ({
2127
+ annotations?: {
2128
+ consequentialHint?: boolean;
2129
+ debugging?: boolean;
2130
+ destructiveHint?: boolean;
2131
+ idempotentHint?: boolean;
2132
+ openWorldHint?: boolean;
2133
+ readOnlyHint?: boolean;
2134
+ untrustedContentHint?: boolean;
2135
+ };
2125
2136
  executionId: string;
2126
2137
  hiddenParameterNames?: Array<string>;
2127
2138
  iteration?: number;
@@ -2220,6 +2231,15 @@ type RuntypeExecutionStreamEvent = ({
2220
2231
  seq: number;
2221
2232
  type: "approval_complete";
2222
2233
  }) | ({
2234
+ annotations?: {
2235
+ consequentialHint?: boolean;
2236
+ debugging?: boolean;
2237
+ destructiveHint?: boolean;
2238
+ idempotentHint?: boolean;
2239
+ openWorldHint?: boolean;
2240
+ readOnlyHint?: boolean;
2241
+ untrustedContentHint?: boolean;
2242
+ };
2223
2243
  awaitReason?: string;
2224
2244
  awaitedAt?: string;
2225
2245
  crawlId?: string;
@@ -2371,6 +2391,15 @@ type RuntypeClientInitResponse = {
2371
2391
  type RuntypeClientChatRequest = {
2372
2392
  assistantMessageId?: string;
2373
2393
  clientTools?: Array<{
2394
+ annotations?: {
2395
+ consequentialHint?: boolean;
2396
+ debugging?: boolean;
2397
+ destructiveHint?: boolean;
2398
+ idempotentHint?: boolean;
2399
+ openWorldHint?: boolean;
2400
+ readOnlyHint?: boolean;
2401
+ untrustedContentHint?: boolean;
2402
+ };
2374
2403
  description: string;
2375
2404
  name: string;
2376
2405
  origin?: "webmcp" | "sdk";
@@ -2422,6 +2451,15 @@ type RuntypeClientResumeRequest = {
2422
2451
  after?: string;
2423
2452
  assistantMessageId?: string;
2424
2453
  clientTools?: Array<{
2454
+ annotations?: {
2455
+ consequentialHint?: boolean;
2456
+ debugging?: boolean;
2457
+ destructiveHint?: boolean;
2458
+ idempotentHint?: boolean;
2459
+ openWorldHint?: boolean;
2460
+ readOnlyHint?: boolean;
2461
+ untrustedContentHint?: boolean;
2462
+ };
2425
2463
  description: string;
2426
2464
  name: string;
2427
2465
  origin?: "webmcp" | "sdk";
@@ -3492,14 +3530,17 @@ type AgentWidgetAgentRequestPayload = {
3492
3530
  /** See {@link AgentWidgetRequestPayload.composerOptions}. */
3493
3531
  composerOptions?: ComposerOptionsPayload;
3494
3532
  };
3495
- /**
3496
- * Wire shape for a single client-discovered tool sent on `dispatch.clientTools[]`.
3497
- *
3498
- * Mirrors the SDK's `ClientToolDefinition` in `@runtypelabs/sdk`. Only the
3499
- * JSON-serializable surface of a WebMCP tool: the `execute` function stays
3500
- * client-side; the server merges these into the agent's tool catalog under
3501
- * the `webmcp:` namespace.
3502
- */
3533
+ /** Advisory WebMCP and MCP hints. These do not grant approval or safe retry. */
3534
+ type ToolAnnotations = {
3535
+ readOnlyHint?: boolean;
3536
+ destructiveHint?: boolean;
3537
+ consequentialHint?: boolean;
3538
+ untrustedContentHint?: boolean;
3539
+ idempotentHint?: boolean;
3540
+ openWorldHint?: boolean;
3541
+ debugging?: boolean;
3542
+ };
3543
+ /** Wire metadata for a client-side tool; its execute function stays in the browser. */
3503
3544
  type ClientToolDefinition = {
3504
3545
  /** Bare tool name; the server prepends `webmcp:` on the wire. */
3505
3546
  name: string;
@@ -3516,20 +3557,16 @@ type ClientToolDefinition = {
3516
3557
  /** Origin of the page that registered the tool: for server-side audit. */
3517
3558
  pageOrigin?: string;
3518
3559
  /**
3519
- * WebMCP `Tool.annotations` (spec). Not used for gating server-side; the
3520
- * widget reads these client-side. Forwarded so traces/dashboards can show
3521
- * `readOnlyHint` / `untrustedContentHint` on tool-call records.
3560
+ * WebMCP hints and MCP compatibility hints forwarded to runtime tool metadata
3561
+ * and confirmation callbacks. No hint skips the default confirmation gate.
3522
3562
  */
3523
- annotations?: {
3524
- readOnlyHint?: boolean;
3525
- untrustedContentHint?: boolean;
3526
- };
3563
+ annotations?: ToolAnnotations;
3527
3564
  /**
3528
3565
  * Hoisted copy of `annotations.untrustedContentHint`. This is the field the
3529
3566
  * server actually acts on (`InlineClientToolSchema`): it spotlights the
3530
3567
  * tool's output before the model reads it, so instructions embedded in
3531
3568
  * page-provided content (reviews, comments, emails) are not treated as
3532
- * instructions. `annotations` itself is trace/dashboard metadata only.
3569
+ * instructions. A nested true hint also opts into output protection.
3533
3570
  */
3534
3571
  untrustedContentHint?: boolean;
3535
3572
  };
@@ -3548,16 +3585,19 @@ type WebMcpConfirmInfo = {
3548
3585
  * didn't declare one.
3549
3586
  */
3550
3587
  title?: string;
3551
- annotations?: {
3552
- readOnlyHint?: boolean;
3553
- untrustedContentHint?: boolean;
3554
- };
3588
+ annotations?: ToolAnnotations;
3555
3589
  /**
3556
3590
  * Why the confirm was requested. Currently always `'gate'`: the default
3557
3591
  * confirm-by-default gate that fires before every `webmcp:*` call. Tool
3558
3592
  * callbacks on v6 receive an AbortSignal, not a nested confirmation API.
3559
3593
  */
3560
3594
  reason: 'gate';
3595
+ /**
3596
+ * Aborts when the call no longer needs an answer (its deadline passed, or it
3597
+ * was cancelled). A confirm UI should close and resolve `false`; the tool
3598
+ * never runs after it aborts either way.
3599
+ */
3600
+ signal?: AbortSignal;
3561
3601
  };
3562
3602
  /**
3563
3603
  * Resolves to `true` if the user approves the tool call; `false` to decline.
@@ -7797,7 +7837,112 @@ interface VoiceSessionBridge {
7797
7837
  * declined too, as the approval TTL would.
7798
7838
  */
7799
7839
  dropDelegation?(delegationId: string, expired?: boolean): void;
7840
+ /**
7841
+ * The page tools a voice call may offer the server's fast tier
7842
+ * (`client_tools` / `client_tool_call`). Returns `null` when WebMCP is not
7843
+ * enabled on this widget; the provider then does not declare `client_tools`.
7844
+ */
7845
+ clientTools?(): VoiceClientTools | null;
7846
+ /**
7847
+ * The server answered a delegation itself (`delegation_completed.route ===
7848
+ * 'direct'`): record the visitor's turn and the spoken answer in the chat,
7849
+ * as a delegated turn would have. `assistantText` may be empty (no readout).
7850
+ */
7851
+ recordDirectTurn?(turn: VoiceDirectTurn): void;
7800
7852
  }
7853
+ /** A delegation the server answered on its fast tier, for the chat history. */
7854
+ type VoiceDirectTurn = {
7855
+ delegationId: string;
7856
+ userText: string;
7857
+ userUtteranceIds: string[];
7858
+ assistantText: string;
7859
+ };
7860
+ /** `client_tool_result.status` (open enum on the wire). */
7861
+ type VoiceClientToolStatus = 'completed' | 'failed' | 'denied' | 'stale' | 'timeout' | (string & {});
7862
+ /** What running one `client_tool_call` produced. */
7863
+ type VoiceClientToolOutcome = {
7864
+ status: VoiceClientToolStatus;
7865
+ /** The page tool's return value (any JSON), on `completed`. */
7866
+ result?: unknown;
7867
+ error?: {
7868
+ message: string;
7869
+ };
7870
+ };
7871
+ /** The page's tool set as of now, plus its content fingerprint. */
7872
+ type VoiceClientToolsSnapshot = {
7873
+ /** Exactly what `/v1/client/chat` would send as `clientTools[]` (bare names). */
7874
+ tools: ClientToolDefinition[];
7875
+ fingerprint: string;
7876
+ };
7877
+ /** WebMCP access for a voice call (see {@link VoiceSessionBridge.clientTools}). */
7878
+ interface VoiceClientTools {
7879
+ snapshot(): Promise<VoiceClientToolsSnapshot>;
7880
+ /** Subscribe to registry changes; returns an unsubscribe. */
7881
+ onChange(listener: () => void): () => void;
7882
+ /**
7883
+ * Run a page tool. `autoConfirmReadOnly`: skip the confirm gate when the
7884
+ * tool's registry entry has `annotations.readOnlyHint === true`.
7885
+ */
7886
+ execute(name: string, args: Record<string, unknown>, options: {
7887
+ signal: AbortSignal;
7888
+ autoConfirmReadOnly: boolean;
7889
+ }): Promise<VoiceClientToolOutcome>;
7890
+ /**
7891
+ * Start the call's fast-tier session (loads its lazy chunk): it sends
7892
+ * `client_tools` through `channel` now and on every change, and answers
7893
+ * the `client_tool_call` frames handed to it.
7894
+ */
7895
+ open(channel: VoiceClientToolsChannel): Promise<VoiceClientToolsSession>;
7896
+ }
7897
+ /** The call socket, as the fast-tier session sees it. */
7898
+ type VoiceClientToolsChannel = {
7899
+ /** Send a frame; `false` when the call (socket) is gone. */
7900
+ send(frame: ClientToolsFrame | ClientToolResultFrame): boolean;
7901
+ /** The server cancelled this delegation: its tool results are not sent. */
7902
+ cancelled(delegationId: string): boolean;
7903
+ };
7904
+ /** A call's fast-tier session (see {@link VoiceClientTools.open}). */
7905
+ interface VoiceClientToolsSession {
7906
+ call(frame: Partial<ClientToolCallFrame>): void;
7907
+ /** Abort running tool calls (of one delegation, or all); they send nothing. */
7908
+ abort(delegationId?: string): void;
7909
+ close(): void;
7910
+ }
7911
+ /**
7912
+ * Client → server (`runtype-browser-v1`, `client_tools` capability): the page's
7913
+ * tool set, after `session_config` and whenever its fingerprint changes. Names
7914
+ * are the FULL names the server calls back with: `webmcp:` prefixed for
7915
+ * `origin: 'webmcp'`, bare for `sdk`.
7916
+ */
7917
+ type ClientToolsFrame = {
7918
+ type: 'client_tools';
7919
+ /** The content fingerprint the chat path computes for the same `clientTools[]`. */
7920
+ fingerprint: string;
7921
+ tools: ClientToolDefinition[];
7922
+ };
7923
+ /** Server → client: the fast tier picked a page tool for this delegation. */
7924
+ type ClientToolCallFrame = {
7925
+ type: 'client_tool_call';
7926
+ delegationId: string;
7927
+ toolCallId: string;
7928
+ /** `webmcp:<name>` or bare; the client accepts both. */
7929
+ name: string;
7930
+ arguments: Record<string, unknown>;
7931
+ /** The `client_tools` fingerprint the call was chosen from. */
7932
+ fingerprint: string;
7933
+ timeoutMs: number;
7934
+ };
7935
+ /** Client → server: the answer to one {@link ClientToolCallFrame}. */
7936
+ type ClientToolResultFrame = {
7937
+ type: 'client_tool_result';
7938
+ delegationId: string;
7939
+ toolCallId: string;
7940
+ status: VoiceClientToolStatus;
7941
+ result?: unknown;
7942
+ error?: {
7943
+ message: string;
7944
+ };
7945
+ };
7801
7946
  /**
7802
7947
  * Extra context for an approval decision, surfaced to `onDecision` and to the
7803
7948
  * `approve`/`deny` callbacks passed to the `renderApproval` plugin hook.
@@ -11016,5 +11161,5 @@ type AgentWidgetInitOptions = {
11016
11161
  debugTools?: boolean;
11017
11162
  };
11018
11163
  //#endregion
11019
- export { AgentWidgetHistoryCopy as $, RuntypeStopReasonKind as $i, ComposerResubmitOptions as $n, SlotRenderer as $r, AgentWidgetSuggestionSurfaceConfig as $t, AgentWidgetContextMentionComposerCapability as A, AgentWidgetRailSection as Aa, HistoryListOptions as Ai, ComposerActionContributionContext as An, LoadingIndicatorRenderContext as Ar, AgentWidgetScrollBehaviorFeature as At, AgentWidgetContextMentionTokenRenderContext as B, ResolvedTarget as Bi, ComposerDisabledOption as Bn, PersonaArtifactFilesDisplayRules as Br, AgentWidgetStoredState as Bt, AgentWidgetComponentRenderer as C, TextStyleTokens as Ca, WidgetLayoutSlot as Ci, ClientInitResponse as Cn, IdleIndicatorRenderContext as Cr, AgentWidgetRenderHistoryOpenErrorContext as Ct, AgentWidgetContentSegment as D, TokenReference as Da, registerIcons as Di, ComposerAction as Dn, InjectMessageOptions as Dr, AgentWidgetResolvedSuggestion as Dt, AgentWidgetConfigPatch as E, ToggleGroupTokens as Ea, IconName as Ei, ClientVisitorGrant as En, InjectComponentDirectiveOptions as Er, AgentWidgetRequestPayload as Et, AgentWidgetContextMentionPayload as F, AgentWidgetTransformSuggestionsContext as Fa, HistoryProvider as Fi, ComposerActionVisibility as Fn, PersonaArtifactCustomAction as Fr, AgentWidgetSessionInitTrigger as Ft, AgentWidgetCustomMessageAction as G, RuntypeClientFeedbackResponse as Gi, ComposerModeGroup as Gn, PersonaArtifactStatusLabelContext as Gr, AgentWidgetStreamAnimationType as Gt, AgentWidgetContextProviderContext as H, RuntypeClientChatRequest as Hi, ComposerLayout as Hn, PersonaArtifactManualUpsert as Hr, AgentWidgetStreamAnimationBuiltinType as Ht, AgentWidgetContextMentionRef as I, AgentWidgetPluginStorage as Ia, HistoryProviderError as Ii, ComposerAttachmentState as In, PersonaArtifactDisplayMode as Ir, AgentWidgetStarterSuggestionsConfig as It, AgentWidgetEvent as J, RuntypeClientInitResponse as Ji, ComposerModelPickerConfig as Jn, ResolvedHistoryCopy as Jr, AgentWidgetSuggestion as Jt, AgentWidgetCustomMessageActionRole as K, RuntypeClientFeedbackType as Ki, ComposerModeGroupPresentation as Kn, PreparedClientSession as Kr, AgentWidgetStreamParser as Kt, AgentWidgetContextMentionResolveContext as L, ResolvedWelcomeConfig as La, HistoryProviderErrorCode as Li, ComposerBeforeSendResult as Ln, PersonaArtifactDisplayModeInput as Lr, AgentWidgetStateSnapshot as Lt, AgentWidgetContextMentionItem as M, AgentWidgetRenderSuggestionContext as Ma, HistoryOperationContext as Mi, ComposerActionPlacement as Mn, MessageRenderContext as Mr, AgentWidgetScrollRestorePosition as Mt, AgentWidgetContextMentionItemRenderContext as N, AgentWidgetRenderWelcomeContext as Na, HistoryPageOptions as Ni, ComposerActionPresentation as Nn, PcmStreamPlayer as Nr, AgentWidgetScrollToBottomFeature as Nt, AgentWidgetContextMentionChipRenderContext as O, TypographyScale as Oa, renderLucideIcon as Oi, ComposerActionBase as On, InjectSystemMessageOptions as Or, AgentWidgetSSEEventParser as Ot, AgentWidgetContextMentionMenuRenderContext as P, AgentWidgetSuggestionSelectContext as Pa, HistoryPageResult as Pi, ComposerActionRenderContext as Pn, PersonaArtifactActionContext as Pr, AgentWidgetSessionInitHook as Pt, AgentWidgetHeadersFunction as Q, RuntypeStepCompleteEvent as Qi, ComposerQuote as Qn, SlotRenderContext as Qr, AgentWidgetSuggestionSurface as Qt, AgentWidgetContextMentionSearchContext as R, isWelcomeVisible as Ra, PreparedHistoryActivation as Ri, ComposerButtonAction as Rn, PersonaArtifactDisplayRules as Rr, AgentWidgetStorageAdapter as Rt, AgentWidgetAvatarConfig as S, SpacingScale as Sa, WidgetHistoryInternals as Si, ClientFeedbackType as Sn, HistoryViewState as Sr, AgentWidgetRenderHistoryHeaderContext as St, AgentWidgetConfig as T, ThemeValidationResult as Ta, WidgetPreferenceSlice as Ti, ClientToolDefinition as Tn, InjectAssistantMessageOptions as Tr, AgentWidgetRenderHistoryViewContext as Tt, AgentWidgetControllerEventMap as U, RuntypeClientChatStreamEvent as Ui, ComposerMode as Un, PersonaArtifactPresentation as Ur, AgentWidgetStreamAnimationFeature as Ut, AgentWidgetContextProvider as V, TargetResolver as Vi, ComposerInputAttributes as Vn, PersonaArtifactKind as Vr, AgentWidgetStreamAnimationBuffer as Vt, AgentWidgetCustomFetch as W, RuntypeClientFeedbackRequest as Wi, ComposerModeChipVisibility as Wn, PersonaArtifactRecord as Wr, AgentWidgetStreamAnimationPlaceholder as Wt, AgentWidgetFollowUpSuggestionsConfig as X, RuntypeClientResumeStreamEvent as Xi, ComposerOptionsPayload as Xn, ResumableHandle as Xr, AgentWidgetSuggestionChipsConfig as Xt, AgentWidgetFeatureFlags as Y, RuntypeClientResumeRequest as Yi, ComposerModelPickerPresentation as Yn, ResolvedHistoryPresentation as Yr, AgentWidgetSuggestionBehavior as Yt, AgentWidgetHeaderLayoutConfig as Z, RuntypeExecutionStreamEvent as Zi, ComposerPhase as Zn, SSEEventRecord as Zr, AgentWidgetSuggestionSource as Zt, AgentWidgetArtifactsLayoutConfig as _, SemanticColors as _a, VoiceTranscriptMetadata as _i, AskUserQuestionPayload as _n, HistoryDisplayProjection as _r, AgentWidgetMessageLayoutConfig as _t, AgentRequestOptions as a, BorderScale as aa, TextContentPart as ai, AgentWidgetVoicePrewarmTrigger as an, ContentPart as ar, AgentWidgetLauncherTeaserConfig as at, AgentWidgetAttachmentAdapter as b, SemanticTypography as ba, WebMcpToolResult as bi, ClientChatRequest as bn, HistoryReturnSurface as br, AgentWidgetReadAloudEvent as bt, AgentWidgetActionEventPayload as c, ComponentTokens as ca, VoiceDelegationRequest as ci, AgentWidgetWelcomeAlign as cn, EventStreamPayloadRenderContext as cr, AgentWidgetMarkdownConfig as ct, AgentWidgetActionParser as d, IconButtonTokens as da, VoiceMetrics as di, AgentWidgetWelcomeIcon as dn, EventStreamViewRenderContext as dr, AgentWidgetMentionLlmEntry as dt, RuntypeStreamEventOf as ea, SpeechCallbacks as ei, AgentWidgetSuggestionVariant as en, ComposerState as er, AgentWidgetHistoryFeature as et, AgentWidgetAgentRequestPayload as f, LabelButtonTokens as fa, VoicePlaybackEngine as fi, AgentWidgetWelcomeIconBase as fn, HeaderRenderContext as fr, AgentWidgetMentionTriggerChannel as ft, AgentWidgetArtifactsFeature as g, ResolvedToken as ga, VoiceStatus as gi, AskUserQuestionOption as gn, HistoryConversationSummary as gr, AgentWidgetMessageFeedback as gt, AgentWidgetApprovalDecisionOptions as h, RadiusScale as ha, VoiceSessionBridge as hi, ArtifactConfigPayload as hn, HistoryConversationPatch as hr, AgentWidgetMessageActionsConfig as ht, AgentMessageMetadata as i, ArtifactToolbarTokens as ia, StreamAnimationPlugin as ii, AgentWidgetVoicePrewarmHook as in, ComposerSubmitKey as ir, AgentWidgetLauncherConfig as it, AgentWidgetContextMentionConfig as j, AgentWidgetRailSectionContext as ja, HistoryListResult as ji, ComposerActionOverflowConfig as jn, MessageContent as jr, AgentWidgetScrollMode as jt, AgentWidgetContextMentionCommandContext as k, AgentWidgetPlugin as ka, HistoryDeleteAllOptions as ki, ComposerActionContext as kn, InjectUserMessageOptions as kr, AgentWidgetSSEEventResult as kt, AgentWidgetActionHandler as l, CreateThemeOptions as la, VoiceDelegationResult as li, AgentWidgetWelcomeConfig as ln, EventStreamRowRenderContext as lr, AgentWidgetMarkdownOptions as lt, AgentWidgetApprovalConfig as m, PersonaThemePlugin as ma, VoiceResult as mi, AgentWidgetWelcomeVariant as mn, HistoryConversationPage as mr, AgentWidgetMessage as mt, AgentExecutionState as n, ArtifactPaneTokens as na, SpeechRequest as ni, AgentWidgetTimestampConfig as nn, ComposerSubmissionOptions as nr, AgentWidgetHistoryRenderActions as nt, AgentToolsConfig as o, ColorPalette as oa, VoiceConfig as oi, AgentWidgetVoiceStatusEvent as on, EventStreamBadgeColor as or, AgentWidgetLayoutConfig as ot, AgentWidgetApproval as p, PersonaTheme as pa, VoiceProvider as pi, AgentWidgetWelcomeIconPlacement as pn, HistoryConversationDetail as pr, AgentWidgetMentionTriggerPosition as pt, AgentWidgetDockConfig as q, RuntypeClientInitRequest as qi, ComposerModel as qn, ReadAloudState as qr, AgentWidgetStreamParserResult as qt, AgentLoopConfig as r, ArtifactTabTokens as ra, StreamAnimationContext as ri, AgentWidgetTooltipConfig as rn, ComposerSubmissionSnapshot as rr, AgentWidgetInitOptions as rt, AgentWidgetActionContext as s, ColorShade as sa, VoiceDelegationFollowUp as si, AgentWidgetWebMcpConfig as sn, EventStreamConfig as sr, AgentWidgetLoadingIndicatorConfig as st, AgentConfig as t, RuntypeTurnCompleteEvent as ta, SpeechEngine as ti, AgentWidgetSuggestionsConfig as tn, ComposerStreamingSubmitBehavior as tr, AgentWidgetHistoryListAction as tt, AgentWidgetActionHandlerResult as u, DeepPartial as ua, VoiceDelegationStatus as ui, AgentWidgetWelcomeDismiss as un, EventStreamToolbarRenderContext as ur, AgentWidgetMarkdownRendererOverrides as ut, AgentWidgetAskUserQuestionFeature as v, SemanticSpacing as va, WebMcpConfirmHandler as vi, AskUserQuestionPrompt as vn, HistoryIdentityStatus as vr, AgentWidgetMessageRoleLayout as vt, AgentWidgetComposerConfig as w, ThemeValidationError as wa, WidgetPreferenceCapabilities as wi, ClientSession as wn, ImageContentPart as wr, AgentWidgetRenderHistoryStateContext as wt, AgentWidgetAttachmentsConfig as x, ShadowScale as xa, WidgetArtifactLayoutPreference as xi, ClientFeedbackRequest as xn, HistoryScope as xr, AgentWidgetRenderHistoryConversationContext as xt, AgentWidgetAskUserQuestionStyles as y, SemanticTokens as ya, WebMcpConfirmInfo as yi, AttachmentUploadContext as yn, HistoryPendingAction as yr, AgentWidgetParsedAction as yt, AgentWidgetContextMentionSource as z, resolveWelcomeConfig as za, isHistoryProviderError as zi, ComposerCustomAction as zn, PersonaArtifactFileMeta as zr, AgentWidgetStoredDraft as zt };
11164
+ export { AgentWidgetHistoryCopy as $, RuntypeClientChatRequest as $i, ComposerOptionsPayload as $n, ResumableHandle as $r, AgentWidgetSuggestionSurfaceConfig as $t, AgentWidgetContextMentionComposerCapability as A, SemanticTokens as Aa, WebMcpConfirmInfo as Ai, ComposerAction as An, InjectMessageOptions as Ar, AgentWidgetScrollBehaviorFeature as At, AgentWidgetContextMentionTokenRenderContext as B, AgentWidgetPlugin as Ba, HistoryDeleteAllOptions as Bi, ComposerBeforeSendResult as Bn, PersonaArtifactDisplayModeInput as Br, AgentWidgetStoredState as Bt, AgentWidgetComponentRenderer as C, LabelButtonTokens as Ca, VoicePlaybackEngine as Ci, ClientInitResponse as Cn, HistoryReturnSurface as Cr, AgentWidgetRenderHistoryOpenErrorContext as Ct, AgentWidgetContentSegment as D, ResolvedToken as Da, VoiceStatus as Di, ClientToolResultFrame as Dn, ImageContentPart as Dr, AgentWidgetResolvedSuggestion as Dt, AgentWidgetConfigPatch as E, RadiusScale as Ea, VoiceSessionBridge as Ei, ClientToolDefinition as En, IdleIndicatorRenderContext as Er, AgentWidgetRequestPayload as Et, AgentWidgetContextMentionPayload as F, ThemeValidationError as Fa, WidgetPreferenceCapabilities as Fi, ComposerActionPlacement as Fn, MessageRenderContext as Fr, AgentWidgetSessionInitTrigger as Ft, AgentWidgetCustomMessageAction as G, AgentWidgetSuggestionSelectContext as Ga, HistoryPageResult as Gi, ComposerLayout as Gn, PersonaArtifactManualUpsert as Gr, AgentWidgetStreamAnimationType as Gt, AgentWidgetContextProviderContext as H, AgentWidgetRailSectionContext as Ha, HistoryListResult as Hi, ComposerCustomAction as Hn, PersonaArtifactFileMeta as Hr, AgentWidgetStreamAnimationBuiltinType as Ht, AgentWidgetContextMentionRef as I, ThemeValidationResult as Ia, WidgetPreferenceSlice as Ii, ComposerActionPresentation as In, PcmStreamPlayer as Ir, AgentWidgetStarterSuggestionsConfig as It, AgentWidgetEvent as J, ResolvedWelcomeConfig as Ja, HistoryProviderErrorCode as Ji, ComposerModeGroup as Jn, PersonaArtifactStatusLabelContext as Jr, AgentWidgetSuggestion as Jt, AgentWidgetCustomMessageActionRole as K, AgentWidgetTransformSuggestionsContext as Ka, HistoryProvider as Ki, ComposerMode as Kn, PersonaArtifactPresentation as Kr, AgentWidgetStreamParser as Kt, AgentWidgetContextMentionResolveContext as L, ToggleGroupTokens as La, IconName as Li, ComposerActionRenderContext as Ln, PersonaArtifactActionContext as Lr, AgentWidgetStateSnapshot as Lt, AgentWidgetContextMentionItem as M, ShadowScale as Ma, WidgetArtifactLayoutPreference as Mi, ComposerActionContext as Mn, InjectUserMessageOptions as Mr, AgentWidgetScrollRestorePosition as Mt, AgentWidgetContextMentionItemRenderContext as N, SpacingScale as Na, WidgetHistoryInternals as Ni, ComposerActionContributionContext as Nn, LoadingIndicatorRenderContext as Nr, AgentWidgetScrollToBottomFeature as Nt, AgentWidgetContextMentionChipRenderContext as O, SemanticColors as Oa, VoiceTranscriptMetadata as Oi, ClientToolsFrame as On, InjectAssistantMessageOptions as Or, AgentWidgetSSEEventParser as Ot, AgentWidgetContextMentionMenuRenderContext as P, TextStyleTokens as Pa, WidgetLayoutSlot as Pi, ComposerActionOverflowConfig as Pn, MessageContent as Pr, AgentWidgetSessionInitHook as Pt, AgentWidgetHeadersFunction as Q, TargetResolver as Qi, ComposerModelPickerPresentation as Qn, ResolvedHistoryPresentation as Qr, AgentWidgetSuggestionSurface as Qt, AgentWidgetContextMentionSearchContext as R, TokenReference as Ra, registerIcons as Ri, ComposerActionVisibility as Rn, PersonaArtifactCustomAction as Rr, AgentWidgetStorageAdapter as Rt, AgentWidgetAvatarConfig as S, IconButtonTokens as Sa, VoiceMetrics as Si, ClientFeedbackType as Sn, HistoryPendingAction as Sr, AgentWidgetRenderHistoryHeaderContext as St, AgentWidgetConfig as T, PersonaThemePlugin as Ta, VoiceResult as Ti, ClientToolCallFrame as Tn, HistoryViewState as Tr, AgentWidgetRenderHistoryViewContext as Tt, AgentWidgetControllerEventMap as U, AgentWidgetRenderSuggestionContext as Ua, HistoryOperationContext as Ui, ComposerDisabledOption as Un, PersonaArtifactFilesDisplayRules as Ur, AgentWidgetStreamAnimationFeature as Ut, AgentWidgetContextProvider as V, AgentWidgetRailSection as Va, HistoryListOptions as Vi, ComposerButtonAction as Vn, PersonaArtifactDisplayRules as Vr, AgentWidgetStreamAnimationBuffer as Vt, AgentWidgetCustomFetch as W, AgentWidgetRenderWelcomeContext as Wa, HistoryPageOptions as Wi, ComposerInputAttributes as Wn, PersonaArtifactKind as Wr, AgentWidgetStreamAnimationPlaceholder as Wt, AgentWidgetFollowUpSuggestionsConfig as X, resolveWelcomeConfig as Xa, isHistoryProviderError as Xi, ComposerModel as Xn, ReadAloudState as Xr, AgentWidgetSuggestionChipsConfig as Xt, AgentWidgetFeatureFlags as Y, isWelcomeVisible as Ya, PreparedHistoryActivation as Yi, ComposerModeGroupPresentation as Yn, PreparedClientSession as Yr, AgentWidgetSuggestionBehavior as Yt, AgentWidgetHeaderLayoutConfig as Z, ResolvedTarget as Zi, ComposerModelPickerConfig as Zn, ResolvedHistoryCopy as Zr, AgentWidgetSuggestionSource as Zt, AgentWidgetArtifactsLayoutConfig as _, ColorPalette as _a, VoiceDelegationFollowUp as _i, AskUserQuestionPayload as _n, HistoryConversationPage as _r, AgentWidgetMessageLayoutConfig as _t, AgentRequestOptions as a, RuntypeClientInitResponse as aa, SpeechRequest as ai, AgentWidgetVoicePrewarmTrigger as an, ComposerSubmissionOptions as ar, AgentWidgetLauncherTeaserConfig as at, AgentWidgetAttachmentAdapter as b, CreateThemeOptions as ba, VoiceDelegationStatus as bi, ClientChatRequest as bn, HistoryDisplayProjection as br, AgentWidgetReadAloudEvent as bt, AgentWidgetActionEventPayload as c, RuntypeExecutionStreamEvent as ca, TextContentPart as ci, AgentWidgetWelcomeAlign as cn, ContentPart as cr, AgentWidgetMarkdownConfig as ct, AgentWidgetActionParser as d, RuntypeStreamEventOf as da, VoiceClientToolStatus as di, AgentWidgetWelcomeIcon as dn, EventStreamPayloadRenderContext as dr, AgentWidgetMentionLlmEntry as dt, RuntypeClientChatStreamEvent as ea, SSEEventRecord as ei, AgentWidgetSuggestionVariant as en, ComposerPhase as er, AgentWidgetHistoryFeature as et, AgentWidgetAgentRequestPayload as f, RuntypeTurnCompleteEvent as fa, VoiceClientTools as fi, AgentWidgetWelcomeIconBase as fn, EventStreamRowRenderContext as fr, AgentWidgetMentionTriggerChannel as ft, AgentWidgetArtifactsFeature as g, BorderScale as ga, VoiceConfig as gi, AskUserQuestionOption as gn, HistoryConversationDetail as gr, AgentWidgetMessageFeedback as gt, AgentWidgetApprovalDecisionOptions as h, ArtifactToolbarTokens as ha, VoiceClientToolsSnapshot as hi, ArtifactConfigPayload as hn, HeaderRenderContext as hr, AgentWidgetMessageActionsConfig as ht, AgentMessageMetadata as i, RuntypeClientInitRequest as ia, SpeechEngine as ii, AgentWidgetVoicePrewarmHook as in, ComposerStreamingSubmitBehavior as ir, AgentWidgetLauncherConfig as it, AgentWidgetContextMentionConfig as j, SemanticTypography as ja, WebMcpToolResult as ji, ComposerActionBase as jn, InjectSystemMessageOptions as jr, AgentWidgetScrollMode as jt, AgentWidgetContextMentionCommandContext as k, SemanticSpacing as ka, WebMcpConfirmHandler as ki, ClientVisitorGrant as kn, InjectComponentDirectiveOptions as kr, AgentWidgetSSEEventResult as kt, AgentWidgetActionHandler as l, RuntypeStepCompleteEvent as la, ToolAnnotations as li, AgentWidgetWelcomeConfig as ln, EventStreamBadgeColor as lr, AgentWidgetMarkdownOptions as lt, AgentWidgetApprovalConfig as m, ArtifactTabTokens as ma, VoiceClientToolsSession as mi, AgentWidgetWelcomeVariant as mn, EventStreamViewRenderContext as mr, AgentWidgetMessage as mt, AgentExecutionState as n, RuntypeClientFeedbackResponse as na, SlotRenderer as ni, AgentWidgetTimestampConfig as nn, ComposerResubmitOptions as nr, AgentWidgetHistoryRenderActions as nt, AgentToolsConfig as o, RuntypeClientResumeRequest as oa, StreamAnimationContext as oi, AgentWidgetVoiceStatusEvent as on, ComposerSubmissionSnapshot as or, AgentWidgetLayoutConfig as ot, AgentWidgetApproval as p, ArtifactPaneTokens as pa, VoiceClientToolsChannel as pi, AgentWidgetWelcomeIconPlacement as pn, EventStreamToolbarRenderContext as pr, AgentWidgetMentionTriggerPosition as pt, AgentWidgetDockConfig as q, AgentWidgetPluginStorage as qa, HistoryProviderError as qi, ComposerModeChipVisibility as qn, PersonaArtifactRecord as qr, AgentWidgetStreamParserResult as qt, AgentLoopConfig as r, RuntypeClientFeedbackType as ra, SpeechCallbacks as ri, AgentWidgetTooltipConfig as rn, ComposerState as rr, AgentWidgetInitOptions as rt, AgentWidgetActionContext as s, RuntypeClientResumeStreamEvent as sa, StreamAnimationPlugin as si, AgentWidgetWebMcpConfig as sn, ComposerSubmitKey as sr, AgentWidgetLoadingIndicatorConfig as st, AgentConfig as t, RuntypeClientFeedbackRequest as ta, SlotRenderContext as ti, AgentWidgetSuggestionsConfig as tn, ComposerQuote as tr, AgentWidgetHistoryListAction as tt, AgentWidgetActionHandlerResult as u, RuntypeStopReasonKind as ua, VoiceClientToolOutcome as ui, AgentWidgetWelcomeDismiss as un, EventStreamConfig as ur, AgentWidgetMarkdownRendererOverrides as ut, AgentWidgetAskUserQuestionFeature as v, ColorShade as va, VoiceDelegationRequest as vi, AskUserQuestionPrompt as vn, HistoryConversationPatch as vr, AgentWidgetMessageRoleLayout as vt, AgentWidgetComposerConfig as w, PersonaTheme as wa, VoiceProvider as wi, ClientSession as wn, HistoryScope as wr, AgentWidgetRenderHistoryStateContext as wt, AgentWidgetAttachmentsConfig as x, DeepPartial as xa, VoiceDirectTurn as xi, ClientFeedbackRequest as xn, HistoryIdentityStatus as xr, AgentWidgetRenderHistoryConversationContext as xt, AgentWidgetAskUserQuestionStyles as y, ComponentTokens as ya, VoiceDelegationResult as yi, AttachmentUploadContext as yn, HistoryConversationSummary as yr, AgentWidgetParsedAction as yt, AgentWidgetContextMentionSource as z, TypographyScale as za, renderLucideIcon as zi, ComposerAttachmentState as zn, PersonaArtifactDisplayMode as zr, AgentWidgetStoredDraft as zt };
11020
11165
  export {}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=`webmcp:`;function t(t){return t.origin===`webmcp`&&!t.name.startsWith(e)?e+t.name:t.name}function n(n,r){let i=!1,a=Promise.resolve(),o=null,s=/* @__PURE__ */ new Map,c=/* @__PURE__ */ new Map,l=()=>{a=a.then(async()=>{let e=i?null:await n.snapshot().catch(()=>null);if(!e||i||e.fingerprint===o)return;let a=e.tools.map(e=>({...e,name:t(e)})),c={type:`client_tools`,fingerprint:e.fingerprint,tools:a};r.send(c)&&(o=e.fingerprint,s=new Map(a.map(e=>[e.name,e])))})},u=e=>{for(let[t,n]of c)(e===void 0||n.delegationId===e)&&(c.delete(t),n.abort.abort())},d=n.onChange(l);return l(),{abort:u,close(){i=!0,d(),u()},call(t){let{delegationId:a,toolCallId:l}=t;if(i||typeof a!=`string`||!a||typeof l!=`string`||!l)return;let u=new AbortController;c.get(l)?.abort.abort(),c.set(l,{delegationId:a,abort:u});let d=({status:e,result:t,error:n})=>{c.get(l)?.abort===u&&(c.delete(l),!(i||r.cancelled(a))&&r.send({type:`client_tool_result`,delegationId:a,toolCallId:l,status:e,...t!==void 0&&{result:t},...n&&{error:{message:n.message}}}))},f=typeof t.name==`string`?t.name:``,p=s.get(f)??s.get(e+f);if(!p||t.fingerprint!==o)return d({status:`stale`,error:{message:p?`The page's tools changed.`:`Unknown tool: ${f}`}});let m=t.arguments&&typeof t.arguments==`object`&&!Array.isArray(t.arguments)?t.arguments:{},h=typeof t.timeoutMs==`number`&&t.timeoutMs>0?t.timeoutMs:0,g,_=n.execute(p.name,m,{signal:u.signal,autoConfirmReadOnly:!0}).catch(e=>({status:`failed`,error:{message:e instanceof Error?e.message:String(e)}})),v=new Promise(e=>{h&&(g=setTimeout(()=>{u.abort(),e({status:`timeout`,error:{message:`Page tool exceeded ${h}ms.`}})},h))});Promise.race([_,v]).then(e=>{clearTimeout(g),d(e)})}}}exports.createVoiceClientToolsSession=n,exports.voiceClientToolName=t;
@@ -0,0 +1,13 @@
1
+ import { En as ClientToolDefinition, fi as VoiceClientTools, mi as VoiceClientToolsSession, pi as VoiceClientToolsChannel } from "./types-oAZ1VReS.cjs";
2
+ //#region src/voice/voice-client-tools-session.d.ts
3
+ /** The name the server calls a client tool back with: `webmcp:` prefixed for page tools. */
4
+ export declare function voiceClientToolName(tool: ClientToolDefinition): string;
5
+ /**
6
+ * The fast-tier half of a voice call (see runtype-voice-provider.ts): keeps the
7
+ * server's `client_tools` snapshot current and answers each `client_tool_call`
8
+ * with exactly one `client_tool_result`. Ships in the lazy
9
+ * `voice-client-tools` chunk, loaded only when the server negotiates it.
10
+ */
11
+ export declare function createVoiceClientToolsSession(surface: VoiceClientTools, channel: VoiceClientToolsChannel): VoiceClientToolsSession;
12
+ //#endregion
13
+ export {}
@@ -0,0 +1,13 @@
1
+ import { En as ClientToolDefinition, fi as VoiceClientTools, mi as VoiceClientToolsSession, pi as VoiceClientToolsChannel } from "./types-oAZ1VReS.js";
2
+ //#region src/voice/voice-client-tools-session.d.ts
3
+ /** The name the server calls a client tool back with: `webmcp:` prefixed for page tools. */
4
+ export declare function voiceClientToolName(tool: ClientToolDefinition): string;
5
+ /**
6
+ * The fast-tier half of a voice call (see runtype-voice-provider.ts): keeps the
7
+ * server's `client_tools` snapshot current and answers each `client_tool_call`
8
+ * with exactly one `client_tool_result`. Ships in the lazy
9
+ * `voice-client-tools` chunk, loaded only when the server negotiates it.
10
+ */
11
+ export declare function createVoiceClientToolsSession(surface: VoiceClientTools, channel: VoiceClientToolsChannel): VoiceClientToolsSession;
12
+ //#endregion
13
+ export {}
@@ -0,0 +1 @@
1
+ const e=`webmcp:`;function t(t){return t.origin===`webmcp`&&!t.name.startsWith(e)?e+t.name:t.name}function n(n,r){let i=!1,a=Promise.resolve(),o=null,s=/* @__PURE__ */ new Map,c=/* @__PURE__ */ new Map,l=()=>{a=a.then(async()=>{let e=i?null:await n.snapshot().catch(()=>null);if(!e||i||e.fingerprint===o)return;let a=e.tools.map(e=>({...e,name:t(e)})),c={type:`client_tools`,fingerprint:e.fingerprint,tools:a};r.send(c)&&(o=e.fingerprint,s=new Map(a.map(e=>[e.name,e])))})},u=e=>{for(let[t,n]of c)(e===void 0||n.delegationId===e)&&(c.delete(t),n.abort.abort())},d=n.onChange(l);return l(),{abort:u,close(){i=!0,d(),u()},call(t){let{delegationId:a,toolCallId:l}=t;if(i||typeof a!=`string`||!a||typeof l!=`string`||!l)return;let u=new AbortController;c.get(l)?.abort.abort(),c.set(l,{delegationId:a,abort:u});let d=({status:e,result:t,error:n})=>{c.get(l)?.abort===u&&(c.delete(l),!(i||r.cancelled(a))&&r.send({type:`client_tool_result`,delegationId:a,toolCallId:l,status:e,...t!==void 0&&{result:t},...n&&{error:{message:n.message}}}))},f=typeof t.name==`string`?t.name:``,p=s.get(f)??s.get(e+f);if(!p||t.fingerprint!==o)return d({status:`stale`,error:{message:p?`The page's tools changed.`:`Unknown tool: ${f}`}});let m=t.arguments&&typeof t.arguments==`object`&&!Array.isArray(t.arguments)?t.arguments:{},h=typeof t.timeoutMs==`number`&&t.timeoutMs>0?t.timeoutMs:0,g,_=n.execute(p.name,m,{signal:u.signal,autoConfirmReadOnly:!0}).catch(e=>({status:`failed`,error:{message:e instanceof Error?e.message:String(e)}})),v=new Promise(e=>{h&&(g=setTimeout(()=>{u.abort(),e({status:`timeout`,error:{message:`Page tool exceeded ${h}ms.`}})},h))});Promise.race([_,v]).then(e=>{clearTimeout(g),d(e)})}}}export{n as createVoiceClientToolsSession,t as voiceClientToolName};
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{#e=null;#t=0;#n=[];#r=[];#i=[];#a=!1;#o=!1;#s=0;#c=!1;#l=!1;#u;#d=[];#f=0;#p=!1;#m;#h;#g;#_=null;constructor(e=24e3,t={}){this.#h=e;let n=Math.max(0,t.prebufferMs??0);this.#g=Math.round(e*n/1e3),this.#u=this.#g>0}#v(){if(!this.#e){let e=typeof window<`u`?window:void 0;if(!e)throw Error(`AudioPlaybackManager requires a browser environment`);let t=e.AudioContext||e.webkitAudioContext;this.#e=new t({sampleRate:this.#h})}let e=this.#e;return e.state===`suspended`&&!this.#l&&e.resume(),e}enqueue(e){if(e.length===0)return;let t=e;if(this.#_){let n=new Uint8Array(this.#_.length+e.length);n.set(this.#_),n.set(e,this.#_.length),t=n,this.#_=null}if(t.length%2!=0&&(this.#_=new Uint8Array([t[t.length-1]]),t=t.subarray(0,t.length-1)),t.length===0)return;let n=this.#S(t);n.length!==0&&(this.#u?(this.#d.push(n),this.#f+=n.length,clearTimeout(this.#m),this.#f>=this.#g?this.#y():this.#p&&(this.#m=setTimeout(()=>this.#y(),this.#g/this.#h*1e3))):this.#b(n))}markStreamEnd(){this.#d.length>0&&this.#y(),this.#o=!0,this.#x()}flush(){for(let e of this.#n){e.onended=null;try{e.stop(),e.disconnect()}catch{}}this.#n=[],this.#s=0,this.#t=0,this.#a=!1,this.#o=!1,this.#r=[],this.#i=[],this.#_=null,this.#d=[],this.#f=0,this.#u=this.#g>0,this.#c=!1,clearTimeout(this.#m)}setContinuousMode(e){this.#p=e}isPlaying(){return this.#a}onFinished(e){this.#r.push(e)}onStarted(e){this.#i.push(e)}pause(){this.#l=!0,this.#e&&this.#e.state===`running`&&this.#e.suspend()}resume(){this.#l=!1,this.#e&&this.#e.state===`suspended`&&this.#e.resume()}async destroy(){this.flush(),this.#e&&=(await this.#e.close(),null)}#y(){this.#u=!1;let e=this.#d;this.#d=[],this.#f=0;for(let t of e)this.#b(t)}#b(e){if(e.length===0)return;let t=this.#v(),n=t.createBuffer(1,e.length,this.#h);n.getChannelData(0).set(e);let r=t.createBufferSource();r.buffer=n,r.connect(t.destination);let i=t.currentTime;if(this.#t===0?this.#t=i:this.#t<i&&(this.#t=i,this.#g>0&&(this.#u=!0)),r.start(this.#t),this.#t+=n.duration,this.#n.push(r),this.#s++,this.#a=!0,!this.#c){this.#c=!0;let e=this.#i.slice();this.#i=[];for(let t of e)t()}r.onended=()=>{let e=this.#n.indexOf(r);e!==-1&&(this.#n.splice(e,1),this.#s--,this.#x())}}#x(){if(this.#o&&this.#s<=0&&this.#d.length===0){this.#a=!1,this.#o=!1;let e=this.#r.slice();this.#r=[];for(let t of e)t()}}#S(e){let t=Math.floor(e.length/2),n=new Float32Array(t),r=new DataView(e.buffer,e.byteOffset,e.byteLength);for(let e=0;e<t;e++){let t=r.getInt16(e*2,!0);n[e]=t/32768}return n}};const t=16e3,n=/* @__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.`]]),r=[`provider_error`,`server_restart`],i=`Voice connection lost.`;function a(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
2
  `)}`]:[];return n&&a.push(n),a.join(`
3
3
 
4
- `)}function o(e){return e.byteLength>=44&&new DataView(e).getUint32(0,!1)===1380533830?new Uint8Array(e,44):new Uint8Array(e)}function s(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 c(e){return s(e).replace(/^ws/i,`http`)}function l(e){return typeof e!=`number`||!Number.isFinite(e)?3e4:Math.min(6e5,Math.max(3e4,Math.round(e)))}var u=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f;#p;#m;#h;#g;#_;#v;#y;#b;#x;#S;#C;#w;#T;#E;#D;#O;#k;#A;#j;#M;#N;#P;#F;#I;#L;#R;#z;#B;#V;#H;#U;#W;#G;constructor(e){this.config=e,this.type=`runtype`,this.#e=null,this.#t=null,this.#n=[],this.#r=null,this.#i=null,this.#a=null,this.#o=[],this.#s=0,this.#c=null,this.#l=!1,this.#u=!1,this.#d=0,this.#f=!1,this.#p=-1/0,this.#m=null,this.#h=!1,this.#g=!1,this.#_=0,this.#v=0,this.#b=!1,this.bridge=null,this.#x=!1,this.#S=/* @__PURE__ */ new Set,this.#C=/* @__PURE__ */ new Map,this.#w=/* @__PURE__ */ new Set,this.#E=null,this.#D=null,this.#k=!1,this.#A=!1,this.#j=!1,this.#M=null,this.#N=null,this.#P=Promise.resolve(),this.#F=/* @__PURE__ */ new Set,this.#I=/* @__PURE__ */ new Set,this.#L=null,this.#R=!1,this.#z=/* @__PURE__ */ new Set,this.#B=/* @__PURE__ */ new Set,this.#V=[],this.#H=[],this.#U=[],this.#W=[],this.#G=[]}async connect(){}setSessionBridge(e){this.bridge=e}prewarm(){if(this.#l||this.#m)return;let e=this.config?.agentId,t=this.config?.clientToken,n=this.config?.host;if(!e||!t||!n)return;let r=Date.now();if(!(r-this.#p<3e4)){this.#p=r;try{this.config?.prewarmMode===`attach`?this.#q(n,e,t):this.#K(n,e,t)}catch{}}}#K(e,t,n){if(typeof fetch!=`function`)return;let r=`${c(e)}/v1/client/agents/${encodeURIComponent(t)}/voice/prewarm`;fetch(r,{method:`POST`,headers:{Authorization:`Bearer ${n}`},keepalive:!0}).catch(()=>{})}#q(e,t,n){let r=new URLSearchParams,i=this.config?.attachIdleMs,a=l(i);i!==void 0&&r.set(`attachIdleMs`,String(a));let o=new WebSocket(this.#Z(e,t,r),[`runtype.bearer`,`runtype.attach`,n]);o.binaryType=`arraybuffer`;let s=()=>{},c={ws:o,state:`connecting`,ready:new Promise(e=>{s=e}),settle:s,openedAt:0,idleTimer:void 0};this.#m=c,o.onopen=()=>{this.#m===c&&(c.state=o.protocol===`runtype.attach`?`attached`:`live`,c.openedAt=Date.now(),this.#J(c,a),c.state===`attached`&&o.send(`{"type":"ping"}`),c.settle())},o.onmessage=e=>{if(this.#m!==c||typeof e.data!=`string`)return;let t;try{t=JSON.parse(e.data)}catch{return}t.type===`attached`&&typeof t.idleMs==`number`&&this.#J(c,t.idleMs-(Date.now()-c.openedAt))},o.onerror=()=>{},o.onclose=()=>{this.#m===c&&this.#Y()}}#J(e,t){clearTimeout(e.idleTimer),e.idleTimer=setTimeout(()=>{this.#m===e&&this.#Y()},Math.max(0,t))}#Y(){let e=this.#m;if(!e)return;this.#m=null,clearTimeout(e.idleTimer);let{ws:t}=e;if(t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,e.settle(),t.readyState===WebSocket.CONNECTING||t.readyState===WebSocket.OPEN)try{t.close(1e3,`prewarm released`)}catch{}}async#X(){let e=this.#m;if(!e)return null;if(e.state===`connecting`){let t;await Promise.race([e.ready,new Promise(e=>{t=setTimeout(e,5e3)})]),clearTimeout(t)}return this.#m===e?e.state===`connecting`||e.ws.readyState!==WebSocket.OPEN?(this.#Y(),null):(this.#m=null,clearTimeout(e.idleTimer),{ws:e.ws,live:e.state===`live`}):null}#Z(e,t,n){let r=[`partial_transcript`,`context`];this.bridge&&this.config?.clientDelegation!==!1&&r.push(`client_delegation`,`delegation_update`,`delegation_read_back`,`delegation_stream`),n&&r.unshift(`attach`);let i=new URLSearchParams({voiceProtocol:`runtype-browser-v1`,clientVersion:`persona/4.28.2`,voiceCapabilities:`full-duplex-v1`,clientCapabilities:r.join(`,`)});return n?.forEach((e,t)=>i.set(t,e)),`${s(e)}/ws/agents/${encodeURIComponent(t)}/voice?${i}`}async startListening(){if(this.#l)return;let n=this.#A;n||(this.#k=!1,this.#D=null),this.#A=!1;let r=this.config?.agentId,a=this.config?.clientToken,o=this.config?.host;if(!r)throw Error(`Runtype voice requires an agentId`);if(!a)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:t,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:t});if(this.#t=l,l.state===`suspended`){if(await Promise.race([l.resume().catch(()=>{}),new Promise(e=>setTimeout(e,n?500:1e3))]),s!==this.#d)return;if(l.state!==`running`)throw Error(n?this.#D=`${i} Tap the mic to reconnect.`:`Audio blocked until a tap`)}let u=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new e(24e3);if(s!==this.#d){u.destroy(),c.getTracks().forEach(e=>e.stop()),l.close().catch(()=>{});return}this.#c=u,this.#de(),this.#ee(l,c,s);let d=await this.#X();if(s!==this.#d){d?.ws.close(1e3,`client ended call`);return}if(d){let{ws:e}=d;this.#e=e,this.#Q(e,s),d.live||e.send(`{"type":"start"}`),this.#te(e),this.#ge(`listening`);return}let f=new WebSocket(this.#Z(o,r),[`runtype.bearer`,a]);f.binaryType=`arraybuffer`,this.#e=f,f.onopen=()=>{s===this.#d&&(this.#te(f),this.#ge(`listening`))},this.#Q(f,s)}catch(e){throw this.#he(),this.#_e(e),this.#ge(`error`),e}}#Q(e,t){e.onmessage=e=>this.#ne(e,t),e.onerror=()=>{t!==this.#d||this.#E||(this.#_e(/* @__PURE__ */ Error(`Voice connection failed`)),this.#ge(`error`),this.#he())},e.onclose=e=>{if(this.#f){this.#f=!1;return}if(t!==this.#d)return;let n=this.#E??(e.code===4408?{reason:`idle_timeout`}:null);if(n)this.#$(n.reason,n.message);else{if(e.code!==1e3){let t=e.code?` (code ${e.code})`:``;this.#_e(/* @__PURE__ */ Error(`Voice connection closed${t}`)),this.#ge(`error`)}else this.#ge(`idle`);this.#he()}}}#$(e,t){let a=r.includes(e)&&!this.#k;if(this.#he(),a)this.#k=!0,this.#l=!0,this.#D=e===`provider_error`?`${i} Reconnecting…`:`Reconnecting…`,this.#O=setTimeout(()=>{this.#l=!1,this.#A=!0,this.startListening().catch(()=>{})},1e3+Math.random()*1e3),this.#ge(`idle`);else{if(r.includes(e))return this.#D=i,this.#_e(/* @__PURE__ */ Error(i)),this.#ge(`error`);if(e===`error`)return this.#ge(`error`);this.#D=e===`quota`&&t||n.get(e)||null,this.#ge(`idle`)}}takeNotice(){let e=this.#D;return this.#D=null,e}getDisclosure(){let e=this.config?.disclosureText;return this.#l&&this.#h&&e!==!1?e||`You're talking to an AI assistant. Voice is processed by OpenAI.`:null}async stopListening(){this.#he(),this.#ge(`idle`)}async disconnect(){this.#he(),this.#ge(`disconnected`),this.#V=[],this.#H=[],this.#U=[],this.#W=[],this.#G=[]}stopPlayback(){this.#me();let e=this.#e;e&&e.readyState===WebSocket.OPEN&&(this.#h&&(this.#_=Date.now()+2e3,e.send(`{"type":"cancel"}`)),this.#ge(`listening`))}getInterruptionMode(){return`barge-in`}isBargeInActive(){return this.#l}onLevel(e){this.#n.push(e)}async deactivateBargeIn(){this.#he(),this.#ge(`idle`)}#ee(e,t,n){let r=e.createMediaStreamSource(t);this.#i=r;let i=e.createScriptProcessor(4096,1,1);this.#a=i,i.onaudioprocess=e=>{if(n!==this.#d)return;let t=this.#e,r=t?.readyState===WebSocket.OPEN;if(t&&!r&&t.readyState!==WebSocket.CONNECTING)return;let i=e.inputBuffer.getChannelData(0),a=new Int16Array(i.length),o=0;for(let e=0;e<i.length;e++){let t=Math.max(-1,Math.min(1,i[e]));o+=t*t,a[e]=t<0?t*32768:t*32767}if(t&&r)this.#te(t),t.send(a.buffer);else for(this.#o.push(a.buffer),this.#s+=a.byteLength;this.#s>256e3;)this.#s-=this.#o.shift().byteLength;if(this.#n.length>0){let e=Math.sqrt(o/i.length),t=Math.max(0,Math.min(1,e*4));for(let e of this.#n)e(t)}},r.connect(i),i.connect(e.destination)}#te(e){for(let t of this.#o)e.send(t);this.#o=[],this.#s=0}#ne(e,t){if(t!==this.#d)return;if(e.data instanceof ArrayBuffer){this.#le(e.data,t);return}let n;try{n=JSON.parse(e.data)}catch{return}switch(n.type){case`session_config`:n.speechMode&&(this.#h=n.speechMode===`speech_to_speech`,this.#c?.setContinuousMode?.(this.#h)),Array.isArray(n.capabilities)&&(this.#S=new Set(n.capabilities)),typeof n.callId==`string`&&(this.#T=n.callId),this.#x=this.#h&&this.#S.has(`client_delegation`)&&!!this.bridge,this.#h&&!this.#u&&this.#ge(`listening`),this.#S.has(`context`)&&!this.#j&&(this.#j=!0,this.#M=this.#re());break;case`transcript_update`:{let e=n.role===`assistant`?`assistant`:`user`,r=n.utteranceId??n.turnId;if(!r||e===`assistant`&&this.#ue())break;let i=String(r);if(e===`user`)n.final===!0&&this.#ie(t),this.#R=!1;else{if(this.#S.has(`delegation_read_back`)){let e=n.delegationId;(typeof e==`string`&&this.#F.has(e)&&!this.#z.has(i)||this.#R&&!this.#z.has(i))&&(this.#B.add(i),this.#R=!1)}else this.#R&&!this.#z.has(i)&&(this.#B.add(i),this.#R=!1);if(this.#z.add(i),this.#B.has(i))break}this.#ve(e,n.text??``,n.final===!0,{turnId:i,...typeof n.startMs==`number`&&{startMs:n.startMs},...typeof n.endMs==`number`&&{endMs:n.endMs},...this.#x&&{caption:!0}});break}case`delegation_started`:case`delegation_completed`:{let e=String(n.delegationId??n.turnId);if(n.type===`delegation_started`){this.#ie(t);let r=n.input;this.#x&&r&&this.#ce(e,{delegationId:e,userText:String(r.text??``),userUtteranceIds:Array.isArray(r.userUtteranceIds)?r.userUtteranceIds.filter(e=>typeof e==`string`):[],messages:Array.isArray(r.messages)?r.messages:[]},t)}else n.speak!==!1&&this.#F.has(e)&&!this.#I.delete(e)&&!this.#S.has(`delegation_read_back`)&&this.#oe(e);this.#g=n.type===`delegation_started`,!this.#u&&!this.#ue()&&this.#ge(this.#g?`processing`:`listening`);break}case`delegation_progress`:{let e=String(n.delegationId);this.#F.has(e)&&!this.#I.has(e)&&!this.#w.has(e)&&(this.#I.add(e),this.#oe(e));break}case`delegation_cancelled`:this.#se(String(n.delegationId),n.reason!==`session_ending`&&n.reason!==`provider_cancelled`);break;case`warning`:console.warn(`[Persona voice] ${n.code}: ${n.message??``}`,this.#T??``),n.delegationId&&(n.code===`UNKNOWN_DELEGATION`||n.code===`LATE_RESULT_LIMIT`)&&this.#se(String(n.delegationId));break;case`audio_clear`:this.#me(),this.#_=0,this.#ge(`listening`);break;case`transcript_interim`:this.#ge(`listening`),this.#ve(`user`,n.text??``,!1);break;case`transcript_final`:{let e=n.role===`assistant`?`assistant`:`user`;this.#ge(e===`user`?`processing`:`speaking`),this.#ve(e,n.text??``,!0);break}case`audio_end`:this.#c?this.#c.markStreamEnd():(this.#u=!1,this.#ge(`listening`));break;case`metrics`:this.#ye({llmMs:n.llm_ms,ttsMs:n.tts_ms,firstAudioMs:n.first_audio_ms,totalMs:n.total_ms});break;case`error`:this.#_e(Error(n.error||`Voice error`)),this.#ge(`error`);break;case`session_end`:this.#E={reason:String(n.reason),...typeof n.message==`string`&&{message:n.message}}}}async#re(){let e=this.bridge?.getHistory()??[],t=``;try{let e=this.config?.callContext;t=String((typeof e==`function`?await e():e)??``)}catch{}return a(e,t)}#ie(e){let t=this.#M;if(!t)return;this.#M=null;let n=!1,r=t.then(t=>{let r=this.#e;!n&&t&&e===this.#d&&r?.readyState===WebSocket.OPEN&&r.send(JSON.stringify({type:`context`,text:t}))});this.#N={done:r,drop:()=>n=!0}}async#ae(){let e=this.#N;if(!e)return;let t,n=await Promise.race([e.done.then(()=>!1),new Promise(e=>{t=setTimeout(()=>e(!0),2e3)})]);clearTimeout(t),n&&e.drop()}#oe(e){this.#R=!0,this.#L=e}#se(e,t=!1){this.#w.add(e),this.#L===e&&(this.#R=!1),this.#I.delete(e),this.bridge?.dropDelegation?.(e,t),this.#C.get(e)?.abort()}#ce(e,t,n){let r=this.bridge,i=({type:t,...r})=>{let i=this.#e;return n!==this.#d||i?.readyState!==WebSocket.OPEN||this.#w.has(e)?!1:(i.send(JSON.stringify({type:t,delegationId:e,...r})),!0)},a=(e,t,n,r=0)=>i({type:e,status:t,text:n,...r>0&&{streamedChars:r}});this.#P=this.#P.then(async()=>{if(n!==this.#d||this.#w.has(e))return;let o=null,s=this.#S.has(`delegation_stream`)&&this.#S.has(`delegation_read_back`),c=t=>{o=(o??this.#ae()).then(()=>{i({type:`delegation_delta`,text:t})&&this.#F.add(e)})},l=await r.runDelegatedTurn(s?{...t,stream:c}:t).catch(()=>({status:`failed`,text:``}));await this.#ae(),await o;let u=s?l.streamedChars??0:0,d=!!l.followUp,f=d&&this.#S.has(`delegation_update`);if(!a(f?`delegation_update`:`delegation_result`,d&&!f?`completed`:l.status,l.text,u)||(l.status!==`failed`&&l.inChat!==!1&&this.#F.add(e),!l.followUp))return;let p=new AbortController;this.#C.set(e,p),l.followUp({signal:p.signal,approvalTimeoutMs:this.config?.approvalTimeoutMs&&Math.min(this.config.approvalTimeoutMs,54e4),readBack:f,onUpdate:e=>a(`delegation_update`,`pending_approval`,e)}).then(t=>{this.#C.delete(e),f&&t&&!p.signal.aborted&&a(`delegation_result`,t.status,t.text)})})}#le(e,t){if(t!==this.#d||!this.#c||this.#ue())return;let n=o(e);n.length!==0&&(this.#u||(this.#u=!0,this.#ge(`speaking`)),this.#de(),this.#c.enqueue(n),this.#h&&this.#fe(n.length))}#ue(){return Date.now()<this.#_}#de(){if(this.#b||!this.#c)return;this.#b=!0;let e=this.#d;this.#c.onFinished(()=>{e===this.#d&&(this.#b=!1,this.#pe())})}#fe(e){let t=Date.now();this.#v=Math.max(t,this.#v)+e/48,clearTimeout(this.#y),this.#y=setTimeout(()=>this.#pe(),this.#v-t+300)}#pe(){this.#u=!1,this.#v=0,this.#e&&this.#e.readyState===WebSocket.OPEN&&this.#ge(this.#g?`processing`:`listening`)}#me(){this.#c?.flush(),this.#b=!1,this.#de(),this.#u=!1,this.#v=0,clearTimeout(this.#y)}#he(){this.#d+=1,this.#l=!1,this.#u=!1,this.#Y(),this.#h=!1,this.#g=!1,this.#x=!1,this.#S=/* @__PURE__ */ new Set;for(let e of this.#C.values())e.abort();if(this.#C.clear(),this.#w.clear(),this.#T=void 0,this.#E=null,clearTimeout(this.#O),this.#j=!1,this.#M=null,this.#N=null,this.#P=Promise.resolve(),this.#F.clear(),this.#I.clear(),this.#L=null,this.#R=!1,this.#z.clear(),this.#B.clear(),this.#b=!1,this.#_=0,this.#v=0,clearTimeout(this.#y),this.#o=[],this.#s=0,this.#a&&=(this.#a.onaudioprocess=null,this.#a.disconnect(),null),this.#i&&=(this.#i.disconnect(),null),this.#r&&=(this.#r.getTracks().forEach(e=>e.stop()),null),this.#t&&=(this.#t.close().catch(()=>{}),null),this.#c&&=(this.#c.destroy(),null),this.#e){this.#f=!0;try{this.#e.close(1e3,`client ended call`)}catch{}this.#e=null}}onResult(e){this.#V.push(e)}onError(e){this.#H.push(e)}onStatusChange(e){this.#U.push(e)}onTranscript(e){this.#W.push(e)}onMetrics(e){this.#G.push(e)}#ge(e){this.#U.forEach(t=>t(e))}#_e(e){this.#H.forEach(t=>t(e))}#ve(e,t,n,r){this.#W.forEach(i=>i(e,t,n,r))}#ye(e){this.#G.forEach(t=>t(e))}},d=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 f(e){switch(e.type){case`runtype`:if(!e.runtype)throw Error(`Runtype voice provider requires configuration`);return new u(e.runtype);case`browser`:if(!d.isSupported())throw Error(`Browser speech recognition not supported`);return new d(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 p(e){if(e?.type===`custom`&&e.custom)return f({type:`custom`,custom:e.custom});if(e?.type===`runtype`&&e.runtype)return f({type:`runtype`,runtype:e.runtype});if(d.isSupported())return f({type:`browser`,browser:e?.browser||{language:`en-US`}});throw Error(`No supported voice providers available`)}function m(e){try{return p(e),!0}catch{return!1}}const h=e=>e.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,``);var g=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=h(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:h(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 _=/* @__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(`,`)),v=/([.!?]+|[,;:])(["'”’)\]*_]*)(\s+)|\n\s*/g;function y(e){let t=/(\S+)$/.exec(e)?.[1];if(!t)return!1;let n=t.replace(/^[("'“‘[*_]+/,``).toLowerCase();if(_.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*b(e,t){let n=new RegExp(v.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===`.`&&y(e.slice(0,r.index))))continue;let i=r.index+r[0].length;i<e.length&&(yield i)}}function x(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 S(e){let t=0;for(let n of b(e.slice(0,220),!0))t=n;if(t)return t;let n=x(e,220);if(n)return n;let r=e.charCodeAt(219);return r>=55296&&r<=56319?219:220}var C=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?S(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?S(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=b(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=x(e,220);if(t)return t}}return e.length>220?S(e):0}};const w=(e,t)=>{let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n+=1;return n},T=`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)`,E=RegExp(`^(?:${T})(?: (?:${T}))?(?: thanks| thank you)?$`),D=e=>E.test(e.toLowerCase().replace(/[^a-z' ]+/g,` `).replace(/\s+/g,` `).trim()),O=()=>new Promise(e=>setTimeout(e,50)),k=(e,t)=>e.length>t?`${e.slice(0,t-1).trimEnd()}…`:e,A=e=>e.replace(/^webmcp:/,``).replace(/([a-z\d])([A-Z])/g,`$1 $2`).replace(/[_\-.]+/g,` `).trim().toLowerCase();function j(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=>j(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=j(n,t+1);return r&&(t?`${A(e)} ${r}`:`${A(e)}: ${r}`)}).filter(Boolean).join(t?`, `:`; `)}function M(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=[A(t.toolName)];t.description&&r.push(`(${k(t.description.trim(),160)})`);let i=j(t.parameters);return i&&r.push(`with ${i}`),t.reason&&r.push(`because: ${k(t.reason.trim(),160)}`),k(`- ${r.join(` `)}`,Math.floor(n/e.length)-1)}).join(`
4
+ `)}function o(e){return e.byteLength>=44&&new DataView(e).getUint32(0,!1)===1380533830?new Uint8Array(e,44):new Uint8Array(e)}function s(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 c(e){return s(e).replace(/^ws/i,`http`)}function l(e){return typeof e!=`number`||!Number.isFinite(e)?3e4:Math.min(6e5,Math.max(3e4,Math.round(e)))}var u=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=`${c(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=l(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(e,t,n){let r=[`partial_transcript`,`context`];this.bridge&&this.config?.clientDelegation!==!1&&(r.push(`client_delegation`,`delegation_update`,`delegation_read_back`,`delegation_stream`),this.bridge.clientTools?.()&&r.push(`client_tools`)),n&&r.unshift(`attach`);let i=new URLSearchParams({voiceProtocol:`runtype-browser-v1`,clientVersion:`persona/4.29.0`,voiceCapabilities:`full-duplex-v1`,clientCapabilities:r.join(`,`)});return n?.forEach((e,t)=>i.set(t,e)),`${s(e)}/ws/agents/${encodeURIComponent(t)}/voice?${i}`}async startListening(){if(this.#l)return;let n=this.#A;n||(this.#k=!1,this.#D=null),this.#A=!1;let r=this.config?.agentId,a=this.config?.clientToken,o=this.config?.host;if(!r)throw Error(`Runtype voice requires an agentId`);if(!a)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:t,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:t});if(this.#t=l,l.state===`suspended`){if(await Promise.race([l.resume().catch(()=>{}),new Promise(e=>setTimeout(e,n?500:1e3))]),s!==this.#d)return;if(l.state!==`running`)throw Error(n?this.#D=`${i} Tap the mic to reconnect.`:`Audio blocked until a tap`)}let u=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new e(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`,a]);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 a=r.includes(e)&&!this.#k;if(this.#ye(),a)this.#k=!0,this.#l=!0,this.#D=e===`provider_error`?`${i} Reconnecting…`:`Reconnecting…`,this.#O=setTimeout(()=>{this.#l=!1,this.#A=!0,this.startListening().catch(()=>{})},1e3+Math.random()*1e3),this.#be(`idle`);else{if(r.includes(e))return this.#D=i,this.#xe(/* @__PURE__ */ Error(i)),this.#be(`error`);if(e===`error`)return this.#be(`error`);this.#D=e===`quota`&&t||n.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 a(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=o(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))}},d=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 f(e){switch(e.type){case`runtype`:if(!e.runtype)throw Error(`Runtype voice provider requires configuration`);return new u(e.runtype);case`browser`:if(!d.isSupported())throw Error(`Browser speech recognition not supported`);return new d(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 p(e){if(e?.type===`custom`&&e.custom)return f({type:`custom`,custom:e.custom});if(e?.type===`runtype`&&e.runtype)return f({type:`runtype`,runtype:e.runtype});if(d.isSupported())return f({type:`browser`,browser:e?.browser||{language:`en-US`}});throw Error(`No supported voice providers available`)}function m(e){try{return p(e),!0}catch{return!1}}const h=e=>e.toLowerCase().replace(/[^\p{L}\p{N}]+/gu,``);var g=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=h(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:h(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 _=/* @__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(`,`)),v=/([.!?]+|[,;:])(["'”’)\]*_]*)(\s+)|\n\s*/g;function y(e){let t=/(\S+)$/.exec(e)?.[1];if(!t)return!1;let n=t.replace(/^[("'“‘[*_]+/,``).toLowerCase();if(_.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*b(e,t){let n=new RegExp(v.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===`.`&&y(e.slice(0,r.index))))continue;let i=r.index+r[0].length;i<e.length&&(yield i)}}function x(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 S(e){let t=0;for(let n of b(e.slice(0,220),!0))t=n;if(t)return t;let n=x(e,220);if(n)return n;let r=e.charCodeAt(219);return r>=55296&&r<=56319?219:220}var C=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?S(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?S(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=b(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=x(e,220);if(t)return t}}return e.length>220?S(e):0}};const w=(e,t)=>{let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n+=1;return n},T=`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)`,E=RegExp(`^(?:${T})(?: (?:${T}))?(?: thanks| thank you)?$`),D=e=>E.test(e.toLowerCase().replace(/[^a-z' ]+/g,` `).replace(/\s+/g,` `).trim()),O=()=>new Promise(e=>setTimeout(e,50)),k=(e,t)=>e.length>t?`${e.slice(0,t-1).trimEnd()}…`:e,A=e=>e.replace(/^webmcp:/,``).replace(/([a-z\d])([A-Z])/g,`$1 $2`).replace(/[_\-.]+/g,` `).trim().toLowerCase();function j(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=>j(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=j(n,t+1);return r&&(t?`${A(e)} ${r}`:`${A(e)}: ${r}`)}).filter(Boolean).join(t?`, `:`; `)}function M(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=[A(t.toolName)];t.description&&r.push(`(${k(t.description.trim(),160)})`);let i=j(t.parameters);return i&&r.push(`with ${i}`),t.reason&&r.push(`because: ${k(t.reason.trim(),160)}`),k(`- ${r.join(` `)}`,Math.floor(n/e.length)-1)}).join(`
5
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 N=e=>e.variant===`approval`&&e.approval?.status===`pending`;function P(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=>A(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
6
 
7
- `),p=async t=>{do await O();while(e.busy()&&!(t&&(e.parked()||t.failed)))};return{getHistory:()=>{let t=e.messages().filter(e=>(e.role===`user`||e.role===`assistant`)&&!e.variant&&!e.voiceProcessing&&!e.streaming&&e.content),n=!1,r=[];for(let e=t.length-1;e>=0;--e){let i=t[e];if(i.role===`user`)n=!1;else if(!i.voiceCaption)n=!0;else if(n)continue;r.unshift({role:i.role,content:i.content})}return r},dropDelegation(t,n){o.set(t,!!n),o.size>32&&o.delete(o.keys().next().value);let r=n&&i.find(e=>e.delegationId===t);r&&!r.outcome&&d(r,`timeout`,``);for(let n of a.get(t)??[])n.stopStream?.(),n.dropped=!0,n.ids.length&&e.unspoken(n.ids)},async runDelegatedTurn({delegationId:m,userText:h,userUtteranceIds:g,stream:_}){let v=i.filter(e=>l(e).length),y=v.flatMap(l);if(y.length===1&&D(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=>!N(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`),T={ids:[],failed:!1},E=_?new C:null,k=``,j=``,P=!1,F=e=>{for(let t of e)j+=t,_(t)},I;E&&(T.onUpdate=()=>{if(P)return;let e=f(T.ids);if(!e.startsWith(k)){P=!0,clearTimeout(I);return}if(e.length===k.length)return;let t=e.slice(k.length);k=e,F(E.push(t)),clearTimeout(I),I=setTimeout(()=>{P||F(E.idle())},200)},T.stopStream=()=>{clearTimeout(I),P=!0,T.onUpdate=void 0}),s(m,T),t=T,r();try{await e.send(h,e.claim(h,g)??void 0),await p(T)}catch{T.failed=!0}finally{t=null,r()}E&&(T.onUpdate?.(),clearTimeout(I),P||F(E.flush()),T.onUpdate=void 0,T.stopStream=void 0);let L=e=>{let t=w(j,e);return t>0?{streamedChars:t}:{}},R=T.ids.flatMap(t=>e.messages().find(e=>e.id===t)??[]),z=f(T.ids),B=T.failed?[]:S().filter(N),V=new Set(B.map(e=>A(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${M(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=>N(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(N));){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(),_?.(M(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 O()}}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=>A(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)),k=w(e=>e.approval?.status===`timeout`),j=[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.`,k&&`The ${k} request timed out, so it was not done.`].filter(Boolean).join(`
7
+ `),p=async t=>{do await O();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&&D(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=>!N(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`),T={ids:[],failed:!1},E=_?new C:null,k=``,j=``,P=!1,F=e=>{for(let t of e)j+=t,_(t)},I;E&&(T.onUpdate=()=>{if(P)return;let e=f(T.ids);if(!e.startsWith(k)){P=!0,clearTimeout(I);return}if(e.length===k.length)return;let t=e.slice(k.length);k=e,F(E.push(t)),clearTimeout(I),I=setTimeout(()=>{P||F(E.idle())},200)},T.stopStream=()=>{clearTimeout(I),P=!0,T.onUpdate=void 0}),s(m,T),t=T,r();try{await e.send(h,e.claim(h,g)??void 0),await p(T)}catch{T.failed=!0}finally{t=null,r()}E&&(T.onUpdate?.(),clearTimeout(I),P||F(E.flush()),T.onUpdate=void 0,T.stopStream=void 0);let L=e=>{let t=w(j,e);return t>0?{streamedChars:t}:{}},R=T.ids.flatMap(t=>e.messages().find(e=>e.id===t)??[]),z=f(T.ids),B=T.failed?[]:S().filter(N),V=new Set(B.map(e=>A(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${M(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=>N(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(N));){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(),_?.(M(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 O()}}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=>A(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)),k=w(e=>e.approval?.status===`timeout`),j=[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.`,k&&`The ${k} request timed out, so it was not done.`].filter(Boolean).join(`
8
8
 
9
- `);return{status:T?`completed`:E?`denied`:D?`cancelled`:k?`timeout`:`completed`,text:j}}}}return!T.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:T.failed?`failed`:`completed`,text:z,...L(z)}):{status:!T.failed&&z?`completed`:`failed`,text:z,...L(z)}}}}const F=(e,t,n,r)=>{let i=e.session;try{e.keyed=n?new n({find:e=>i.messages.find(t=>t.id===e),inject:e=>i.injectMessage(e),upsert:e=>i.upsertMessage(e),settle:e=>{i.messages=i.messages.map(t=>e.has(t.id)?{...t,streaming:!1,voiceProcessing:!1}:t),i.callbacks.onMessagesChanged([...i.messages])},setStreaming:t=>{(t||!e.busy())&&e.setStreaming(t)},markSpoken:e=>{i.ttsSpokenMessageIds.add(e)}}):null,r&&t.setSessionBridge&&t.setSessionBridge(r({messages:()=>i.messages,busy:()=>e.busy(),parked:()=>i.webMcpApprovalResolvers.size>0,claim:(t,n)=>e.keyed?.claimUserTurn(t,n)??null,send:(e,t)=>i.sendMessage(e,{viaVoice:!0,voiceTurn:{userMessageId:t}}),track:t=>{e.setDelegation(t)},unspoken:e=>{for(let t of e)i.ttsSpokenMessageIds.delete(t);i.streaming||i.speakLatestAssistantMessage(e)},decide:e=>{if(i.webMcpApprovalResolvers.has(e))return i.resolveWebMcpApproval(e,`denied`);let t=i.messages.find(t=>t.id===e)?.approval;t?.status===`pending`&&i.resolveApproval(t,`denied`)}}));let a=e.generation(),o=()=>e.provider()===t&&a===e.generation(),s=(i.config.voiceRecognition??{}).processingErrorText??`Voice processing failed. Please try again.`;t.onResult(e=>{o()&&e.provider!==`runtype`&&e.text&&e.text.trim()&&i.sendMessage(e.text,{viaVoice:!0})}),t.onTranscript&&t.onTranscript((t,n,r,a)=>{if(o()){if(a?.turnId)e.keyed?.apply(t,n,r,a.turnId,a.startMs,a.caption);else if(t===`user`)e.pendingUser?i.upsertMessage({id:e.pendingUser,role:`user`,content:n,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,voiceProcessing:!r}):e.pendingUser=i.injectMessage({role:`user`,content:n,streaming:!1,voiceProcessing:!r}).id,r&&(e.turns().start(a?.turnId),e.pendingUser=null,e.pendingAssistant=i.injectMessage({role:`assistant`,content:``,streaming:!0,voiceProcessing:!0}).id,e.setStreaming(!0));else{if(!e.turns().accepts(a?.turnId))return;e.pendingAssistant?i.upsertMessage({id:e.pendingAssistant,role:`assistant`,content:n,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!r,voiceProcessing:!r}):e.pendingAssistant=i.injectMessage({role:`assistant`,content:n,streaming:!r,voiceProcessing:!r}).id,r&&(e.pendingAssistant&&i.ttsSpokenMessageIds.add(e.pendingAssistant),e.setStreaming(!1),e.pendingAssistant=null)}}}),t.onLevel&&t.onLevel(t=>{o()&&e.setLevel(Number.isFinite(t)?Math.max(0,Math.min(1,t)):0)}),t.onMetrics&&t.onMetrics(e=>{o()&&i.config.voiceRecognition?.onMetrics?.(e)}),t.onError(t=>{o()&&(console.error(`Voice error:`,t),e.pendingAssistant&&=(i.upsertMessage({id:e.pendingAssistant,role:`assistant`,content:s,createdAt:(/* @__PURE__ */ new Date()).toISOString(),streaming:!1,voiceProcessing:!1}),e.setStreaming(!1),e.pendingUser=null,null),e.keyed?.fail(s))}),t.onStatusChange(t=>{o()&&(e.setStatus(t),(t===`listening`||t===`idle`||t===`disconnected`)&&e.settlePending(t!==`listening`),(t===`idle`||t===`disconnected`)&&e.keyed?.settle(),i.callbacks.onVoiceStatusChanged?.(t))}),t.connect()}catch(e){console.error(`Failed to setup voice:`,e)}},I=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`)}}};exports.BrowserVoiceProvider=d,exports.KeyedVoiceTranscript=g,exports.RuntypeVoiceProvider=u,exports.createBestAvailableVoiceProvider=p,exports.createMicStateStyles=I,exports.createVoiceProvider=f,exports.createVoiceSessionBridge=P,exports.isVoiceSupported=m,exports.wireSessionVoice=F;
9
+ `);return{status:T?`completed`:E?`denied`:D?`cancelled`:k?`timeout`:`completed`,text:j}}}}return!T.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:T.failed?`failed`:`completed`,text:z,...L(z)}):{status:!T.failed&&z?`completed`:`failed`,text:z,...L(z)}}}}const F=(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)}},I=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`)}}};exports.BrowserVoiceProvider=d,exports.KeyedVoiceTranscript=g,exports.RuntypeVoiceProvider=u,exports.createBestAvailableVoiceProvider=p,exports.createMicStateStyles=I,exports.createVoiceProvider=f,exports.createVoiceSessionBridge=P,exports.isVoiceSupported=m,exports.wireSessionVoice=F;
@@ -1,5 +1,5 @@
1
- import { Dr as InjectMessageOptions, T as AgentWidgetConfig, gi as VoiceStatus, hi as VoiceSessionBridge, mt as AgentWidgetMessage, pi as VoiceProvider } from "./types-BdO1jNRm.cjs";
2
- import { J as isVoiceSupported, K as createBestAvailableVoiceProvider, X as RuntypeVoiceProvider, Y as BrowserVoiceProvider, q as createVoiceProvider, t as AgentWidgetSession } from "./session-a_qIp4xp.cjs";
1
+ import { Ar as InjectMessageOptions, Di as VoiceStatus, Ei as VoiceSessionBridge, T as AgentWidgetConfig, fi as VoiceClientTools, mt as AgentWidgetMessage, wi as VoiceProvider, xi as VoiceDirectTurn } from "./types-oAZ1VReS.cjs";
2
+ import { J as isVoiceSupported, K as createBestAvailableVoiceProvider, X as RuntypeVoiceProvider, Y as BrowserVoiceProvider, q as createVoiceProvider, t as AgentWidgetSession } from "./session-DleMr9dZ.cjs";
3
3
  //#region src/voice/keyed-voice-transcript.d.ts
4
4
  /** The session surface the keyed reconciler drives. */
5
5
  interface KeyedVoiceTranscriptHost {
@@ -111,6 +111,10 @@ interface VoiceDelegationHost {
111
111
  decide(approvalMessageId: string): void;
112
112
  /** Let browser TTS read these messages after all (their spoken result was dropped). */
113
113
  unspoken(messageIds: string[]): void;
114
+ /** WebMCP access for the voice fast tier; `null` when WebMCP is off. */
115
+ clientTools?(): VoiceClientTools | null;
116
+ /** Write a server-answered (`route: 'direct'`) turn into the chat. */
117
+ recordDirect?(turn: VoiceDirectTurn): void;
114
118
  }
115
119
  /**
116
120
  * Builds the {@link VoiceSessionBridge} a full-duplex provider uses to run
@@ -130,7 +134,7 @@ declare class VoiceTurnTracker {
130
134
  //#endregion
131
135
  //#region src/voice/session-voice-wiring.d.ts
132
136
  /** The session members the wiring touches (some are TS-private on the class). */
133
- type VoiceWiringSession = Pick<AgentWidgetSession, "injectMessage" | "sendMessage" | "resolveWebMcpApproval" | "resolveApproval"> & {
137
+ type VoiceWiringSession = Pick<AgentWidgetSession, "injectMessage" | "sendMessage" | "resolveWebMcpApproval" | "resolveApproval" | "getClient"> & {
134
138
  messages: AgentWidgetMessage[];
135
139
  callbacks: AgentWidgetSession["callbacks"];
136
140
  config: AgentWidgetSession["config"];
@@ -1,5 +1,5 @@
1
- import { Dr as InjectMessageOptions, T as AgentWidgetConfig, gi as VoiceStatus, hi as VoiceSessionBridge, mt as AgentWidgetMessage, pi as VoiceProvider } from "./types-BdO1jNRm.js";
2
- import { J as isVoiceSupported, K as createBestAvailableVoiceProvider, X as RuntypeVoiceProvider, Y as BrowserVoiceProvider, q as createVoiceProvider, t as AgentWidgetSession } from "./session-a_qIp4xp.js";
1
+ import { Ar as InjectMessageOptions, Di as VoiceStatus, Ei as VoiceSessionBridge, T as AgentWidgetConfig, fi as VoiceClientTools, mt as AgentWidgetMessage, wi as VoiceProvider, xi as VoiceDirectTurn } from "./types-oAZ1VReS.js";
2
+ import { J as isVoiceSupported, K as createBestAvailableVoiceProvider, X as RuntypeVoiceProvider, Y as BrowserVoiceProvider, q as createVoiceProvider, t as AgentWidgetSession } from "./session-DleMr9dZ.js";
3
3
  //#region src/voice/keyed-voice-transcript.d.ts
4
4
  /** The session surface the keyed reconciler drives. */
5
5
  interface KeyedVoiceTranscriptHost {
@@ -111,6 +111,10 @@ interface VoiceDelegationHost {
111
111
  decide(approvalMessageId: string): void;
112
112
  /** Let browser TTS read these messages after all (their spoken result was dropped). */
113
113
  unspoken(messageIds: string[]): void;
114
+ /** WebMCP access for the voice fast tier; `null` when WebMCP is off. */
115
+ clientTools?(): VoiceClientTools | null;
116
+ /** Write a server-answered (`route: 'direct'`) turn into the chat. */
117
+ recordDirect?(turn: VoiceDirectTurn): void;
114
118
  }
115
119
  /**
116
120
  * Builds the {@link VoiceSessionBridge} a full-duplex provider uses to run
@@ -130,7 +134,7 @@ declare class VoiceTurnTracker {
130
134
  //#endregion
131
135
  //#region src/voice/session-voice-wiring.d.ts
132
136
  /** The session members the wiring touches (some are TS-private on the class). */
133
- type VoiceWiringSession = Pick<AgentWidgetSession, "injectMessage" | "sendMessage" | "resolveWebMcpApproval" | "resolveApproval"> & {
137
+ type VoiceWiringSession = Pick<AgentWidgetSession, "injectMessage" | "sendMessage" | "resolveWebMcpApproval" | "resolveApproval" | "getClient"> & {
134
138
  messages: AgentWidgetMessage[];
135
139
  callbacks: AgentWidgetSession["callbacks"];
136
140
  config: AgentWidgetSession["config"];