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