@meridial/react 0.1.2 → 0.1.5

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.
@@ -22,107 +22,438 @@ import {
22
22
  } from "./chunk-PRTYKFO3.js";
23
23
 
24
24
  // src/voicebox.tsx
25
+ import { AnimatePresence as AnimatePresence4 } from "motion/react";
26
+ import { useState as useState10, useEffect as useEffect7 } from "react";
27
+
28
+ // src/components/workflow-execution.tsx
29
+ import { useState, useCallback, useEffect, useRef } from "react";
30
+ import { createPortal } from "react-dom";
25
31
  import {
26
- useSession,
27
- useAgent,
28
- useSessionContext as useSessionContext3,
29
- useEnsureRoom as useEnsureRoom3
30
- } from "@livekit/components-react";
31
- import { AnimatePresence as AnimatePresence3, motion as motion3 } from "motion/react";
32
- import { TokenSource, RpcError as RpcError2 } from "livekit-client";
33
- import { useDraggable } from "@neodrag/react";
32
+ motion,
33
+ useMotionValue,
34
+ useSpring,
35
+ AnimatePresence
36
+ } from "motion/react";
34
37
  import {
35
- useRef as useRef6,
36
- useState as useState9,
37
- useMemo as useMemo5,
38
- useEffect as useEffect6,
39
- useCallback as useCallback5
40
- } from "react";
41
- import { ChatFeedback01Icon, Loading03Icon as Loading03Icon3 } from "@hugeicons/core-free-icons";
42
- import { HugeiconsIcon as HugeiconsIcon7 } from "@hugeicons/react";
43
-
44
- // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/toggle/Toggle.js
45
- import * as React7 from "react";
46
-
47
- // ../../node_modules/.pnpm/@base-ui+utils@0.2.5_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/utils/esm/useControlled.js
48
- import * as React from "react";
49
- function useControlled({
50
- controlled,
51
- default: defaultProp,
52
- name,
53
- state = "value"
38
+ Cursor02Icon,
39
+ ArrowLeft01Icon,
40
+ ArrowRight01Icon,
41
+ Tick01Icon
42
+ } from "@hugeicons/core-free-icons";
43
+ import { HugeiconsIcon } from "@hugeicons/react";
44
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
45
+ var SPRING_CONFIG = { stiffness: 120, damping: 20, mass: 0.8 };
46
+ var CURSOR_OFFSET = 16;
47
+ function WorkflowExecution({
48
+ workflow,
49
+ attribute = "data-meridial-id",
50
+ cursor,
51
+ onClose,
52
+ onStepChange,
53
+ onError
54
54
  }) {
55
- const {
56
- current: isControlled
57
- } = React.useRef(controlled !== void 0);
58
- const [valueState, setValue] = React.useState(defaultProp);
59
- const value = isControlled ? controlled : valueState;
60
- if (process.env.NODE_ENV !== "production") {
61
- React.useEffect(() => {
62
- if (isControlled !== (controlled !== void 0)) {
63
- console.error([`Base UI: A component is changing the ${isControlled ? "" : "un"}controlled ${state} state of ${name} to be ${isControlled ? "un" : ""}controlled.`, "Elements should not switch from uncontrolled to controlled (or vice versa).", `Decide between using a controlled or uncontrolled ${name} element for the lifetime of the component.`, "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", "More info: https://fb.me/react-controlled-components"].join("\n"));
64
- }
65
- }, [state, name, controlled]);
66
- const {
67
- current: defaultValue
68
- } = React.useRef(defaultProp);
69
- React.useEffect(() => {
70
- if (!isControlled && JSON.stringify(defaultValue) !== JSON.stringify(defaultProp)) {
71
- console.error([`Base UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. To suppress this warning opt to use a controlled ${name}.`].join("\n"));
55
+ const [currentIndex, setCurrentIndex] = useState(0);
56
+ const steps = workflow.steps;
57
+ const currentStep = steps[currentIndex];
58
+ const isFirstStep = currentIndex === 0;
59
+ const isLastStep = currentIndex === steps.length - 1;
60
+ useEffect(() => {
61
+ onStepChange?.(currentIndex);
62
+ }, [currentIndex, onStepChange]);
63
+ const handleBack = useCallback(() => {
64
+ setCurrentIndex((prev) => Math.max(0, prev - 1));
65
+ }, []);
66
+ const handleNext = useCallback(() => {
67
+ setCurrentIndex((prev) => {
68
+ if (prev >= steps.length - 1) {
69
+ onClose();
70
+ return prev;
72
71
  }
73
- }, [JSON.stringify(defaultProp)]);
74
- }
75
- const setValueIfUncontrolled = React.useCallback((newValue) => {
76
- if (!isControlled) {
77
- setValue(newValue);
72
+ return prev + 1;
73
+ });
74
+ }, [steps.length, onClose]);
75
+ if (!currentStep) return null;
76
+ return /* @__PURE__ */ jsx(
77
+ ExecutionOverlay,
78
+ {
79
+ step: currentStep,
80
+ stepIndex: currentIndex,
81
+ totalSteps: steps.length,
82
+ isFirstStep,
83
+ isLastStep,
84
+ attribute,
85
+ cursor,
86
+ onBack: handleBack,
87
+ onNext: handleNext,
88
+ onError
78
89
  }
79
- }, []);
80
- return [value, setValueIfUncontrolled];
90
+ );
81
91
  }
82
-
83
- // ../../node_modules/.pnpm/@base-ui+utils@0.2.5_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/utils/esm/useId.js
84
- import * as React2 from "react";
85
- var globalId = 0;
86
- function useGlobalId(idOverride, prefix = "mui") {
87
- const [defaultId, setDefaultId] = React2.useState(idOverride);
88
- const id = idOverride || defaultId;
89
- React2.useEffect(() => {
90
- if (defaultId == null) {
91
- globalId += 1;
92
- setDefaultId(`${prefix}-${globalId}`);
92
+ function ExecutionOverlay({
93
+ step,
94
+ stepIndex,
95
+ totalSteps,
96
+ isFirstStep,
97
+ isLastStep,
98
+ attribute,
99
+ cursor,
100
+ onBack,
101
+ onNext,
102
+ onError
103
+ }) {
104
+ const cssSelector = `[${attribute}="${step.elementId}"]`;
105
+ const { rect } = useElementTracker({
106
+ selector: cssSelector,
107
+ urlPath: step.urlPath,
108
+ onError: onError ? (msg) => {
109
+ if (msg !== null) onError(msg);
110
+ } : void 0,
111
+ onClick: onNext
112
+ });
113
+ const hasAnimated = useRef(false);
114
+ const springX = useSpring(useMotionValue(0), SPRING_CONFIG);
115
+ const springY = useSpring(useMotionValue(0), SPRING_CONFIG);
116
+ if (rect) {
117
+ const targetX = rect.right + CURSOR_OFFSET;
118
+ const targetY = rect.bottom + CURSOR_OFFSET;
119
+ if (!hasAnimated.current) {
120
+ springX.jump(targetX);
121
+ springY.jump(targetY);
122
+ hasAnimated.current = true;
123
+ } else {
124
+ springX.set(targetX);
125
+ springY.set(targetY);
93
126
  }
94
- }, [defaultId, prefix]);
95
- return id;
96
- }
97
- var maybeReactUseId = SafeReact.useId;
98
- function useId(idOverride, prefix) {
99
- if (maybeReactUseId !== void 0) {
100
- const reactId = maybeReactUseId();
101
- return idOverride ?? (prefix ? `${prefix}-${reactId}` : reactId);
102
- }
103
- return useGlobalId(idOverride, prefix);
104
- }
105
-
106
- // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/utils/useBaseUiId.js
107
- function useBaseUiId(idOverride) {
108
- return useId(idOverride, "base-ui");
109
- }
110
-
111
- // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/toggle-group/ToggleGroupContext.js
112
- import * as React3 from "react";
113
- var ToggleGroupContext = /* @__PURE__ */ React3.createContext(void 0);
114
- if (process.env.NODE_ENV !== "production") ToggleGroupContext.displayName = "ToggleGroupContext";
115
- function useToggleGroupContext(optional = true) {
116
- const context = React3.useContext(ToggleGroupContext);
117
- if (context === void 0 && !optional) {
118
- throw new Error(process.env.NODE_ENV !== "production" ? "Base UI: ToggleGroupContext is missing. ToggleGroup parts must be placed within <ToggleGroup>." : formatErrorMessage(7));
127
+ } else {
128
+ hasAnimated.current = false;
119
129
  }
120
- return context;
130
+ return createPortal(
131
+ /* @__PURE__ */ jsx(AnimatePresence, { children: rect && /* @__PURE__ */ jsxs(
132
+ motion.div,
133
+ {
134
+ "data-meridial-ui": true,
135
+ className: "pointer-events-none fixed z-[99999] flex items-start gap-3",
136
+ style: { top: springY, left: springX },
137
+ initial: { opacity: 0, scale: 0.6 },
138
+ animate: { opacity: 1, scale: 1 },
139
+ exit: { opacity: 0, scale: 0.6 },
140
+ transition: { duration: 0.2 },
141
+ children: [
142
+ cursor ?? /* @__PURE__ */ jsx(
143
+ HugeiconsIcon,
144
+ {
145
+ icon: Cursor02Icon,
146
+ strokeWidth: 2,
147
+ size: 32,
148
+ className: "mt-1 shrink-0 fill-primary/60 text-primary"
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsxs(
152
+ "div",
153
+ {
154
+ "data-meridial-ui": true,
155
+ className: "pointer-events-auto w-72 overflow-hidden rounded-lg border border-border bg-card shadow-lg",
156
+ children: [
157
+ /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxs(
158
+ motion.div,
159
+ {
160
+ initial: { opacity: 0, y: 8 },
161
+ animate: { opacity: 1, y: 0 },
162
+ exit: { opacity: 0, y: -8 },
163
+ transition: { duration: 0.2, ease: "easeInOut" },
164
+ className: "px-4 pt-3 pb-2",
165
+ children: [
166
+ /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-foreground", children: step.description || /* @__PURE__ */ jsx("span", { className: "text-muted-foreground italic", children: "No description" }) }),
167
+ /* @__PURE__ */ jsxs("span", { className: "mt-1 block text-xs text-muted-foreground", children: [
168
+ "Step ",
169
+ stepIndex + 1,
170
+ " of ",
171
+ totalSteps
172
+ ] })
173
+ ]
174
+ },
175
+ step.id
176
+ ) }),
177
+ /* @__PURE__ */ jsxs(
178
+ "div",
179
+ {
180
+ "data-meridial-ui": true,
181
+ className: "flex justify-end gap-2 border-t px-3 py-2",
182
+ children: [
183
+ /* @__PURE__ */ jsxs(
184
+ Button,
185
+ {
186
+ variant: "outline",
187
+ size: "sm",
188
+ "data-meridial-ui": true,
189
+ onClick: onBack,
190
+ disabled: isFirstStep,
191
+ children: [
192
+ /* @__PURE__ */ jsx(HugeiconsIcon, { icon: ArrowLeft01Icon, size: 14 }),
193
+ "Back"
194
+ ]
195
+ }
196
+ ),
197
+ /* @__PURE__ */ jsx(
198
+ Button,
199
+ {
200
+ variant: "default",
201
+ size: "sm",
202
+ "data-meridial-ui": true,
203
+ onClick: onNext,
204
+ children: isLastStep ? /* @__PURE__ */ jsxs(Fragment, { children: [
205
+ "Finish",
206
+ /* @__PURE__ */ jsx(HugeiconsIcon, { icon: Tick01Icon, size: 14 })
207
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
208
+ "Next",
209
+ /* @__PURE__ */ jsx(HugeiconsIcon, { icon: ArrowRight01Icon, size: 14 })
210
+ ] })
211
+ }
212
+ )
213
+ ]
214
+ }
215
+ )
216
+ ]
217
+ }
218
+ )
219
+ ]
220
+ }
221
+ ) }),
222
+ document.body
223
+ );
121
224
  }
122
225
 
123
- // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/composite/item/useCompositeItem.js
124
- import * as React6 from "react";
125
-
226
+ // src/components/meridial-logo.tsx
227
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
228
+ function MeridialLogo(props) {
229
+ return /* @__PURE__ */ jsxs2(
230
+ "svg",
231
+ {
232
+ viewBox: "0 0 120 120",
233
+ fill: "none",
234
+ xmlns: "http://www.w3.org/2000/svg",
235
+ ...props,
236
+ children: [
237
+ /* @__PURE__ */ jsx2(
238
+ "path",
239
+ {
240
+ d: "M13.281 74.0881L15.7251 69.8003L37.7371 89.6218L83.4484 98.732L102.441 97.8991L83.2815 101.205L35.3287 95.2458L13.281 74.0881Z",
241
+ fill: "#009EBC",
242
+ stroke: "#009EBC",
243
+ strokeWidth: "0.5"
244
+ }
245
+ ),
246
+ /* @__PURE__ */ jsx2(
247
+ "path",
248
+ {
249
+ d: "M88.6986 90.1613L15.4758 69.5032L36.8477 90.3775L83.0111 99.2024L102.445 97.7944L88.6986 90.1613Z",
250
+ fill: "url(#fl-g0)"
251
+ }
252
+ ),
253
+ /* @__PURE__ */ jsx2(
254
+ "path",
255
+ {
256
+ d: "M9.59212 38.8499L12.934 33.2319L34.6462 62.7104L86.7973 80.1624L108.813 81.1994L86.6098 82.9394L33.6228 69.8917L9.59212 38.8499Z",
257
+ fill: "#009EBC",
258
+ stroke: "#009EBC",
259
+ strokeWidth: "0.5"
260
+ }
261
+ ),
262
+ /* @__PURE__ */ jsx2(
263
+ "path",
264
+ {
265
+ d: "M94.1734 69.4478L12.7627 33.0524L34.7293 62.7357L86.5626 80.2897L109.003 81.1016L94.1734 69.4478Z",
266
+ fill: "url(#fl-g1)"
267
+ }
268
+ ),
269
+ /* @__PURE__ */ jsx2(
270
+ "path",
271
+ {
272
+ d: "M28.3329 17.4895L33.7347 13.5331L45.9901 38.7534L78.8505 55.5351L93.5023 57.1106L78.3627 57.1381L38.9556 40.7981L28.3329 17.4895Z",
273
+ fill: "#009EBC",
274
+ stroke: "#009EBC",
275
+ strokeWidth: "0.5"
276
+ }
277
+ ),
278
+ /* @__PURE__ */ jsx2(
279
+ "path",
280
+ {
281
+ d: "M84.6112 46.7121L33.6396 12.9639L46.1488 38.6786L78.9538 55.4676L93.5814 57.0605L84.6112 46.7121Z",
282
+ fill: "url(#fl-g2)"
283
+ }
284
+ ),
285
+ /* @__PURE__ */ jsxs2("defs", { children: [
286
+ /* @__PURE__ */ jsxs2(
287
+ "linearGradient",
288
+ {
289
+ id: "fl-g0",
290
+ x1: "57.7988",
291
+ y1: "66.4369",
292
+ x2: "60.2919",
293
+ y2: "100.848",
294
+ gradientUnits: "userSpaceOnUse",
295
+ children: [
296
+ /* @__PURE__ */ jsx2("stop", { stopColor: "#C3F6FF" }),
297
+ /* @__PURE__ */ jsx2("stop", { offset: "1", stopColor: "#007B92" })
298
+ ]
299
+ }
300
+ ),
301
+ /* @__PURE__ */ jsxs2(
302
+ "linearGradient",
303
+ {
304
+ id: "fl-g1",
305
+ x1: "61.633",
306
+ y1: "34.8205",
307
+ x2: "60.0227",
308
+ y2: "79.3295",
309
+ gradientUnits: "userSpaceOnUse",
310
+ children: [
311
+ /* @__PURE__ */ jsx2("stop", { stopColor: "#B8F3FF" }),
312
+ /* @__PURE__ */ jsx2("stop", { offset: "1", stopColor: "#007F99" })
313
+ ]
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsxs2(
317
+ "linearGradient",
318
+ {
319
+ id: "fl-g2",
320
+ x1: "65.4953",
321
+ y1: "16.4329",
322
+ x2: "61.4521",
323
+ y2: "53.5618",
324
+ gradientUnits: "userSpaceOnUse",
325
+ children: [
326
+ /* @__PURE__ */ jsx2("stop", { stopColor: "#D0F8FF" }),
327
+ /* @__PURE__ */ jsx2("stop", { offset: "1", stopColor: "#009EBC" })
328
+ ]
329
+ }
330
+ )
331
+ ] })
332
+ ]
333
+ }
334
+ );
335
+ }
336
+
337
+ // src/components/voicebox-badge.tsx
338
+ import { jsx as jsx3 } from "react/jsx-runtime";
339
+ function VoiceboxBadge({
340
+ triggerIcon,
341
+ onClick
342
+ }) {
343
+ return /* @__PURE__ */ jsx3(
344
+ "button",
345
+ {
346
+ "data-meridial-ui": true,
347
+ onClick,
348
+ "aria-label": "Open assistant menu",
349
+ className: "group size-10 flex cursor-pointer items-center justify-center rounded-full border border-border bg-background shadow-lg transition-transform duration-200 ease-out hover:scale-110",
350
+ children: triggerIcon ?? /* @__PURE__ */ jsx3(MeridialLogo, { className: "size-6" })
351
+ }
352
+ );
353
+ }
354
+
355
+ // src/components/voicebox-content.tsx
356
+ import {
357
+ useSession,
358
+ useAgent,
359
+ useSessionContext as useSessionContext3,
360
+ useEnsureRoom as useEnsureRoom3
361
+ } from "@livekit/components-react";
362
+ import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
363
+ import { TokenSource, RpcError as RpcError2 } from "livekit-client";
364
+ import { useDraggable } from "@neodrag/react";
365
+ import {
366
+ useRef as useRef6,
367
+ useState as useState8,
368
+ useMemo as useMemo5,
369
+ useEffect as useEffect6,
370
+ useCallback as useCallback5
371
+ } from "react";
372
+ import { ChatFeedback01Icon, Loading03Icon as Loading03Icon3 } from "@hugeicons/core-free-icons";
373
+ import { HugeiconsIcon as HugeiconsIcon6 } from "@hugeicons/react";
374
+
375
+ // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/toggle/Toggle.js
376
+ import * as React7 from "react";
377
+
378
+ // ../../node_modules/.pnpm/@base-ui+utils@0.2.5_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/utils/esm/useControlled.js
379
+ import * as React from "react";
380
+ function useControlled({
381
+ controlled,
382
+ default: defaultProp,
383
+ name,
384
+ state = "value"
385
+ }) {
386
+ const {
387
+ current: isControlled
388
+ } = React.useRef(controlled !== void 0);
389
+ const [valueState, setValue] = React.useState(defaultProp);
390
+ const value = isControlled ? controlled : valueState;
391
+ if (process.env.NODE_ENV !== "production") {
392
+ React.useEffect(() => {
393
+ if (isControlled !== (controlled !== void 0)) {
394
+ console.error([`Base UI: A component is changing the ${isControlled ? "" : "un"}controlled ${state} state of ${name} to be ${isControlled ? "un" : ""}controlled.`, "Elements should not switch from uncontrolled to controlled (or vice versa).", `Decide between using a controlled or uncontrolled ${name} element for the lifetime of the component.`, "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", "More info: https://fb.me/react-controlled-components"].join("\n"));
395
+ }
396
+ }, [state, name, controlled]);
397
+ const {
398
+ current: defaultValue
399
+ } = React.useRef(defaultProp);
400
+ React.useEffect(() => {
401
+ if (!isControlled && JSON.stringify(defaultValue) !== JSON.stringify(defaultProp)) {
402
+ console.error([`Base UI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. To suppress this warning opt to use a controlled ${name}.`].join("\n"));
403
+ }
404
+ }, [JSON.stringify(defaultProp)]);
405
+ }
406
+ const setValueIfUncontrolled = React.useCallback((newValue) => {
407
+ if (!isControlled) {
408
+ setValue(newValue);
409
+ }
410
+ }, []);
411
+ return [value, setValueIfUncontrolled];
412
+ }
413
+
414
+ // ../../node_modules/.pnpm/@base-ui+utils@0.2.5_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/utils/esm/useId.js
415
+ import * as React2 from "react";
416
+ var globalId = 0;
417
+ function useGlobalId(idOverride, prefix = "mui") {
418
+ const [defaultId, setDefaultId] = React2.useState(idOverride);
419
+ const id = idOverride || defaultId;
420
+ React2.useEffect(() => {
421
+ if (defaultId == null) {
422
+ globalId += 1;
423
+ setDefaultId(`${prefix}-${globalId}`);
424
+ }
425
+ }, [defaultId, prefix]);
426
+ return id;
427
+ }
428
+ var maybeReactUseId = SafeReact.useId;
429
+ function useId(idOverride, prefix) {
430
+ if (maybeReactUseId !== void 0) {
431
+ const reactId = maybeReactUseId();
432
+ return idOverride ?? (prefix ? `${prefix}-${reactId}` : reactId);
433
+ }
434
+ return useGlobalId(idOverride, prefix);
435
+ }
436
+
437
+ // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/utils/useBaseUiId.js
438
+ function useBaseUiId(idOverride) {
439
+ return useId(idOverride, "base-ui");
440
+ }
441
+
442
+ // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/toggle-group/ToggleGroupContext.js
443
+ import * as React3 from "react";
444
+ var ToggleGroupContext = /* @__PURE__ */ React3.createContext(void 0);
445
+ if (process.env.NODE_ENV !== "production") ToggleGroupContext.displayName = "ToggleGroupContext";
446
+ function useToggleGroupContext(optional = true) {
447
+ const context = React3.useContext(ToggleGroupContext);
448
+ if (context === void 0 && !optional) {
449
+ throw new Error(process.env.NODE_ENV !== "production" ? "Base UI: ToggleGroupContext is missing. ToggleGroup parts must be placed within <ToggleGroup>." : formatErrorMessage(7));
450
+ }
451
+ return context;
452
+ }
453
+
454
+ // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/composite/item/useCompositeItem.js
455
+ import * as React6 from "react";
456
+
126
457
  // ../../node_modules/.pnpm/@base-ui+react@1.2.0_@types+react@19.2.14_react-dom@19.2.4_react@19.2.4__react@19.2.4/node_modules/@base-ui/react/esm/composite/list/useCompositeListItem.js
127
458
  import * as React5 from "react";
128
459
 
@@ -469,7 +800,7 @@ var Toggle = /* @__PURE__ */ React7.forwardRef(function Toggle2(componentProps,
469
800
  if (process.env.NODE_ENV !== "production") Toggle.displayName = "Toggle";
470
801
 
471
802
  // ../ui/src/components/toggle.tsx
472
- import { jsx } from "react/jsx-runtime";
803
+ import { jsx as jsx4 } from "react/jsx-runtime";
473
804
  var toggleVariants = cva(
474
805
  "group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
475
806
  {
@@ -496,7 +827,7 @@ function Toggle3({
496
827
  size = "default",
497
828
  ...props
498
829
  }) {
499
- return /* @__PURE__ */ jsx(
830
+ return /* @__PURE__ */ jsx4(
500
831
  Toggle,
501
832
  {
502
833
  "data-slot": "toggle",
@@ -519,12 +850,12 @@ function serializeTools(tools) {
519
850
  }
520
851
 
521
852
  // src/hooks/use-tool-registration.ts
522
- import { useEffect as useEffect3 } from "react";
853
+ import { useEffect as useEffect4 } from "react";
523
854
  import { RpcError } from "livekit-client";
524
855
  import { useEnsureRoom } from "@livekit/components-react";
525
856
  function useToolRegistration(tools, onToolComplete) {
526
857
  const room = useEnsureRoom();
527
- useEffect3(() => {
858
+ useEffect4(() => {
528
859
  if (!tools || tools.length === 0) return;
529
860
  const cleanups = [];
530
861
  for (const tool of tools) {
@@ -558,26 +889,26 @@ import {
558
889
  SessionProvider,
559
890
  RoomAudioRenderer
560
891
  } from "@livekit/components-react";
561
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
892
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
562
893
  function AgentSessionProvider({
563
894
  session,
564
895
  children,
565
896
  ...roomAudioRendererProps
566
897
  }) {
567
- return /* @__PURE__ */ jsxs(SessionProvider, { session, children: [
898
+ return /* @__PURE__ */ jsxs3(SessionProvider, { session, children: [
568
899
  children,
569
- /* @__PURE__ */ jsx2(RoomAudioRenderer, { ...roomAudioRendererProps })
900
+ /* @__PURE__ */ jsx5(RoomAudioRenderer, { ...roomAudioRendererProps })
570
901
  ] });
571
902
  }
572
903
 
573
904
  // src/components/agent-audio-visualizer-bar.tsx
574
- import { Fragment, useMemo as useMemo3 } from "react";
905
+ import { Fragment as Fragment2, useMemo as useMemo3 } from "react";
575
906
  import {
576
907
  useMultibandTrackVolume
577
908
  } from "@livekit/components-react";
578
909
 
579
910
  // src/hooks/use-agent-audio-visualizer-bar.ts
580
- import { useEffect as useEffect4, useRef as useRef4, useState as useState4 } from "react";
911
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState5 } from "react";
581
912
  function generateConnectingSequenceBar(columns) {
582
913
  const seq = [];
583
914
  for (let x = 0; x < columns; x++) {
@@ -590,9 +921,9 @@ function generateListeningSequenceBar(columns) {
590
921
  return [[center], [-1]];
591
922
  }
592
923
  function useAgentAudioVisualizerBarAnimator(state, columns, interval) {
593
- const [index, setIndex] = useState4(0);
594
- const [sequence, setSequence] = useState4([[]]);
595
- useEffect4(() => {
924
+ const [index, setIndex] = useState5(0);
925
+ const [sequence, setSequence] = useState5([[]]);
926
+ useEffect5(() => {
596
927
  if (state === "thinking") {
597
928
  setSequence(generateListeningSequenceBar(columns));
598
929
  } else if (state === "connecting" || state === "initializing") {
@@ -606,8 +937,8 @@ function useAgentAudioVisualizerBarAnimator(state, columns, interval) {
606
937
  }
607
938
  setIndex(0);
608
939
  }, [state, columns]);
609
- const animationFrameId = useRef4(null);
610
- useEffect4(() => {
940
+ const animationFrameId = useRef5(null);
941
+ useEffect5(() => {
611
942
  let startTime = performance.now();
612
943
  const animate = (time) => {
613
944
  if (time - startTime >= interval) {
@@ -627,7 +958,7 @@ function useAgentAudioVisualizerBarAnimator(state, columns, interval) {
627
958
  }
628
959
 
629
960
  // src/components/agent-audio-visualizer-bar.tsx
630
- import { jsx as jsx3 } from "react/jsx-runtime";
961
+ import { jsx as jsx6 } from "react/jsx-runtime";
631
962
  function AgentAudioVisualizerBar({
632
963
  state = "connecting",
633
964
  barCount = 3,
@@ -663,7 +994,7 @@ function AgentAudioVisualizerBar({
663
994
  () => state === "speaking" ? volumeBands : new Array(barCount).fill(0),
664
995
  [state, volumeBands, barCount]
665
996
  );
666
- return /* @__PURE__ */ jsx3(
997
+ return /* @__PURE__ */ jsx6(
667
998
  "div",
668
999
  {
669
1000
  "data-lk-state": state,
@@ -672,7 +1003,7 @@ function AgentAudioVisualizerBar({
672
1003
  className
673
1004
  ),
674
1005
  children: bands.map(
675
- (band, idx) => children ? /* @__PURE__ */ jsx3(Fragment, { children }, idx) : /* @__PURE__ */ jsx3(
1006
+ (band, idx) => children ? /* @__PURE__ */ jsx6(Fragment2, { children }, idx) : /* @__PURE__ */ jsx6(
676
1007
  "div",
677
1008
  {
678
1009
  "data-lk-index": idx,
@@ -688,7 +1019,7 @@ function AgentAudioVisualizerBar({
688
1019
  }
689
1020
 
690
1021
  // src/components/agent-track-toggle.tsx
691
- import { useMemo as useMemo4, useState as useState5 } from "react";
1022
+ import { useMemo as useMemo4, useState as useState6 } from "react";
692
1023
  import { Track } from "livekit-client";
693
1024
  import {
694
1025
  MicIcon,
@@ -697,8 +1028,8 @@ import {
697
1028
  VideoIcon,
698
1029
  VideoOffIcon
699
1030
  } from "@hugeicons/core-free-icons";
700
- import { HugeiconsIcon } from "@hugeicons/react";
701
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1031
+ import { HugeiconsIcon as HugeiconsIcon2 } from "@hugeicons/react";
1032
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
702
1033
  function getSourceIcon(source, enabled, pending = false) {
703
1034
  if (pending) return Loading03Icon;
704
1035
  switch (source) {
@@ -719,7 +1050,7 @@ function AgentTrackToggle({
719
1050
  onPressedChange,
720
1051
  ...props
721
1052
  }) {
722
- const [uncontrolledPressed, setUncontrolledPressed] = useState5(
1053
+ const [uncontrolledPressed, setUncontrolledPressed] = useState6(
723
1054
  defaultPressed ?? false
724
1055
  );
725
1056
  const isControlled = pressed !== void 0;
@@ -736,7 +1067,7 @@ function AgentTrackToggle({
736
1067
  if (!isControlled) setUncontrolledPressed(nextPressed);
737
1068
  onPressedChange?.(nextPressed);
738
1069
  };
739
- return /* @__PURE__ */ jsxs2(
1070
+ return /* @__PURE__ */ jsxs4(
740
1071
  Toggle3,
741
1072
  {
742
1073
  pressed: isControlled ? pressed : void 0,
@@ -751,8 +1082,8 @@ function AgentTrackToggle({
751
1082
  ),
752
1083
  ...props,
753
1084
  children: [
754
- /* @__PURE__ */ jsx4(
755
- HugeiconsIcon,
1085
+ /* @__PURE__ */ jsx7(
1086
+ HugeiconsIcon2,
756
1087
  {
757
1088
  icon: IconComponent,
758
1089
  className: cn(pending && "animate-spin")
@@ -765,7 +1096,7 @@ function AgentTrackToggle({
765
1096
  }
766
1097
 
767
1098
  // src/components/agent-track-control.tsx
768
- import { jsx as jsx5 } from "react/jsx-runtime";
1099
+ import { jsx as jsx8 } from "react/jsx-runtime";
769
1100
  function AgentTrackControl({
770
1101
  source,
771
1102
  pressed,
@@ -775,7 +1106,7 @@ function AgentTrackControl({
775
1106
  audioTrack,
776
1107
  onPressedChange
777
1108
  }) {
778
- return /* @__PURE__ */ jsx5("div", { className: cn("flex items-center gap-0 rounded-md", className), children: /* @__PURE__ */ jsx5(
1109
+ return /* @__PURE__ */ jsx8("div", { className: cn("flex items-center gap-0 rounded-md", className), children: /* @__PURE__ */ jsx8(
779
1110
  AgentTrackToggle,
780
1111
  {
781
1112
  source,
@@ -784,7 +1115,7 @@ function AgentTrackControl({
784
1115
  disabled: disabled2,
785
1116
  onPressedChange,
786
1117
  className: "peer/track group/track focus:z-10 has-[.audiovisualizer]:w-auto has-[.audiovisualizer]:px-3 has-[~_button]:rounded-r-none has-[~_button]:border-r-0 has-[~_button]:pr-2 has-[~_button]:pl-3",
787
- children: audioTrack && /* @__PURE__ */ jsx5(
1118
+ children: audioTrack && /* @__PURE__ */ jsx8(
788
1119
  AgentAudioVisualizerBar,
789
1120
  {
790
1121
  barCount: 3,
@@ -800,8 +1131,8 @@ function AgentTrackControl({
800
1131
  // src/components/agent-disconnect-button.tsx
801
1132
  import { useSessionContext } from "@livekit/components-react";
802
1133
  import { CallEnd03Icon } from "@hugeicons/core-free-icons";
803
- import { HugeiconsIcon as HugeiconsIcon2 } from "@hugeicons/react";
804
- import { jsx as jsx6 } from "react/jsx-runtime";
1134
+ import { HugeiconsIcon as HugeiconsIcon3 } from "@hugeicons/react";
1135
+ import { jsx as jsx9 } from "react/jsx-runtime";
805
1136
  function AgentDisconnectButton({
806
1137
  children,
807
1138
  onClick,
@@ -813,7 +1144,7 @@ function AgentDisconnectButton({
813
1144
  onClick?.(event);
814
1145
  if (typeof end === "function") end();
815
1146
  };
816
- return /* @__PURE__ */ jsx6(
1147
+ return /* @__PURE__ */ jsx9(
817
1148
  Button,
818
1149
  {
819
1150
  variant: "destructive",
@@ -821,21 +1152,21 @@ function AgentDisconnectButton({
821
1152
  onClick: handleClick,
822
1153
  className,
823
1154
  ...props,
824
- children: children ?? /* @__PURE__ */ jsx6(HugeiconsIcon2, { icon: CallEnd03Icon })
1155
+ children: children ?? /* @__PURE__ */ jsx9(HugeiconsIcon3, { icon: CallEnd03Icon })
825
1156
  }
826
1157
  );
827
1158
  }
828
1159
 
829
1160
  // src/components/agent-transcript-panel.tsx
830
- import { useState as useState6 } from "react";
1161
+ import { useState as useState7 } from "react";
831
1162
  import { useChat } from "@livekit/components-react";
832
- import { HugeiconsIcon as HugeiconsIcon3 } from "@hugeicons/react";
1163
+ import { HugeiconsIcon as HugeiconsIcon4 } from "@hugeicons/react";
833
1164
  import { Loading03Icon as Loading03Icon2, Navigation03Icon } from "@hugeicons/core-free-icons";
834
- import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1165
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
835
1166
  function AgentTranscriptPanel() {
836
1167
  const { send } = useChat();
837
- const [message, setMessage] = useState6("");
838
- const [isSending, setIsSending] = useState6(false);
1168
+ const [message, setMessage] = useState7("");
1169
+ const [isSending, setIsSending] = useState7(false);
839
1170
  const isDisabled = isSending || message.trim().length === 0;
840
1171
  const handleSend = async () => {
841
1172
  if (isDisabled) return;
@@ -854,20 +1185,21 @@ function AgentTranscriptPanel() {
854
1185
  handleSend();
855
1186
  }
856
1187
  };
857
- return /* @__PURE__ */ jsx7("div", { className: "flex h-full flex-col border-b", children: /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-1 px-2 py-1", children: [
858
- /* @__PURE__ */ jsx7(
1188
+ return /* @__PURE__ */ jsxs5("div", { className: "flex items-end gap-1 px-2 py-1 border-b relative", children: [
1189
+ /* @__PURE__ */ jsx10(
859
1190
  "textarea",
860
1191
  {
861
1192
  autoFocus: true,
862
1193
  value: message,
863
1194
  disabled: isSending,
1195
+ maxLength: 500,
864
1196
  placeholder: "Type something...",
865
1197
  onKeyDown: handleKeyDown,
866
- onChange: (e) => setMessage(e.target.value),
867
- className: "field-sizing-content max-h-20 min-h-6 flex-1 resize-none py-1 text-xs [scrollbar-width:thin] focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
1198
+ onChange: (e) => setMessage(e.target.value.slice(0, 500)),
1199
+ className: "field-sizing-content h-16 min-h-6 flex-1 resize-none py-1 text-xs [scrollbar-width:thin] focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
868
1200
  }
869
1201
  ),
870
- /* @__PURE__ */ jsx7(
1202
+ /* @__PURE__ */ jsx10(
871
1203
  "button",
872
1204
  {
873
1205
  type: "button",
@@ -875,18 +1207,18 @@ function AgentTranscriptPanel() {
875
1207
  onClick: handleSend,
876
1208
  title: isSending ? "Sending\u2026" : "Send",
877
1209
  className: cn(
878
- "flex size-6 flex-shrink-0 items-center justify-center self-end rounded",
1210
+ "flex size-6 flex-shrink-0 items-center justify-center self-end rounded absolute bottom-2 right-2",
879
1211
  isDisabled ? "cursor-not-allowed text-muted-foreground" : "cursor-pointer text-foreground hover:opacity-80"
880
1212
  ),
881
- children: isSending ? /* @__PURE__ */ jsx7(
882
- HugeiconsIcon3,
1213
+ children: isSending ? /* @__PURE__ */ jsx10(
1214
+ HugeiconsIcon4,
883
1215
  {
884
1216
  icon: Loading03Icon2,
885
1217
  size: 18,
886
1218
  className: "animate-spin"
887
1219
  }
888
- ) : /* @__PURE__ */ jsx7(
889
- HugeiconsIcon3,
1220
+ ) : /* @__PURE__ */ jsx10(
1221
+ HugeiconsIcon4,
890
1222
  {
891
1223
  icon: Navigation03Icon,
892
1224
  size: 18,
@@ -895,11 +1227,11 @@ function AgentTranscriptPanel() {
895
1227
  )
896
1228
  }
897
1229
  )
898
- ] }) });
1230
+ ] });
899
1231
  }
900
1232
 
901
1233
  // src/hooks/use-input-controls.ts
902
- import { useCallback as useCallback3 } from "react";
1234
+ import { useCallback as useCallback4 } from "react";
903
1235
  import { Track as Track2 } from "livekit-client";
904
1236
  import {
905
1237
  useTrackToggle,
@@ -932,19 +1264,19 @@ function useInputControls({
932
1264
  saveAudioInputDeviceId,
933
1265
  saveVideoInputDeviceId
934
1266
  } = usePersistentUserChoices({ preventSave: !saveUserChoices });
935
- const handleAudioDeviceChange = useCallback3(
1267
+ const handleAudioDeviceChange = useCallback4(
936
1268
  (deviceId) => {
937
1269
  saveAudioInputDeviceId(deviceId ?? "default");
938
1270
  },
939
1271
  [saveAudioInputDeviceId]
940
1272
  );
941
- const handleVideoDeviceChange = useCallback3(
1273
+ const handleVideoDeviceChange = useCallback4(
942
1274
  (deviceId) => {
943
1275
  saveVideoInputDeviceId(deviceId ?? "default");
944
1276
  },
945
1277
  [saveVideoInputDeviceId]
946
1278
  );
947
- const handleToggleCamera = useCallback3(
1279
+ const handleToggleCamera = useCallback4(
948
1280
  async (enabled) => {
949
1281
  if (screenShareToggle.enabled) {
950
1282
  screenShareToggle.toggle(false);
@@ -954,14 +1286,14 @@ function useInputControls({
954
1286
  },
955
1287
  [cameraToggle, screenShareToggle, saveVideoInputEnabled]
956
1288
  );
957
- const handleToggleMicrophone = useCallback3(
1289
+ const handleToggleMicrophone = useCallback4(
958
1290
  async (enabled) => {
959
1291
  await microphoneToggle.toggle(enabled);
960
1292
  saveAudioInputEnabled(!microphoneToggle.enabled);
961
1293
  },
962
1294
  [microphoneToggle, saveAudioInputEnabled]
963
1295
  );
964
- const handleToggleScreenShare = useCallback3(
1296
+ const handleToggleScreenShare = useCallback4(
965
1297
  async (enabled) => {
966
1298
  if (cameraToggle.enabled) {
967
1299
  cameraToggle.toggle(false);
@@ -970,11 +1302,11 @@ function useInputControls({
970
1302
  },
971
1303
  [cameraToggle, screenShareToggle]
972
1304
  );
973
- const handleMicrophoneDeviceSelectError = useCallback3(
1305
+ const handleMicrophoneDeviceSelectError = useCallback4(
974
1306
  (error2) => onDeviceError?.({ source: Track2.Source.Microphone, error: error2 }),
975
1307
  [onDeviceError]
976
1308
  );
977
- const handleCameraDeviceSelectError = useCallback3(
1309
+ const handleCameraDeviceSelectError = useCallback4(
978
1310
  (error2) => onDeviceError?.({ source: Track2.Source.Camera, error: error2 }),
979
1311
  [onDeviceError]
980
1312
  );
@@ -1001,7 +1333,7 @@ function useInputControls({
1001
1333
 
1002
1334
  // src/components/start-audio-button.tsx
1003
1335
  import { useEnsureRoom as useEnsureRoom2, useStartAudio } from "@livekit/components-react";
1004
- import { jsx as jsx8 } from "react/jsx-runtime";
1336
+ import { jsx as jsx11 } from "react/jsx-runtime";
1005
1337
  function StartAudioButton({
1006
1338
  size = "default",
1007
1339
  variant = "default",
@@ -1011,368 +1343,329 @@ function StartAudioButton({
1011
1343
  }) {
1012
1344
  const roomEnsured = useEnsureRoom2(room);
1013
1345
  const { mergedProps } = useStartAudio({ room: roomEnsured, props });
1014
- return /* @__PURE__ */ jsx8(Button, { size, variant, ...props, ...mergedProps, children: label });
1346
+ return /* @__PURE__ */ jsx11(Button, { size, variant, ...props, ...mergedProps, children: label });
1015
1347
  }
1016
1348
 
1017
- // src/components/workflow-execution.tsx
1018
- import { useState as useState7, useCallback as useCallback4, useEffect as useEffect5, useRef as useRef5 } from "react";
1019
- import { createPortal } from "react-dom";
1020
- import {
1021
- motion,
1022
- useMotionValue,
1023
- useSpring,
1024
- AnimatePresence
1025
- } from "motion/react";
1349
+ // src/components/outcome-bar.tsx
1026
1350
  import {
1027
- Cursor02Icon,
1028
- ArrowLeft01Icon,
1029
- ArrowRight01Icon,
1030
- Tick01Icon
1031
- } from "@hugeicons/core-free-icons";
1032
- import { HugeiconsIcon as HugeiconsIcon4 } from "@hugeicons/react";
1033
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1034
- var SPRING_CONFIG = { stiffness: 120, damping: 20, mass: 0.8 };
1035
- var CURSOR_OFFSET = 16;
1036
- function WorkflowExecution({
1037
- workflow,
1038
- attribute = "data-meridial-id",
1039
- cursor,
1040
- onClose,
1041
- onStepChange,
1042
- onError
1043
- }) {
1044
- const [currentIndex, setCurrentIndex] = useState7(0);
1045
- const steps = workflow.steps;
1046
- const currentStep = steps[currentIndex];
1047
- const isFirstStep = currentIndex === 0;
1048
- const isLastStep = currentIndex === steps.length - 1;
1049
- useEffect5(() => {
1050
- onStepChange?.(currentIndex);
1051
- }, [currentIndex, onStepChange]);
1052
- const handleBack = useCallback4(() => {
1053
- setCurrentIndex((prev) => Math.max(0, prev - 1));
1054
- }, []);
1055
- const handleNext = useCallback4(() => {
1056
- setCurrentIndex((prev) => {
1057
- if (prev >= steps.length - 1) {
1058
- onClose();
1059
- return prev;
1060
- }
1061
- return prev + 1;
1062
- });
1063
- }, [steps.length, onClose]);
1064
- if (!currentStep) return null;
1065
- return /* @__PURE__ */ jsx9(
1066
- ExecutionOverlay,
1067
- {
1068
- step: currentStep,
1069
- stepIndex: currentIndex,
1070
- totalSteps: steps.length,
1071
- isFirstStep,
1072
- isLastStep,
1073
- attribute,
1074
- cursor,
1075
- onBack: handleBack,
1076
- onNext: handleNext,
1077
- onError
1078
- }
1079
- );
1080
- }
1081
- function ExecutionOverlay({
1082
- step,
1083
- stepIndex,
1084
- totalSteps,
1085
- isFirstStep,
1086
- isLastStep,
1087
- attribute,
1088
- cursor,
1089
- onBack,
1090
- onNext,
1091
- onError
1092
- }) {
1093
- const cssSelector = `[${attribute}="${step.elementId}"]`;
1094
- const { rect } = useElementTracker({
1095
- selector: cssSelector,
1096
- urlPath: step.urlPath,
1097
- onError: onError ? (msg) => {
1098
- if (msg !== null) onError(msg);
1099
- } : void 0,
1100
- onClick: onNext
1101
- });
1102
- const hasAnimated = useRef5(false);
1103
- const springX = useSpring(useMotionValue(0), SPRING_CONFIG);
1104
- const springY = useSpring(useMotionValue(0), SPRING_CONFIG);
1105
- if (rect) {
1106
- const targetX = rect.right + CURSOR_OFFSET;
1107
- const targetY = rect.bottom + CURSOR_OFFSET;
1108
- if (!hasAnimated.current) {
1109
- springX.jump(targetX);
1110
- springY.jump(targetY);
1111
- hasAnimated.current = true;
1112
- } else {
1113
- springX.set(targetX);
1114
- springY.set(targetY);
1115
- }
1116
- } else {
1117
- hasAnimated.current = false;
1118
- }
1119
- return createPortal(
1120
- /* @__PURE__ */ jsx9(AnimatePresence, { children: rect && /* @__PURE__ */ jsxs4(
1121
- motion.div,
1122
- {
1123
- "data-meridial-ui": true,
1124
- className: "pointer-events-none fixed z-[99999] flex items-start gap-3",
1125
- style: { top: springY, left: springX },
1126
- initial: { opacity: 0, scale: 0.6 },
1127
- animate: { opacity: 1, scale: 1 },
1128
- exit: { opacity: 0, scale: 0.6 },
1129
- transition: { duration: 0.2 },
1130
- children: [
1131
- cursor ?? /* @__PURE__ */ jsx9(
1132
- HugeiconsIcon4,
1133
- {
1134
- icon: Cursor02Icon,
1135
- strokeWidth: 2,
1136
- size: 32,
1137
- className: "mt-1 shrink-0 fill-primary/60 text-primary"
1138
- }
1139
- ),
1140
- /* @__PURE__ */ jsxs4(
1141
- "div",
1142
- {
1143
- "data-meridial-ui": true,
1144
- className: "pointer-events-auto w-72 overflow-hidden rounded-lg border border-border bg-card shadow-lg",
1145
- children: [
1146
- /* @__PURE__ */ jsx9(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxs4(
1147
- motion.div,
1148
- {
1149
- initial: { opacity: 0, y: 8 },
1150
- animate: { opacity: 1, y: 0 },
1151
- exit: { opacity: 0, y: -8 },
1152
- transition: { duration: 0.2, ease: "easeInOut" },
1153
- className: "px-4 pt-3 pb-2",
1154
- children: [
1155
- /* @__PURE__ */ jsx9("p", { className: "text-sm leading-relaxed text-foreground", children: step.description || /* @__PURE__ */ jsx9("span", { className: "text-muted-foreground italic", children: "No description" }) }),
1156
- /* @__PURE__ */ jsxs4("span", { className: "mt-1 block text-xs text-muted-foreground", children: [
1157
- "Step ",
1158
- stepIndex + 1,
1159
- " of ",
1160
- totalSteps
1161
- ] })
1162
- ]
1163
- },
1164
- step.id
1165
- ) }),
1166
- /* @__PURE__ */ jsxs4(
1167
- "div",
1168
- {
1169
- "data-meridial-ui": true,
1170
- className: "flex justify-end gap-2 border-t px-3 py-2",
1171
- children: [
1172
- /* @__PURE__ */ jsxs4(
1173
- Button,
1174
- {
1175
- variant: "outline",
1176
- size: "sm",
1177
- "data-meridial-ui": true,
1178
- onClick: onBack,
1179
- disabled: isFirstStep,
1180
- children: [
1181
- /* @__PURE__ */ jsx9(HugeiconsIcon4, { icon: ArrowLeft01Icon, size: 14 }),
1182
- "Back"
1183
- ]
1184
- }
1185
- ),
1186
- /* @__PURE__ */ jsx9(
1187
- Button,
1188
- {
1189
- variant: "default",
1190
- size: "sm",
1191
- "data-meridial-ui": true,
1192
- onClick: onNext,
1193
- children: isLastStep ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1194
- "Finish",
1195
- /* @__PURE__ */ jsx9(HugeiconsIcon4, { icon: Tick01Icon, size: 14 })
1196
- ] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
1197
- "Next",
1198
- /* @__PURE__ */ jsx9(HugeiconsIcon4, { icon: ArrowRight01Icon, size: 14 })
1199
- ] })
1200
- }
1201
- )
1202
- ]
1203
- }
1204
- )
1205
- ]
1206
- }
1207
- )
1208
- ]
1209
- }
1210
- ) }),
1211
- document.body
1212
- );
1213
- }
1214
-
1215
- // src/components/outcome-bar.tsx
1216
- import {
1217
- ThumbsUpIcon,
1218
- ThumbsDownIcon,
1219
- MultiplicationSignIcon
1351
+ ThumbsUpIcon,
1352
+ ThumbsDownIcon,
1353
+ MultiplicationSignIcon
1220
1354
  } from "@hugeicons/core-free-icons";
1221
1355
  import { HugeiconsIcon as HugeiconsIcon5 } from "@hugeicons/react";
1222
- import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
1356
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1223
1357
  function OutcomeBar({ onSubmit }) {
1224
- return /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [
1225
- /* @__PURE__ */ jsx10("span", { className: "text-sm text-muted-foreground", children: "Did we help?" }),
1226
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1", children: [
1227
- /* @__PURE__ */ jsx10(
1358
+ return /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [
1359
+ /* @__PURE__ */ jsx12("span", { className: "text-sm text-muted-foreground", children: "Did we help?" }),
1360
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
1361
+ /* @__PURE__ */ jsx12(
1228
1362
  Button,
1229
1363
  {
1230
1364
  variant: "ghost",
1231
1365
  size: "icon-sm",
1232
1366
  onClick: () => onSubmit("POSITIVE"),
1233
1367
  "aria-label": "Yes, this helped",
1234
- children: /* @__PURE__ */ jsx10(HugeiconsIcon5, { icon: ThumbsUpIcon, className: "size-4" })
1368
+ children: /* @__PURE__ */ jsx12(HugeiconsIcon5, { icon: ThumbsUpIcon, className: "size-4" })
1235
1369
  }
1236
1370
  ),
1237
- /* @__PURE__ */ jsx10(
1371
+ /* @__PURE__ */ jsx12(
1238
1372
  Button,
1239
1373
  {
1240
1374
  variant: "ghost",
1241
1375
  size: "icon-sm",
1242
1376
  onClick: () => onSubmit("NEGATIVE"),
1243
1377
  "aria-label": "No, this didn't help",
1244
- children: /* @__PURE__ */ jsx10(HugeiconsIcon5, { icon: ThumbsDownIcon, className: "size-4" })
1378
+ children: /* @__PURE__ */ jsx12(HugeiconsIcon5, { icon: ThumbsDownIcon, className: "size-4" })
1245
1379
  }
1246
1380
  ),
1247
- /* @__PURE__ */ jsx10(
1381
+ /* @__PURE__ */ jsx12(
1248
1382
  Button,
1249
1383
  {
1250
1384
  variant: "ghost",
1251
1385
  size: "icon-sm",
1252
1386
  onClick: () => onSubmit("NEUTRAL"),
1253
1387
  "aria-label": "Dismiss",
1254
- children: /* @__PURE__ */ jsx10(HugeiconsIcon5, { icon: MultiplicationSignIcon, className: "size-4" })
1388
+ children: /* @__PURE__ */ jsx12(HugeiconsIcon5, { icon: MultiplicationSignIcon, className: "size-4" })
1255
1389
  }
1256
1390
  )
1257
1391
  ] })
1258
1392
  ] });
1259
1393
  }
1260
1394
 
1261
- // src/components/meridial-logo.tsx
1262
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
1263
- function MeridialLogo(props) {
1264
- return /* @__PURE__ */ jsxs6(
1265
- "svg",
1395
+ // src/components/voicebox-content.tsx
1396
+ import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1397
+ function VoiceboxContent({
1398
+ baseUrl,
1399
+ publishableKey,
1400
+ identifier,
1401
+ firstMessage,
1402
+ instructions,
1403
+ attribute,
1404
+ tools,
1405
+ cursor,
1406
+ metadata,
1407
+ initialWorkflow,
1408
+ onDisconnect,
1409
+ onError
1410
+ }) {
1411
+ const serializedTools = useMemo5(
1412
+ () => tools && tools.length > 0 ? serializeTools(tools) : [],
1413
+ [tools]
1414
+ );
1415
+ const tokenSource = useMemo5(
1416
+ () => TokenSource.custom(async () => {
1417
+ const response = await fetch(`${baseUrl}/api/auth/livekit`, {
1418
+ method: "POST",
1419
+ body: JSON.stringify({
1420
+ publishableKey,
1421
+ identifier,
1422
+ firstMessage,
1423
+ instructions,
1424
+ tools: serializedTools,
1425
+ metadata
1426
+ })
1427
+ });
1428
+ if (!response.ok) {
1429
+ const body = await response.json().catch(() => ({}));
1430
+ onError?.(body.error ?? `Token request failed (${response.status})`);
1431
+ return null;
1432
+ }
1433
+ return response.json();
1434
+ }),
1435
+ [
1436
+ baseUrl,
1437
+ publishableKey,
1438
+ identifier,
1439
+ firstMessage,
1440
+ instructions,
1441
+ serializedTools,
1442
+ metadata,
1443
+ onError
1444
+ ]
1445
+ );
1446
+ const session = useSession(tokenSource);
1447
+ return /* @__PURE__ */ jsx13(AgentSessionProvider, { session, children: /* @__PURE__ */ jsx13(
1448
+ VoiceboxContentInner,
1266
1449
  {
1267
- viewBox: "0 0 120 120",
1268
- fill: "none",
1269
- xmlns: "http://www.w3.org/2000/svg",
1270
- ...props,
1271
- children: [
1272
- /* @__PURE__ */ jsx11(
1273
- "path",
1274
- {
1275
- d: "M13.281 74.0881L15.7251 69.8003L37.7371 89.6218L83.4484 98.732L102.441 97.8991L83.2815 101.205L35.3287 95.2458L13.281 74.0881Z",
1276
- fill: "#009EBC",
1277
- stroke: "#009EBC",
1278
- strokeWidth: "0.5"
1279
- }
1280
- ),
1281
- /* @__PURE__ */ jsx11(
1282
- "path",
1283
- {
1284
- d: "M88.6986 90.1613L15.4758 69.5032L36.8477 90.3775L83.0111 99.2024L102.445 97.7944L88.6986 90.1613Z",
1285
- fill: "url(#fl-g0)"
1286
- }
1287
- ),
1288
- /* @__PURE__ */ jsx11(
1289
- "path",
1290
- {
1291
- d: "M9.59212 38.8499L12.934 33.2319L34.6462 62.7104L86.7973 80.1624L108.813 81.1994L86.6098 82.9394L33.6228 69.8917L9.59212 38.8499Z",
1292
- fill: "#009EBC",
1293
- stroke: "#009EBC",
1294
- strokeWidth: "0.5"
1295
- }
1296
- ),
1297
- /* @__PURE__ */ jsx11(
1298
- "path",
1299
- {
1300
- d: "M94.1734 69.4478L12.7627 33.0524L34.7293 62.7357L86.5626 80.2897L109.003 81.1016L94.1734 69.4478Z",
1301
- fill: "url(#fl-g1)"
1302
- }
1303
- ),
1304
- /* @__PURE__ */ jsx11(
1305
- "path",
1306
- {
1307
- d: "M28.3329 17.4895L33.7347 13.5331L45.9901 38.7534L78.8505 55.5351L93.5023 57.1106L78.3627 57.1381L38.9556 40.7981L28.3329 17.4895Z",
1308
- fill: "#009EBC",
1309
- stroke: "#009EBC",
1310
- strokeWidth: "0.5"
1311
- }
1312
- ),
1313
- /* @__PURE__ */ jsx11(
1314
- "path",
1315
- {
1316
- d: "M84.6112 46.7121L33.6396 12.9639L46.1488 38.6786L78.9538 55.4676L93.5814 57.0605L84.6112 46.7121Z",
1317
- fill: "url(#fl-g2)"
1318
- }
1319
- ),
1320
- /* @__PURE__ */ jsxs6("defs", { children: [
1321
- /* @__PURE__ */ jsxs6(
1322
- "linearGradient",
1323
- {
1324
- id: "fl-g0",
1325
- x1: "57.7988",
1326
- y1: "66.4369",
1327
- x2: "60.2919",
1328
- y2: "100.848",
1329
- gradientUnits: "userSpaceOnUse",
1330
- children: [
1331
- /* @__PURE__ */ jsx11("stop", { stopColor: "#C3F6FF" }),
1332
- /* @__PURE__ */ jsx11("stop", { offset: "1", stopColor: "#007B92" })
1333
- ]
1334
- }
1335
- ),
1336
- /* @__PURE__ */ jsxs6(
1337
- "linearGradient",
1338
- {
1339
- id: "fl-g1",
1340
- x1: "61.633",
1341
- y1: "34.8205",
1342
- x2: "60.0227",
1343
- y2: "79.3295",
1344
- gradientUnits: "userSpaceOnUse",
1345
- children: [
1346
- /* @__PURE__ */ jsx11("stop", { stopColor: "#B8F3FF" }),
1347
- /* @__PURE__ */ jsx11("stop", { offset: "1", stopColor: "#007F99" })
1348
- ]
1349
- }
1350
- ),
1351
- /* @__PURE__ */ jsxs6(
1352
- "linearGradient",
1353
- {
1354
- id: "fl-g2",
1355
- x1: "65.4953",
1356
- y1: "16.4329",
1357
- x2: "61.4521",
1358
- y2: "53.5618",
1359
- gradientUnits: "userSpaceOnUse",
1360
- children: [
1361
- /* @__PURE__ */ jsx11("stop", { stopColor: "#D0F8FF" }),
1362
- /* @__PURE__ */ jsx11("stop", { offset: "1", stopColor: "#009EBC" })
1363
- ]
1364
- }
1365
- )
1366
- ] })
1367
- ]
1450
+ baseUrl,
1451
+ publishableKey,
1452
+ attribute,
1453
+ tools,
1454
+ cursor,
1455
+ initialWorkflow,
1456
+ onDisconnect,
1457
+ onError
1458
+ }
1459
+ ) });
1460
+ }
1461
+ function VoiceboxContentInner({
1462
+ baseUrl,
1463
+ publishableKey,
1464
+ attribute,
1465
+ tools,
1466
+ cursor,
1467
+ initialWorkflow,
1468
+ onDisconnect,
1469
+ onError
1470
+ }) {
1471
+ const [showTranscript, setShowTranscript] = useState8(false);
1472
+ const [showOutcomeBar, setShowOutcomeBar] = useState8(false);
1473
+ const [activeWorkflow, setActiveWorkflow] = useState8(initialWorkflow ?? null);
1474
+ const workflowsRef = useRef6([]);
1475
+ const room = useEnsureRoom3();
1476
+ const autoStarted = useRef6(false);
1477
+ const outcomeShown = useRef6(false);
1478
+ const draggableRef = useRef6(null);
1479
+ const triggerOutcomeBar = useCallback5(() => {
1480
+ if (!outcomeShown.current) {
1481
+ outcomeShown.current = true;
1482
+ setShowOutcomeBar(true);
1368
1483
  }
1484
+ }, []);
1485
+ const handleOutcomeSubmit = useCallback5(
1486
+ async (outcome) => {
1487
+ setShowOutcomeBar(false);
1488
+ try {
1489
+ const sessionId = await room.getSid();
1490
+ await fetch(`${baseUrl}/api/outcome`, {
1491
+ method: "POST",
1492
+ headers: { "Content-Type": "application/json" },
1493
+ body: JSON.stringify({ publishableKey, sessionId, outcome })
1494
+ });
1495
+ } catch {
1496
+ }
1497
+ },
1498
+ [room, baseUrl, publishableKey]
1369
1499
  );
1500
+ useToolRegistration(tools, triggerOutcomeBar);
1501
+ useDraggable(draggableRef);
1502
+ useEffect6(() => {
1503
+ if (!publishableKey) return;
1504
+ fetch(`${baseUrl}/api/workflows`, {
1505
+ headers: { Authorization: `Bearer ${publishableKey}` }
1506
+ }).then((r) => r.json()).then((data) => {
1507
+ if (data.workflows) workflowsRef.current = data.workflows;
1508
+ }).catch((error2) => {
1509
+ onError?.(
1510
+ error2 instanceof Error ? error2.message : "Workflows fetch failed"
1511
+ );
1512
+ });
1513
+ }, [baseUrl, publishableKey]);
1514
+ useEffect6(() => {
1515
+ room.registerRpcMethod("workflow:execute", async (rpcData) => {
1516
+ try {
1517
+ const { slug } = JSON.parse(rpcData.payload);
1518
+ const apiWf = workflowsRef.current.find((w) => w.slug === slug);
1519
+ if (!apiWf) throw new Error(`Workflow '${slug}' not found`);
1520
+ const workflow = {
1521
+ id: apiWf.id,
1522
+ name: apiWf.name,
1523
+ steps: apiWf.steps,
1524
+ configured: true,
1525
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
1526
+ };
1527
+ setActiveWorkflow({ id: apiWf.id, workflow });
1528
+ triggerOutcomeBar();
1529
+ return JSON.stringify({ success: true });
1530
+ } catch (error2) {
1531
+ onError?.(
1532
+ error2 instanceof Error ? error2.message : "Workflow execution failed"
1533
+ );
1534
+ throw new RpcError2(
1535
+ 1,
1536
+ error2 instanceof Error ? error2.message : "Workflow execution failed"
1537
+ );
1538
+ }
1539
+ });
1540
+ return () => {
1541
+ room.unregisterRpcMethod("workflow:execute");
1542
+ };
1543
+ }, [room]);
1544
+ const { state } = useAgent();
1545
+ const { start } = useSessionContext3();
1546
+ useEffect6(() => {
1547
+ if (!autoStarted.current) {
1548
+ autoStarted.current = true;
1549
+ start();
1550
+ }
1551
+ }, [start]);
1552
+ const isConnecting = state === "connecting" || state === "initializing" || state === "pre-connect-buffering";
1553
+ const isDisconnected = state === "disconnected" || state === "failed";
1554
+ const { microphoneTrack, microphoneToggle } = useInputControls();
1555
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
1556
+ activeWorkflow && /* @__PURE__ */ jsx13(
1557
+ WorkflowExecution,
1558
+ {
1559
+ workflow: activeWorkflow.workflow,
1560
+ attribute,
1561
+ cursor,
1562
+ onClose: () => {
1563
+ setActiveWorkflow(null);
1564
+ triggerOutcomeBar();
1565
+ },
1566
+ onError
1567
+ }
1568
+ ),
1569
+ /* @__PURE__ */ jsx13(
1570
+ motion2.div,
1571
+ {
1572
+ initial: { opacity: 0, y: 20 },
1573
+ animate: { opacity: 1, y: 0 },
1574
+ transition: { duration: 0.3, ease: "easeOut" },
1575
+ className: "fixed inset-x-0 bottom-8 z-50 flex justify-center",
1576
+ children: /* @__PURE__ */ jsxs7(
1577
+ "div",
1578
+ {
1579
+ ref: draggableRef,
1580
+ "data-meridial-ui": true,
1581
+ className: "w-72 items-stretch rounded border border-border bg-card shadow-md",
1582
+ children: [
1583
+ /* @__PURE__ */ jsx13(AnimatePresence2, { initial: false, children: showTranscript && /* @__PURE__ */ jsx13(
1584
+ motion2.div,
1585
+ {
1586
+ initial: { height: 0, opacity: 0 },
1587
+ animate: { height: "auto", opacity: 1 },
1588
+ exit: { height: 0, opacity: 0 },
1589
+ transition: { duration: 0.24, ease: "easeOut" },
1590
+ style: { overflow: "hidden" },
1591
+ children: /* @__PURE__ */ jsx13(AgentTranscriptPanel, {})
1592
+ }
1593
+ ) }),
1594
+ /* @__PURE__ */ jsx13(AnimatePresence2, { initial: false, children: showOutcomeBar && /* @__PURE__ */ jsx13(
1595
+ motion2.div,
1596
+ {
1597
+ initial: { height: 0, opacity: 0 },
1598
+ animate: { height: "auto", opacity: 1 },
1599
+ exit: { height: 0, opacity: 0 },
1600
+ transition: { duration: 0.24, ease: "easeOut" },
1601
+ style: { overflow: "hidden" },
1602
+ children: /* @__PURE__ */ jsx13(OutcomeBar, { onSubmit: handleOutcomeSubmit })
1603
+ }
1604
+ ) }),
1605
+ /* @__PURE__ */ jsxs7("div", { "data-meridial-ui": true, className: "flex h-12 items-center", children: [
1606
+ /* @__PURE__ */ jsx13(DragHandle, { className: "px-2" }),
1607
+ /* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "h-full" }),
1608
+ /* @__PURE__ */ jsxs7("div", { className: "relative flex h-full flex-1 items-center justify-between px-2", children: [
1609
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1610
+ /* @__PURE__ */ jsx13(
1611
+ AgentTrackControl,
1612
+ {
1613
+ source: "microphone",
1614
+ pressed: microphoneToggle.enabled,
1615
+ pending: microphoneToggle.pending,
1616
+ disabled: microphoneToggle.pending,
1617
+ audioTrack: microphoneTrack,
1618
+ onPressedChange: microphoneToggle.toggle
1619
+ }
1620
+ ),
1621
+ /* @__PURE__ */ jsx13(
1622
+ Toggle3,
1623
+ {
1624
+ disabled: isDisconnected || isConnecting,
1625
+ pressed: showTranscript,
1626
+ "aria-label": "Toggle transcript",
1627
+ onPressedChange: setShowTranscript,
1628
+ className: cn(
1629
+ "size-9 rounded-lg",
1630
+ showTranscript ? "bg-muted text-foreground" : "bg-transparent text-muted-foreground hover:text-foreground"
1631
+ ),
1632
+ children: /* @__PURE__ */ jsx13(HugeiconsIcon6, { icon: ChatFeedback01Icon })
1633
+ }
1634
+ )
1635
+ ] }),
1636
+ /* @__PURE__ */ jsx13(
1637
+ AgentAudioVisualizerBar,
1638
+ {
1639
+ barCount: 16,
1640
+ state,
1641
+ audioTrack: microphoneTrack
1642
+ }
1643
+ ),
1644
+ isConnecting ? /* @__PURE__ */ jsxs7(Button, { variant: "outline", children: [
1645
+ /* @__PURE__ */ jsx13("span", { children: "Connecting" }),
1646
+ /* @__PURE__ */ jsx13(
1647
+ HugeiconsIcon6,
1648
+ {
1649
+ icon: Loading03Icon3,
1650
+ className: "animate-spin"
1651
+ }
1652
+ )
1653
+ ] }) : /* @__PURE__ */ jsx13(AgentDisconnectButton, { onClick: onDisconnect }),
1654
+ /* @__PURE__ */ jsx13(StartAudioButton, { label: "Start Audio" })
1655
+ ] })
1656
+ ] })
1657
+ ]
1658
+ }
1659
+ )
1660
+ }
1661
+ )
1662
+ ] });
1370
1663
  }
1371
1664
 
1372
1665
  // src/components/voicebox-menu.tsx
1373
- import { useState as useState8 } from "react";
1374
- import { motion as motion2, AnimatePresence as AnimatePresence2 } from "motion/react";
1375
- import { HugeiconsIcon as HugeiconsIcon6 } from "@hugeicons/react";
1666
+ import { useState as useState9 } from "react";
1667
+ import { motion as motion3, AnimatePresence as AnimatePresence3 } from "motion/react";
1668
+ import { HugeiconsIcon as HugeiconsIcon7 } from "@hugeicons/react";
1376
1669
  import {
1377
1670
  Call02Icon,
1378
1671
  ViewOffSlashIcon,
@@ -1380,7 +1673,7 @@ import {
1380
1673
  Cancel01Icon,
1381
1674
  StarIcon
1382
1675
  } from "@hugeicons/core-free-icons";
1383
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
1676
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1384
1677
  var POSITION_LABELS = {
1385
1678
  "top-left": "Top Left",
1386
1679
  "top-right": "Top Right",
@@ -1421,14 +1714,14 @@ function VoiceboxMenu({
1421
1714
  onAbortGuide
1422
1715
  }) {
1423
1716
  const placement = MENU_PLACEMENT[position];
1424
- const [activeTab, setActiveTab] = useState8("settings");
1717
+ const [activeTab, setActiveTab] = useState9("settings");
1425
1718
  const sortedWorkflows = [...workflows].sort((a, b) => {
1426
1719
  if (a.isFavorite && !b.isFavorite) return -1;
1427
1720
  if (!a.isFavorite && b.isFavorite) return 1;
1428
1721
  return 0;
1429
1722
  });
1430
- return /* @__PURE__ */ jsxs7(
1431
- motion2.div,
1723
+ return /* @__PURE__ */ jsxs8(
1724
+ motion3.div,
1432
1725
  {
1433
1726
  "data-meridial-ui": true,
1434
1727
  onClick: (e) => e.stopPropagation(),
@@ -1445,8 +1738,8 @@ function VoiceboxMenu({
1445
1738
  },
1446
1739
  transition: { duration: 0.15, ease: "easeOut" },
1447
1740
  children: [
1448
- /* @__PURE__ */ jsxs7("div", { "data-meridial-ui": true, className: "flex border-b border-border", children: [
1449
- /* @__PURE__ */ jsx12(
1741
+ /* @__PURE__ */ jsxs8("div", { "data-meridial-ui": true, className: "flex border-b border-border", children: [
1742
+ /* @__PURE__ */ jsx14(
1450
1743
  "button",
1451
1744
  {
1452
1745
  "data-meridial-ui": true,
@@ -1458,7 +1751,7 @@ function VoiceboxMenu({
1458
1751
  children: "Settings"
1459
1752
  }
1460
1753
  ),
1461
- /* @__PURE__ */ jsx12(
1754
+ /* @__PURE__ */ jsx14(
1462
1755
  "button",
1463
1756
  {
1464
1757
  "data-meridial-ui": true,
@@ -1471,8 +1764,8 @@ function VoiceboxMenu({
1471
1764
  }
1472
1765
  )
1473
1766
  ] }),
1474
- /* @__PURE__ */ jsx12(AnimatePresence2, { mode: "wait", children: activeTab === "settings" ? /* @__PURE__ */ jsxs7(
1475
- motion2.div,
1767
+ /* @__PURE__ */ jsx14(AnimatePresence3, { mode: "wait", children: activeTab === "settings" ? /* @__PURE__ */ jsxs8(
1768
+ motion3.div,
1476
1769
  {
1477
1770
  initial: { opacity: 0 },
1478
1771
  animate: { opacity: 1 },
@@ -1480,14 +1773,14 @@ function VoiceboxMenu({
1480
1773
  transition: { duration: 0.1 },
1481
1774
  className: "flex flex-col gap-0 h-[200px]",
1482
1775
  children: [
1483
- /* @__PURE__ */ jsxs7(
1776
+ /* @__PURE__ */ jsxs8(
1484
1777
  "div",
1485
1778
  {
1486
1779
  "data-meridial-ui": true,
1487
1780
  className: "border-b border-border px-3 py-2.5",
1488
1781
  children: [
1489
- /* @__PURE__ */ jsx12("span", { className: "mb-1.5 block text-xs font-medium tracking-wider text-muted-foreground", children: "Position" }),
1490
- /* @__PURE__ */ jsx12("div", { className: "grid grid-cols-2 gap-1", children: Object.entries(POSITION_LABELS).map(([pos, label]) => /* @__PURE__ */ jsx12(
1782
+ /* @__PURE__ */ jsx14("span", { className: "mb-1.5 block text-xs font-medium tracking-wider text-muted-foreground", children: "Position" }),
1783
+ /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-2 gap-1", children: Object.entries(POSITION_LABELS).map(([pos, label]) => /* @__PURE__ */ jsx14(
1491
1784
  "button",
1492
1785
  {
1493
1786
  "data-meridial-ui": true,
@@ -1503,17 +1796,17 @@ function VoiceboxMenu({
1503
1796
  ]
1504
1797
  }
1505
1798
  ),
1506
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between border-b border-border px-3 py-2.5", children: [
1507
- /* @__PURE__ */ jsx12("span", { className: "text-xs font-medium tracking-wider text-muted-foreground", children: "Hide Until Next Visit" }),
1508
- /* @__PURE__ */ jsx12(
1799
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-border px-3 py-2.5", children: [
1800
+ /* @__PURE__ */ jsx14("span", { className: "text-xs font-medium tracking-wider text-muted-foreground", children: "Hide Until Next Visit" }),
1801
+ /* @__PURE__ */ jsx14(
1509
1802
  Button,
1510
1803
  {
1511
1804
  variant: "ghost",
1512
1805
  size: "sm",
1513
1806
  "data-meridial-ui": true,
1514
1807
  onClick: onHide,
1515
- children: /* @__PURE__ */ jsx12(
1516
- HugeiconsIcon6,
1808
+ children: /* @__PURE__ */ jsx14(
1809
+ HugeiconsIcon7,
1517
1810
  {
1518
1811
  icon: ViewOffSlashIcon,
1519
1812
  size: 16,
@@ -1523,7 +1816,7 @@ function VoiceboxMenu({
1523
1816
  }
1524
1817
  )
1525
1818
  ] }),
1526
- /* @__PURE__ */ jsx12("div", { className: "flex items-center justify-center p-2", children: /* @__PURE__ */ jsxs7(
1819
+ /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center p-2", children: /* @__PURE__ */ jsxs8(
1527
1820
  Button,
1528
1821
  {
1529
1822
  "data-meridial-ui": true,
@@ -1531,8 +1824,8 @@ function VoiceboxMenu({
1531
1824
  variant: "default",
1532
1825
  className: "w-full",
1533
1826
  children: [
1534
- /* @__PURE__ */ jsx12(
1535
- HugeiconsIcon6,
1827
+ /* @__PURE__ */ jsx14(
1828
+ HugeiconsIcon7,
1536
1829
  {
1537
1830
  icon: Call02Icon,
1538
1831
  size: 16,
@@ -1546,55 +1839,55 @@ function VoiceboxMenu({
1546
1839
  ]
1547
1840
  },
1548
1841
  "settings"
1549
- ) : /* @__PURE__ */ jsx12(
1550
- motion2.div,
1842
+ ) : /* @__PURE__ */ jsx14(
1843
+ motion3.div,
1551
1844
  {
1552
1845
  initial: { opacity: 0 },
1553
1846
  animate: { opacity: 1 },
1554
1847
  exit: { opacity: 0 },
1555
1848
  transition: { duration: 0.1 },
1556
1849
  className: "h-[200px] overflow-y-auto",
1557
- children: sortedWorkflows.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: "No guides available" }) : /* @__PURE__ */ jsx12("div", { className: "flex flex-col gap-0.5 p-2", children: sortedWorkflows.map((wf) => {
1850
+ children: sortedWorkflows.length === 0 ? /* @__PURE__ */ jsx14("div", { className: "flex h-full items-center justify-center text-xs text-muted-foreground", children: "No guides available" }) : /* @__PURE__ */ jsx14("div", { className: "flex flex-col gap-0.5 p-2", children: sortedWorkflows.map((wf) => {
1558
1851
  const isPlaying = wf.id === playingWorkflowId;
1559
1852
  const totalSteps = wf.steps.length;
1560
1853
  const progressPercent = isPlaying && totalSteps > 0 ? (playingStepIndex + 1) / totalSteps * 100 : 0;
1561
- return /* @__PURE__ */ jsxs7(
1854
+ return /* @__PURE__ */ jsxs8(
1562
1855
  "div",
1563
1856
  {
1564
1857
  "data-meridial-ui": true,
1565
1858
  className: "relative overflow-hidden rounded-md px-3 py-2 hover:bg-muted",
1566
1859
  children: [
1567
- isPlaying && /* @__PURE__ */ jsx12(
1860
+ isPlaying && /* @__PURE__ */ jsx14(
1568
1861
  "div",
1569
1862
  {
1570
1863
  className: "absolute inset-0 bg-primary/10 transition-[width] duration-300 ease-out",
1571
1864
  style: { width: `${progressPercent}%` }
1572
1865
  }
1573
1866
  ),
1574
- /* @__PURE__ */ jsxs7("div", { className: "relative flex items-start gap-2", children: [
1575
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1576
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1", children: [
1577
- wf.isFavorite && /* @__PURE__ */ jsx12(
1578
- HugeiconsIcon6,
1867
+ /* @__PURE__ */ jsxs8("div", { className: "relative flex items-start gap-2", children: [
1868
+ /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
1869
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1", children: [
1870
+ wf.isFavorite && /* @__PURE__ */ jsx14(
1871
+ HugeiconsIcon7,
1579
1872
  {
1580
1873
  icon: StarIcon,
1581
1874
  size: 12,
1582
1875
  className: "shrink-0 fill-amber-400 text-amber-400"
1583
1876
  }
1584
1877
  ),
1585
- /* @__PURE__ */ jsx12("span", { className: "line-clamp-1 text-sm font-medium text-foreground", children: wf.name })
1878
+ /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-sm font-medium text-foreground", children: wf.name })
1586
1879
  ] }),
1587
- wf.description && /* @__PURE__ */ jsx12("p", { className: "line-clamp-2 mt-0.5 text-xs text-muted-foreground", children: wf.description })
1880
+ wf.description && /* @__PURE__ */ jsx14("p", { className: "line-clamp-2 mt-0.5 text-xs text-muted-foreground", children: wf.description })
1588
1881
  ] }),
1589
- /* @__PURE__ */ jsx12(
1882
+ /* @__PURE__ */ jsx14(
1590
1883
  Button,
1591
1884
  {
1592
1885
  variant: "ghost",
1593
1886
  size: "icon",
1594
1887
  "data-meridial-ui": true,
1595
1888
  onClick: () => isPlaying ? onAbortGuide() : onPlayGuide(wf),
1596
- children: /* @__PURE__ */ jsx12(
1597
- HugeiconsIcon6,
1889
+ children: /* @__PURE__ */ jsx14(
1890
+ HugeiconsIcon7,
1598
1891
  {
1599
1892
  icon: isPlaying ? Cancel01Icon : PlayIcon,
1600
1893
  size: 16,
@@ -1618,235 +1911,13 @@ function VoiceboxMenu({
1618
1911
  }
1619
1912
 
1620
1913
  // src/voicebox.tsx
1621
- import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
1914
+ import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
1622
1915
  var BADGE_POSITION_CLASSES = {
1623
1916
  "bottom-right": "right-6 bottom-6",
1624
1917
  "bottom-left": "left-6 bottom-6",
1625
1918
  "top-right": "right-6 top-6",
1626
1919
  "top-left": "left-6 top-6"
1627
1920
  };
1628
- function VoiceboxBadge({
1629
- triggerIcon,
1630
- onClick
1631
- }) {
1632
- return /* @__PURE__ */ jsx13(
1633
- "button",
1634
- {
1635
- "data-meridial-ui": true,
1636
- onClick,
1637
- "aria-label": "Open assistant menu",
1638
- className: "group size-10 flex cursor-pointer items-center justify-center rounded-full border border-border bg-background shadow-lg transition-transform duration-200 ease-out hover:scale-110",
1639
- children: triggerIcon ?? /* @__PURE__ */ jsx13(MeridialLogo, { className: "size-6" })
1640
- }
1641
- );
1642
- }
1643
- function VoiceboxContent({
1644
- baseUrl,
1645
- publishableKey,
1646
- attribute,
1647
- tools,
1648
- cursor,
1649
- initialWorkflow,
1650
- onDisconnect,
1651
- onError
1652
- }) {
1653
- const [showTranscript, setShowTranscript] = useState9(false);
1654
- const [showOutcomeBar, setShowOutcomeBar] = useState9(false);
1655
- const [activeWorkflow, setActiveWorkflow] = useState9(initialWorkflow ?? null);
1656
- const workflowsRef = useRef6([]);
1657
- const room = useEnsureRoom3();
1658
- const autoStarted = useRef6(false);
1659
- const outcomeShown = useRef6(false);
1660
- const draggableRef = useRef6(null);
1661
- const triggerOutcomeBar = useCallback5(() => {
1662
- if (!outcomeShown.current) {
1663
- outcomeShown.current = true;
1664
- setShowOutcomeBar(true);
1665
- }
1666
- }, []);
1667
- const handleOutcomeSubmit = useCallback5(
1668
- async (outcome) => {
1669
- setShowOutcomeBar(false);
1670
- try {
1671
- const sessionId = await room.getSid();
1672
- await fetch(`${baseUrl}/api/outcome`, {
1673
- method: "POST",
1674
- headers: { "Content-Type": "application/json" },
1675
- body: JSON.stringify({ publishableKey, sessionId, outcome })
1676
- });
1677
- } catch {
1678
- }
1679
- },
1680
- [room, baseUrl, publishableKey]
1681
- );
1682
- useToolRegistration(tools, triggerOutcomeBar);
1683
- useDraggable(draggableRef);
1684
- useEffect6(() => {
1685
- if (!publishableKey) return;
1686
- fetch(`${baseUrl}/api/workflows`, {
1687
- headers: { Authorization: `Bearer ${publishableKey}` }
1688
- }).then((r) => r.json()).then((data) => {
1689
- if (data.workflows) workflowsRef.current = data.workflows;
1690
- }).catch((error2) => {
1691
- onError?.(
1692
- error2 instanceof Error ? error2.message : "Workflows fetch failed"
1693
- );
1694
- });
1695
- }, [baseUrl, publishableKey]);
1696
- useEffect6(() => {
1697
- room.registerRpcMethod("workflow:execute", async (rpcData) => {
1698
- try {
1699
- const { slug } = JSON.parse(rpcData.payload);
1700
- const apiWf = workflowsRef.current.find((w) => w.slug === slug);
1701
- if (!apiWf) throw new Error(`Workflow '${slug}' not found`);
1702
- const workflow = {
1703
- id: apiWf.id,
1704
- name: apiWf.name,
1705
- steps: apiWf.steps,
1706
- configured: true,
1707
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
1708
- };
1709
- setActiveWorkflow({ id: apiWf.id, workflow });
1710
- triggerOutcomeBar();
1711
- return JSON.stringify({ success: true });
1712
- } catch (error2) {
1713
- onError?.(
1714
- error2 instanceof Error ? error2.message : "Workflow execution failed"
1715
- );
1716
- throw new RpcError2(
1717
- 1,
1718
- error2 instanceof Error ? error2.message : "Workflow execution failed"
1719
- );
1720
- }
1721
- });
1722
- return () => {
1723
- room.unregisterRpcMethod("workflow:execute");
1724
- };
1725
- }, [room]);
1726
- const { state } = useAgent();
1727
- const { start } = useSessionContext3();
1728
- useEffect6(() => {
1729
- if (!autoStarted.current) {
1730
- autoStarted.current = true;
1731
- start();
1732
- }
1733
- }, [start]);
1734
- const isConnecting = state === "connecting" || state === "initializing" || state === "pre-connect-buffering";
1735
- const isDisconnected = state === "disconnected" || state === "failed";
1736
- const { microphoneTrack, microphoneToggle } = useInputControls();
1737
- const handleDisconnect = () => {
1738
- onDisconnect();
1739
- };
1740
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
1741
- activeWorkflow && /* @__PURE__ */ jsx13(
1742
- WorkflowExecution,
1743
- {
1744
- workflow: activeWorkflow.workflow,
1745
- attribute,
1746
- cursor,
1747
- onClose: () => {
1748
- setActiveWorkflow(null);
1749
- triggerOutcomeBar();
1750
- },
1751
- onError
1752
- }
1753
- ),
1754
- /* @__PURE__ */ jsx13(
1755
- motion3.div,
1756
- {
1757
- initial: { opacity: 0, y: 20 },
1758
- animate: { opacity: 1, y: 0 },
1759
- transition: { duration: 0.3, ease: "easeOut" },
1760
- className: "fixed inset-x-0 bottom-8 z-50 flex justify-center",
1761
- children: /* @__PURE__ */ jsxs8(
1762
- "div",
1763
- {
1764
- ref: draggableRef,
1765
- "data-meridial-ui": true,
1766
- className: "w-96 items-stretch rounded border border-border bg-card shadow-md",
1767
- children: [
1768
- /* @__PURE__ */ jsx13(AnimatePresence3, { initial: false, children: showTranscript && /* @__PURE__ */ jsx13(
1769
- motion3.div,
1770
- {
1771
- initial: { height: 0, opacity: 0 },
1772
- animate: { height: "auto", opacity: 1 },
1773
- exit: { height: 0, opacity: 0 },
1774
- transition: { duration: 0.24, ease: "easeOut" },
1775
- style: { overflow: "hidden" },
1776
- children: /* @__PURE__ */ jsx13(AgentTranscriptPanel, {})
1777
- }
1778
- ) }),
1779
- /* @__PURE__ */ jsx13(AnimatePresence3, { initial: false, children: showOutcomeBar && /* @__PURE__ */ jsx13(
1780
- motion3.div,
1781
- {
1782
- initial: { height: 0, opacity: 0 },
1783
- animate: { height: "auto", opacity: 1 },
1784
- exit: { height: 0, opacity: 0 },
1785
- transition: { duration: 0.24, ease: "easeOut" },
1786
- style: { overflow: "hidden" },
1787
- children: /* @__PURE__ */ jsx13(OutcomeBar, { onSubmit: handleOutcomeSubmit })
1788
- }
1789
- ) }),
1790
- /* @__PURE__ */ jsxs8("div", { "data-meridial-ui": true, className: "flex h-12 items-center", children: [
1791
- /* @__PURE__ */ jsx13(DragHandle, { className: "px-2" }),
1792
- /* @__PURE__ */ jsx13(Separator, { orientation: "vertical", className: "h-full" }),
1793
- /* @__PURE__ */ jsxs8("div", { className: "relative flex h-full flex-1 items-center justify-between px-2", children: [
1794
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
1795
- /* @__PURE__ */ jsx13(
1796
- AgentTrackControl,
1797
- {
1798
- source: "microphone",
1799
- pressed: microphoneToggle.enabled,
1800
- pending: microphoneToggle.pending,
1801
- disabled: microphoneToggle.pending,
1802
- audioTrack: microphoneTrack,
1803
- onPressedChange: microphoneToggle.toggle
1804
- }
1805
- ),
1806
- /* @__PURE__ */ jsx13(
1807
- Toggle3,
1808
- {
1809
- disabled: isDisconnected || isConnecting,
1810
- pressed: showTranscript,
1811
- "aria-label": "Toggle transcript",
1812
- onPressedChange: setShowTranscript,
1813
- className: cn(
1814
- "size-9 rounded-lg",
1815
- showTranscript ? "bg-muted text-foreground" : "bg-transparent text-muted-foreground hover:text-foreground"
1816
- ),
1817
- children: /* @__PURE__ */ jsx13(HugeiconsIcon7, { icon: ChatFeedback01Icon })
1818
- }
1819
- ),
1820
- /* @__PURE__ */ jsx13(
1821
- AgentAudioVisualizerBar,
1822
- {
1823
- barCount: 12,
1824
- state,
1825
- audioTrack: microphoneTrack,
1826
- className: "mx-4"
1827
- }
1828
- )
1829
- ] }),
1830
- isConnecting ? /* @__PURE__ */ jsxs8(Button, { variant: "outline", children: [
1831
- /* @__PURE__ */ jsx13("span", { children: "Connecting" }),
1832
- /* @__PURE__ */ jsx13(
1833
- HugeiconsIcon7,
1834
- {
1835
- icon: Loading03Icon3,
1836
- className: "animate-spin"
1837
- }
1838
- )
1839
- ] }) : /* @__PURE__ */ jsx13(AgentDisconnectButton, { onClick: handleDisconnect }),
1840
- /* @__PURE__ */ jsx13(StartAudioButton, { label: "Start Audio" })
1841
- ] })
1842
- ] })
1843
- ]
1844
- }
1845
- )
1846
- }
1847
- )
1848
- ] });
1849
- }
1850
1921
  function Voicebox({
1851
1922
  baseUrl = "",
1852
1923
  publishableKey,
@@ -1860,25 +1931,25 @@ function Voicebox({
1860
1931
  metadata,
1861
1932
  onError
1862
1933
  }) {
1863
- const [view, setView] = useState9("badge");
1864
- const [hidden, setHidden] = useState9(false);
1865
- const [badgePosition, setBadgePosition] = useState9(() => {
1934
+ const [view, setView] = useState10("badge");
1935
+ const [hidden, setHidden] = useState10(false);
1936
+ const [badgePosition, setBadgePosition] = useState10(() => {
1866
1937
  if (typeof window === "undefined") return "bottom-right";
1867
1938
  return localStorage.getItem(STORAGE_KEYS.triggerPos) || "bottom-right";
1868
1939
  });
1869
- const [allWorkflows, setAllWorkflows] = useState9([]);
1870
- const [initialWorkflow, setInitialWorkflow] = useState9(null);
1871
- const [guideWorkflow, setGuideWorkflow] = useState9(null);
1872
- const [playingWorkflowId, setPlayingWorkflowId] = useState9(
1940
+ const [allWorkflows, setAllWorkflows] = useState10([]);
1941
+ const [initialWorkflow, setInitialWorkflow] = useState10(null);
1942
+ const [guideWorkflow, setGuideWorkflow] = useState10(null);
1943
+ const [playingWorkflowId, setPlayingWorkflowId] = useState10(
1873
1944
  null
1874
1945
  );
1875
- const [playingStepIndex, setPlayingStepIndex] = useState9(0);
1876
- useEffect6(() => {
1946
+ const [playingStepIndex, setPlayingStepIndex] = useState10(0);
1947
+ useEffect7(() => {
1877
1948
  if (sessionStorage.getItem(STORAGE_KEYS.hidden) === "true") {
1878
1949
  setHidden(true);
1879
1950
  }
1880
1951
  }, []);
1881
- useEffect6(() => {
1952
+ useEffect7(() => {
1882
1953
  if (!publishableKey) return;
1883
1954
  fetch(`${baseUrl}/api/workflows`, {
1884
1955
  headers: { Authorization: `Bearer ${publishableKey}` }
@@ -1890,42 +1961,6 @@ function Voicebox({
1890
1961
  }).catch(() => {
1891
1962
  });
1892
1963
  }, [baseUrl, publishableKey]);
1893
- const serializedTools = useMemo5(
1894
- () => tools && tools.length > 0 ? serializeTools(tools) : [],
1895
- [tools]
1896
- );
1897
- const tokenSource = useMemo5(
1898
- () => TokenSource.custom(async () => {
1899
- const response = await fetch(`${baseUrl}/api/auth/livekit`, {
1900
- method: "POST",
1901
- body: JSON.stringify({
1902
- publishableKey,
1903
- identifier,
1904
- firstMessage,
1905
- instructions,
1906
- tools: serializedTools,
1907
- metadata
1908
- })
1909
- });
1910
- if (!response.ok) {
1911
- const body = await response.json().catch(() => ({}));
1912
- onError?.(body.error ?? `Token request failed (${response.status})`);
1913
- return null;
1914
- }
1915
- return response.json();
1916
- }),
1917
- [
1918
- baseUrl,
1919
- publishableKey,
1920
- identifier,
1921
- firstMessage,
1922
- instructions,
1923
- serializedTools,
1924
- metadata,
1925
- onError
1926
- ]
1927
- );
1928
- const session = useSession(tokenSource);
1929
1964
  const handleDisconnect = () => {
1930
1965
  setView("badge");
1931
1966
  setInitialWorkflow(null);
@@ -1963,8 +1998,8 @@ function Voicebox({
1963
1998
  setView((prev) => prev === "menu" ? "badge" : "menu");
1964
1999
  };
1965
2000
  if (hidden) return null;
1966
- return /* @__PURE__ */ jsxs8(AgentSessionProvider, { session, children: [
1967
- guideWorkflow && /* @__PURE__ */ jsx13(
2001
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2002
+ guideWorkflow && /* @__PURE__ */ jsx15(
1968
2003
  WorkflowExecution,
1969
2004
  {
1970
2005
  workflow: guideWorkflow,
@@ -1979,24 +2014,28 @@ function Voicebox({
1979
2014
  onError
1980
2015
  }
1981
2016
  ),
1982
- view === "call" ? /* @__PURE__ */ jsx13(
2017
+ view === "call" ? /* @__PURE__ */ jsx15(
1983
2018
  VoiceboxContent,
1984
2019
  {
1985
2020
  baseUrl,
1986
2021
  publishableKey,
2022
+ identifier,
2023
+ firstMessage,
2024
+ instructions,
1987
2025
  attribute,
1988
2026
  tools,
1989
2027
  cursor,
2028
+ metadata,
1990
2029
  initialWorkflow,
1991
2030
  onDisconnect: handleDisconnect,
1992
2031
  onError
1993
2032
  }
1994
- ) : /* @__PURE__ */ jsxs8(
2033
+ ) : /* @__PURE__ */ jsxs9(
1995
2034
  "div",
1996
2035
  {
1997
2036
  className: cn("fixed z-50", BADGE_POSITION_CLASSES[badgePosition]),
1998
2037
  children: [
1999
- /* @__PURE__ */ jsx13(AnimatePresence3, { children: view === "menu" && /* @__PURE__ */ jsx13(
2038
+ /* @__PURE__ */ jsx15(AnimatePresence4, { children: view === "menu" && /* @__PURE__ */ jsx15(
2000
2039
  VoiceboxMenu,
2001
2040
  {
2002
2041
  workflows: allWorkflows,
@@ -2010,7 +2049,7 @@ function Voicebox({
2010
2049
  onAbortGuide: handleAbortGuide
2011
2050
  }
2012
2051
  ) }),
2013
- /* @__PURE__ */ jsx13(VoiceboxBadge, { triggerIcon, onClick: handleBadgeClick })
2052
+ /* @__PURE__ */ jsx15(VoiceboxBadge, { triggerIcon, onClick: handleBadgeClick })
2014
2053
  ]
2015
2054
  }
2016
2055
  )
@@ -2020,4 +2059,4 @@ function Voicebox({
2020
2059
  export {
2021
2060
  Voicebox
2022
2061
  };
2023
- //# sourceMappingURL=chunk-BWBGNRKO.js.map
2062
+ //# sourceMappingURL=chunk-N4DZEH4G.js.map