@webless/agent 0.6.11 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/embed.cjs CHANGED
@@ -64,7 +64,7 @@ function submitAgentPanel(customerId, message, options) {
64
64
  }
65
65
 
66
66
  // src/react/components/AgentWidget/AgentWidget.tsx
67
- var import_react12 = require("react");
67
+ var import_react15 = require("react");
68
68
 
69
69
  // src/react/page-shift.ts
70
70
  var import_react = require("react");
@@ -920,6 +920,20 @@ function latestTurnEvents(events) {
920
920
  }
921
921
  return startIndex >= 0 ? events.slice(startIndex) : [];
922
922
  }
923
+ function streamIndexBeforeLastTurn(input) {
924
+ let turnStart = -1;
925
+ for (let index = input.events.length - 1; index >= 0; index -= 1) {
926
+ if (input.events[index]?.type === "message.received") {
927
+ turnStart = index;
928
+ break;
929
+ }
930
+ }
931
+ if (turnStart < 0) return null;
932
+ return Math.max(
933
+ 0,
934
+ input.currentStreamIndex - (input.events.length - turnStart)
935
+ );
936
+ }
923
937
  function renderTurn(events) {
924
938
  let rendered = "";
925
939
  for (const event of events) {
@@ -1104,6 +1118,40 @@ var AgentSession = class {
1104
1118
  this.storeOptions
1105
1119
  );
1106
1120
  }
1121
+ async rewindBeforeLastTurn(signal) {
1122
+ const persisted = loadPersistedAgentSession(
1123
+ this.visitorSessionId,
1124
+ this.storeOptions
1125
+ );
1126
+ if (!persisted?.sessionId) return false;
1127
+ const client = this.ensureClient();
1128
+ const attached = client.sessions.attach(persisted.sessionId, {
1129
+ streamIndex: persisted.streamIndex
1130
+ });
1131
+ const snapshot = await withCapabilityRefresh(
1132
+ this.capability,
1133
+ () => attached.snapshot({ signal })
1134
+ );
1135
+ const rewindStreamIndex = streamIndexBeforeLastTurn({
1136
+ currentStreamIndex: snapshot.session.streamIndex,
1137
+ events: snapshot.events
1138
+ });
1139
+ if (rewindStreamIndex === null) return false;
1140
+ this.session = client.sessions.attach(persisted.sessionId, {
1141
+ streamIndex: rewindStreamIndex
1142
+ });
1143
+ savePersistedAgentSession(
1144
+ this.visitorSessionId,
1145
+ persisted.sessionId,
1146
+ rewindStreamIndex,
1147
+ this.storeOptions
1148
+ );
1149
+ return true;
1150
+ }
1151
+ async regenerateTurn(message, signal, handlers) {
1152
+ await this.rewindBeforeLastTurn(signal);
1153
+ return this.sendTurn(message, signal, handlers);
1154
+ }
1107
1155
  ensureClient() {
1108
1156
  const config = resolveAgentRuntimeConfig({
1109
1157
  indexId: this.indexId,
@@ -1439,6 +1487,11 @@ function createAgentClient(options) {
1439
1487
  respondOptions.signal ?? new AbortController().signal,
1440
1488
  respondOptions.handlers
1441
1489
  ),
1490
+ regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
1491
+ message,
1492
+ regenerateOptions.signal ?? new AbortController().signal,
1493
+ regenerateOptions.handlers
1494
+ ),
1442
1495
  reset: () => session.reset(),
1443
1496
  cancelActive: () => session.cancelActive(),
1444
1497
  getActiveSessionId: () => session.getActiveSessionId()
@@ -2881,6 +2934,7 @@ function useAgentChat({
2881
2934
  const {
2882
2935
  controller,
2883
2936
  initialText = "",
2937
+ regenerate: regenerate2 = false,
2884
2938
  responses,
2885
2939
  resume,
2886
2940
  visitorText
@@ -2992,6 +3046,9 @@ function useAgentChat({
2992
3046
  initialText,
2993
3047
  message: visitorText,
2994
3048
  signal
3049
+ }) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
3050
+ handlers,
3051
+ signal
2995
3052
  }) : await clientRef.current.sendTurn(visitorText, {
2996
3053
  handlers,
2997
3054
  signal
@@ -3208,6 +3265,49 @@ ${outgoing}` : outgoing;
3208
3265
  visitorText: visitorTurnText(visitorMessage)
3209
3266
  });
3210
3267
  }, [runTurn, state.messages]);
3268
+ const regenerate = (0, import_react2.useCallback)(async () => {
3269
+ let lastVisitorIndex = -1;
3270
+ for (let index = state.messages.length - 1; index >= 0; index -= 1) {
3271
+ if (state.messages[index]?.role === "visitor") {
3272
+ lastVisitorIndex = index;
3273
+ break;
3274
+ }
3275
+ }
3276
+ const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
3277
+ if (!visitorMessage) return null;
3278
+ if (runRef.current) {
3279
+ runRef.current.abort();
3280
+ clientRef.current.cancelActive();
3281
+ }
3282
+ const controller = new AbortController();
3283
+ runRef.current = controller;
3284
+ setState((prev) => ({
3285
+ ...prev,
3286
+ phase: "thinking",
3287
+ messages: prev.messages.slice(0, lastVisitorIndex + 1),
3288
+ toolSteps: [
3289
+ {
3290
+ id: "planning",
3291
+ kind: "planning",
3292
+ label: "Understanding your question",
3293
+ state: "active"
3294
+ }
3295
+ ],
3296
+ journey: null,
3297
+ followUps: [],
3298
+ streamingText: "",
3299
+ pendingOffer: null,
3300
+ pendingInputs: [],
3301
+ toolResults: [],
3302
+ error: null
3303
+ }));
3304
+ return await runTurn({
3305
+ controller,
3306
+ regenerate: true,
3307
+ resume: false,
3308
+ visitorText: visitorTurnText(visitorMessage)
3309
+ });
3310
+ }, [runTurn, state.messages]);
3211
3311
  const respondToToolInput = (0, import_react2.useCallback)(
3212
3312
  async (surface, values) => {
3213
3313
  await submit(`${surface.title} submitted`, {
@@ -3284,6 +3384,7 @@ ${outgoing}` : outgoing;
3284
3384
  state,
3285
3385
  reset,
3286
3386
  retry,
3387
+ regenerate,
3287
3388
  respondToInput,
3288
3389
  respondToToolInput,
3289
3390
  submit,
@@ -3334,7 +3435,7 @@ function normalizeAgentPlacement(placement) {
3334
3435
  }
3335
3436
 
3336
3437
  // src/react/components/AgentRail/AgentRail.tsx
3337
- var import_react11 = require("react");
3438
+ var import_react14 = require("react");
3338
3439
 
3339
3440
  // src/react/types/conversation.ts
3340
3441
  var defaultAgentRailTheme = {
@@ -3456,6 +3557,60 @@ function stepDetail(step, steps) {
3456
3557
  return "Searched this site";
3457
3558
  return step.detail;
3458
3559
  }
3560
+ function AgentWorkSteps({
3561
+ brandLabel = "",
3562
+ onRetryStep,
3563
+ steps
3564
+ }) {
3565
+ const delegationCount = steps.filter(
3566
+ (step) => step.kind === "specialist"
3567
+ ).length;
3568
+ const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3569
+ const visibleSteps = steps.filter(
3570
+ (step) => step.kind !== "planning" || Boolean(brandLabel)
3571
+ );
3572
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3573
+ const detail = stepDetail(step, steps);
3574
+ const child = delegated && step.kind === "specialist";
3575
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3576
+ "li",
3577
+ {
3578
+ className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3579
+ "data-kind": step.kind,
3580
+ "data-state": step.state,
3581
+ children: [
3582
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3583
+ "span",
3584
+ {
3585
+ className: "agent-activity-bubble__step-icon",
3586
+ "aria-hidden": "true"
3587
+ }
3588
+ ),
3589
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3590
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
3591
+ detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3592
+ delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3593
+ "Delegated ",
3594
+ delegationCount,
3595
+ " ",
3596
+ delegationCount === 1 ? "task" : "tasks"
3597
+ ] }) : null,
3598
+ step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3599
+ "button",
3600
+ {
3601
+ type: "button",
3602
+ className: "agent-activity-bubble__step-retry",
3603
+ onClick: () => onRetryStep(step),
3604
+ children: "Retry"
3605
+ }
3606
+ ) : null
3607
+ ] })
3608
+ ]
3609
+ },
3610
+ step.id
3611
+ );
3612
+ }) });
3613
+ }
3459
3614
  function AgentActivityBubble({
3460
3615
  brandLabel = "",
3461
3616
  failed = false,
@@ -3467,14 +3622,7 @@ function AgentActivityBubble({
3467
3622
  const [expandedReceiptId, setExpandedReceiptId] = (0, import_react5.useState)(
3468
3623
  null
3469
3624
  );
3470
- const detailsOpen = active || expandedReceiptId === receiptId;
3471
- const delegationCount = steps.filter(
3472
- (step) => step.kind === "specialist"
3473
- ).length;
3474
- const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3475
- const visibleSteps = steps.filter(
3476
- (step) => step.kind !== "planning" || Boolean(brandLabel)
3477
- );
3625
+ const detailsOpen = !active && expandedReceiptId === receiptId;
3478
3626
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
3479
3627
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
3480
3628
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -3484,9 +3632,10 @@ function AgentActivityBubble({
3484
3632
  "aria-hidden": "true"
3485
3633
  }
3486
3634
  ),
3487
- workSummary(steps, failed, brandLabel)
3635
+ workSummary(steps, failed, brandLabel),
3636
+ active ? "\u2026" : ""
3488
3637
  ] }),
3489
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3638
+ !active ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3490
3639
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3491
3640
  "button",
3492
3641
  {
@@ -3494,7 +3643,6 @@ function AgentActivityBubble({
3494
3643
  className: "agent-activity-bubble__summary",
3495
3644
  "aria-expanded": detailsOpen,
3496
3645
  onClick: () => {
3497
- if (active) return;
3498
3646
  setExpandedReceiptId(
3499
3647
  (current) => current === receiptId ? null : receiptId
3500
3648
  );
@@ -3502,56 +3650,145 @@ function AgentActivityBubble({
3502
3650
  children: "How this answer was made"
3503
3651
  }
3504
3652
  ),
3505
- detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3506
- const detail = stepDetail(step, steps);
3507
- const child = delegated && step.kind === "specialist";
3508
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3509
- "li",
3510
- {
3511
- className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3512
- "data-kind": step.kind,
3513
- "data-state": step.state,
3514
- children: [
3515
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3516
- "span",
3517
- {
3518
- className: "agent-activity-bubble__step-icon",
3519
- "aria-hidden": "true"
3520
- }
3521
- ),
3522
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3523
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
3524
- detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3525
- delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3526
- "Delegated ",
3527
- delegationCount,
3528
- " ",
3529
- delegationCount === 1 ? "task" : "tasks"
3530
- ] }) : null,
3531
- step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3532
- "button",
3533
- {
3534
- type: "button",
3535
- className: "agent-activity-bubble__step-retry",
3536
- onClick: () => onRetryStep(step),
3537
- children: "Retry"
3538
- }
3539
- ) : null
3540
- ] })
3541
- ]
3542
- },
3543
- step.id
3544
- );
3545
- }) }) : null
3546
- ] })
3653
+ detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3654
+ AgentWorkSteps,
3655
+ {
3656
+ brandLabel,
3657
+ onRetryStep,
3658
+ steps
3659
+ }
3660
+ ) : null
3661
+ ] }) : null
3547
3662
  ] });
3548
3663
  }
3549
3664
 
3550
- // src/react/components/Composer/Composer.tsx
3665
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3666
+ var import_react7 = require("react");
3667
+ var import_react_dom = require("react-dom");
3668
+
3669
+ // src/react/components/AgentRail/AgentRailOverlayContext.tsx
3551
3670
  var import_react6 = require("react");
3671
+ var AgentRailOverlayContext = (0, import_react6.createContext)(null);
3672
+ function useAgentRailPortalRoots() {
3673
+ return (0, import_react6.useContext)(AgentRailOverlayContext);
3674
+ }
3675
+ function useAgentRailMenuPortalRoot() {
3676
+ return (0, import_react6.useContext)(AgentRailOverlayContext)?.railRef ?? null;
3677
+ }
3678
+
3679
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3552
3680
  var import_jsx_runtime2 = require("react/jsx-runtime");
3553
- function SendIcon() {
3681
+ var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
3682
+ function CloseIcon() {
3554
3683
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3684
+ "path",
3685
+ {
3686
+ d: "M4 4l8 8M12 4l-8 8",
3687
+ stroke: "currentColor",
3688
+ strokeWidth: "1.5",
3689
+ strokeLinecap: "round"
3690
+ }
3691
+ ) });
3692
+ }
3693
+ function AnswerReceiptDialog({
3694
+ brandLabel = "",
3695
+ onClose,
3696
+ steps
3697
+ }) {
3698
+ const portalRoots = useAgentRailPortalRoots();
3699
+ const overlayRoot = portalRoots?.overlayRef ?? null;
3700
+ const cardRef = (0, import_react7.useRef)(null);
3701
+ const closeButtonRef = (0, import_react7.useRef)(null);
3702
+ const previouslyFocusedRef = (0, import_react7.useRef)(null);
3703
+ (0, import_react7.useEffect)(() => {
3704
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
3705
+ closeButtonRef.current?.focus({ preventScroll: true });
3706
+ const handleKeyDown = (event) => {
3707
+ if (event.key === "Escape") {
3708
+ event.preventDefault();
3709
+ event.stopPropagation();
3710
+ onClose();
3711
+ return;
3712
+ }
3713
+ if (event.key !== "Tab" || !cardRef.current) return;
3714
+ const focusable = cardRef.current.querySelectorAll(
3715
+ FOCUSABLE_SELECTOR
3716
+ );
3717
+ if (focusable.length === 0) return;
3718
+ const first = focusable.item(0);
3719
+ const last = focusable.item(focusable.length - 1);
3720
+ if (event.shiftKey && document.activeElement === first) {
3721
+ event.preventDefault();
3722
+ last.focus({ preventScroll: true });
3723
+ } else if (!event.shiftKey && document.activeElement === last) {
3724
+ event.preventDefault();
3725
+ first.focus({ preventScroll: true });
3726
+ }
3727
+ };
3728
+ document.addEventListener("keydown", handleKeyDown);
3729
+ return () => {
3730
+ document.removeEventListener("keydown", handleKeyDown);
3731
+ previouslyFocusedRef.current?.focus({ preventScroll: true });
3732
+ };
3733
+ }, [onClose]);
3734
+ const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog", children: [
3735
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3736
+ "button",
3737
+ {
3738
+ type: "button",
3739
+ className: "agent-receipt-dialog__backdrop",
3740
+ "aria-label": "Close",
3741
+ tabIndex: -1,
3742
+ onClick: onClose
3743
+ }
3744
+ ),
3745
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3746
+ "div",
3747
+ {
3748
+ ref: cardRef,
3749
+ className: "agent-receipt-dialog__card",
3750
+ role: "dialog",
3751
+ "aria-modal": "true",
3752
+ "aria-labelledby": "agent-receipt-dialog-title",
3753
+ children: [
3754
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog__header", children: [
3755
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3756
+ "p",
3757
+ {
3758
+ className: "agent-receipt-dialog__title",
3759
+ id: "agent-receipt-dialog-title",
3760
+ children: "How this answer was made"
3761
+ }
3762
+ ),
3763
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3764
+ "button",
3765
+ {
3766
+ ref: closeButtonRef,
3767
+ type: "button",
3768
+ className: "agent-receipt-dialog__close",
3769
+ "aria-label": "Close",
3770
+ onClick: onClose,
3771
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
3772
+ }
3773
+ )
3774
+ ] }),
3775
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
3776
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AgentWorkSteps, { brandLabel, steps }) })
3777
+ ]
3778
+ }
3779
+ )
3780
+ ] });
3781
+ if (overlayRoot?.current) {
3782
+ return (0, import_react_dom.createPortal)(content, overlayRoot.current);
3783
+ }
3784
+ return content;
3785
+ }
3786
+
3787
+ // src/react/components/Composer/Composer.tsx
3788
+ var import_react8 = require("react");
3789
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3790
+ function SendIcon() {
3791
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3555
3792
  "path",
3556
3793
  {
3557
3794
  d: "M8 12V4M8 4l-3 3M8 4l3 3",
@@ -3574,21 +3811,21 @@ function Composer({
3574
3811
  form = null,
3575
3812
  onSubmit
3576
3813
  }) {
3577
- const [value, setValue] = (0, import_react6.useState)("");
3578
- const [values, setValues] = (0, import_react6.useState)(
3814
+ const [value, setValue] = (0, import_react8.useState)("");
3815
+ const [values, setValues] = (0, import_react8.useState)(
3579
3816
  () => emptyValues(form)
3580
3817
  );
3581
- const [blurred, setBlurred] = (0, import_react6.useState)({});
3582
- const inputRef = (0, import_react6.useRef)(null);
3583
- const firstFieldRef = (0, import_react6.useRef)(null);
3584
- const formId = (0, import_react6.useId)();
3818
+ const [blurred, setBlurred] = (0, import_react8.useState)({});
3819
+ const inputRef = (0, import_react8.useRef)(null);
3820
+ const firstFieldRef = (0, import_react8.useRef)(null);
3821
+ const formId = (0, import_react8.useId)();
3585
3822
  const activeForm = form;
3586
3823
  const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
3587
- (0, import_react6.useEffect)(() => {
3824
+ (0, import_react8.useEffect)(() => {
3588
3825
  setValues(emptyValues(form));
3589
3826
  setBlurred({});
3590
3827
  }, [form?.id]);
3591
- (0, import_react6.useEffect)(() => {
3828
+ (0, import_react8.useEffect)(() => {
3592
3829
  if (activeForm) firstFieldRef.current?.focus();
3593
3830
  }, [activeForm?.id]);
3594
3831
  function submitChat() {
@@ -3623,7 +3860,7 @@ function Composer({
3623
3860
  submitForm();
3624
3861
  }
3625
3862
  }
3626
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3863
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3627
3864
  "form",
3628
3865
  {
3629
3866
  className: [
@@ -3632,7 +3869,7 @@ function Composer({
3632
3869
  activeForm ? "composer--form" : ""
3633
3870
  ].filter(Boolean).join(" "),
3634
3871
  onSubmit: handleSubmit,
3635
- children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3872
+ children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3636
3873
  activeForm.fields.map((field, index) => {
3637
3874
  const fieldId = `${formId}-${field.id}`;
3638
3875
  const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
@@ -3657,7 +3894,7 @@ function Composer({
3657
3894
  },
3658
3895
  onKeyDown: handleFormKeyDown
3659
3896
  };
3660
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3897
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3661
3898
  "div",
3662
3899
  {
3663
3900
  className: [
@@ -3665,9 +3902,9 @@ function Composer({
3665
3902
  field.kind === "textarea" ? "composer__row--grow" : ""
3666
3903
  ].filter(Boolean).join(" "),
3667
3904
  children: [
3668
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3669
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "composer__sr-only", children: field.label }),
3670
- field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3905
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3906
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "composer__sr-only", children: field.label }),
3907
+ field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3671
3908
  "textarea",
3672
3909
  {
3673
3910
  ...controlProps,
@@ -3677,7 +3914,7 @@ function Composer({
3677
3914
  className: "composer__control composer__control--area",
3678
3915
  rows: 3
3679
3916
  }
3680
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3917
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3681
3918
  "input",
3682
3919
  {
3683
3920
  ...controlProps,
@@ -3690,24 +3927,24 @@ function Composer({
3690
3927
  }
3691
3928
  )
3692
3929
  ] }),
3693
- invalid ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to continue." : `Add your ${field.label.toLowerCase()} to continue.` }) : null
3930
+ invalid ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to continue." : `Add your ${field.label.toLowerCase()} to continue.` }) : null
3694
3931
  ]
3695
3932
  },
3696
3933
  field.id
3697
3934
  );
3698
3935
  }),
3699
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3936
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3700
3937
  "button",
3701
3938
  {
3702
3939
  type: "submit",
3703
3940
  className: "composer__send",
3704
3941
  disabled: disabled || !canSendForm,
3705
3942
  "aria-label": "Send details",
3706
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3943
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3707
3944
  }
3708
3945
  ) })
3709
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__field", children: [
3710
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3946
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
3947
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3711
3948
  "textarea",
3712
3949
  {
3713
3950
  ref: inputRef,
@@ -3722,14 +3959,14 @@ function Composer({
3722
3959
  onKeyDown: handleChatKeyDown
3723
3960
  }
3724
3961
  ),
3725
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3962
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3726
3963
  "button",
3727
3964
  {
3728
3965
  type: "submit",
3729
3966
  className: "composer__send",
3730
3967
  disabled: disabled || !value.trim(),
3731
3968
  "aria-label": "Send message",
3732
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3969
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3733
3970
  }
3734
3971
  )
3735
3972
  ] })
@@ -3738,7 +3975,7 @@ function Composer({
3738
3975
  }
3739
3976
 
3740
3977
  // src/react/components/FollowUpChips/FollowUpChips.tsx
3741
- var import_jsx_runtime3 = require("react/jsx-runtime");
3978
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3742
3979
  function FollowUpChips({
3743
3980
  suggestions,
3744
3981
  disabled = false,
@@ -3748,7 +3985,7 @@ function FollowUpChips({
3748
3985
  }) {
3749
3986
  if (suggestions.length === 0) return null;
3750
3987
  if (variant === "dock") {
3751
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3988
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3752
3989
  "button",
3753
3990
  {
3754
3991
  type: "button",
@@ -3760,9 +3997,9 @@ function FollowUpChips({
3760
3997
  suggestion.id
3761
3998
  )) }) });
3762
3999
  }
3763
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "followups", children: [
3764
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "followups__label", children: label }),
3765
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4000
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
4001
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
4002
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3766
4003
  "button",
3767
4004
  {
3768
4005
  type: "button",
@@ -3777,11 +4014,11 @@ function FollowUpChips({
3777
4014
  }
3778
4015
 
3779
4016
  // src/react/components/MessageBubble/MessageBubble.tsx
3780
- var import_react8 = require("react");
4017
+ var import_react10 = require("react");
3781
4018
 
3782
4019
  // src/react/components/BookingCard/BookingCard.tsx
3783
- var import_react7 = require("react");
3784
- var import_jsx_runtime4 = require("react/jsx-runtime");
4020
+ var import_react9 = require("react");
4021
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3785
4022
  var BOOKING_STEPS = [
3786
4023
  { id: "date", label: "Date" },
3787
4024
  { id: "time", label: "Time" },
@@ -3812,34 +4049,34 @@ function calendarCells(year, month) {
3812
4049
  return cells;
3813
4050
  }
3814
4051
  function BookingCardLoader() {
3815
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
4052
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
3816
4053
  }
3817
4054
  function BookingCard({
3818
4055
  disabled = false,
3819
4056
  offer,
3820
4057
  onBook
3821
4058
  }) {
3822
- const fieldId = (0, import_react7.useId)();
4059
+ const fieldId = (0, import_react9.useId)();
3823
4060
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
3824
- const [step, setStep] = (0, import_react7.useState)("date");
3825
- const [eventTypeUri, setEventTypeUri] = (0, import_react7.useState)(defaultType);
3826
- const [selectedDate, setSelectedDate] = (0, import_react7.useState)("");
3827
- const [startTime, setStartTime] = (0, import_react7.useState)("");
3828
- const [name, setName] = (0, import_react7.useState)("");
3829
- const [email, setEmail] = (0, import_react7.useState)("");
3830
- const activeStepRef = (0, import_react7.useRef)(null);
3831
- const previousStepRef = (0, import_react7.useRef)(step);
4061
+ const [step, setStep] = (0, import_react9.useState)("date");
4062
+ const [eventTypeUri, setEventTypeUri] = (0, import_react9.useState)(defaultType);
4063
+ const [selectedDate, setSelectedDate] = (0, import_react9.useState)("");
4064
+ const [startTime, setStartTime] = (0, import_react9.useState)("");
4065
+ const [name, setName] = (0, import_react9.useState)("");
4066
+ const [email, setEmail] = (0, import_react9.useState)("");
4067
+ const activeStepRef = (0, import_react9.useRef)(null);
4068
+ const previousStepRef = (0, import_react9.useRef)(step);
3832
4069
  const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
3833
- (0, import_react7.useEffect)(() => {
4070
+ (0, import_react9.useEffect)(() => {
3834
4071
  if (previousStepRef.current === step) return;
3835
4072
  previousStepRef.current = step;
3836
4073
  activeStepRef.current?.scrollIntoView({ block: "nearest" });
3837
4074
  }, [step]);
3838
- const slots = (0, import_react7.useMemo)(
4075
+ const slots = (0, import_react9.useMemo)(
3839
4076
  () => bookingSlotsForEventType(offer.slots, eventTypeUri),
3840
4077
  [eventTypeUri, offer.slots]
3841
4078
  );
3842
- const availableByDate = (0, import_react7.useMemo)(() => {
4079
+ const availableByDate = (0, import_react9.useMemo)(() => {
3843
4080
  const next = /* @__PURE__ */ new Map();
3844
4081
  for (const slot of slots) {
3845
4082
  const key = slotDateKey(slot.startTime);
@@ -3847,7 +4084,7 @@ function BookingCard({
3847
4084
  }
3848
4085
  return next;
3849
4086
  }, [slots]);
3850
- const [visibleMonth, setVisibleMonth] = (0, import_react7.useState)(
4087
+ const [visibleMonth, setVisibleMonth] = (0, import_react9.useState)(
3851
4088
  () => firstAvailableBookingMonth(slots)
3852
4089
  );
3853
4090
  function selectEventType(nextType) {
@@ -3860,7 +4097,7 @@ function BookingCard({
3860
4097
  )
3861
4098
  );
3862
4099
  }
3863
- const daySlots = (0, import_react7.useMemo)(
4100
+ const daySlots = (0, import_react9.useMemo)(
3864
4101
  () => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
3865
4102
  [selectedDate, slots]
3866
4103
  );
@@ -3869,7 +4106,7 @@ function BookingCard({
3869
4106
  );
3870
4107
  const selectedSample = availableByDate.get(selectedDate) ?? startTime;
3871
4108
  const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
3872
- const weekdays = (0, import_react7.useMemo)(() => weekdayLabels(), []);
4109
+ const weekdays = (0, import_react9.useMemo)(() => weekdayLabels(), []);
3873
4110
  const cells = calendarCells(visibleMonth.year, visibleMonth.month);
3874
4111
  const canPrevMonth = [...availableByDate.keys()].some((key) => {
3875
4112
  const month = monthFromKey(key);
@@ -3911,14 +4148,14 @@ function BookingCard({
3911
4148
  })
3912
4149
  });
3913
4150
  }
3914
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4151
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3915
4152
  "section",
3916
4153
  {
3917
4154
  className: "booking-card",
3918
4155
  "aria-busy": disabled || void 0,
3919
4156
  "aria-label": "Book a meeting",
3920
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3921
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4157
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
4158
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3922
4159
  "li",
3923
4160
  {
3924
4161
  className: [
@@ -3928,40 +4165,40 @@ function BookingCard({
3928
4165
  ].filter(Boolean).join(" "),
3929
4166
  "aria-current": index === stepIndex ? "step" : void 0,
3930
4167
  children: [
3931
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
3932
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: item.label })
4168
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
4169
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: item.label })
3933
4170
  ]
3934
4171
  },
3935
4172
  item.id
3936
4173
  )) }),
3937
- step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
3938
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3939
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
4174
+ step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4175
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
4176
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
3940
4177
  "Times in ",
3941
4178
  timeZone
3942
4179
  ] }) : null,
3943
- offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4180
+ offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3944
4181
  "label",
3945
4182
  {
3946
4183
  className: "booking-card__field",
3947
4184
  htmlFor: `${fieldId}-type`,
3948
4185
  children: [
3949
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Meeting" }),
3950
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4186
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Meeting" }),
4187
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3951
4188
  "select",
3952
4189
  {
3953
4190
  id: `${fieldId}-type`,
3954
4191
  value: eventTypeUri,
3955
4192
  disabled,
3956
4193
  onChange: (event) => selectEventType(event.target.value),
3957
- children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: item.uri, children: item.name }, item.uri))
4194
+ children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: item.uri, children: item.name }, item.uri))
3958
4195
  }
3959
4196
  )
3960
4197
  ]
3961
4198
  }
3962
4199
  ) : null,
3963
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__month", children: [
3964
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4200
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__month", children: [
4201
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3965
4202
  "button",
3966
4203
  {
3967
4204
  type: "button",
@@ -3972,8 +4209,8 @@ function BookingCard({
3972
4209
  children: "\u2039"
3973
4210
  }
3974
4211
  ),
3975
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3976
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4212
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
4213
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3977
4214
  "button",
3978
4215
  {
3979
4216
  type: "button",
@@ -3985,9 +4222,9 @@ function BookingCard({
3985
4222
  }
3986
4223
  )
3987
4224
  ] }),
3988
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: label }, label)) }),
3989
- offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3990
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4225
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: label }, label)) }),
4226
+ offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
4227
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3991
4228
  "div",
3992
4229
  {
3993
4230
  className: "booking-card__calendar",
@@ -3995,7 +4232,7 @@ function BookingCard({
3995
4232
  "aria-label": "Available dates",
3996
4233
  children: cells.map((cell, index) => {
3997
4234
  if (!cell) {
3998
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4235
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3999
4236
  "span",
4000
4237
  {
4001
4238
  className: "booking-card__day"
@@ -4005,7 +4242,7 @@ function BookingCard({
4005
4242
  }
4006
4243
  const available = availableByDate.has(cell.key);
4007
4244
  const selected = cell.key === selectedDate;
4008
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4245
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4009
4246
  "button",
4010
4247
  {
4011
4248
  type: "button",
@@ -4025,9 +4262,9 @@ function BookingCard({
4025
4262
  }
4026
4263
  )
4027
4264
  ] }, "date") : null,
4028
- step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4029
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
4030
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4265
+ step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4266
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4267
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4031
4268
  "button",
4032
4269
  {
4033
4270
  type: "button",
@@ -4038,15 +4275,15 @@ function BookingCard({
4038
4275
  children: "\u2039"
4039
4276
  }
4040
4277
  ),
4041
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
4042
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4043
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
4278
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4279
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4280
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
4044
4281
  "Times in ",
4045
4282
  timeZone
4046
4283
  ] }) : null
4047
4284
  ] })
4048
4285
  ] }),
4049
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4286
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4050
4287
  "button",
4051
4288
  {
4052
4289
  type: "button",
@@ -4058,9 +4295,9 @@ function BookingCard({
4058
4295
  slot.startTime
4059
4296
  )) })
4060
4297
  ] }, "time") : null,
4061
- step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4062
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
4063
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4298
+ step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4299
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4300
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4064
4301
  "button",
4065
4302
  {
4066
4303
  type: "button",
@@ -4071,21 +4308,21 @@ function BookingCard({
4071
4308
  children: "\u2039"
4072
4309
  }
4073
4310
  ),
4074
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
4075
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4076
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4077
- selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4311
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4312
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4313
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4314
+ selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4078
4315
  ] })
4079
4316
  ] }),
4080
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__identity", children: [
4081
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4317
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__identity", children: [
4318
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4082
4319
  "label",
4083
4320
  {
4084
4321
  className: "booking-card__field",
4085
4322
  htmlFor: `${fieldId}-name`,
4086
4323
  children: [
4087
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Name" }),
4088
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4324
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Name" }),
4325
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4089
4326
  "input",
4090
4327
  {
4091
4328
  id: `${fieldId}-name`,
@@ -4099,14 +4336,14 @@ function BookingCard({
4099
4336
  ]
4100
4337
  }
4101
4338
  ),
4102
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4339
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4103
4340
  "label",
4104
4341
  {
4105
4342
  className: "booking-card__field",
4106
4343
  htmlFor: `${fieldId}-email`,
4107
4344
  children: [
4108
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Email" }),
4109
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4345
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Email" }),
4346
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4110
4347
  "input",
4111
4348
  {
4112
4349
  id: `${fieldId}-email`,
@@ -4122,7 +4359,7 @@ function BookingCard({
4122
4359
  }
4123
4360
  )
4124
4361
  ] }),
4125
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4362
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4126
4363
  "button",
4127
4364
  {
4128
4365
  type: "submit",
@@ -4140,7 +4377,7 @@ function BookingCard({
4140
4377
  // src/react/components/MessageBubble/MessageBubble.tsx
4141
4378
  var import_streamdown = require("streamdown");
4142
4379
  var import_styles = require("streamdown/styles.css");
4143
- var import_jsx_runtime5 = require("react/jsx-runtime");
4380
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4144
4381
  function normalizeDedupeText(text) {
4145
4382
  return text.trim().replace(/\s+/g, " ").toLowerCase();
4146
4383
  }
@@ -4184,7 +4421,7 @@ function MessageBubble({
4184
4421
  onBook
4185
4422
  }) {
4186
4423
  const resolvedLogoUrl = brandLogoUrl?.trim();
4187
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react8.useState)(null);
4424
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react10.useState)(null);
4188
4425
  const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
4189
4426
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
4190
4427
  const extractedOffers = cards.filter(
@@ -4197,11 +4434,11 @@ function MessageBubble({
4197
4434
  offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
4198
4435
  );
4199
4436
  if (message.role === "visitor") {
4200
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "message-bubble__text", children: message.text }) });
4437
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "message-bubble__text", children: message.text }) });
4201
4438
  }
4202
4439
  const citations = message.citations ?? [];
4203
- const agentText = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__text", children: [
4204
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4440
+ const agentText = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__text", children: [
4441
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4205
4442
  import_streamdown.Streamdown,
4206
4443
  {
4207
4444
  animated: isStreaming,
@@ -4215,8 +4452,8 @@ function MessageBubble({
4215
4452
  children: displayText
4216
4453
  }
4217
4454
  ),
4218
- citations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
4219
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4455
+ citations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
4456
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4220
4457
  "span",
4221
4458
  {
4222
4459
  className: "message-bubble__source-icon",
@@ -4224,12 +4461,12 @@ function MessageBubble({
4224
4461
  children: "\u25A6"
4225
4462
  }
4226
4463
  ),
4227
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: citation.label })
4464
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: citation.label })
4228
4465
  ] }) }, citation.id)) }) : null
4229
4466
  ] });
4230
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4231
- displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__agent-row", children: [
4232
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4467
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4468
+ displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__agent-row", children: [
4469
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4233
4470
  "img",
4234
4471
  {
4235
4472
  src: resolvedLogoUrl,
@@ -4241,7 +4478,7 @@ function MessageBubble({
4241
4478
  ) }),
4242
4479
  agentText
4243
4480
  ] }) : agentText : null,
4244
- offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4481
+ offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4245
4482
  BookingCard,
4246
4483
  {
4247
4484
  disabled: bookingDisabled,
@@ -4253,77 +4490,564 @@ function MessageBubble({
4253
4490
  ] });
4254
4491
  }
4255
4492
 
4256
- // src/react/components/HumanInputCard/HumanInputCard.tsx
4257
- var import_react10 = require("react");
4493
+ // src/react/components/MessageActions/MessageActions.tsx
4494
+ var import_react11 = require("react");
4495
+ var import_react_dom2 = require("react-dom");
4258
4496
 
4259
- // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4260
- var import_jsx_runtime6 = require("react/jsx-runtime");
4261
- function ConfirmationCard({
4262
- disabled = false,
4263
- request,
4264
- onRespond
4265
- }) {
4266
- const options = request.options ?? [];
4267
- const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4268
- const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4269
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4270
- "section",
4271
- {
4272
- className: "confirmation-card",
4273
- "aria-labelledby": `confirmation-${request.requestId}`,
4274
- children: [
4275
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "confirmation-card__heading", children: [
4276
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4277
- prompt ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: prompt }) : null
4278
- ] }),
4279
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4280
- "button",
4281
- {
4282
- type: "button",
4283
- className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
4284
- disabled,
4285
- onClick: () => onRespond?.({
4286
- requestId: request.requestId,
4287
- optionId: option.id
4288
- }),
4289
- children: option.label
4290
- },
4291
- option.id
4292
- )) })
4293
- ]
4294
- }
4295
- );
4497
+ // src/react/lib/speech.ts
4498
+ function toSpeechText(text) {
4499
+ let out = hideToolCardFences(text);
4500
+ out = out.replace(/```[\s\S]*?```/g, " ");
4501
+ out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
4502
+ out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
4503
+ out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
4504
+ out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
4505
+ out = out.replace(/(\*|_)(.*?)\1/g, "$2");
4506
+ out = out.replace(/~~(.*?)~~/g, "$1");
4507
+ out = out.replace(/`([^`]*)`/g, "$1");
4508
+ out = out.replace(/^\s*>\s?/gm, "");
4509
+ out = out.replace(/^\s*[-*+]\s+/gm, "");
4510
+ out = out.replace(/^\s*\d+\.\s+/gm, "");
4511
+ out = out.replace(/\|/g, " ");
4512
+ out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
4513
+ out = out.replace(/\s*\n\s*/g, ". ");
4514
+ out = out.replace(/(?:\.\s*){2,}/g, ". ");
4515
+ return out.replace(/\s{2,}/g, " ").trim();
4516
+ }
4517
+ function isSpeechSupported() {
4518
+ return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
4296
4519
  }
4297
4520
 
4298
- // src/react/components/ToolInputCard/ToolInputCard.tsx
4299
- var import_react9 = require("react");
4521
+ // src/react/components/MessageActions/MessageActions.tsx
4300
4522
  var import_jsx_runtime7 = require("react/jsx-runtime");
4301
- function isRecord5(value) {
4302
- return value !== null && typeof value === "object" && !Array.isArray(value);
4303
- }
4304
- function pathSegments(path) {
4305
- return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
4523
+ function CopyIcon() {
4524
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4525
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4526
+ "rect",
4527
+ {
4528
+ x: "5.75",
4529
+ y: "5.75",
4530
+ width: "7.5",
4531
+ height: "7.5",
4532
+ rx: "1.5",
4533
+ stroke: "currentColor",
4534
+ strokeWidth: "1.5"
4535
+ }
4536
+ ),
4537
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4538
+ "path",
4539
+ {
4540
+ d: "M10.25 5.25V4.5a1.75 1.75 0 0 0-1.75-1.75h-4A1.75 1.75 0 0 0 2.75 4.5v4c0 .97.78 1.75 1.75 1.75h.75",
4541
+ stroke: "currentColor",
4542
+ strokeWidth: "1.5"
4543
+ }
4544
+ )
4545
+ ] });
4306
4546
  }
4307
- function valueAtPath(root, path) {
4308
- let current = root;
4309
- for (const segment of pathSegments(path)) {
4310
- if (Array.isArray(current)) {
4311
- const index = Number(segment);
4312
- current = Number.isInteger(index) ? current[index] : void 0;
4313
- continue;
4547
+ function CheckIcon() {
4548
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4549
+ "path",
4550
+ {
4551
+ d: "M3.5 8.5l3 3 6-7",
4552
+ stroke: "currentColor",
4553
+ strokeWidth: "1.6",
4554
+ strokeLinecap: "round",
4555
+ strokeLinejoin: "round"
4314
4556
  }
4315
- current = isRecord5(current) ? current[segment] : void 0;
4316
- }
4317
- return current;
4318
- }
4319
- function initialFieldValue(field, surface) {
4320
- const supplied = valueAtPath(surface.values, field.path);
4321
- if (supplied !== void 0) return supplied;
4322
- if (field.defaultValue !== void 0) return field.defaultValue;
4323
- if (field.kind === "checkbox" || field.kind === "confirmation") return false;
4324
- if (field.kind === "multi-select") return [];
4325
- if (field.kind === "range") return field.min ?? 0;
4326
- return "";
4557
+ ) });
4558
+ }
4559
+ function ThumbUpIcon() {
4560
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4561
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4562
+ "path",
4563
+ {
4564
+ d: "M4.67 6.67v8",
4565
+ stroke: "currentColor",
4566
+ strokeWidth: "1.5",
4567
+ strokeLinecap: "round"
4568
+ }
4569
+ ),
4570
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4571
+ "path",
4572
+ {
4573
+ d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
4574
+ stroke: "currentColor",
4575
+ strokeWidth: "1.5",
4576
+ strokeLinecap: "round",
4577
+ strokeLinejoin: "round"
4578
+ }
4579
+ )
4580
+ ] });
4581
+ }
4582
+ function ThumbDownIcon() {
4583
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("g", { transform: "rotate(180 8 8)", children: [
4584
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4585
+ "path",
4586
+ {
4587
+ d: "M4.67 6.67v8",
4588
+ stroke: "currentColor",
4589
+ strokeWidth: "1.5",
4590
+ strokeLinecap: "round"
4591
+ }
4592
+ ),
4593
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4594
+ "path",
4595
+ {
4596
+ d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
4597
+ stroke: "currentColor",
4598
+ strokeWidth: "1.5",
4599
+ strokeLinecap: "round",
4600
+ strokeLinejoin: "round"
4601
+ }
4602
+ )
4603
+ ] }) });
4604
+ }
4605
+ function RegenerateIcon() {
4606
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4607
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4608
+ "path",
4609
+ {
4610
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
4611
+ stroke: "currentColor",
4612
+ strokeWidth: "1.5",
4613
+ strokeLinecap: "round"
4614
+ }
4615
+ ),
4616
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4617
+ "path",
4618
+ {
4619
+ d: "M14 2v3.33h-3.33",
4620
+ stroke: "currentColor",
4621
+ strokeWidth: "1.5",
4622
+ strokeLinecap: "round",
4623
+ strokeLinejoin: "round"
4624
+ }
4625
+ ),
4626
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4627
+ "path",
4628
+ {
4629
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
4630
+ stroke: "currentColor",
4631
+ strokeWidth: "1.5",
4632
+ strokeLinecap: "round"
4633
+ }
4634
+ ),
4635
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4636
+ "path",
4637
+ {
4638
+ d: "M5.33 10.67H2V14",
4639
+ stroke: "currentColor",
4640
+ strokeWidth: "1.5",
4641
+ strokeLinecap: "round",
4642
+ strokeLinejoin: "round"
4643
+ }
4644
+ )
4645
+ ] });
4646
+ }
4647
+ function MoreIcon() {
4648
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4649
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
4650
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
4651
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
4652
+ ] });
4653
+ }
4654
+ function SourcesIcon() {
4655
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4657
+ "path",
4658
+ {
4659
+ d: "M8 4.5C6.9 3.4 5.3 3 3.5 3c-.4 0-.8 0-1.2.1-.3 0-.5.3-.5.6v8.1c0 .4.4.7.8.6.3-.1.7-.1 1.1-.1 1.6 0 3.2.4 4.3 1.3 1.1-.9 2.7-1.3 4.3-1.3.4 0 .8 0 1.1.1.4.1.8-.2.8-.6V3.7c0-.3-.2-.6-.5-.6-.4-.1-.8-.1-1.2-.1-1.8 0-3.4.4-4.5 1.5Z",
4660
+ stroke: "currentColor",
4661
+ strokeWidth: "1.4",
4662
+ strokeLinecap: "round",
4663
+ strokeLinejoin: "round"
4664
+ }
4665
+ ),
4666
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4667
+ "path",
4668
+ {
4669
+ d: "M8 4.5v9",
4670
+ stroke: "currentColor",
4671
+ strokeWidth: "1.4",
4672
+ strokeLinecap: "round"
4673
+ }
4674
+ )
4675
+ ] });
4676
+ }
4677
+ function ReadAloudIcon() {
4678
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4679
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4680
+ "path",
4681
+ {
4682
+ d: "M8.5 3.8 5.8 6H3.5c-.6 0-1 .4-1 1v2c0 .6.4 1 1 1h2.3l2.7 2.2c.4.3 1 0 1-.5V4.3c0-.5-.6-.8-1-.5Z",
4683
+ stroke: "currentColor",
4684
+ strokeWidth: "1.4",
4685
+ strokeLinecap: "round",
4686
+ strokeLinejoin: "round"
4687
+ }
4688
+ ),
4689
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4690
+ "path",
4691
+ {
4692
+ d: "M11 6.2c.5.5.8 1.1.8 1.8s-.3 1.3-.8 1.8M12.8 4.5c.9.8 1.4 2 1.4 3.5s-.5 2.7-1.4 3.5",
4693
+ stroke: "currentColor",
4694
+ strokeWidth: "1.4",
4695
+ strokeLinecap: "round"
4696
+ }
4697
+ )
4698
+ ] });
4699
+ }
4700
+ function StopIcon() {
4701
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4702
+ "rect",
4703
+ {
4704
+ x: "4",
4705
+ y: "4",
4706
+ width: "8",
4707
+ height: "8",
4708
+ rx: "1.5",
4709
+ stroke: "currentColor",
4710
+ strokeWidth: "1.5"
4711
+ }
4712
+ ) });
4713
+ }
4714
+ async function writeToClipboard(text) {
4715
+ try {
4716
+ await navigator.clipboard.writeText(text);
4717
+ } catch {
4718
+ const textarea = document.createElement("textarea");
4719
+ textarea.value = text;
4720
+ textarea.style.position = "fixed";
4721
+ textarea.style.opacity = "0";
4722
+ document.body.appendChild(textarea);
4723
+ textarea.select();
4724
+ document.execCommand("copy");
4725
+ textarea.remove();
4726
+ }
4727
+ }
4728
+ function formatAnsweredAt(answeredAt) {
4729
+ if (!answeredAt) return null;
4730
+ const date = new Date(answeredAt);
4731
+ if (Number.isNaN(date.getTime())) return null;
4732
+ return new Intl.DateTimeFormat(void 0, {
4733
+ dateStyle: "medium",
4734
+ timeStyle: "short"
4735
+ }).format(date);
4736
+ }
4737
+ function resolveMenuPosition(input) {
4738
+ const padding = 8;
4739
+ const { button, menuHeight, menuWidth, rail } = input;
4740
+ if (!rail) {
4741
+ return {
4742
+ left: button.left,
4743
+ top: button.top - menuHeight - 6
4744
+ };
4745
+ }
4746
+ let left = button.left - rail.left;
4747
+ let top = button.top - rail.top - menuHeight - 6;
4748
+ left = Math.min(
4749
+ Math.max(left, padding),
4750
+ rail.width - menuWidth - padding
4751
+ );
4752
+ if (top < padding) {
4753
+ top = button.bottom - rail.top + 6;
4754
+ }
4755
+ top = Math.min(top, rail.height - menuHeight - padding);
4756
+ return { left, top };
4757
+ }
4758
+ function MessageActions({
4759
+ answeredAt,
4760
+ copyText,
4761
+ disabled = false,
4762
+ onOpenReceipt,
4763
+ onRegenerate,
4764
+ onFeedback,
4765
+ readAloud = false,
4766
+ receiptSteps,
4767
+ speechText
4768
+ }) {
4769
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
4770
+ const [copied, setCopied] = (0, import_react11.useState)(false);
4771
+ const [rating, setRating] = (0, import_react11.useState)(null);
4772
+ const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4773
+ const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4774
+ const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4775
+ const copyTimerRef = (0, import_react11.useRef)(null);
4776
+ const menuRef = (0, import_react11.useRef)(null);
4777
+ const portaledMenuRef = (0, import_react11.useRef)(null);
4778
+ const moreButtonRef = (0, import_react11.useRef)(null);
4779
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4780
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4781
+ const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
4782
+ const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
4783
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4784
+ (0, import_react11.useLayoutEffect)(() => {
4785
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4786
+ setMenuPosition(null);
4787
+ return;
4788
+ }
4789
+ const button = moreButtonRef.current.getBoundingClientRect();
4790
+ const menu2 = portaledMenuRef.current;
4791
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
4792
+ setMenuPosition(
4793
+ resolveMenuPosition({
4794
+ button,
4795
+ menuHeight: menu2.offsetHeight,
4796
+ menuWidth: menu2.offsetWidth || 190,
4797
+ rail
4798
+ })
4799
+ );
4800
+ }, [menuOpen, menuPortalRoot]);
4801
+ (0, import_react11.useEffect)(
4802
+ () => () => {
4803
+ if (copyTimerRef.current !== null) {
4804
+ window.clearTimeout(copyTimerRef.current);
4805
+ }
4806
+ if (speaking) window.speechSynthesis.cancel();
4807
+ },
4808
+ // Cancel speech only when this answer's actions unmount.
4809
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4810
+ []
4811
+ );
4812
+ (0, import_react11.useEffect)(() => {
4813
+ if (!menuOpen) return;
4814
+ const handlePointerDown = (event) => {
4815
+ const target = event.target;
4816
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
4817
+ setMenuOpen(false);
4818
+ }
4819
+ };
4820
+ const handleKeyDown = (event) => {
4821
+ if (event.key !== "Escape") return;
4822
+ event.preventDefault();
4823
+ event.stopPropagation();
4824
+ setMenuOpen(false);
4825
+ };
4826
+ document.addEventListener("pointerdown", handlePointerDown);
4827
+ document.addEventListener("keydown", handleKeyDown);
4828
+ return () => {
4829
+ document.removeEventListener("pointerdown", handlePointerDown);
4830
+ document.removeEventListener("keydown", handleKeyDown);
4831
+ };
4832
+ }, [menuOpen]);
4833
+ function handleCopy() {
4834
+ void writeToClipboard(copyText);
4835
+ setCopied(true);
4836
+ if (copyTimerRef.current !== null) {
4837
+ window.clearTimeout(copyTimerRef.current);
4838
+ }
4839
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
4840
+ }
4841
+ function handleFeedback(next) {
4842
+ const resolved = rating === next ? null : next;
4843
+ setRating(resolved);
4844
+ if (resolved) onFeedback?.(resolved);
4845
+ }
4846
+ function handleReadAloud() {
4847
+ if (!canReadAloud) return;
4848
+ setMenuOpen(false);
4849
+ if (speaking) {
4850
+ window.speechSynthesis.cancel();
4851
+ setSpeaking(false);
4852
+ return;
4853
+ }
4854
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4855
+ utterance.onend = () => setSpeaking(false);
4856
+ utterance.onerror = () => setSpeaking(false);
4857
+ window.speechSynthesis.cancel();
4858
+ window.speechSynthesis.speak(utterance);
4859
+ setSpeaking(true);
4860
+ }
4861
+ const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4862
+ "div",
4863
+ {
4864
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
4865
+ ref: portaledMenuRef,
4866
+ role: "menu",
4867
+ style: menuPosition ? {
4868
+ left: `${menuPosition.left}px`,
4869
+ top: `${menuPosition.top}px`
4870
+ } : { visibility: "hidden" },
4871
+ children: [
4872
+ answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
4873
+ "Answered ",
4874
+ answeredLabel
4875
+ ] }) : null,
4876
+ canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4877
+ "button",
4878
+ {
4879
+ type: "button",
4880
+ className: "agent-message-actions__menu-item",
4881
+ role: "menuitem",
4882
+ onClick: () => {
4883
+ setMenuOpen(false);
4884
+ onOpenReceipt?.();
4885
+ },
4886
+ children: [
4887
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
4888
+ "View sources"
4889
+ ]
4890
+ }
4891
+ ) : null,
4892
+ canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4893
+ "button",
4894
+ {
4895
+ type: "button",
4896
+ className: "agent-message-actions__menu-item",
4897
+ role: "menuitem",
4898
+ onClick: handleReadAloud,
4899
+ children: [
4900
+ speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
4901
+ speaking ? "Stop reading" : "Read aloud"
4902
+ ]
4903
+ }
4904
+ ) : null
4905
+ ]
4906
+ }
4907
+ ) : null;
4908
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
4909
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4910
+ "button",
4911
+ {
4912
+ type: "button",
4913
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
4914
+ "aria-label": copied ? "Copied" : "Copy answer",
4915
+ title: copied ? "Copied" : "Copy answer",
4916
+ disabled,
4917
+ onClick: handleCopy,
4918
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
4919
+ }
4920
+ ),
4921
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4922
+ "button",
4923
+ {
4924
+ type: "button",
4925
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
4926
+ "aria-label": "Good answer",
4927
+ "aria-pressed": rating === "positive",
4928
+ title: "Good answer",
4929
+ disabled,
4930
+ onClick: () => handleFeedback("positive"),
4931
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
4932
+ }
4933
+ ),
4934
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4935
+ "button",
4936
+ {
4937
+ type: "button",
4938
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
4939
+ "aria-label": "Bad answer",
4940
+ "aria-pressed": rating === "negative",
4941
+ title: "Bad answer",
4942
+ disabled,
4943
+ onClick: () => handleFeedback("negative"),
4944
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
4945
+ }
4946
+ ),
4947
+ onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4948
+ "button",
4949
+ {
4950
+ type: "button",
4951
+ className: "agent-message-actions__button",
4952
+ "aria-label": "Regenerate answer",
4953
+ title: "Regenerate answer",
4954
+ disabled,
4955
+ onClick: onRegenerate,
4956
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
4957
+ }
4958
+ ) : null,
4959
+ showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
4960
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4961
+ "button",
4962
+ {
4963
+ ref: moreButtonRef,
4964
+ type: "button",
4965
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
4966
+ "aria-label": "More actions",
4967
+ "aria-haspopup": "menu",
4968
+ "aria-expanded": menuOpen,
4969
+ title: "More actions",
4970
+ disabled,
4971
+ onClick: () => setMenuOpen((open) => !open),
4972
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
4973
+ }
4974
+ ),
4975
+ menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
4976
+ ] }) : null
4977
+ ] });
4978
+ }
4979
+
4980
+ // src/react/components/HumanInputCard/HumanInputCard.tsx
4981
+ var import_react13 = require("react");
4982
+
4983
+ // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4984
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4985
+ function ConfirmationCard({
4986
+ disabled = false,
4987
+ request,
4988
+ onRespond
4989
+ }) {
4990
+ const options = request.options ?? [];
4991
+ const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4992
+ const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4993
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
4994
+ "section",
4995
+ {
4996
+ className: "confirmation-card",
4997
+ "aria-labelledby": `confirmation-${request.requestId}`,
4998
+ children: [
4999
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
5000
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
5001
+ prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
5002
+ ] }),
5003
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5004
+ "button",
5005
+ {
5006
+ type: "button",
5007
+ className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
5008
+ disabled,
5009
+ onClick: () => onRespond?.({
5010
+ requestId: request.requestId,
5011
+ optionId: option.id
5012
+ }),
5013
+ children: option.label
5014
+ },
5015
+ option.id
5016
+ )) })
5017
+ ]
5018
+ }
5019
+ );
5020
+ }
5021
+
5022
+ // src/react/components/ToolInputCard/ToolInputCard.tsx
5023
+ var import_react12 = require("react");
5024
+ var import_jsx_runtime9 = require("react/jsx-runtime");
5025
+ function isRecord5(value) {
5026
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5027
+ }
5028
+ function pathSegments(path) {
5029
+ return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
5030
+ }
5031
+ function valueAtPath(root, path) {
5032
+ let current = root;
5033
+ for (const segment of pathSegments(path)) {
5034
+ if (Array.isArray(current)) {
5035
+ const index = Number(segment);
5036
+ current = Number.isInteger(index) ? current[index] : void 0;
5037
+ continue;
5038
+ }
5039
+ current = isRecord5(current) ? current[segment] : void 0;
5040
+ }
5041
+ return current;
5042
+ }
5043
+ function initialFieldValue(field, surface) {
5044
+ const supplied = valueAtPath(surface.values, field.path);
5045
+ if (supplied !== void 0) return supplied;
5046
+ if (field.defaultValue !== void 0) return field.defaultValue;
5047
+ if (field.kind === "checkbox" || field.kind === "confirmation") return false;
5048
+ if (field.kind === "multi-select") return [];
5049
+ if (field.kind === "range") return field.min ?? 0;
5050
+ return "";
4327
5051
  }
4328
5052
  function initialValues(surface) {
4329
5053
  return Object.fromEntries(
@@ -4421,7 +5145,7 @@ function FieldDescription({
4421
5145
  field,
4422
5146
  id
4423
5147
  }) {
4424
- return field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5148
+ return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4425
5149
  }
4426
5150
  function ChoiceField({
4427
5151
  field,
@@ -4440,7 +5164,7 @@ function ChoiceField({
4440
5164
  const selectedIndex = options.findIndex(
4441
5165
  (option) => valuesMatch(option.value, value)
4442
5166
  );
4443
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5167
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4444
5168
  "select",
4445
5169
  {
4446
5170
  id,
@@ -4455,13 +5179,13 @@ function ChoiceField({
4455
5179
  if (option) onChange(option.value);
4456
5180
  },
4457
5181
  children: [
4458
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
4459
- options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: index, children: option.label }, optionKey(option)))
5182
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
5183
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
4460
5184
  ]
4461
5185
  }
4462
5186
  );
4463
5187
  }
4464
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5188
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4465
5189
  "div",
4466
5190
  {
4467
5191
  className: "tool-input-card__choices",
@@ -4472,8 +5196,8 @@ function ChoiceField({
4472
5196
  "aria-required": field.required,
4473
5197
  children: options.map((option, index) => {
4474
5198
  const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
4475
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__choice", children: [
4476
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5199
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
5200
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4477
5201
  "input",
4478
5202
  {
4479
5203
  type: multiple ? "checkbox" : "radio",
@@ -4495,7 +5219,7 @@ function ChoiceField({
4495
5219
  }
4496
5220
  }
4497
5221
  ),
4498
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
5222
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
4499
5223
  ] }, optionKey(option));
4500
5224
  })
4501
5225
  }
@@ -4515,9 +5239,9 @@ function ToolField({
4515
5239
  error ? `${id}-error` : ""
4516
5240
  ].filter(Boolean).join(" ");
4517
5241
  if (field.kind === "checkbox" || field.kind === "confirmation") {
4518
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
4519
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
4520
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5242
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
5243
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
5244
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4521
5245
  "input",
4522
5246
  {
4523
5247
  id,
@@ -4530,17 +5254,17 @@ function ToolField({
4530
5254
  onChange: (event) => onChange(event.target.checked)
4531
5255
  }
4532
5256
  ),
4533
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
4534
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: field.label }),
4535
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-description`, children: field.description }) : null
5257
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
5258
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
5259
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
4536
5260
  ] })
4537
5261
  ] }),
4538
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5262
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4539
5263
  ] });
4540
5264
  }
4541
- const label = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
5265
+ const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
4542
5266
  field.label,
4543
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5267
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4544
5268
  ] });
4545
5269
  const common = {
4546
5270
  id,
@@ -4552,7 +5276,7 @@ function ToolField({
4552
5276
  };
4553
5277
  let control;
4554
5278
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4555
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5279
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4556
5280
  ChoiceField,
4557
5281
  {
4558
5282
  field,
@@ -4566,7 +5290,7 @@ function ToolField({
4566
5290
  }
4567
5291
  );
4568
5292
  } else if (field.kind === "textarea" || field.kind === "json") {
4569
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5293
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4570
5294
  "textarea",
4571
5295
  {
4572
5296
  ...common,
@@ -4580,8 +5304,8 @@ function ToolField({
4580
5304
  );
4581
5305
  } else if (field.kind === "range") {
4582
5306
  const numericValue = typeof value === "number" ? value : field.min ?? 0;
4583
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__range", children: [
4584
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5307
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
5308
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4585
5309
  "input",
4586
5310
  {
4587
5311
  ...common,
@@ -4593,11 +5317,11 @@ function ToolField({
4593
5317
  onChange: (event) => onChange(Number(event.target.value))
4594
5318
  }
4595
5319
  ),
4596
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("output", { htmlFor: id, children: numericValue })
5320
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
4597
5321
  ] });
4598
5322
  } else {
4599
5323
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4600
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5324
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4601
5325
  "input",
4602
5326
  {
4603
5327
  ...common,
@@ -4615,11 +5339,11 @@ function ToolField({
4615
5339
  }
4616
5340
  );
4617
5341
  }
4618
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
5342
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
4619
5343
  label,
4620
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldDescription, { field, id: `${id}-description` }),
5344
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
4621
5345
  control,
4622
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5346
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4623
5347
  ] });
4624
5348
  }
4625
5349
  function ToolInputCard({
@@ -4627,11 +5351,11 @@ function ToolInputCard({
4627
5351
  surface,
4628
5352
  onSubmit
4629
5353
  }) {
4630
- const [values, setValues] = (0, import_react9.useState)(
5354
+ const [values, setValues] = (0, import_react12.useState)(
4631
5355
  () => initialValues(surface)
4632
5356
  );
4633
- const [touched, setTouched] = (0, import_react9.useState)(() => /* @__PURE__ */ new Set());
4634
- const [submitted, setSubmitted] = (0, import_react9.useState)(false);
5357
+ const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
5358
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
4635
5359
  const errors = Object.fromEntries(
4636
5360
  surface.fields.map((field) => [
4637
5361
  field.path,
@@ -4656,14 +5380,14 @@ function ToolInputCard({
4656
5380
  onSubmit?.(surface, result);
4657
5381
  }
4658
5382
  if (submitted) {
4659
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5383
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4660
5384
  "section",
4661
5385
  {
4662
5386
  className: "tool-input-card tool-input-card--submitted",
4663
5387
  role: "status",
4664
5388
  children: [
4665
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
4666
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5389
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
5390
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
4667
5391
  surface.title,
4668
5392
  " submitted"
4669
5393
  ] })
@@ -4671,18 +5395,18 @@ function ToolInputCard({
4671
5395
  }
4672
5396
  );
4673
5397
  }
4674
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5398
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4675
5399
  "section",
4676
5400
  {
4677
5401
  className: "tool-input-card",
4678
5402
  "aria-labelledby": `tool-input-${surface.id}`,
4679
5403
  children: [
4680
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__heading", children: [
4681
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
4682
- surface.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: surface.description }) : null
5404
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
5405
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5406
+ surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
4683
5407
  ] }),
4684
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
4685
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5408
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
5409
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4686
5410
  ToolField,
4687
5411
  {
4688
5412
  disabled,
@@ -4695,8 +5419,8 @@ function ToolInputCard({
4695
5419
  },
4696
5420
  field.path
4697
5421
  )) }),
4698
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__actions", children: [
4699
- surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5422
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
5423
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4700
5424
  "button",
4701
5425
  {
4702
5426
  type: "button",
@@ -4709,7 +5433,7 @@ function ToolInputCard({
4709
5433
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4710
5434
  }
4711
5435
  ) : null,
4712
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5436
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4713
5437
  ] })
4714
5438
  ] })
4715
5439
  ]
@@ -4718,17 +5442,17 @@ function ToolInputCard({
4718
5442
  }
4719
5443
 
4720
5444
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4721
- var import_jsx_runtime8 = require("react/jsx-runtime");
5445
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4722
5446
  function HumanInputCard({
4723
5447
  disabled = false,
4724
5448
  request,
4725
5449
  onRespond
4726
5450
  }) {
4727
- const [text, setText] = (0, import_react10.useState)("");
5451
+ const [text, setText] = (0, import_react13.useState)("");
4728
5452
  const options = request.options ?? [];
4729
5453
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4730
5454
  if (request.ui) {
4731
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5455
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4732
5456
  ToolInputCard,
4733
5457
  {
4734
5458
  disabled,
@@ -4738,7 +5462,7 @@ function HumanInputCard({
4738
5462
  );
4739
5463
  }
4740
5464
  if (options.length > 0) {
4741
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5465
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4742
5466
  ConfirmationCard,
4743
5467
  {
4744
5468
  disabled,
@@ -4753,17 +5477,17 @@ function HumanInputCard({
4753
5477
  if (!value || disabled) return;
4754
5478
  onRespond?.({ requestId: request.requestId, text: value });
4755
5479
  }
4756
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5480
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4757
5481
  "section",
4758
5482
  {
4759
5483
  className: "human-input-card",
4760
5484
  "aria-labelledby": `human-input-${request.requestId}`,
4761
5485
  children: [
4762
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "human-input-card__heading", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
4763
- showText ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: submitText, children: [
4764
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
4765
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
4766
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5486
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "human-input-card__heading", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
5487
+ showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
5488
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5489
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
5490
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4767
5491
  "input",
4768
5492
  {
4769
5493
  id: `human-input-text-${request.requestId}`,
@@ -4772,39 +5496,39 @@ function HumanInputCard({
4772
5496
  onChange: (event) => setText(event.target.value)
4773
5497
  }
4774
5498
  ),
4775
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5499
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4776
5500
  ] })
4777
5501
  ] }) : null,
4778
- !showText && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
5502
+ !showText && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
4779
5503
  ]
4780
5504
  }
4781
5505
  );
4782
5506
  }
4783
5507
 
4784
5508
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4785
- var import_jsx_runtime9 = require("react/jsx-runtime");
5509
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4786
5510
  function CollectionResultCard({
4787
5511
  result
4788
5512
  }) {
4789
5513
  const empty = result.items.length === 0;
4790
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5514
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4791
5515
  "section",
4792
5516
  {
4793
5517
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4794
5518
  "aria-label": result.title,
4795
5519
  children: [
4796
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-result-card__heading", children: [
4797
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4798
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: result.title })
5520
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
5521
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5522
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
4799
5523
  ] }),
4800
- empty ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { children: [
4801
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
4802
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: item.description }) : null,
4803
- item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
4804
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: detail.label }),
4805
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: detail.value })
5524
+ empty ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
5526
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
5527
+ item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
5528
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
5529
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
4806
5530
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4807
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
5531
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4808
5532
  ] }, item.title)) })
4809
5533
  ]
4810
5534
  }
@@ -4812,26 +5536,26 @@ function CollectionResultCard({
4812
5536
  }
4813
5537
 
4814
5538
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4815
- var import_jsx_runtime10 = require("react/jsx-runtime");
5539
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4816
5540
  function EntityResultCard({
4817
5541
  result
4818
5542
  }) {
4819
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5543
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4820
5544
  "section",
4821
5545
  {
4822
5546
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4823
5547
  "aria-label": result.title,
4824
5548
  children: [
4825
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "tool-result-card__heading", children: [
4826
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4827
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: result.title })
5549
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
5550
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5551
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
4828
5552
  ] }),
4829
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: result.description }) : null,
4830
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
4831
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dt", { children: detail.label }),
4832
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dd", { children: detail.value })
5553
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
5554
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
5555
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
5556
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
4833
5557
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4834
- result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5558
+ result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4835
5559
  "a",
4836
5560
  {
4837
5561
  href: link.href,
@@ -4847,24 +5571,24 @@ function EntityResultCard({
4847
5571
  }
4848
5572
 
4849
5573
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4850
- var import_jsx_runtime11 = require("react/jsx-runtime");
5574
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4851
5575
  function SignatureResultCard({
4852
5576
  result
4853
5577
  }) {
4854
5578
  const primaryLink = result.links?.[0];
4855
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5579
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4856
5580
  "section",
4857
5581
  {
4858
5582
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4859
5583
  "aria-label": result.title,
4860
5584
  children: [
4861
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
4862
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4863
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
5585
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
5586
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5587
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
4864
5588
  ] }),
4865
- result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
4866
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: result.description }) : null,
4867
- primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5589
+ result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5590
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
5591
+ primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4868
5592
  "a",
4869
5593
  {
4870
5594
  className: "signature-result-card__cta",
@@ -4880,26 +5604,26 @@ function SignatureResultCard({
4880
5604
  }
4881
5605
 
4882
5606
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4883
- var import_jsx_runtime12 = require("react/jsx-runtime");
5607
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4884
5608
  function ToolResultCard({
4885
5609
  result
4886
5610
  }) {
4887
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5611
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4888
5612
  "section",
4889
5613
  {
4890
5614
  className: `tool-result-card tool-result-card--${result.status}`,
4891
5615
  "aria-label": result.title,
4892
5616
  children: [
4893
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
4894
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4895
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
5617
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
5618
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5619
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
4896
5620
  ] }),
4897
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
4898
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
4899
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
4900
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
5621
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
5622
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5623
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
5624
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
4901
5625
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4902
- result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5626
+ result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4903
5627
  "a",
4904
5628
  {
4905
5629
  href: link.href,
@@ -4915,14 +5639,14 @@ function ToolResultCard({
4915
5639
  }
4916
5640
 
4917
5641
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4918
- var import_jsx_runtime13 = require("react/jsx-runtime");
5642
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4919
5643
  function VisitorToolResultView({
4920
5644
  disabled = false,
4921
5645
  onToolInput,
4922
5646
  result
4923
5647
  }) {
4924
5648
  if (result.kind === "input") {
4925
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5649
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4926
5650
  ToolInputCard,
4927
5651
  {
4928
5652
  disabled,
@@ -4932,16 +5656,16 @@ function VisitorToolResultView({
4932
5656
  );
4933
5657
  }
4934
5658
  if (result.kind === "entity") {
4935
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EntityResultCard, { result });
5659
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
4936
5660
  }
4937
5661
  if (result.kind === "collection") {
4938
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollectionResultCard, { result });
5662
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
4939
5663
  }
4940
5664
  if (result.kind === "signature") {
4941
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SignatureResultCard, { result });
5665
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
4942
5666
  }
4943
5667
  if (result.kind === "summary") {
4944
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResultCard, { result });
5668
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
4945
5669
  }
4946
5670
  return null;
4947
5671
  }
@@ -4950,9 +5674,9 @@ function isRenderableVisitorToolResult(result) {
4950
5674
  }
4951
5675
 
4952
5676
  // src/react/components/AgentRail/AgentRail.tsx
4953
- var import_jsx_runtime14 = require("react/jsx-runtime");
5677
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4954
5678
  function MinimizeIcon() {
4955
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5679
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4956
5680
  "path",
4957
5681
  {
4958
5682
  d: "M3.5 8h9",
@@ -4962,8 +5686,8 @@ function MinimizeIcon() {
4962
5686
  }
4963
5687
  ) });
4964
5688
  }
4965
- function CloseIcon() {
4966
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5689
+ function CloseIcon2() {
5690
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4967
5691
  "path",
4968
5692
  {
4969
5693
  d: "M4 4l8 8M12 4l-8 8",
@@ -4974,7 +5698,7 @@ function CloseIcon() {
4974
5698
  ) });
4975
5699
  }
4976
5700
  function NewChatIcon() {
4977
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5701
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4978
5702
  "path",
4979
5703
  {
4980
5704
  d: "M9.5 3.5h3v3M12.25 3.75 8 8M7 4H4.5A1.5 1.5 0 0 0 3 5.5v6A1.5 1.5 0 0 0 4.5 13h6a1.5 1.5 0 0 0 1.5-1.5V9",
@@ -4986,7 +5710,7 @@ function NewChatIcon() {
4986
5710
  ) });
4987
5711
  }
4988
5712
  function ExpandIcon() {
4989
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5713
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4990
5714
  "path",
4991
5715
  {
4992
5716
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4998,7 +5722,7 @@ function ExpandIcon() {
4998
5722
  ) });
4999
5723
  }
5000
5724
  function RestoreIcon() {
5001
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5725
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5002
5726
  "path",
5003
5727
  {
5004
5728
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -5009,6 +5733,19 @@ function RestoreIcon() {
5009
5733
  }
5010
5734
  ) });
5011
5735
  }
5736
+ function ChevronDownIcon() {
5737
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5738
+ "path",
5739
+ {
5740
+ d: "M4 6.5l4 4 4-4",
5741
+ stroke: "currentColor",
5742
+ strokeWidth: "1.6",
5743
+ strokeLinecap: "round",
5744
+ strokeLinejoin: "round"
5745
+ }
5746
+ ) });
5747
+ }
5748
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
5012
5749
  function AgentRail({
5013
5750
  state,
5014
5751
  theme,
@@ -5016,6 +5753,9 @@ function AgentRail({
5016
5753
  brandLabel = "",
5017
5754
  brandLogoUrl,
5018
5755
  poweredByLabel = "Powered by Webless",
5756
+ disclaimerLabel,
5757
+ answerReceipt = false,
5758
+ readAloud = false,
5019
5759
  composerPlaceholder = "Ask anything\u2026",
5020
5760
  mobileFullscreen = false,
5021
5761
  expanded = false,
@@ -5024,16 +5764,26 @@ function AgentRail({
5024
5764
  onExpandToggle,
5025
5765
  onReset,
5026
5766
  onRetry,
5767
+ onRegenerate,
5768
+ onFeedback,
5027
5769
  onSubmit,
5028
5770
  onFollowUpSelect,
5029
5771
  onBook,
5030
5772
  onInputResponse,
5031
5773
  onToolInput
5032
5774
  }) {
5033
- const transcriptRef = (0, import_react11.useRef)(null);
5775
+ const railRef = (0, import_react14.useRef)(null);
5776
+ const overlayRef = (0, import_react14.useRef)(null);
5777
+ const transcriptRef = (0, import_react14.useRef)(null);
5778
+ const pinnedToBottomRef = (0, import_react14.useRef)(true);
5779
+ const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
5780
+ const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
5781
+ const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
5782
+ const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
5034
5783
  const resolvedBrandLabel = brandLabel.trim();
5035
5784
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
5036
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react11.useState)(null);
5785
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5786
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
5037
5787
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
5038
5788
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
5039
5789
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -5084,10 +5834,15 @@ function AgentRail({
5084
5834
  );
5085
5835
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
5086
5836
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
5087
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5837
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5838
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
5088
5839
  const hasVisitorMessages2 = state.messages.some(
5089
5840
  (message) => message.role === "visitor"
5090
5841
  );
5842
+ const hasAgentResponseAfterVisitor = state.messages.some(
5843
+ (message) => message.role === "agent" && message.id !== "greeting"
5844
+ );
5845
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
5091
5846
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
5092
5847
  const greeting = state.messages.find(
5093
5848
  (message) => message.role === "agent" && message.id === "greeting"
@@ -5109,6 +5864,7 @@ function AgentRail({
5109
5864
  }
5110
5865
  }
5111
5866
  const lastIsAgent = lastMessage?.role === "agent";
5867
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
5112
5868
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
5113
5869
  createdAt: 0,
5114
5870
  id: "streaming-response",
@@ -5135,10 +5891,36 @@ function AgentRail({
5135
5891
  hasPendingConfirmation,
5136
5892
  enabled: lastIsAgent && !isBusy
5137
5893
  });
5138
- (0, import_react11.useEffect)(() => {
5894
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
5895
+ (0, import_react14.useEffect)(() => {
5896
+ if (state.phase !== "complete") {
5897
+ setReceiptOpen(false);
5898
+ }
5899
+ }, [state.phase]);
5900
+ function handleSubmit(message) {
5901
+ setReceiptOpen(false);
5902
+ onSubmit?.(message);
5903
+ }
5904
+ function handleRegenerate() {
5905
+ setReceiptOpen(false);
5906
+ onRegenerate?.();
5907
+ }
5908
+ function handleReset() {
5909
+ setReceiptOpen(false);
5910
+ onReset?.();
5911
+ }
5912
+ function handleFollowUpSelect(label) {
5913
+ setReceiptOpen(false);
5914
+ onFollowUpSelect?.(label);
5915
+ }
5916
+ (0, import_react14.useEffect)(() => {
5139
5917
  const node = transcriptRef.current;
5140
5918
  if (!node) return;
5141
- node.scrollTop = node.scrollHeight;
5919
+ const lastMessage2 = state.messages.at(-1);
5920
+ const visitorJustSent = lastMessage2?.role === "visitor";
5921
+ if (pinnedToBottomRef.current || visitorJustSent) {
5922
+ node.scrollTop = node.scrollHeight;
5923
+ }
5142
5924
  }, [
5143
5925
  state.messages,
5144
5926
  state.toolSteps,
@@ -5146,10 +5928,75 @@ function AgentRail({
5146
5928
  state.followUps,
5147
5929
  state.journey
5148
5930
  ]);
5149
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5931
+ (0, import_react14.useEffect)(() => {
5932
+ const node = transcriptRef.current;
5933
+ if (!node) return;
5934
+ const handleScroll = () => {
5935
+ if (node.clientHeight === 0) return;
5936
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5937
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
5938
+ pinnedToBottomRef.current = pinned;
5939
+ setShowJumpToLatest(!pinned);
5940
+ };
5941
+ node.addEventListener("scroll", handleScroll, { passive: true });
5942
+ handleScroll();
5943
+ return () => node.removeEventListener("scroll", handleScroll);
5944
+ }, []);
5945
+ (0, import_react14.useEffect)(() => {
5946
+ const node = transcriptRef.current;
5947
+ if (!node) return;
5948
+ const observer = new ResizeObserver(() => {
5949
+ if (node.clientHeight === 0) return;
5950
+ if (pinnedToBottomRef.current) {
5951
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5952
+ }
5953
+ });
5954
+ observer.observe(node);
5955
+ return () => observer.disconnect();
5956
+ }, []);
5957
+ (0, import_react14.useEffect)(() => {
5958
+ if (!receiptOpen) {
5959
+ lockedTranscriptScrollTopRef.current = null;
5960
+ return;
5961
+ }
5962
+ const node = transcriptRef.current;
5963
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
5964
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
5965
+ }, [receiptOpen]);
5966
+ function openReceipt() {
5967
+ const node = transcriptRef.current;
5968
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
5969
+ setReceiptOpen(true);
5970
+ }
5971
+ function scrollToLatest() {
5972
+ const node = transcriptRef.current;
5973
+ if (!node) return;
5974
+ pinnedToBottomRef.current = true;
5975
+ setShowJumpToLatest(false);
5976
+ const reduceMotion = window.matchMedia(
5977
+ "(prefers-reduced-motion: reduce)"
5978
+ ).matches;
5979
+ if (reduceMotion) {
5980
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5981
+ return;
5982
+ }
5983
+ smoothScrollToLatestRef.current = true;
5984
+ const settle = () => {
5985
+ smoothScrollToLatestRef.current = false;
5986
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5987
+ const pinned = distanceFromBottom < 48;
5988
+ pinnedToBottomRef.current = pinned;
5989
+ setShowJumpToLatest(!pinned);
5990
+ };
5991
+ node.addEventListener("scrollend", settle, { once: true });
5992
+ window.setTimeout(settle, 900);
5993
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
5994
+ }
5995
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5150
5996
  "aside",
5151
5997
  {
5152
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
5998
+ ref: railRef,
5999
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
5153
6000
  "data-not-typeset": "",
5154
6001
  "data-color-scheme": resolvedColorScheme,
5155
6002
  spellCheck: false,
@@ -5159,196 +6006,234 @@ function AgentRail({
5159
6006
  autoFocus: mobileFullscreen || expanded,
5160
6007
  role: mobileFullscreen || expanded ? "dialog" : void 0,
5161
6008
  tabIndex: mobileFullscreen || expanded ? -1 : void 0,
5162
- children: [
5163
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__brand-row", children: [
5164
- onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5165
- "button",
5166
- {
5167
- type: "button",
5168
- className: "agent-rail__collapse",
5169
- "aria-label": "Collapse assist",
5170
- onClick: onCollapse,
5171
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MinimizeIcon, {})
5172
- }
5173
- ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5174
- "button",
5175
- {
5176
- type: "button",
5177
- className: "agent-rail__close",
5178
- "aria-label": "Close agent",
5179
- onClick: onClose,
5180
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {})
5181
- }
5182
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
5183
- resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__identity", children: [
5184
- showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5185
- "img",
5186
- {
5187
- className: "agent-rail__brand-logo",
5188
- src: resolvedBrandLogoUrl,
5189
- alt: "",
5190
- onError: () => {
5191
- setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
5192
- }
5193
- }
5194
- ) }) : null,
5195
- resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
5196
- ] }) : null,
5197
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__actions", children: [
5198
- onReset ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5199
- "button",
5200
- {
5201
- type: "button",
5202
- className: "agent-rail__new-chat",
5203
- "aria-label": "Start a new conversation",
5204
- disabled: !hasVisitorMessages2,
5205
- onClick: onReset,
5206
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NewChatIcon, {})
5207
- }
5208
- ) : null,
5209
- onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5210
- "button",
5211
- {
5212
- type: "button",
5213
- className: "agent-rail__expand",
5214
- "aria-label": expanded ? "Exit full screen" : "Open full screen",
5215
- onClick: onExpandToggle,
5216
- children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ExpandIcon, {})
5217
- }
5218
- ) : null
5219
- ] })
5220
- ] }) }),
5221
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__thread", children: [
5222
- !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
5223
- greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5224
- MessageBubble,
5225
- {
5226
- message: greeting,
5227
- bookingDisabled: isBusy,
5228
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5229
- onBook
5230
- }
5231
- ) : null,
5232
- showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5233
- FollowUpChips,
5234
- {
5235
- suggestions: state.followUps,
5236
- disabled: isBusy,
5237
- label: "Start here",
5238
- onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
5239
- }
5240
- ) }) : null,
5241
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5242
- AgentActivityBubble,
6009
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6010
+ AgentRailOverlayContext.Provider,
6011
+ {
6012
+ value: { railRef, overlayRef },
6013
+ children: [
6014
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
6015
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__brand-row", children: [
6016
+ onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6017
+ "button",
6018
+ {
6019
+ type: "button",
6020
+ className: "agent-rail__collapse",
6021
+ "aria-label": "Collapse assist",
6022
+ onClick: onCollapse,
6023
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
6024
+ }
6025
+ ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6026
+ "button",
6027
+ {
6028
+ type: "button",
6029
+ className: "agent-rail__close",
6030
+ "aria-label": "Close agent",
6031
+ onClick: onClose,
6032
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
6033
+ }
6034
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
6035
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
6036
+ showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6037
+ "img",
6038
+ {
6039
+ className: "agent-rail__brand-logo",
6040
+ src: resolvedBrandLogoUrl,
6041
+ alt: "",
6042
+ onError: () => {
6043
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6044
+ }
6045
+ }
6046
+ ) }) : null,
6047
+ resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
6048
+ ] }) : null,
6049
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
6050
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6051
+ "button",
6052
+ {
6053
+ type: "button",
6054
+ className: "agent-rail__new-chat",
6055
+ "aria-label": "Start a new conversation",
6056
+ disabled: !hasVisitorMessages2,
6057
+ onClick: handleReset,
6058
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
6059
+ }
6060
+ ) : null,
6061
+ onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6062
+ "button",
6063
+ {
6064
+ type: "button",
6065
+ className: "agent-rail__expand",
6066
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
6067
+ onClick: onExpandToggle,
6068
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
6069
+ }
6070
+ ) : null
6071
+ ] })
6072
+ ] }) }),
6073
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__thread", children: [
6074
+ !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
6075
+ greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6076
+ MessageBubble,
6077
+ {
6078
+ message: greeting,
6079
+ bookingDisabled: isBusy,
6080
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6081
+ onBook
6082
+ }
6083
+ ) : null,
6084
+ showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6085
+ FollowUpChips,
6086
+ {
6087
+ suggestions: state.followUps,
6088
+ disabled: isBusy,
6089
+ label: "Start here",
6090
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
6091
+ }
6092
+ ) }) : null,
6093
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6094
+ AgentActivityBubble,
6095
+ {
6096
+ brandLabel: resolvedBrandLabel,
6097
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6098
+ failed: state.phase === "error",
6099
+ steps: state.toolSteps
6100
+ }
6101
+ ) : null,
6102
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6103
+ VisitorToolResultView,
6104
+ {
6105
+ result,
6106
+ disabled: semanticSurfaceDisabled,
6107
+ onToolInput
6108
+ },
6109
+ result.id
6110
+ )),
6111
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6112
+ HumanInputCard,
6113
+ {
6114
+ request,
6115
+ onRespond: onInputResponse
6116
+ },
6117
+ request.requestId
6118
+ ))
6119
+ ] }) : null,
6120
+ visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
6121
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6122
+ MessageBubble,
6123
+ {
6124
+ message,
6125
+ bookingDisabled: isBusy,
6126
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6127
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6128
+ onBook
6129
+ }
6130
+ ),
6131
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6132
+ MessageActions,
6133
+ {
6134
+ answeredAt: message.createdAt,
6135
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6136
+ readAloud,
6137
+ receiptSteps,
6138
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6139
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6140
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6141
+ }
6142
+ ) : null,
6143
+ index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
6144
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6145
+ AgentActivityBubble,
6146
+ {
6147
+ brandLabel: resolvedBrandLabel,
6148
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6149
+ failed: state.phase === "error",
6150
+ steps: state.toolSteps
6151
+ }
6152
+ ) : null,
6153
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6154
+ VisitorToolResultView,
6155
+ {
6156
+ result,
6157
+ disabled: semanticSurfaceDisabled,
6158
+ onToolInput
6159
+ },
6160
+ result.id
6161
+ )),
6162
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6163
+ HumanInputCard,
6164
+ {
6165
+ request,
6166
+ onRespond: onInputResponse
6167
+ },
6168
+ request.requestId
6169
+ ))
6170
+ ] }) : null
6171
+ ] }, message.id)),
6172
+ streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6173
+ MessageBubble,
6174
+ {
6175
+ message: streamingMessage,
6176
+ bookingDisabled: isBusy,
6177
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6178
+ offer: state.pendingOffer,
6179
+ onBook
6180
+ }
6181
+ ) : null,
6182
+ waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
6183
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
6184
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
6185
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
6186
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
6187
+ ] }),
6188
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6189
+ ] }) : null
6190
+ ] }) }),
6191
+ showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: resolvedDisclaimerLabel }) }) : null,
6192
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6193
+ showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6194
+ "button",
6195
+ {
6196
+ type: "button",
6197
+ className: "agent-rail__jump-to-latest",
6198
+ "aria-label": "Jump to the latest message",
6199
+ title: "Jump to the latest message",
6200
+ onClick: scrollToLatest,
6201
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
6202
+ }
6203
+ ) : null,
6204
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6205
+ Composer,
6206
+ {
6207
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6208
+ disabled: isBusy,
6209
+ form: composerForm,
6210
+ placeholder: composerPlaceholder,
6211
+ onSubmit: handleSubmit
6212
+ }
6213
+ ),
6214
+ poweredByLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: poweredByLabel }) }) }) : null
6215
+ ] })
6216
+ ] }),
6217
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6218
+ receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6219
+ AnswerReceiptDialog,
5243
6220
  {
5244
6221
  brandLabel: resolvedBrandLabel,
5245
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5246
- failed: state.phase === "error",
5247
- steps: state.toolSteps
6222
+ onClose: () => setReceiptOpen(false),
6223
+ steps: receiptSteps
5248
6224
  }
5249
- ) : null,
5250
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5251
- VisitorToolResultView,
5252
- {
5253
- result,
5254
- disabled: semanticSurfaceDisabled,
5255
- onToolInput
5256
- },
5257
- result.id
5258
- )),
5259
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5260
- HumanInputCard,
5261
- {
5262
- request,
5263
- onRespond: onInputResponse
5264
- },
5265
- request.requestId
5266
- ))
5267
- ] }) : null,
5268
- visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__turn-block", children: [
5269
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5270
- MessageBubble,
5271
- {
5272
- message,
5273
- bookingDisabled: isBusy,
5274
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5275
- offer: index === lastAgentIndex ? state.pendingOffer : void 0,
5276
- onBook
5277
- }
5278
- ),
5279
- index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
5280
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5281
- AgentActivityBubble,
5282
- {
5283
- brandLabel: resolvedBrandLabel,
5284
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5285
- failed: state.phase === "error",
5286
- steps: state.toolSteps
5287
- }
5288
- ) : null,
5289
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5290
- VisitorToolResultView,
5291
- {
5292
- result,
5293
- disabled: semanticSurfaceDisabled,
5294
- onToolInput
5295
- },
5296
- result.id
5297
- )),
5298
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5299
- HumanInputCard,
5300
- {
5301
- request,
5302
- onRespond: onInputResponse
5303
- },
5304
- request.requestId
5305
- ))
5306
- ] }) : null
5307
- ] }, message.id)),
5308
- streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5309
- MessageBubble,
5310
- {
5311
- message: streamingMessage,
5312
- bookingDisabled: isBusy,
5313
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5314
- offer: state.pendingOffer,
5315
- onBook
5316
- }
5317
- ) : null,
5318
- waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BookingCardLoader, {}) : null,
5319
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
5320
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5321
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: "Something went wrong" }),
5322
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: state.error })
5323
- ] }),
5324
- onRetry ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
5325
- ] }) : null
5326
- ] }) }),
5327
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
5328
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5329
- Composer,
5330
- {
5331
- variant: expanded || mobileFullscreen ? "dock" : "default",
5332
- disabled: isBusy,
5333
- form: composerForm,
5334
- placeholder: composerPlaceholder,
5335
- onSubmit
5336
- }
5337
- ),
5338
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
5339
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "AI can make mistakes. Check important info." }),
5340
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: poweredByLabel })
5341
- ] }) })
5342
- ] })
5343
- ]
6225
+ ) : null
6226
+ ]
6227
+ }
6228
+ )
5344
6229
  }
5345
6230
  );
5346
6231
  }
5347
6232
 
5348
6233
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5349
- var import_jsx_runtime15 = require("react/jsx-runtime");
6234
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5350
6235
  function SparklesIcon() {
5351
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6236
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5352
6237
  "svg",
5353
6238
  {
5354
6239
  className: "assist-edge-tab__sparkles",
@@ -5356,21 +6241,21 @@ function SparklesIcon() {
5356
6241
  fill: "none",
5357
6242
  "aria-hidden": "true",
5358
6243
  children: [
5359
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6244
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5360
6245
  "path",
5361
6246
  {
5362
6247
  d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z",
5363
6248
  fill: "currentColor"
5364
6249
  }
5365
6250
  ),
5366
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6251
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5367
6252
  "path",
5368
6253
  {
5369
6254
  d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z",
5370
6255
  fill: "currentColor"
5371
6256
  }
5372
6257
  ),
5373
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6258
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5374
6259
  "path",
5375
6260
  {
5376
6261
  d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z",
@@ -5384,7 +6269,7 @@ function SparklesIcon() {
5384
6269
  function TabMarkIcon({ customIconUrl }) {
5385
6270
  const url = customIconUrl?.trim();
5386
6271
  if (url) {
5387
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6272
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5388
6273
  "img",
5389
6274
  {
5390
6275
  alt: "",
@@ -5394,10 +6279,10 @@ function TabMarkIcon({ customIconUrl }) {
5394
6279
  }
5395
6280
  );
5396
6281
  }
5397
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SparklesIcon, {});
6282
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
5398
6283
  }
5399
6284
  function ChevronLeftIcon() {
5400
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6285
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5401
6286
  "path",
5402
6287
  {
5403
6288
  d: "M10 4L6 8l4 4",
@@ -5408,8 +6293,8 @@ function ChevronLeftIcon() {
5408
6293
  }
5409
6294
  ) });
5410
6295
  }
5411
- function ChevronDownIcon() {
5412
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6296
+ function ChevronDownIcon2() {
6297
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5413
6298
  "path",
5414
6299
  {
5415
6300
  d: "M4 6l4 4 4-4",
@@ -5421,7 +6306,7 @@ function ChevronDownIcon() {
5421
6306
  ) });
5422
6307
  }
5423
6308
  function DragDots() {
5424
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("i", {}, index)) });
6309
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("i", {}, index)) });
5425
6310
  }
5426
6311
  var VARIANT_COPY = {
5427
6312
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5467,7 +6352,7 @@ function AssistEdgeTab({
5467
6352
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5468
6353
  colorScheme: resolvedColorScheme
5469
6354
  };
5470
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6355
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5471
6356
  "button",
5472
6357
  {
5473
6358
  type: "button",
@@ -5479,15 +6364,15 @@ function AssistEdgeTab({
5479
6364
  tabIndex: visible ? 0 : -1,
5480
6365
  onClick: onOpen,
5481
6366
  children: [
5482
- mobile ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5483
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6367
+ mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6368
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5484
6369
  "span",
5485
6370
  {
5486
6371
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5487
6372
  "aria-hidden": "true",
5488
6373
  children: [
5489
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5490
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6374
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6375
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5491
6376
  "img",
5492
6377
  {
5493
6378
  className: "assist-edge-tab__logo",
@@ -5501,11 +6386,11 @@ function AssistEdgeTab({
5501
6386
  ]
5502
6387
  }
5503
6388
  ),
5504
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
5505
- ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5506
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5507
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5508
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
6390
+ ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6391
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6392
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6393
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5509
6394
  "img",
5510
6395
  {
5511
6396
  className: "assist-edge-tab__logo",
@@ -5517,18 +6402,18 @@ function AssistEdgeTab({
5517
6402
  }
5518
6403
  ) : null
5519
6404
  ] }),
5520
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5521
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronDownIcon, {})
6405
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6406
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
5522
6407
  ] }) : null,
5523
- variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5524
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {}),
5525
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5526
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DragDots, {})
6408
+ variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6409
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
6410
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6411
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
5527
6412
  ] }) : null,
5528
- variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5529
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5530
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5531
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6413
+ variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6414
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6415
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6416
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5532
6417
  "img",
5533
6418
  {
5534
6419
  className: "assist-edge-tab__logo",
@@ -5540,16 +6425,72 @@ function AssistEdgeTab({
5540
6425
  }
5541
6426
  ) : null
5542
6427
  ] }),
5543
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5544
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {})
6428
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6429
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
5545
6430
  ] }) : null
5546
6431
  ]
5547
6432
  }
5548
6433
  );
5549
6434
  }
5550
6435
 
6436
+ // src/react/lib/agent-feedback.ts
6437
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6438
+ function findPrecedingVisitorText(messages, agentMessageId) {
6439
+ const agentIndex = messages.findIndex(
6440
+ (message) => message.id === agentMessageId && message.role === "agent"
6441
+ );
6442
+ if (agentIndex < 0) return void 0;
6443
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6444
+ const message = messages[index];
6445
+ if (message?.role === "visitor") {
6446
+ return message.text.trim() || void 0;
6447
+ }
6448
+ }
6449
+ return void 0;
6450
+ }
6451
+ function normalizeAgentFeedbackAnswerText(text) {
6452
+ const normalized = text.replace(/\s+/g, " ").trim();
6453
+ if (!normalized) return void 0;
6454
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6455
+ }
6456
+ function buildAgentAnswerFeedbackEvent(input) {
6457
+ const positive = input.rating === "positive";
6458
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6459
+ return {
6460
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6461
+ company: input.analytics.companyIndex,
6462
+ session_id: input.visitorSessionId,
6463
+ page: input.page,
6464
+ timestamp: Date.now(),
6465
+ tracking_consent: input.analytics.trackingConsent,
6466
+ feedback_value: positive ? 1 : -1,
6467
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6468
+ feedback_rating: positive ? "helpful" : "not_helpful",
6469
+ surface: "agent_panel",
6470
+ index_id: input.indexId,
6471
+ index_version: input.version,
6472
+ message_id: input.messageId,
6473
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6474
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6475
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6476
+ };
6477
+ }
6478
+ function sendAgentAnswerFeedback(eventUrl, event) {
6479
+ try {
6480
+ void fetch(eventUrl, {
6481
+ body: JSON.stringify(event),
6482
+ credentials: "omit",
6483
+ headers: { "Content-Type": "application/json" },
6484
+ keepalive: true,
6485
+ method: "POST"
6486
+ }).catch(() => {
6487
+ });
6488
+ } catch {
6489
+ }
6490
+ }
6491
+
5551
6492
  // src/react/components/AgentWidget/AgentWidget.tsx
5552
- var import_jsx_runtime16 = require("react/jsx-runtime");
6493
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5553
6494
  function AgentWidget({
5554
6495
  indexId,
5555
6496
  customerId,
@@ -5563,13 +6504,14 @@ function AgentWidget({
5563
6504
  registerPanelController = false,
5564
6505
  colorScheme = "auto",
5565
6506
  branding,
6507
+ analytics,
5566
6508
  toolResultRegistry
5567
6509
  }) {
5568
6510
  const isMobile = useIsMobile();
5569
6511
  const placement = normalizeAgentPlacement(placementInput);
5570
- const railSlotRef = (0, import_react12.useRef)(null);
5571
- const [railCollapsed, setRailCollapsed] = (0, import_react12.useState)(defaultCollapsed);
5572
- const [railExpanded, setRailExpanded] = (0, import_react12.useState)(false);
6512
+ const railSlotRef = (0, import_react15.useRef)(null);
6513
+ const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
6514
+ const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
5573
6515
  const pageShiftActive = shouldApplyPageShift({
5574
6516
  pageShift,
5575
6517
  isMobile,
@@ -5580,7 +6522,17 @@ function AgentWidget({
5580
6522
  active: pageShiftActive,
5581
6523
  railSlotRef
5582
6524
  });
5583
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6525
+ const {
6526
+ state,
6527
+ reset,
6528
+ retry,
6529
+ regenerate,
6530
+ respondToInput,
6531
+ respondToToolInput,
6532
+ submit,
6533
+ visitorSessionId,
6534
+ sessionId
6535
+ } = useAgentChat({
5584
6536
  customerId,
5585
6537
  getUnpublishedPreviewGrant,
5586
6538
  indexId,
@@ -5612,7 +6564,7 @@ function AgentWidget({
5612
6564
  } : {},
5613
6565
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5614
6566
  };
5615
- (0, import_react12.useEffect)(() => {
6567
+ (0, import_react15.useEffect)(() => {
5616
6568
  if (!registerPanelController) return;
5617
6569
  registerAgentPanelController(customerId, {
5618
6570
  open: () => setRailCollapsed(false),
@@ -5629,7 +6581,25 @@ function AgentWidget({
5629
6581
  if (isMobile) setRailCollapsed(false);
5630
6582
  await submit(message);
5631
6583
  }
5632
- (0, import_react12.useEffect)(() => {
6584
+ function handleFeedback(rating, message) {
6585
+ if (!analytics) return;
6586
+ sendAgentAnswerFeedback(
6587
+ analytics.eventUrl,
6588
+ buildAgentAnswerFeedbackEvent({
6589
+ agentSessionId: sessionId,
6590
+ analytics,
6591
+ indexId,
6592
+ messageId: message.id,
6593
+ page: window.location.href,
6594
+ query: findPrecedingVisitorText(state.messages, message.id),
6595
+ answer: message.text,
6596
+ rating,
6597
+ version: version ?? "published",
6598
+ visitorSessionId
6599
+ })
6600
+ );
6601
+ }
6602
+ (0, import_react15.useEffect)(() => {
5633
6603
  if (railCollapsed) return;
5634
6604
  const handleKeyDown = (event) => {
5635
6605
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5663,19 +6633,19 @@ function AgentWidget({
5663
6633
  window.addEventListener("keydown", handleKeyDown);
5664
6634
  return () => window.removeEventListener("keydown", handleKeyDown);
5665
6635
  }, [isMobile, railCollapsed, railExpanded]);
5666
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "webless-agent-root", children: [
5667
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6636
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
6637
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5668
6638
  "div",
5669
6639
  {
5670
6640
  className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
5671
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6641
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5672
6642
  "div",
5673
6643
  {
5674
6644
  ref: railSlotRef,
5675
6645
  className: "webless-agent-root__rail-slot",
5676
6646
  inert: railCollapsed || void 0,
5677
6647
  "aria-hidden": railCollapsed,
5678
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6648
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5679
6649
  AgentRail,
5680
6650
  {
5681
6651
  theme,
@@ -5684,6 +6654,9 @@ function AgentWidget({
5684
6654
  brandLogoUrl: branding?.logoUrl,
5685
6655
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5686
6656
  poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6657
+ disclaimerLabel: branding?.disclaimer,
6658
+ answerReceipt: branding?.answerReceipt,
6659
+ readAloud: branding?.readAloud,
5687
6660
  state,
5688
6661
  mobileFullscreen: isMobile && !railCollapsed,
5689
6662
  expanded: railExpanded,
@@ -5693,6 +6666,8 @@ function AgentWidget({
5693
6666
  onSubmit: handleSubmit,
5694
6667
  onReset: reset,
5695
6668
  onRetry: () => void retry(),
6669
+ onRegenerate: () => void regenerate(),
6670
+ onFeedback: analytics ? handleFeedback : void 0,
5696
6671
  onInputResponse: (response) => void respondToInput(response),
5697
6672
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5698
6673
  onFollowUpSelect: (label) => void handleSubmit(label),
@@ -5706,7 +6681,7 @@ function AgentWidget({
5706
6681
  )
5707
6682
  }
5708
6683
  ),
5709
- railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6684
+ railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5710
6685
  AssistEdgeTab,
5711
6686
  {
5712
6687
  variant: placement.variant,
@@ -5745,12 +6720,12 @@ function readUnpublishedPreviewBuildId(href) {
5745
6720
  }
5746
6721
 
5747
6722
  // src/embed/AgentWidget.tsx
5748
- var import_jsx_runtime17 = require("react/jsx-runtime");
6723
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5749
6724
  function AgentWidget2({
5750
6725
  manifest
5751
6726
  }) {
5752
6727
  const defaultCollapsed = manifest.version !== "unpublished";
5753
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6728
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5754
6729
  AgentWidget,
5755
6730
  {
5756
6731
  indexId: manifest.indexId,
@@ -5762,6 +6737,7 @@ function AgentWidget2({
5762
6737
  pageShift: manifest.pageShift,
5763
6738
  colorScheme: manifest.colorScheme,
5764
6739
  branding: manifest.branding,
6740
+ analytics: manifest.analytics,
5765
6741
  defaultCollapsed,
5766
6742
  registerPanelController: true
5767
6743
  }
@@ -5792,6 +6768,7 @@ function normalizeAgentTagManifest(manifest) {
5792
6768
  runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN
5793
6769
  });
5794
6770
  const branding = normalizeAgentBranding(manifest.branding);
6771
+ const analytics = normalizeAgentAnalytics(manifest.analytics);
5795
6772
  return {
5796
6773
  customerId,
5797
6774
  indexId,
@@ -5804,7 +6781,27 @@ function normalizeAgentTagManifest(manifest) {
5804
6781
  placement: normalizeAgentPlacement(manifest.placement),
5805
6782
  pageShift: manifest.pageShift ?? true,
5806
6783
  colorScheme,
5807
- ...branding ? { branding } : {}
6784
+ ...branding ? { branding } : {},
6785
+ ...analytics ? { analytics } : {}
6786
+ };
6787
+ }
6788
+ function normalizeAgentAnalytics(analytics) {
6789
+ if (!analytics) return void 0;
6790
+ const companyIndex = analytics.companyIndex?.trim() ?? "";
6791
+ const eventUrl = analytics.eventUrl?.trim() ?? "";
6792
+ if (!companyIndex || !eventUrl) return void 0;
6793
+ try {
6794
+ const parsed = new URL(eventUrl);
6795
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
6796
+ return void 0;
6797
+ }
6798
+ } catch {
6799
+ return void 0;
6800
+ }
6801
+ return {
6802
+ companyIndex,
6803
+ eventUrl,
6804
+ trackingConsent: analytics.trackingConsent === true
5808
6805
  };
5809
6806
  }
5810
6807
  function normalizeOptionalValue(value) {
@@ -5827,6 +6824,9 @@ function normalizeAgentBranding(branding) {
5827
6824
  greeting: normalizeOptionalValue(branding.greeting),
5828
6825
  composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),
5829
6826
  poweredByLabel: normalizeOptionalValue(branding.poweredByLabel),
6827
+ disclaimer: branding.disclaimer === null ? null : normalizeOptionalValue(branding.disclaimer),
6828
+ answerReceipt: branding.answerReceipt === true ? true : void 0,
6829
+ readAloud: branding.readAloud === true ? true : void 0,
5830
6830
  fontFamily: normalizeOptionalValue(branding.fontFamily),
5831
6831
  colors: colors && Object.keys(colors).length > 0 ? colors : void 0
5832
6832
  };
@@ -5834,7 +6834,7 @@ function normalizeAgentBranding(branding) {
5834
6834
  }
5835
6835
 
5836
6836
  // src/embed/mount.tsx
5837
- var import_jsx_runtime18 = require("react/jsx-runtime");
6837
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5838
6838
  var mountedHandles = /* @__PURE__ */ new Map();
5839
6839
  var latestCustomerId = null;
5840
6840
  function resolveMountHost(manifest, script) {
@@ -5864,7 +6864,7 @@ function mountAgent(input) {
5864
6864
  const host = createHost(manifest.customerId);
5865
6865
  mountTarget.append(host);
5866
6866
  const root = (0, import_client5.createRoot)(host);
5867
- root.render(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AgentWidget2, { manifest }));
6867
+ root.render(/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AgentWidget2, { manifest }));
5868
6868
  const handle = {
5869
6869
  customerId: manifest.customerId,
5870
6870
  manifest,