@webless/agent 0.6.11 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,84 +4490,695 @@ 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
- ]
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";
4519
+ }
4520
+ function stopSpeech() {
4521
+ if (!isSpeechSupported()) return;
4522
+ window.speechSynthesis.cancel();
4523
+ }
4524
+ var speechInterruptListeners = /* @__PURE__ */ new Set();
4525
+ var pageListenersAttached = false;
4526
+ var lastPathname = "";
4527
+ var originalPushState = null;
4528
+ var originalReplaceState = null;
4529
+ var patchedPushState = null;
4530
+ var patchedReplaceState = null;
4531
+ function currentPathname() {
4532
+ return window.location.pathname;
4533
+ }
4534
+ function notifySpeechInterrupts() {
4535
+ if (speechInterruptListeners.size === 0) return;
4536
+ stopSpeech();
4537
+ for (const listener of speechInterruptListeners) {
4538
+ listener();
4539
+ }
4540
+ }
4541
+ function interruptIfPathChanged(nextPath) {
4542
+ if (nextPath === lastPathname) return;
4543
+ lastPathname = nextPath;
4544
+ notifySpeechInterrupts();
4545
+ }
4546
+ function patchHistoryMethod(original) {
4547
+ return function patched(data, unused, url) {
4548
+ const result = original.call(this, data, unused, url);
4549
+ interruptIfPathChanged(currentPathname());
4550
+ return result;
4551
+ };
4552
+ }
4553
+ function historyMethodState(name) {
4554
+ return name === "pushState" ? {
4555
+ original: originalPushState,
4556
+ patched: patchedPushState,
4557
+ set(original, patched) {
4558
+ originalPushState = original;
4559
+ patchedPushState = patched;
4294
4560
  }
4295
- );
4561
+ } : {
4562
+ original: originalReplaceState,
4563
+ patched: patchedReplaceState,
4564
+ set(original, patched) {
4565
+ originalReplaceState = original;
4566
+ patchedReplaceState = patched;
4567
+ }
4568
+ };
4296
4569
  }
4297
-
4298
- // src/react/components/ToolInputCard/ToolInputCard.tsx
4299
- var import_react9 = require("react");
4300
- var import_jsx_runtime7 = require("react/jsx-runtime");
4301
- function isRecord5(value) {
4302
- return value !== null && typeof value === "object" && !Array.isArray(value);
4570
+ function patchHistoryNamed(name) {
4571
+ const state = historyMethodState(name);
4572
+ const current = history[name];
4573
+ if (state.patched && current === state.patched) return;
4574
+ const patched = patchHistoryMethod(current);
4575
+ state.set(current, patched);
4576
+ history[name] = patched;
4577
+ }
4578
+ function restoreHistoryMethod(name) {
4579
+ const state = historyMethodState(name);
4580
+ if (!state.patched || !state.original || typeof history === "undefined") {
4581
+ return false;
4582
+ }
4583
+ if (history[name] !== state.patched) return false;
4584
+ history[name] = state.original;
4585
+ state.set(null, null);
4586
+ return true;
4303
4587
  }
4304
- function pathSegments(path) {
4305
- return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
4588
+ function handlePageHide() {
4589
+ notifySpeechInterrupts();
4306
4590
  }
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;
4314
- }
4315
- current = isRecord5(current) ? current[segment] : void 0;
4591
+ function handlePopState() {
4592
+ interruptIfPathChanged(currentPathname());
4593
+ }
4594
+ function handleVisibilityChange() {
4595
+ if (document.visibilityState === "hidden") {
4596
+ notifySpeechInterrupts();
4316
4597
  }
4317
- return current;
4318
4598
  }
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 "";
4599
+ function attachPageListeners() {
4600
+ if (pageListenersAttached || typeof window === "undefined") return;
4601
+ pageListenersAttached = true;
4602
+ window.addEventListener("pagehide", handlePageHide);
4603
+ window.addEventListener("popstate", handlePopState);
4604
+ document.addEventListener("visibilitychange", handleVisibilityChange);
4327
4605
  }
4328
- function initialValues(surface) {
4329
- return Object.fromEntries(
4330
- surface.fields.map((field) => [
4331
- field.path,
4332
- initialFieldValue(field, surface)
4333
- ])
4606
+ function detachPageListeners() {
4607
+ if (!pageListenersAttached || typeof window === "undefined") return;
4608
+ window.removeEventListener("pagehide", handlePageHide);
4609
+ window.removeEventListener("popstate", handlePopState);
4610
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
4611
+ pageListenersAttached = false;
4612
+ }
4613
+ function ensureSpeechInterruptsPatched() {
4614
+ if (typeof window === "undefined") return;
4615
+ lastPathname = currentPathname();
4616
+ patchHistoryNamed("pushState");
4617
+ patchHistoryNamed("replaceState");
4618
+ attachPageListeners();
4619
+ }
4620
+ function teardownSpeechInterrupts() {
4621
+ detachPageListeners();
4622
+ restoreHistoryMethod("pushState");
4623
+ restoreHistoryMethod("replaceState");
4624
+ if (!patchedPushState && !patchedReplaceState) {
4625
+ lastPathname = "";
4626
+ }
4627
+ }
4628
+ function subscribeSpeechInterrupts(onInterrupt) {
4629
+ if (typeof window === "undefined") return () => {
4630
+ };
4631
+ ensureSpeechInterruptsPatched();
4632
+ speechInterruptListeners.add(onInterrupt);
4633
+ return () => {
4634
+ speechInterruptListeners.delete(onInterrupt);
4635
+ if (speechInterruptListeners.size === 0) {
4636
+ teardownSpeechInterrupts();
4637
+ }
4638
+ };
4639
+ }
4640
+
4641
+ // src/react/components/MessageActions/MessageActions.tsx
4642
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4643
+ function CopyIcon() {
4644
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4645
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4646
+ "rect",
4647
+ {
4648
+ x: "5.75",
4649
+ y: "5.75",
4650
+ width: "7.5",
4651
+ height: "7.5",
4652
+ rx: "1.5",
4653
+ stroke: "currentColor",
4654
+ strokeWidth: "1.5"
4655
+ }
4656
+ ),
4657
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4658
+ "path",
4659
+ {
4660
+ 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",
4661
+ stroke: "currentColor",
4662
+ strokeWidth: "1.5"
4663
+ }
4664
+ )
4665
+ ] });
4666
+ }
4667
+ function CheckIcon() {
4668
+ 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)(
4669
+ "path",
4670
+ {
4671
+ d: "M3.5 8.5l3 3 6-7",
4672
+ stroke: "currentColor",
4673
+ strokeWidth: "1.6",
4674
+ strokeLinecap: "round",
4675
+ strokeLinejoin: "round"
4676
+ }
4677
+ ) });
4678
+ }
4679
+ function ThumbUpIcon() {
4680
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4681
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4682
+ "path",
4683
+ {
4684
+ d: "M4.67 6.67v8",
4685
+ stroke: "currentColor",
4686
+ strokeWidth: "1.5",
4687
+ strokeLinecap: "round"
4688
+ }
4689
+ ),
4690
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4691
+ "path",
4692
+ {
4693
+ 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",
4694
+ stroke: "currentColor",
4695
+ strokeWidth: "1.5",
4696
+ strokeLinecap: "round",
4697
+ strokeLinejoin: "round"
4698
+ }
4699
+ )
4700
+ ] });
4701
+ }
4702
+ function ThumbDownIcon() {
4703
+ 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: [
4704
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4705
+ "path",
4706
+ {
4707
+ d: "M4.67 6.67v8",
4708
+ stroke: "currentColor",
4709
+ strokeWidth: "1.5",
4710
+ strokeLinecap: "round"
4711
+ }
4712
+ ),
4713
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4714
+ "path",
4715
+ {
4716
+ 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",
4717
+ stroke: "currentColor",
4718
+ strokeWidth: "1.5",
4719
+ strokeLinecap: "round",
4720
+ strokeLinejoin: "round"
4721
+ }
4722
+ )
4723
+ ] }) });
4724
+ }
4725
+ function RegenerateIcon() {
4726
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4727
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4728
+ "path",
4729
+ {
4730
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
4731
+ stroke: "currentColor",
4732
+ strokeWidth: "1.5",
4733
+ strokeLinecap: "round"
4734
+ }
4735
+ ),
4736
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4737
+ "path",
4738
+ {
4739
+ d: "M14 2v3.33h-3.33",
4740
+ stroke: "currentColor",
4741
+ strokeWidth: "1.5",
4742
+ strokeLinecap: "round",
4743
+ strokeLinejoin: "round"
4744
+ }
4745
+ ),
4746
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4747
+ "path",
4748
+ {
4749
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
4750
+ stroke: "currentColor",
4751
+ strokeWidth: "1.5",
4752
+ strokeLinecap: "round"
4753
+ }
4754
+ ),
4755
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4756
+ "path",
4757
+ {
4758
+ d: "M5.33 10.67H2V14",
4759
+ stroke: "currentColor",
4760
+ strokeWidth: "1.5",
4761
+ strokeLinecap: "round",
4762
+ strokeLinejoin: "round"
4763
+ }
4764
+ )
4765
+ ] });
4766
+ }
4767
+ function MoreIcon() {
4768
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4769
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
4770
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
4771
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
4772
+ ] });
4773
+ }
4774
+ function SourcesIcon() {
4775
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4776
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4777
+ "path",
4778
+ {
4779
+ 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",
4780
+ stroke: "currentColor",
4781
+ strokeWidth: "1.4",
4782
+ strokeLinecap: "round",
4783
+ strokeLinejoin: "round"
4784
+ }
4785
+ ),
4786
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4787
+ "path",
4788
+ {
4789
+ d: "M8 4.5v9",
4790
+ stroke: "currentColor",
4791
+ strokeWidth: "1.4",
4792
+ strokeLinecap: "round"
4793
+ }
4794
+ )
4795
+ ] });
4796
+ }
4797
+ function ReadAloudIcon() {
4798
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4799
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4800
+ "path",
4801
+ {
4802
+ 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",
4803
+ stroke: "currentColor",
4804
+ strokeWidth: "1.4",
4805
+ strokeLinecap: "round",
4806
+ strokeLinejoin: "round"
4807
+ }
4808
+ ),
4809
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4810
+ "path",
4811
+ {
4812
+ 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",
4813
+ stroke: "currentColor",
4814
+ strokeWidth: "1.4",
4815
+ strokeLinecap: "round"
4816
+ }
4817
+ )
4818
+ ] });
4819
+ }
4820
+ function StopIcon() {
4821
+ 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)(
4822
+ "rect",
4823
+ {
4824
+ x: "4",
4825
+ y: "4",
4826
+ width: "8",
4827
+ height: "8",
4828
+ rx: "1.5",
4829
+ stroke: "currentColor",
4830
+ strokeWidth: "1.5"
4831
+ }
4832
+ ) });
4833
+ }
4834
+ async function writeToClipboard(text) {
4835
+ try {
4836
+ await navigator.clipboard.writeText(text);
4837
+ } catch {
4838
+ const textarea = document.createElement("textarea");
4839
+ textarea.value = text;
4840
+ textarea.style.position = "fixed";
4841
+ textarea.style.opacity = "0";
4842
+ document.body.appendChild(textarea);
4843
+ textarea.select();
4844
+ document.execCommand("copy");
4845
+ textarea.remove();
4846
+ }
4847
+ }
4848
+ function formatAnsweredAt(answeredAt) {
4849
+ if (!answeredAt) return null;
4850
+ const date = new Date(answeredAt);
4851
+ if (Number.isNaN(date.getTime())) return null;
4852
+ return new Intl.DateTimeFormat(void 0, {
4853
+ dateStyle: "medium",
4854
+ timeStyle: "short"
4855
+ }).format(date);
4856
+ }
4857
+ function resolveMenuPosition(input) {
4858
+ const padding = 8;
4859
+ const { button, menuHeight, menuWidth, rail } = input;
4860
+ if (!rail) {
4861
+ return {
4862
+ left: button.left,
4863
+ top: button.top - menuHeight - 6
4864
+ };
4865
+ }
4866
+ let left = button.left - rail.left;
4867
+ let top = button.top - rail.top - menuHeight - 6;
4868
+ left = Math.min(
4869
+ Math.max(left, padding),
4870
+ rail.width - menuWidth - padding
4871
+ );
4872
+ if (top < padding) {
4873
+ top = button.bottom - rail.top + 6;
4874
+ }
4875
+ top = Math.min(top, rail.height - menuHeight - padding);
4876
+ return { left, top };
4877
+ }
4878
+ function MessageActions({
4879
+ answeredAt,
4880
+ copyText,
4881
+ disabled = false,
4882
+ onOpenReceipt,
4883
+ onRegenerate,
4884
+ onFeedback,
4885
+ readAloud = false,
4886
+ receiptSteps,
4887
+ speechText
4888
+ }) {
4889
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
4890
+ const [copied, setCopied] = (0, import_react11.useState)(false);
4891
+ const [rating, setRating] = (0, import_react11.useState)(null);
4892
+ const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4893
+ const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4894
+ const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4895
+ const [speechSupported, setSpeechSupported] = (0, import_react11.useState)(null);
4896
+ const copyTimerRef = (0, import_react11.useRef)(null);
4897
+ const menuRef = (0, import_react11.useRef)(null);
4898
+ const portaledMenuRef = (0, import_react11.useRef)(null);
4899
+ const moreButtonRef = (0, import_react11.useRef)(null);
4900
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4901
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4902
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4903
+ const readAloudEligible = Boolean(readAloud && resolvedSpeechText);
4904
+ const canReadAloud = readAloudEligible && speechSupported === true;
4905
+ const showMenu = canOpenReceipt || (speechSupported === null ? readAloudEligible : canReadAloud);
4906
+ (0, import_react11.useLayoutEffect)(() => {
4907
+ setSpeechSupported(isSpeechSupported());
4908
+ }, []);
4909
+ (0, import_react11.useLayoutEffect)(() => {
4910
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4911
+ setMenuPosition(null);
4912
+ return;
4913
+ }
4914
+ const button = moreButtonRef.current.getBoundingClientRect();
4915
+ const menu2 = portaledMenuRef.current;
4916
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
4917
+ setMenuPosition(
4918
+ resolveMenuPosition({
4919
+ button,
4920
+ menuHeight: menu2.offsetHeight,
4921
+ menuWidth: menu2.offsetWidth || 190,
4922
+ rail
4923
+ })
4924
+ );
4925
+ }, [menuOpen, menuPortalRoot]);
4926
+ (0, import_react11.useEffect)(() => {
4927
+ const unsubscribe = subscribeSpeechInterrupts(() => setSpeaking(false));
4928
+ return () => {
4929
+ unsubscribe();
4930
+ if (copyTimerRef.current !== null) {
4931
+ window.clearTimeout(copyTimerRef.current);
4932
+ }
4933
+ stopSpeech();
4934
+ };
4935
+ }, []);
4936
+ (0, import_react11.useEffect)(() => {
4937
+ if (!menuOpen) return;
4938
+ const handlePointerDown = (event) => {
4939
+ const target = event.target;
4940
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
4941
+ setMenuOpen(false);
4942
+ }
4943
+ };
4944
+ const handleKeyDown = (event) => {
4945
+ if (event.key !== "Escape") return;
4946
+ event.preventDefault();
4947
+ event.stopPropagation();
4948
+ setMenuOpen(false);
4949
+ };
4950
+ document.addEventListener("pointerdown", handlePointerDown);
4951
+ document.addEventListener("keydown", handleKeyDown);
4952
+ return () => {
4953
+ document.removeEventListener("pointerdown", handlePointerDown);
4954
+ document.removeEventListener("keydown", handleKeyDown);
4955
+ };
4956
+ }, [menuOpen]);
4957
+ function handleCopy() {
4958
+ void writeToClipboard(copyText);
4959
+ setCopied(true);
4960
+ if (copyTimerRef.current !== null) {
4961
+ window.clearTimeout(copyTimerRef.current);
4962
+ }
4963
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
4964
+ }
4965
+ function handleFeedback(next) {
4966
+ const resolved = rating === next ? null : next;
4967
+ setRating(resolved);
4968
+ if (resolved) onFeedback?.(resolved);
4969
+ }
4970
+ function handleReadAloud() {
4971
+ if (!canReadAloud) return;
4972
+ setMenuOpen(false);
4973
+ if (speaking) {
4974
+ stopSpeech();
4975
+ setSpeaking(false);
4976
+ return;
4977
+ }
4978
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4979
+ utterance.onend = () => setSpeaking(false);
4980
+ utterance.onerror = () => setSpeaking(false);
4981
+ stopSpeech();
4982
+ window.speechSynthesis.speak(utterance);
4983
+ setSpeaking(true);
4984
+ }
4985
+ const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4986
+ "div",
4987
+ {
4988
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
4989
+ ref: portaledMenuRef,
4990
+ role: "menu",
4991
+ style: menuPosition ? {
4992
+ left: `${menuPosition.left}px`,
4993
+ top: `${menuPosition.top}px`
4994
+ } : { visibility: "hidden" },
4995
+ children: [
4996
+ answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
4997
+ "Answered ",
4998
+ answeredLabel
4999
+ ] }) : null,
5000
+ canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5001
+ "button",
5002
+ {
5003
+ type: "button",
5004
+ className: "agent-message-actions__menu-item",
5005
+ role: "menuitem",
5006
+ onClick: () => {
5007
+ setMenuOpen(false);
5008
+ onOpenReceipt?.();
5009
+ },
5010
+ children: [
5011
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
5012
+ "View sources"
5013
+ ]
5014
+ }
5015
+ ) : null,
5016
+ canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5017
+ "button",
5018
+ {
5019
+ type: "button",
5020
+ className: "agent-message-actions__menu-item",
5021
+ role: "menuitem",
5022
+ onClick: handleReadAloud,
5023
+ children: [
5024
+ speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
5025
+ speaking ? "Stop reading" : "Read aloud"
5026
+ ]
5027
+ }
5028
+ ) : null
5029
+ ]
5030
+ }
5031
+ ) : null;
5032
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
5033
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5034
+ "button",
5035
+ {
5036
+ type: "button",
5037
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
5038
+ "aria-label": copied ? "Copied" : "Copy answer",
5039
+ title: copied ? "Copied" : "Copy answer",
5040
+ disabled,
5041
+ onClick: handleCopy,
5042
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
5043
+ }
5044
+ ),
5045
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5046
+ "button",
5047
+ {
5048
+ type: "button",
5049
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
5050
+ "aria-label": "Good answer",
5051
+ "aria-pressed": rating === "positive",
5052
+ title: "Good answer",
5053
+ disabled,
5054
+ onClick: () => handleFeedback("positive"),
5055
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
5056
+ }
5057
+ ),
5058
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5059
+ "button",
5060
+ {
5061
+ type: "button",
5062
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
5063
+ "aria-label": "Bad answer",
5064
+ "aria-pressed": rating === "negative",
5065
+ title: "Bad answer",
5066
+ disabled,
5067
+ onClick: () => handleFeedback("negative"),
5068
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
5069
+ }
5070
+ ),
5071
+ onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5072
+ "button",
5073
+ {
5074
+ type: "button",
5075
+ className: "agent-message-actions__button",
5076
+ "aria-label": "Regenerate answer",
5077
+ title: "Regenerate answer",
5078
+ disabled,
5079
+ onClick: onRegenerate,
5080
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
5081
+ }
5082
+ ) : null,
5083
+ showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
5084
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5085
+ "button",
5086
+ {
5087
+ ref: moreButtonRef,
5088
+ type: "button",
5089
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
5090
+ "aria-label": "More actions",
5091
+ "aria-haspopup": "menu",
5092
+ "aria-expanded": menuOpen,
5093
+ title: "More actions",
5094
+ disabled,
5095
+ onClick: () => setMenuOpen((open) => !open),
5096
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
5097
+ }
5098
+ ),
5099
+ menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
5100
+ ] }) : null
5101
+ ] });
5102
+ }
5103
+
5104
+ // src/react/components/HumanInputCard/HumanInputCard.tsx
5105
+ var import_react13 = require("react");
5106
+
5107
+ // src/react/components/ConfirmationCard/ConfirmationCard.tsx
5108
+ var import_jsx_runtime8 = require("react/jsx-runtime");
5109
+ function ConfirmationCard({
5110
+ disabled = false,
5111
+ request,
5112
+ onRespond
5113
+ }) {
5114
+ const options = request.options ?? [];
5115
+ const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
5116
+ const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
5117
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5118
+ "section",
5119
+ {
5120
+ className: "confirmation-card",
5121
+ "aria-labelledby": `confirmation-${request.requestId}`,
5122
+ children: [
5123
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
5124
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
5125
+ prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
5126
+ ] }),
5127
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5128
+ "button",
5129
+ {
5130
+ type: "button",
5131
+ className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
5132
+ disabled,
5133
+ onClick: () => onRespond?.({
5134
+ requestId: request.requestId,
5135
+ optionId: option.id
5136
+ }),
5137
+ children: option.label
5138
+ },
5139
+ option.id
5140
+ )) })
5141
+ ]
5142
+ }
5143
+ );
5144
+ }
5145
+
5146
+ // src/react/components/ToolInputCard/ToolInputCard.tsx
5147
+ var import_react12 = require("react");
5148
+ var import_jsx_runtime9 = require("react/jsx-runtime");
5149
+ function isRecord5(value) {
5150
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5151
+ }
5152
+ function pathSegments(path) {
5153
+ return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
5154
+ }
5155
+ function valueAtPath(root, path) {
5156
+ let current = root;
5157
+ for (const segment of pathSegments(path)) {
5158
+ if (Array.isArray(current)) {
5159
+ const index = Number(segment);
5160
+ current = Number.isInteger(index) ? current[index] : void 0;
5161
+ continue;
5162
+ }
5163
+ current = isRecord5(current) ? current[segment] : void 0;
5164
+ }
5165
+ return current;
5166
+ }
5167
+ function initialFieldValue(field, surface) {
5168
+ const supplied = valueAtPath(surface.values, field.path);
5169
+ if (supplied !== void 0) return supplied;
5170
+ if (field.defaultValue !== void 0) return field.defaultValue;
5171
+ if (field.kind === "checkbox" || field.kind === "confirmation") return false;
5172
+ if (field.kind === "multi-select") return [];
5173
+ if (field.kind === "range") return field.min ?? 0;
5174
+ return "";
5175
+ }
5176
+ function initialValues(surface) {
5177
+ return Object.fromEntries(
5178
+ surface.fields.map((field) => [
5179
+ field.path,
5180
+ initialFieldValue(field, surface)
5181
+ ])
4334
5182
  );
4335
5183
  }
4336
5184
  function cloneJsonValue(value) {
@@ -4421,7 +5269,7 @@ function FieldDescription({
4421
5269
  field,
4422
5270
  id
4423
5271
  }) {
4424
- return field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5272
+ return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4425
5273
  }
4426
5274
  function ChoiceField({
4427
5275
  field,
@@ -4440,7 +5288,7 @@ function ChoiceField({
4440
5288
  const selectedIndex = options.findIndex(
4441
5289
  (option) => valuesMatch(option.value, value)
4442
5290
  );
4443
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5291
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4444
5292
  "select",
4445
5293
  {
4446
5294
  id,
@@ -4455,13 +5303,13 @@ function ChoiceField({
4455
5303
  if (option) onChange(option.value);
4456
5304
  },
4457
5305
  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)))
5306
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
5307
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
4460
5308
  ]
4461
5309
  }
4462
5310
  );
4463
5311
  }
4464
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5312
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4465
5313
  "div",
4466
5314
  {
4467
5315
  className: "tool-input-card__choices",
@@ -4472,8 +5320,8 @@ function ChoiceField({
4472
5320
  "aria-required": field.required,
4473
5321
  children: options.map((option, index) => {
4474
5322
  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)(
5323
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
5324
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4477
5325
  "input",
4478
5326
  {
4479
5327
  type: multiple ? "checkbox" : "radio",
@@ -4495,7 +5343,7 @@ function ChoiceField({
4495
5343
  }
4496
5344
  }
4497
5345
  ),
4498
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
5346
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
4499
5347
  ] }, optionKey(option));
4500
5348
  })
4501
5349
  }
@@ -4515,9 +5363,9 @@ function ToolField({
4515
5363
  error ? `${id}-error` : ""
4516
5364
  ].filter(Boolean).join(" ");
4517
5365
  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)(
5366
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
5367
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
5368
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4521
5369
  "input",
4522
5370
  {
4523
5371
  id,
@@ -4530,17 +5378,17 @@ function ToolField({
4530
5378
  onChange: (event) => onChange(event.target.checked)
4531
5379
  }
4532
5380
  ),
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
5381
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
5382
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
5383
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
4536
5384
  ] })
4537
5385
  ] }),
4538
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5386
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4539
5387
  ] });
4540
5388
  }
4541
- const label = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
5389
+ const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
4542
5390
  field.label,
4543
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5391
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4544
5392
  ] });
4545
5393
  const common = {
4546
5394
  id,
@@ -4552,7 +5400,7 @@ function ToolField({
4552
5400
  };
4553
5401
  let control;
4554
5402
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4555
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5403
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4556
5404
  ChoiceField,
4557
5405
  {
4558
5406
  field,
@@ -4566,7 +5414,7 @@ function ToolField({
4566
5414
  }
4567
5415
  );
4568
5416
  } else if (field.kind === "textarea" || field.kind === "json") {
4569
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5417
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4570
5418
  "textarea",
4571
5419
  {
4572
5420
  ...common,
@@ -4580,8 +5428,8 @@ function ToolField({
4580
5428
  );
4581
5429
  } else if (field.kind === "range") {
4582
5430
  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)(
5431
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
5432
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4585
5433
  "input",
4586
5434
  {
4587
5435
  ...common,
@@ -4593,11 +5441,11 @@ function ToolField({
4593
5441
  onChange: (event) => onChange(Number(event.target.value))
4594
5442
  }
4595
5443
  ),
4596
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("output", { htmlFor: id, children: numericValue })
5444
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
4597
5445
  ] });
4598
5446
  } else {
4599
5447
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4600
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5448
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4601
5449
  "input",
4602
5450
  {
4603
5451
  ...common,
@@ -4615,11 +5463,11 @@ function ToolField({
4615
5463
  }
4616
5464
  );
4617
5465
  }
4618
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
5466
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
4619
5467
  label,
4620
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldDescription, { field, id: `${id}-description` }),
5468
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
4621
5469
  control,
4622
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5470
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4623
5471
  ] });
4624
5472
  }
4625
5473
  function ToolInputCard({
@@ -4627,11 +5475,11 @@ function ToolInputCard({
4627
5475
  surface,
4628
5476
  onSubmit
4629
5477
  }) {
4630
- const [values, setValues] = (0, import_react9.useState)(
5478
+ const [values, setValues] = (0, import_react12.useState)(
4631
5479
  () => initialValues(surface)
4632
5480
  );
4633
- const [touched, setTouched] = (0, import_react9.useState)(() => /* @__PURE__ */ new Set());
4634
- const [submitted, setSubmitted] = (0, import_react9.useState)(false);
5481
+ const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
5482
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
4635
5483
  const errors = Object.fromEntries(
4636
5484
  surface.fields.map((field) => [
4637
5485
  field.path,
@@ -4656,14 +5504,14 @@ function ToolInputCard({
4656
5504
  onSubmit?.(surface, result);
4657
5505
  }
4658
5506
  if (submitted) {
4659
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5507
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4660
5508
  "section",
4661
5509
  {
4662
5510
  className: "tool-input-card tool-input-card--submitted",
4663
5511
  role: "status",
4664
5512
  children: [
4665
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
4666
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5513
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
5514
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
4667
5515
  surface.title,
4668
5516
  " submitted"
4669
5517
  ] })
@@ -4671,18 +5519,18 @@ function ToolInputCard({
4671
5519
  }
4672
5520
  );
4673
5521
  }
4674
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5522
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4675
5523
  "section",
4676
5524
  {
4677
5525
  className: "tool-input-card",
4678
5526
  "aria-labelledby": `tool-input-${surface.id}`,
4679
5527
  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
5528
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
5529
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5530
+ surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
4683
5531
  ] }),
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)(
5532
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
5533
+ /* @__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
5534
  ToolField,
4687
5535
  {
4688
5536
  disabled,
@@ -4695,8 +5543,8 @@ function ToolInputCard({
4695
5543
  },
4696
5544
  field.path
4697
5545
  )) }),
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)(
5546
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
5547
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4700
5548
  "button",
4701
5549
  {
4702
5550
  type: "button",
@@ -4709,7 +5557,7 @@ function ToolInputCard({
4709
5557
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4710
5558
  }
4711
5559
  ) : null,
4712
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5560
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4713
5561
  ] })
4714
5562
  ] })
4715
5563
  ]
@@ -4718,17 +5566,17 @@ function ToolInputCard({
4718
5566
  }
4719
5567
 
4720
5568
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4721
- var import_jsx_runtime8 = require("react/jsx-runtime");
5569
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4722
5570
  function HumanInputCard({
4723
5571
  disabled = false,
4724
5572
  request,
4725
5573
  onRespond
4726
5574
  }) {
4727
- const [text, setText] = (0, import_react10.useState)("");
5575
+ const [text, setText] = (0, import_react13.useState)("");
4728
5576
  const options = request.options ?? [];
4729
5577
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4730
5578
  if (request.ui) {
4731
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5579
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4732
5580
  ToolInputCard,
4733
5581
  {
4734
5582
  disabled,
@@ -4738,7 +5586,7 @@ function HumanInputCard({
4738
5586
  );
4739
5587
  }
4740
5588
  if (options.length > 0) {
4741
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5589
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4742
5590
  ConfirmationCard,
4743
5591
  {
4744
5592
  disabled,
@@ -4753,17 +5601,17 @@ function HumanInputCard({
4753
5601
  if (!value || disabled) return;
4754
5602
  onRespond?.({ requestId: request.requestId, text: value });
4755
5603
  }
4756
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5604
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4757
5605
  "section",
4758
5606
  {
4759
5607
  className: "human-input-card",
4760
5608
  "aria-labelledby": `human-input-${request.requestId}`,
4761
5609
  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)(
5610
+ /* @__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 }) }),
5611
+ showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
5612
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5613
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
5614
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4767
5615
  "input",
4768
5616
  {
4769
5617
  id: `human-input-text-${request.requestId}`,
@@ -4772,39 +5620,39 @@ function HumanInputCard({
4772
5620
  onChange: (event) => setText(event.target.value)
4773
5621
  }
4774
5622
  ),
4775
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5623
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4776
5624
  ] })
4777
5625
  ] }) : 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
5626
+ !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
5627
  ]
4780
5628
  }
4781
5629
  );
4782
5630
  }
4783
5631
 
4784
5632
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4785
- var import_jsx_runtime9 = require("react/jsx-runtime");
5633
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4786
5634
  function CollectionResultCard({
4787
5635
  result
4788
5636
  }) {
4789
5637
  const empty = result.items.length === 0;
4790
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5638
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4791
5639
  "section",
4792
5640
  {
4793
5641
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4794
5642
  "aria-label": result.title,
4795
5643
  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 })
5644
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
5645
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5646
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
4799
5647
  ] }),
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 })
5648
+ 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: [
5649
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
5650
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
5651
+ item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
5652
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
5653
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
4806
5654
  ] }, `${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
5655
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4808
5656
  ] }, item.title)) })
4809
5657
  ]
4810
5658
  }
@@ -4812,26 +5660,26 @@ function CollectionResultCard({
4812
5660
  }
4813
5661
 
4814
5662
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4815
- var import_jsx_runtime10 = require("react/jsx-runtime");
5663
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4816
5664
  function EntityResultCard({
4817
5665
  result
4818
5666
  }) {
4819
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5667
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4820
5668
  "section",
4821
5669
  {
4822
5670
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4823
5671
  "aria-label": result.title,
4824
5672
  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 })
5673
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
5674
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5675
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
4828
5676
  ] }),
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 })
5677
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
5678
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
5679
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
5680
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
4833
5681
  ] }, `${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)(
5682
+ 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
5683
  "a",
4836
5684
  {
4837
5685
  href: link.href,
@@ -4847,24 +5695,24 @@ function EntityResultCard({
4847
5695
  }
4848
5696
 
4849
5697
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4850
- var import_jsx_runtime11 = require("react/jsx-runtime");
5698
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4851
5699
  function SignatureResultCard({
4852
5700
  result
4853
5701
  }) {
4854
5702
  const primaryLink = result.links?.[0];
4855
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5703
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4856
5704
  "section",
4857
5705
  {
4858
5706
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4859
5707
  "aria-label": result.title,
4860
5708
  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 })
5709
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
5710
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5711
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
4864
5712
  ] }),
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)(
5713
+ result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5714
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
5715
+ primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4868
5716
  "a",
4869
5717
  {
4870
5718
  className: "signature-result-card__cta",
@@ -4880,26 +5728,26 @@ function SignatureResultCard({
4880
5728
  }
4881
5729
 
4882
5730
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4883
- var import_jsx_runtime12 = require("react/jsx-runtime");
5731
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4884
5732
  function ToolResultCard({
4885
5733
  result
4886
5734
  }) {
4887
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5735
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4888
5736
  "section",
4889
5737
  {
4890
5738
  className: `tool-result-card tool-result-card--${result.status}`,
4891
5739
  "aria-label": result.title,
4892
5740
  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 })
5741
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
5742
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5743
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
4896
5744
  ] }),
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 })
5745
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
5746
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5747
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
5748
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
4901
5749
  ] }, `${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)(
5750
+ 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
5751
  "a",
4904
5752
  {
4905
5753
  href: link.href,
@@ -4915,14 +5763,14 @@ function ToolResultCard({
4915
5763
  }
4916
5764
 
4917
5765
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4918
- var import_jsx_runtime13 = require("react/jsx-runtime");
5766
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4919
5767
  function VisitorToolResultView({
4920
5768
  disabled = false,
4921
5769
  onToolInput,
4922
5770
  result
4923
5771
  }) {
4924
5772
  if (result.kind === "input") {
4925
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5773
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4926
5774
  ToolInputCard,
4927
5775
  {
4928
5776
  disabled,
@@ -4932,16 +5780,16 @@ function VisitorToolResultView({
4932
5780
  );
4933
5781
  }
4934
5782
  if (result.kind === "entity") {
4935
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EntityResultCard, { result });
5783
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
4936
5784
  }
4937
5785
  if (result.kind === "collection") {
4938
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollectionResultCard, { result });
5786
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
4939
5787
  }
4940
5788
  if (result.kind === "signature") {
4941
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SignatureResultCard, { result });
5789
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
4942
5790
  }
4943
5791
  if (result.kind === "summary") {
4944
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResultCard, { result });
5792
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
4945
5793
  }
4946
5794
  return null;
4947
5795
  }
@@ -4950,9 +5798,9 @@ function isRenderableVisitorToolResult(result) {
4950
5798
  }
4951
5799
 
4952
5800
  // src/react/components/AgentRail/AgentRail.tsx
4953
- var import_jsx_runtime14 = require("react/jsx-runtime");
5801
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4954
5802
  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)(
5803
+ 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
5804
  "path",
4957
5805
  {
4958
5806
  d: "M3.5 8h9",
@@ -4962,8 +5810,8 @@ function MinimizeIcon() {
4962
5810
  }
4963
5811
  ) });
4964
5812
  }
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)(
5813
+ function CloseIcon2() {
5814
+ 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
5815
  "path",
4968
5816
  {
4969
5817
  d: "M4 4l8 8M12 4l-8 8",
@@ -4974,7 +5822,7 @@ function CloseIcon() {
4974
5822
  ) });
4975
5823
  }
4976
5824
  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)(
5825
+ 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
5826
  "path",
4979
5827
  {
4980
5828
  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 +5834,7 @@ function NewChatIcon() {
4986
5834
  ) });
4987
5835
  }
4988
5836
  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)(
5837
+ 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
5838
  "path",
4991
5839
  {
4992
5840
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4998,7 +5846,7 @@ function ExpandIcon() {
4998
5846
  ) });
4999
5847
  }
5000
5848
  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)(
5849
+ 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
5850
  "path",
5003
5851
  {
5004
5852
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -5009,13 +5857,30 @@ function RestoreIcon() {
5009
5857
  }
5010
5858
  ) });
5011
5859
  }
5860
+ function ChevronDownIcon() {
5861
+ 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)(
5862
+ "path",
5863
+ {
5864
+ d: "M4 6.5l4 4 4-4",
5865
+ stroke: "currentColor",
5866
+ strokeWidth: "1.6",
5867
+ strokeLinecap: "round",
5868
+ strokeLinejoin: "round"
5869
+ }
5870
+ ) });
5871
+ }
5872
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
5012
5873
  function AgentRail({
5013
5874
  state,
5014
5875
  theme,
5015
5876
  colorScheme = "auto",
5016
5877
  brandLabel = "",
5017
5878
  brandLogoUrl,
5018
- poweredByLabel = "Powered by Webless",
5879
+ poweredByLabel,
5880
+ disclaimerLabel,
5881
+ disclaimerLink,
5882
+ answerReceipt = false,
5883
+ readAloud = false,
5019
5884
  composerPlaceholder = "Ask anything\u2026",
5020
5885
  mobileFullscreen = false,
5021
5886
  expanded = false,
@@ -5024,16 +5889,26 @@ function AgentRail({
5024
5889
  onExpandToggle,
5025
5890
  onReset,
5026
5891
  onRetry,
5892
+ onRegenerate,
5893
+ onFeedback,
5027
5894
  onSubmit,
5028
5895
  onFollowUpSelect,
5029
5896
  onBook,
5030
5897
  onInputResponse,
5031
5898
  onToolInput
5032
5899
  }) {
5033
- const transcriptRef = (0, import_react11.useRef)(null);
5900
+ const railRef = (0, import_react14.useRef)(null);
5901
+ const overlayRef = (0, import_react14.useRef)(null);
5902
+ const transcriptRef = (0, import_react14.useRef)(null);
5903
+ const pinnedToBottomRef = (0, import_react14.useRef)(true);
5904
+ const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
5905
+ const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
5906
+ const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
5907
+ const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
5034
5908
  const resolvedBrandLabel = brandLabel.trim();
5035
5909
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
5036
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react11.useState)(null);
5910
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5911
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
5037
5912
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
5038
5913
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
5039
5914
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -5084,10 +5959,15 @@ function AgentRail({
5084
5959
  );
5085
5960
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
5086
5961
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
5087
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5962
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5963
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
5088
5964
  const hasVisitorMessages2 = state.messages.some(
5089
5965
  (message) => message.role === "visitor"
5090
5966
  );
5967
+ const hasAgentResponseAfterVisitor = state.messages.some(
5968
+ (message) => message.role === "agent" && message.id !== "greeting"
5969
+ );
5970
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
5091
5971
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
5092
5972
  const greeting = state.messages.find(
5093
5973
  (message) => message.role === "agent" && message.id === "greeting"
@@ -5109,6 +5989,7 @@ function AgentRail({
5109
5989
  }
5110
5990
  }
5111
5991
  const lastIsAgent = lastMessage?.role === "agent";
5992
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
5112
5993
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
5113
5994
  createdAt: 0,
5114
5995
  id: "streaming-response",
@@ -5135,10 +6016,36 @@ function AgentRail({
5135
6016
  hasPendingConfirmation,
5136
6017
  enabled: lastIsAgent && !isBusy
5137
6018
  });
5138
- (0, import_react11.useEffect)(() => {
6019
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
6020
+ (0, import_react14.useEffect)(() => {
6021
+ if (state.phase !== "complete") {
6022
+ setReceiptOpen(false);
6023
+ }
6024
+ }, [state.phase]);
6025
+ function handleSubmit(message) {
6026
+ setReceiptOpen(false);
6027
+ onSubmit?.(message);
6028
+ }
6029
+ function handleRegenerate() {
6030
+ setReceiptOpen(false);
6031
+ onRegenerate?.();
6032
+ }
6033
+ function handleReset() {
6034
+ setReceiptOpen(false);
6035
+ onReset?.();
6036
+ }
6037
+ function handleFollowUpSelect(label) {
6038
+ setReceiptOpen(false);
6039
+ onFollowUpSelect?.(label);
6040
+ }
6041
+ (0, import_react14.useEffect)(() => {
5139
6042
  const node = transcriptRef.current;
5140
6043
  if (!node) return;
5141
- node.scrollTop = node.scrollHeight;
6044
+ const lastMessage2 = state.messages.at(-1);
6045
+ const visitorJustSent = lastMessage2?.role === "visitor";
6046
+ if (pinnedToBottomRef.current || visitorJustSent) {
6047
+ node.scrollTop = node.scrollHeight;
6048
+ }
5142
6049
  }, [
5143
6050
  state.messages,
5144
6051
  state.toolSteps,
@@ -5146,10 +6053,75 @@ function AgentRail({
5146
6053
  state.followUps,
5147
6054
  state.journey
5148
6055
  ]);
5149
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
6056
+ (0, import_react14.useEffect)(() => {
6057
+ const node = transcriptRef.current;
6058
+ if (!node) return;
6059
+ const handleScroll = () => {
6060
+ if (node.clientHeight === 0) return;
6061
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
6062
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
6063
+ pinnedToBottomRef.current = pinned;
6064
+ setShowJumpToLatest(!pinned);
6065
+ };
6066
+ node.addEventListener("scroll", handleScroll, { passive: true });
6067
+ handleScroll();
6068
+ return () => node.removeEventListener("scroll", handleScroll);
6069
+ }, []);
6070
+ (0, import_react14.useEffect)(() => {
6071
+ const node = transcriptRef.current;
6072
+ if (!node) return;
6073
+ const observer = new ResizeObserver(() => {
6074
+ if (node.clientHeight === 0) return;
6075
+ if (pinnedToBottomRef.current) {
6076
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
6077
+ }
6078
+ });
6079
+ observer.observe(node);
6080
+ return () => observer.disconnect();
6081
+ }, []);
6082
+ (0, import_react14.useEffect)(() => {
6083
+ if (!receiptOpen) {
6084
+ lockedTranscriptScrollTopRef.current = null;
6085
+ return;
6086
+ }
6087
+ const node = transcriptRef.current;
6088
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
6089
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
6090
+ }, [receiptOpen]);
6091
+ function openReceipt() {
6092
+ const node = transcriptRef.current;
6093
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
6094
+ setReceiptOpen(true);
6095
+ }
6096
+ function scrollToLatest() {
6097
+ const node = transcriptRef.current;
6098
+ if (!node) return;
6099
+ pinnedToBottomRef.current = true;
6100
+ setShowJumpToLatest(false);
6101
+ const reduceMotion = window.matchMedia(
6102
+ "(prefers-reduced-motion: reduce)"
6103
+ ).matches;
6104
+ if (reduceMotion) {
6105
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
6106
+ return;
6107
+ }
6108
+ smoothScrollToLatestRef.current = true;
6109
+ const settle = () => {
6110
+ smoothScrollToLatestRef.current = false;
6111
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
6112
+ const pinned = distanceFromBottom < 48;
6113
+ pinnedToBottomRef.current = pinned;
6114
+ setShowJumpToLatest(!pinned);
6115
+ };
6116
+ node.addEventListener("scrollend", settle, { once: true });
6117
+ window.setTimeout(settle, 900);
6118
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
6119
+ }
6120
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5150
6121
  "aside",
5151
6122
  {
5152
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
6123
+ ref: railRef,
6124
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
5153
6125
  "data-not-typeset": "",
5154
6126
  "data-color-scheme": resolvedColorScheme,
5155
6127
  spellCheck: false,
@@ -5159,196 +6131,242 @@ function AgentRail({
5159
6131
  autoFocus: mobileFullscreen || expanded,
5160
6132
  role: mobileFullscreen || expanded ? "dialog" : void 0,
5161
6133
  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);
6134
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6135
+ AgentRailOverlayContext.Provider,
6136
+ {
6137
+ value: { railRef, overlayRef },
6138
+ children: [
6139
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
6140
+ /* @__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: [
6141
+ onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6142
+ "button",
6143
+ {
6144
+ type: "button",
6145
+ className: "agent-rail__collapse",
6146
+ "aria-label": "Collapse assist",
6147
+ onClick: onCollapse,
6148
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
6149
+ }
6150
+ ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6151
+ "button",
6152
+ {
6153
+ type: "button",
6154
+ className: "agent-rail__close",
6155
+ "aria-label": "Close agent",
6156
+ onClick: onClose,
6157
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
6158
+ }
6159
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
6160
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
6161
+ showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6162
+ "img",
6163
+ {
6164
+ className: "agent-rail__brand-logo",
6165
+ src: resolvedBrandLogoUrl,
6166
+ alt: "",
6167
+ onError: () => {
6168
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6169
+ }
6170
+ }
6171
+ ) }) : null,
6172
+ resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
6173
+ ] }) : null,
6174
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
6175
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6176
+ "button",
6177
+ {
6178
+ type: "button",
6179
+ className: "agent-rail__new-chat",
6180
+ "aria-label": "Start a new conversation",
6181
+ disabled: !hasVisitorMessages2,
6182
+ onClick: handleReset,
6183
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
6184
+ }
6185
+ ) : null,
6186
+ onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6187
+ "button",
6188
+ {
6189
+ type: "button",
6190
+ className: "agent-rail__expand",
6191
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
6192
+ onClick: onExpandToggle,
6193
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
6194
+ }
6195
+ ) : null
6196
+ ] })
6197
+ ] }) }),
6198
+ /* @__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: [
6199
+ !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
6200
+ greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6201
+ MessageBubble,
6202
+ {
6203
+ message: greeting,
6204
+ bookingDisabled: isBusy,
6205
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6206
+ onBook
6207
+ }
6208
+ ) : null,
6209
+ showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6210
+ FollowUpChips,
6211
+ {
6212
+ suggestions: state.followUps,
6213
+ disabled: isBusy,
6214
+ label: "Start here",
6215
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
6216
+ }
6217
+ ) }) : null,
6218
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6219
+ AgentActivityBubble,
6220
+ {
6221
+ brandLabel: resolvedBrandLabel,
6222
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6223
+ failed: state.phase === "error",
6224
+ steps: state.toolSteps
6225
+ }
6226
+ ) : null,
6227
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6228
+ VisitorToolResultView,
6229
+ {
6230
+ result,
6231
+ disabled: semanticSurfaceDisabled,
6232
+ onToolInput
6233
+ },
6234
+ result.id
6235
+ )),
6236
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6237
+ HumanInputCard,
6238
+ {
6239
+ request,
6240
+ onRespond: onInputResponse
6241
+ },
6242
+ request.requestId
6243
+ ))
6244
+ ] }) : null,
6245
+ visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
6246
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6247
+ MessageBubble,
6248
+ {
6249
+ message,
6250
+ bookingDisabled: isBusy,
6251
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6252
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6253
+ onBook
6254
+ }
6255
+ ),
6256
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6257
+ MessageActions,
6258
+ {
6259
+ answeredAt: message.createdAt,
6260
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6261
+ readAloud,
6262
+ receiptSteps,
6263
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6264
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6265
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6266
+ }
6267
+ ) : null,
6268
+ index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
6269
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6270
+ AgentActivityBubble,
6271
+ {
6272
+ brandLabel: resolvedBrandLabel,
6273
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6274
+ failed: state.phase === "error",
6275
+ steps: state.toolSteps
6276
+ }
6277
+ ) : null,
6278
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6279
+ VisitorToolResultView,
6280
+ {
6281
+ result,
6282
+ disabled: semanticSurfaceDisabled,
6283
+ onToolInput
6284
+ },
6285
+ result.id
6286
+ )),
6287
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6288
+ HumanInputCard,
6289
+ {
6290
+ request,
6291
+ onRespond: onInputResponse
6292
+ },
6293
+ request.requestId
6294
+ ))
6295
+ ] }) : null
6296
+ ] }, message.id)),
6297
+ streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6298
+ MessageBubble,
6299
+ {
6300
+ message: streamingMessage,
6301
+ bookingDisabled: isBusy,
6302
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6303
+ offer: state.pendingOffer,
6304
+ onBook
6305
+ }
6306
+ ) : null,
6307
+ waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
6308
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
6309
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
6310
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
6311
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
6312
+ ] }),
6313
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6314
+ ] }) : null
6315
+ ] }) }),
6316
+ showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: disclaimerLink ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6317
+ "a",
6318
+ {
6319
+ href: disclaimerLink,
6320
+ rel: "noopener noreferrer",
6321
+ target: "_blank",
6322
+ children: resolvedDisclaimerLabel
5192
6323
  }
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,
6324
+ ) : resolvedDisclaimerLabel }) }) : null,
6325
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6326
+ showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6327
+ "button",
6328
+ {
6329
+ type: "button",
6330
+ className: "agent-rail__jump-to-latest",
6331
+ "aria-label": "Jump to the latest message",
6332
+ title: "Jump to the latest message",
6333
+ onClick: scrollToLatest,
6334
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
6335
+ }
6336
+ ) : null,
6337
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6338
+ Composer,
6339
+ {
6340
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6341
+ disabled: isBusy,
6342
+ form: composerForm,
6343
+ placeholder: composerPlaceholder,
6344
+ onSubmit: handleSubmit
6345
+ }
6346
+ ),
6347
+ 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
6348
+ ] })
6349
+ ] }),
6350
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6351
+ receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6352
+ AnswerReceiptDialog,
5243
6353
  {
5244
6354
  brandLabel: resolvedBrandLabel,
5245
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5246
- failed: state.phase === "error",
5247
- steps: state.toolSteps
6355
+ onClose: () => setReceiptOpen(false),
6356
+ steps: receiptSteps
5248
6357
  }
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
- ]
6358
+ ) : null
6359
+ ]
6360
+ }
6361
+ )
5344
6362
  }
5345
6363
  );
5346
6364
  }
5347
6365
 
5348
6366
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5349
- var import_jsx_runtime15 = require("react/jsx-runtime");
6367
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5350
6368
  function SparklesIcon() {
5351
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6369
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5352
6370
  "svg",
5353
6371
  {
5354
6372
  className: "assist-edge-tab__sparkles",
@@ -5356,21 +6374,21 @@ function SparklesIcon() {
5356
6374
  fill: "none",
5357
6375
  "aria-hidden": "true",
5358
6376
  children: [
5359
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6377
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5360
6378
  "path",
5361
6379
  {
5362
6380
  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
6381
  fill: "currentColor"
5364
6382
  }
5365
6383
  ),
5366
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6384
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5367
6385
  "path",
5368
6386
  {
5369
6387
  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
6388
  fill: "currentColor"
5371
6389
  }
5372
6390
  ),
5373
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6391
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5374
6392
  "path",
5375
6393
  {
5376
6394
  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 +6402,7 @@ function SparklesIcon() {
5384
6402
  function TabMarkIcon({ customIconUrl }) {
5385
6403
  const url = customIconUrl?.trim();
5386
6404
  if (url) {
5387
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6405
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5388
6406
  "img",
5389
6407
  {
5390
6408
  alt: "",
@@ -5394,10 +6412,10 @@ function TabMarkIcon({ customIconUrl }) {
5394
6412
  }
5395
6413
  );
5396
6414
  }
5397
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SparklesIcon, {});
6415
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
5398
6416
  }
5399
6417
  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)(
6418
+ 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
6419
  "path",
5402
6420
  {
5403
6421
  d: "M10 4L6 8l4 4",
@@ -5408,8 +6426,8 @@ function ChevronLeftIcon() {
5408
6426
  }
5409
6427
  ) });
5410
6428
  }
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)(
6429
+ function ChevronDownIcon2() {
6430
+ 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
6431
  "path",
5414
6432
  {
5415
6433
  d: "M4 6l4 4 4-4",
@@ -5421,7 +6439,7 @@ function ChevronDownIcon() {
5421
6439
  ) });
5422
6440
  }
5423
6441
  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)) });
6442
+ 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
6443
  }
5426
6444
  var VARIANT_COPY = {
5427
6445
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5467,7 +6485,7 @@ function AssistEdgeTab({
5467
6485
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5468
6486
  colorScheme: resolvedColorScheme
5469
6487
  };
5470
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6488
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5471
6489
  "button",
5472
6490
  {
5473
6491
  type: "button",
@@ -5479,15 +6497,15 @@ function AssistEdgeTab({
5479
6497
  tabIndex: visible ? 0 : -1,
5480
6498
  onClick: onOpen,
5481
6499
  children: [
5482
- mobile ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5483
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6500
+ mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6501
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5484
6502
  "span",
5485
6503
  {
5486
6504
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5487
6505
  "aria-hidden": "true",
5488
6506
  children: [
5489
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5490
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6507
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6508
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5491
6509
  "img",
5492
6510
  {
5493
6511
  className: "assist-edge-tab__logo",
@@ -5501,11 +6519,11 @@ function AssistEdgeTab({
5501
6519
  ]
5502
6520
  }
5503
6521
  ),
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)(
6522
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
6523
+ ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6524
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6525
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6526
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5509
6527
  "img",
5510
6528
  {
5511
6529
  className: "assist-edge-tab__logo",
@@ -5517,18 +6535,18 @@ function AssistEdgeTab({
5517
6535
  }
5518
6536
  ) : null
5519
6537
  ] }),
5520
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5521
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronDownIcon, {})
6538
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6539
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
5522
6540
  ] }) : 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, {})
6541
+ variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6542
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
6543
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6544
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
5527
6545
  ] }) : 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)(
6546
+ variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6547
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6548
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6549
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5532
6550
  "img",
5533
6551
  {
5534
6552
  className: "assist-edge-tab__logo",
@@ -5540,16 +6558,72 @@ function AssistEdgeTab({
5540
6558
  }
5541
6559
  ) : null
5542
6560
  ] }),
5543
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5544
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {})
6561
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6562
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
5545
6563
  ] }) : null
5546
6564
  ]
5547
6565
  }
5548
6566
  );
5549
6567
  }
5550
6568
 
6569
+ // src/react/lib/agent-feedback.ts
6570
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6571
+ function findPrecedingVisitorText(messages, agentMessageId) {
6572
+ const agentIndex = messages.findIndex(
6573
+ (message) => message.id === agentMessageId && message.role === "agent"
6574
+ );
6575
+ if (agentIndex < 0) return void 0;
6576
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6577
+ const message = messages[index];
6578
+ if (message?.role === "visitor") {
6579
+ return message.text.trim() || void 0;
6580
+ }
6581
+ }
6582
+ return void 0;
6583
+ }
6584
+ function normalizeAgentFeedbackAnswerText(text) {
6585
+ const normalized = text.replace(/\s+/g, " ").trim();
6586
+ if (!normalized) return void 0;
6587
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6588
+ }
6589
+ function buildAgentAnswerFeedbackEvent(input) {
6590
+ const positive = input.rating === "positive";
6591
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6592
+ return {
6593
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6594
+ company: input.analytics.companyIndex,
6595
+ session_id: input.visitorSessionId,
6596
+ page: input.page,
6597
+ timestamp: Date.now(),
6598
+ tracking_consent: input.analytics.trackingConsent,
6599
+ feedback_value: positive ? 1 : -1,
6600
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6601
+ feedback_rating: positive ? "helpful" : "not_helpful",
6602
+ surface: "agent_panel",
6603
+ index_id: input.indexId,
6604
+ index_version: input.version,
6605
+ message_id: input.messageId,
6606
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6607
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6608
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6609
+ };
6610
+ }
6611
+ function sendAgentAnswerFeedback(eventUrl, event) {
6612
+ try {
6613
+ void fetch(eventUrl, {
6614
+ body: JSON.stringify(event),
6615
+ credentials: "omit",
6616
+ headers: { "Content-Type": "application/json" },
6617
+ keepalive: true,
6618
+ method: "POST"
6619
+ }).catch(() => {
6620
+ });
6621
+ } catch {
6622
+ }
6623
+ }
6624
+
5551
6625
  // src/react/components/AgentWidget/AgentWidget.tsx
5552
- var import_jsx_runtime16 = require("react/jsx-runtime");
6626
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5553
6627
  function AgentWidget({
5554
6628
  indexId,
5555
6629
  customerId,
@@ -5563,13 +6637,14 @@ function AgentWidget({
5563
6637
  registerPanelController = false,
5564
6638
  colorScheme = "auto",
5565
6639
  branding,
6640
+ analytics,
5566
6641
  toolResultRegistry
5567
6642
  }) {
5568
6643
  const isMobile = useIsMobile();
5569
6644
  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);
6645
+ const railSlotRef = (0, import_react15.useRef)(null);
6646
+ const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
6647
+ const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
5573
6648
  const pageShiftActive = shouldApplyPageShift({
5574
6649
  pageShift,
5575
6650
  isMobile,
@@ -5580,7 +6655,17 @@ function AgentWidget({
5580
6655
  active: pageShiftActive,
5581
6656
  railSlotRef
5582
6657
  });
5583
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6658
+ const {
6659
+ state,
6660
+ reset,
6661
+ retry,
6662
+ regenerate,
6663
+ respondToInput,
6664
+ respondToToolInput,
6665
+ submit,
6666
+ visitorSessionId,
6667
+ sessionId
6668
+ } = useAgentChat({
5584
6669
  customerId,
5585
6670
  getUnpublishedPreviewGrant,
5586
6671
  indexId,
@@ -5612,7 +6697,7 @@ function AgentWidget({
5612
6697
  } : {},
5613
6698
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5614
6699
  };
5615
- (0, import_react12.useEffect)(() => {
6700
+ (0, import_react15.useEffect)(() => {
5616
6701
  if (!registerPanelController) return;
5617
6702
  registerAgentPanelController(customerId, {
5618
6703
  open: () => setRailCollapsed(false),
@@ -5629,7 +6714,25 @@ function AgentWidget({
5629
6714
  if (isMobile) setRailCollapsed(false);
5630
6715
  await submit(message);
5631
6716
  }
5632
- (0, import_react12.useEffect)(() => {
6717
+ function handleFeedback(rating, message) {
6718
+ if (!analytics) return;
6719
+ sendAgentAnswerFeedback(
6720
+ analytics.eventUrl,
6721
+ buildAgentAnswerFeedbackEvent({
6722
+ agentSessionId: sessionId,
6723
+ analytics,
6724
+ indexId,
6725
+ messageId: message.id,
6726
+ page: window.location.href,
6727
+ query: findPrecedingVisitorText(state.messages, message.id),
6728
+ answer: message.text,
6729
+ rating,
6730
+ version: version ?? "published",
6731
+ visitorSessionId
6732
+ })
6733
+ );
6734
+ }
6735
+ (0, import_react15.useEffect)(() => {
5633
6736
  if (railCollapsed) return;
5634
6737
  const handleKeyDown = (event) => {
5635
6738
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5663,19 +6766,19 @@ function AgentWidget({
5663
6766
  window.addEventListener("keydown", handleKeyDown);
5664
6767
  return () => window.removeEventListener("keydown", handleKeyDown);
5665
6768
  }, [isMobile, railCollapsed, railExpanded]);
5666
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "webless-agent-root", children: [
5667
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6769
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
6770
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5668
6771
  "div",
5669
6772
  {
5670
6773
  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)(
6774
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5672
6775
  "div",
5673
6776
  {
5674
6777
  ref: railSlotRef,
5675
6778
  className: "webless-agent-root__rail-slot",
5676
6779
  inert: railCollapsed || void 0,
5677
6780
  "aria-hidden": railCollapsed,
5678
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6781
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5679
6782
  AgentRail,
5680
6783
  {
5681
6784
  theme,
@@ -5683,7 +6786,11 @@ function AgentWidget({
5683
6786
  brandLabel: agentName,
5684
6787
  brandLogoUrl: branding?.logoUrl,
5685
6788
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5686
- poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6789
+ poweredByLabel: branding?.poweredByLabel,
6790
+ disclaimerLabel: branding?.disclaimer,
6791
+ disclaimerLink: branding?.disclaimerLink,
6792
+ answerReceipt: branding?.answerReceipt,
6793
+ readAloud: branding?.readAloud,
5687
6794
  state,
5688
6795
  mobileFullscreen: isMobile && !railCollapsed,
5689
6796
  expanded: railExpanded,
@@ -5693,6 +6800,8 @@ function AgentWidget({
5693
6800
  onSubmit: handleSubmit,
5694
6801
  onReset: reset,
5695
6802
  onRetry: () => void retry(),
6803
+ onRegenerate: () => void regenerate(),
6804
+ onFeedback: analytics ? handleFeedback : void 0,
5696
6805
  onInputResponse: (response) => void respondToInput(response),
5697
6806
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5698
6807
  onFollowUpSelect: (label) => void handleSubmit(label),
@@ -5706,7 +6815,7 @@ function AgentWidget({
5706
6815
  )
5707
6816
  }
5708
6817
  ),
5709
- railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6818
+ railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5710
6819
  AssistEdgeTab,
5711
6820
  {
5712
6821
  variant: placement.variant,
@@ -5745,12 +6854,12 @@ function readUnpublishedPreviewBuildId(href) {
5745
6854
  }
5746
6855
 
5747
6856
  // src/embed/AgentWidget.tsx
5748
- var import_jsx_runtime17 = require("react/jsx-runtime");
6857
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5749
6858
  function AgentWidget2({
5750
6859
  manifest
5751
6860
  }) {
5752
6861
  const defaultCollapsed = manifest.version !== "unpublished";
5753
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6862
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5754
6863
  AgentWidget,
5755
6864
  {
5756
6865
  indexId: manifest.indexId,
@@ -5762,6 +6871,7 @@ function AgentWidget2({
5762
6871
  pageShift: manifest.pageShift,
5763
6872
  colorScheme: manifest.colorScheme,
5764
6873
  branding: manifest.branding,
6874
+ analytics: manifest.analytics,
5765
6875
  defaultCollapsed,
5766
6876
  registerPanelController: true
5767
6877
  }
@@ -5792,6 +6902,7 @@ function normalizeAgentTagManifest(manifest) {
5792
6902
  runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN
5793
6903
  });
5794
6904
  const branding = normalizeAgentBranding(manifest.branding);
6905
+ const analytics = normalizeAgentAnalytics(manifest.analytics);
5795
6906
  return {
5796
6907
  customerId,
5797
6908
  indexId,
@@ -5804,13 +6915,47 @@ function normalizeAgentTagManifest(manifest) {
5804
6915
  placement: normalizeAgentPlacement(manifest.placement),
5805
6916
  pageShift: manifest.pageShift ?? true,
5806
6917
  colorScheme,
5807
- ...branding ? { branding } : {}
6918
+ ...branding ? { branding } : {},
6919
+ ...analytics ? { analytics } : {}
6920
+ };
6921
+ }
6922
+ function normalizeAgentAnalytics(analytics) {
6923
+ if (!analytics) return void 0;
6924
+ const companyIndex = analytics.companyIndex?.trim() ?? "";
6925
+ const eventUrl = analytics.eventUrl?.trim() ?? "";
6926
+ if (!companyIndex || !eventUrl) return void 0;
6927
+ try {
6928
+ const parsed = new URL(eventUrl);
6929
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
6930
+ return void 0;
6931
+ }
6932
+ } catch {
6933
+ return void 0;
6934
+ }
6935
+ return {
6936
+ companyIndex,
6937
+ eventUrl,
6938
+ trackingConsent: analytics.trackingConsent === true
5808
6939
  };
5809
6940
  }
5810
6941
  function normalizeOptionalValue(value) {
5811
6942
  const normalized = value?.trim();
5812
6943
  return normalized || void 0;
5813
6944
  }
6945
+ function normalizeOptionalHttpUrl(value) {
6946
+ if (value === null) return null;
6947
+ const normalized = value?.trim();
6948
+ if (!normalized) return void 0;
6949
+ try {
6950
+ const url = new URL(normalized);
6951
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
6952
+ return void 0;
6953
+ }
6954
+ return normalized;
6955
+ } catch {
6956
+ return void 0;
6957
+ }
6958
+ }
5814
6959
  function normalizeAgentBranding(branding) {
5815
6960
  if (!branding) return void 0;
5816
6961
  const colors = branding.colors ? Object.fromEntries(
@@ -5827,6 +6972,10 @@ function normalizeAgentBranding(branding) {
5827
6972
  greeting: normalizeOptionalValue(branding.greeting),
5828
6973
  composerPlaceholder: normalizeOptionalValue(branding.composerPlaceholder),
5829
6974
  poweredByLabel: normalizeOptionalValue(branding.poweredByLabel),
6975
+ disclaimer: branding.disclaimer === null ? null : normalizeOptionalValue(branding.disclaimer),
6976
+ disclaimerLink: normalizeOptionalHttpUrl(branding.disclaimerLink),
6977
+ answerReceipt: branding.answerReceipt === true ? true : void 0,
6978
+ readAloud: branding.readAloud === true ? true : void 0,
5830
6979
  fontFamily: normalizeOptionalValue(branding.fontFamily),
5831
6980
  colors: colors && Object.keys(colors).length > 0 ? colors : void 0
5832
6981
  };
@@ -5834,7 +6983,7 @@ function normalizeAgentBranding(branding) {
5834
6983
  }
5835
6984
 
5836
6985
  // src/embed/mount.tsx
5837
- var import_jsx_runtime18 = require("react/jsx-runtime");
6986
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5838
6987
  var mountedHandles = /* @__PURE__ */ new Map();
5839
6988
  var latestCustomerId = null;
5840
6989
  function resolveMountHost(manifest, script) {
@@ -5864,7 +7013,7 @@ function mountAgent(input) {
5864
7013
  const host = createHost(manifest.customerId);
5865
7014
  mountTarget.append(host);
5866
7015
  const root = (0, import_client5.createRoot)(host);
5867
- root.render(/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AgentWidget2, { manifest }));
7016
+ root.render(/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(AgentWidget2, { manifest }));
5868
7017
  const handle = {
5869
7018
  customerId: manifest.customerId,
5870
7019
  manifest,