@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/react.cjs CHANGED
@@ -20,27 +20,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/react/index.ts
21
21
  var react_exports = {};
22
22
  __export(react_exports, {
23
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE: () => AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
23
24
  AGENT_STRUCTURED_TOOL_INPUT_HEADER: () => AGENT_STRUCTURED_TOOL_INPUT_HEADER,
24
25
  AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION: () => AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
25
26
  AgentRail: () => AgentRail,
26
27
  AgentWidget: () => AgentWidget,
27
28
  AssistEdgeTab: () => AssistEdgeTab,
28
29
  DEFAULT_AGENT_PLACEMENT: () => DEFAULT_AGENT_PLACEMENT,
30
+ MessageActions: () => MessageActions,
31
+ buildAgentAnswerFeedbackEvent: () => buildAgentAnswerFeedbackEvent,
29
32
  builtInVisitorToolResultRegistry: () => builtInVisitorToolResultRegistry,
30
33
  createIdleSuggestions: () => createIdleSuggestions,
31
34
  defaultAgentRailTheme: () => defaultAgentRailTheme,
32
35
  defaultDarkAgentRailTheme: () => defaultDarkAgentRailTheme,
36
+ findPrecedingVisitorText: () => findPrecedingVisitorText,
33
37
  formatAgentStructuredToolInput: () => formatAgentStructuredToolInput,
34
38
  hasVisitorMessages: () => hasVisitorMessages,
35
39
  isAgentBusy: () => isAgentBusy,
36
40
  normalizeAgentPlacement: () => normalizeAgentPlacement,
37
41
  presentVisitorToolResult: () => presentVisitorToolResult,
42
+ sendAgentAnswerFeedback: () => sendAgentAnswerFeedback,
38
43
  useAgentChat: () => useAgentChat
39
44
  });
40
45
  module.exports = __toCommonJS(react_exports);
41
46
 
42
47
  // src/react/components/AgentWidget/AgentWidget.tsx
43
- var import_react12 = require("react");
48
+ var import_react15 = require("react");
44
49
 
45
50
  // src/react/page-shift.ts
46
51
  var import_react = require("react");
@@ -896,6 +901,20 @@ function latestTurnEvents(events) {
896
901
  }
897
902
  return startIndex >= 0 ? events.slice(startIndex) : [];
898
903
  }
904
+ function streamIndexBeforeLastTurn(input) {
905
+ let turnStart = -1;
906
+ for (let index = input.events.length - 1; index >= 0; index -= 1) {
907
+ if (input.events[index]?.type === "message.received") {
908
+ turnStart = index;
909
+ break;
910
+ }
911
+ }
912
+ if (turnStart < 0) return null;
913
+ return Math.max(
914
+ 0,
915
+ input.currentStreamIndex - (input.events.length - turnStart)
916
+ );
917
+ }
899
918
  function renderTurn(events) {
900
919
  let rendered = "";
901
920
  for (const event of events) {
@@ -1080,6 +1099,40 @@ var AgentSession = class {
1080
1099
  this.storeOptions
1081
1100
  );
1082
1101
  }
1102
+ async rewindBeforeLastTurn(signal) {
1103
+ const persisted = loadPersistedAgentSession(
1104
+ this.visitorSessionId,
1105
+ this.storeOptions
1106
+ );
1107
+ if (!persisted?.sessionId) return false;
1108
+ const client = this.ensureClient();
1109
+ const attached = client.sessions.attach(persisted.sessionId, {
1110
+ streamIndex: persisted.streamIndex
1111
+ });
1112
+ const snapshot = await withCapabilityRefresh(
1113
+ this.capability,
1114
+ () => attached.snapshot({ signal })
1115
+ );
1116
+ const rewindStreamIndex = streamIndexBeforeLastTurn({
1117
+ currentStreamIndex: snapshot.session.streamIndex,
1118
+ events: snapshot.events
1119
+ });
1120
+ if (rewindStreamIndex === null) return false;
1121
+ this.session = client.sessions.attach(persisted.sessionId, {
1122
+ streamIndex: rewindStreamIndex
1123
+ });
1124
+ savePersistedAgentSession(
1125
+ this.visitorSessionId,
1126
+ persisted.sessionId,
1127
+ rewindStreamIndex,
1128
+ this.storeOptions
1129
+ );
1130
+ return true;
1131
+ }
1132
+ async regenerateTurn(message, signal, handlers) {
1133
+ await this.rewindBeforeLastTurn(signal);
1134
+ return this.sendTurn(message, signal, handlers);
1135
+ }
1083
1136
  ensureClient() {
1084
1137
  const config = resolveAgentRuntimeConfig({
1085
1138
  indexId: this.indexId,
@@ -1415,6 +1468,11 @@ function createAgentClient(options) {
1415
1468
  respondOptions.signal ?? new AbortController().signal,
1416
1469
  respondOptions.handlers
1417
1470
  ),
1471
+ regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
1472
+ message,
1473
+ regenerateOptions.signal ?? new AbortController().signal,
1474
+ regenerateOptions.handlers
1475
+ ),
1418
1476
  reset: () => session.reset(),
1419
1477
  cancelActive: () => session.cancelActive(),
1420
1478
  getActiveSessionId: () => session.getActiveSessionId()
@@ -2857,6 +2915,7 @@ function useAgentChat({
2857
2915
  const {
2858
2916
  controller,
2859
2917
  initialText = "",
2918
+ regenerate: regenerate2 = false,
2860
2919
  responses,
2861
2920
  resume,
2862
2921
  visitorText
@@ -2968,6 +3027,9 @@ function useAgentChat({
2968
3027
  initialText,
2969
3028
  message: visitorText,
2970
3029
  signal
3030
+ }) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
3031
+ handlers,
3032
+ signal
2971
3033
  }) : await clientRef.current.sendTurn(visitorText, {
2972
3034
  handlers,
2973
3035
  signal
@@ -3184,6 +3246,49 @@ ${outgoing}` : outgoing;
3184
3246
  visitorText: visitorTurnText(visitorMessage)
3185
3247
  });
3186
3248
  }, [runTurn, state.messages]);
3249
+ const regenerate = (0, import_react2.useCallback)(async () => {
3250
+ let lastVisitorIndex = -1;
3251
+ for (let index = state.messages.length - 1; index >= 0; index -= 1) {
3252
+ if (state.messages[index]?.role === "visitor") {
3253
+ lastVisitorIndex = index;
3254
+ break;
3255
+ }
3256
+ }
3257
+ const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
3258
+ if (!visitorMessage) return null;
3259
+ if (runRef.current) {
3260
+ runRef.current.abort();
3261
+ clientRef.current.cancelActive();
3262
+ }
3263
+ const controller = new AbortController();
3264
+ runRef.current = controller;
3265
+ setState((prev) => ({
3266
+ ...prev,
3267
+ phase: "thinking",
3268
+ messages: prev.messages.slice(0, lastVisitorIndex + 1),
3269
+ toolSteps: [
3270
+ {
3271
+ id: "planning",
3272
+ kind: "planning",
3273
+ label: "Understanding your question",
3274
+ state: "active"
3275
+ }
3276
+ ],
3277
+ journey: null,
3278
+ followUps: [],
3279
+ streamingText: "",
3280
+ pendingOffer: null,
3281
+ pendingInputs: [],
3282
+ toolResults: [],
3283
+ error: null
3284
+ }));
3285
+ return await runTurn({
3286
+ controller,
3287
+ regenerate: true,
3288
+ resume: false,
3289
+ visitorText: visitorTurnText(visitorMessage)
3290
+ });
3291
+ }, [runTurn, state.messages]);
3187
3292
  const respondToToolInput = (0, import_react2.useCallback)(
3188
3293
  async (surface, values) => {
3189
3294
  await submit(`${surface.title} submitted`, {
@@ -3260,6 +3365,7 @@ ${outgoing}` : outgoing;
3260
3365
  state,
3261
3366
  reset,
3262
3367
  retry,
3368
+ regenerate,
3263
3369
  respondToInput,
3264
3370
  respondToToolInput,
3265
3371
  submit,
@@ -3326,7 +3432,7 @@ function unregisterAgentPanelController(customerId) {
3326
3432
  }
3327
3433
 
3328
3434
  // src/react/components/AgentRail/AgentRail.tsx
3329
- var import_react11 = require("react");
3435
+ var import_react14 = require("react");
3330
3436
 
3331
3437
  // src/react/types/conversation.ts
3332
3438
  var defaultAgentRailTheme = {
@@ -3448,6 +3554,60 @@ function stepDetail(step, steps) {
3448
3554
  return "Searched this site";
3449
3555
  return step.detail;
3450
3556
  }
3557
+ function AgentWorkSteps({
3558
+ brandLabel = "",
3559
+ onRetryStep,
3560
+ steps
3561
+ }) {
3562
+ const delegationCount = steps.filter(
3563
+ (step) => step.kind === "specialist"
3564
+ ).length;
3565
+ const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3566
+ const visibleSteps = steps.filter(
3567
+ (step) => step.kind !== "planning" || Boolean(brandLabel)
3568
+ );
3569
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3570
+ const detail = stepDetail(step, steps);
3571
+ const child = delegated && step.kind === "specialist";
3572
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3573
+ "li",
3574
+ {
3575
+ className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3576
+ "data-kind": step.kind,
3577
+ "data-state": step.state,
3578
+ children: [
3579
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3580
+ "span",
3581
+ {
3582
+ className: "agent-activity-bubble__step-icon",
3583
+ "aria-hidden": "true"
3584
+ }
3585
+ ),
3586
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3587
+ /* @__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) }) }),
3588
+ detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3589
+ delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3590
+ "Delegated ",
3591
+ delegationCount,
3592
+ " ",
3593
+ delegationCount === 1 ? "task" : "tasks"
3594
+ ] }) : null,
3595
+ step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3596
+ "button",
3597
+ {
3598
+ type: "button",
3599
+ className: "agent-activity-bubble__step-retry",
3600
+ onClick: () => onRetryStep(step),
3601
+ children: "Retry"
3602
+ }
3603
+ ) : null
3604
+ ] })
3605
+ ]
3606
+ },
3607
+ step.id
3608
+ );
3609
+ }) });
3610
+ }
3451
3611
  function AgentActivityBubble({
3452
3612
  brandLabel = "",
3453
3613
  failed = false,
@@ -3459,14 +3619,7 @@ function AgentActivityBubble({
3459
3619
  const [expandedReceiptId, setExpandedReceiptId] = (0, import_react5.useState)(
3460
3620
  null
3461
3621
  );
3462
- const detailsOpen = active || expandedReceiptId === receiptId;
3463
- const delegationCount = steps.filter(
3464
- (step) => step.kind === "specialist"
3465
- ).length;
3466
- const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3467
- const visibleSteps = steps.filter(
3468
- (step) => step.kind !== "planning" || Boolean(brandLabel)
3469
- );
3622
+ const detailsOpen = !active && expandedReceiptId === receiptId;
3470
3623
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
3471
3624
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
3472
3625
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -3476,9 +3629,10 @@ function AgentActivityBubble({
3476
3629
  "aria-hidden": "true"
3477
3630
  }
3478
3631
  ),
3479
- workSummary(steps, failed, brandLabel)
3632
+ workSummary(steps, failed, brandLabel),
3633
+ active ? "\u2026" : ""
3480
3634
  ] }),
3481
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3635
+ !active ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3482
3636
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3483
3637
  "button",
3484
3638
  {
@@ -3486,7 +3640,6 @@ function AgentActivityBubble({
3486
3640
  className: "agent-activity-bubble__summary",
3487
3641
  "aria-expanded": detailsOpen,
3488
3642
  onClick: () => {
3489
- if (active) return;
3490
3643
  setExpandedReceiptId(
3491
3644
  (current) => current === receiptId ? null : receiptId
3492
3645
  );
@@ -3494,56 +3647,145 @@ function AgentActivityBubble({
3494
3647
  children: "How this answer was made"
3495
3648
  }
3496
3649
  ),
3497
- detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3498
- const detail = stepDetail(step, steps);
3499
- const child = delegated && step.kind === "specialist";
3500
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3501
- "li",
3502
- {
3503
- className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3504
- "data-kind": step.kind,
3505
- "data-state": step.state,
3506
- children: [
3507
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3508
- "span",
3509
- {
3510
- className: "agent-activity-bubble__step-icon",
3511
- "aria-hidden": "true"
3512
- }
3513
- ),
3514
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3515
- /* @__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) }) }),
3516
- detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3517
- delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3518
- "Delegated ",
3519
- delegationCount,
3520
- " ",
3521
- delegationCount === 1 ? "task" : "tasks"
3522
- ] }) : null,
3523
- step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3524
- "button",
3525
- {
3526
- type: "button",
3527
- className: "agent-activity-bubble__step-retry",
3528
- onClick: () => onRetryStep(step),
3529
- children: "Retry"
3530
- }
3531
- ) : null
3532
- ] })
3533
- ]
3534
- },
3535
- step.id
3536
- );
3537
- }) }) : null
3538
- ] })
3650
+ detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3651
+ AgentWorkSteps,
3652
+ {
3653
+ brandLabel,
3654
+ onRetryStep,
3655
+ steps
3656
+ }
3657
+ ) : null
3658
+ ] }) : null
3539
3659
  ] });
3540
3660
  }
3541
3661
 
3542
- // src/react/components/Composer/Composer.tsx
3662
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3663
+ var import_react7 = require("react");
3664
+ var import_react_dom = require("react-dom");
3665
+
3666
+ // src/react/components/AgentRail/AgentRailOverlayContext.tsx
3543
3667
  var import_react6 = require("react");
3668
+ var AgentRailOverlayContext = (0, import_react6.createContext)(null);
3669
+ function useAgentRailPortalRoots() {
3670
+ return (0, import_react6.useContext)(AgentRailOverlayContext);
3671
+ }
3672
+ function useAgentRailMenuPortalRoot() {
3673
+ return (0, import_react6.useContext)(AgentRailOverlayContext)?.railRef ?? null;
3674
+ }
3675
+
3676
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3544
3677
  var import_jsx_runtime2 = require("react/jsx-runtime");
3545
- function SendIcon() {
3678
+ var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
3679
+ function CloseIcon() {
3546
3680
  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)(
3681
+ "path",
3682
+ {
3683
+ d: "M4 4l8 8M12 4l-8 8",
3684
+ stroke: "currentColor",
3685
+ strokeWidth: "1.5",
3686
+ strokeLinecap: "round"
3687
+ }
3688
+ ) });
3689
+ }
3690
+ function AnswerReceiptDialog({
3691
+ brandLabel = "",
3692
+ onClose,
3693
+ steps
3694
+ }) {
3695
+ const portalRoots = useAgentRailPortalRoots();
3696
+ const overlayRoot = portalRoots?.overlayRef ?? null;
3697
+ const cardRef = (0, import_react7.useRef)(null);
3698
+ const closeButtonRef = (0, import_react7.useRef)(null);
3699
+ const previouslyFocusedRef = (0, import_react7.useRef)(null);
3700
+ (0, import_react7.useEffect)(() => {
3701
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
3702
+ closeButtonRef.current?.focus({ preventScroll: true });
3703
+ const handleKeyDown = (event) => {
3704
+ if (event.key === "Escape") {
3705
+ event.preventDefault();
3706
+ event.stopPropagation();
3707
+ onClose();
3708
+ return;
3709
+ }
3710
+ if (event.key !== "Tab" || !cardRef.current) return;
3711
+ const focusable = cardRef.current.querySelectorAll(
3712
+ FOCUSABLE_SELECTOR
3713
+ );
3714
+ if (focusable.length === 0) return;
3715
+ const first = focusable.item(0);
3716
+ const last = focusable.item(focusable.length - 1);
3717
+ if (event.shiftKey && document.activeElement === first) {
3718
+ event.preventDefault();
3719
+ last.focus({ preventScroll: true });
3720
+ } else if (!event.shiftKey && document.activeElement === last) {
3721
+ event.preventDefault();
3722
+ first.focus({ preventScroll: true });
3723
+ }
3724
+ };
3725
+ document.addEventListener("keydown", handleKeyDown);
3726
+ return () => {
3727
+ document.removeEventListener("keydown", handleKeyDown);
3728
+ previouslyFocusedRef.current?.focus({ preventScroll: true });
3729
+ };
3730
+ }, [onClose]);
3731
+ const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog", children: [
3732
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3733
+ "button",
3734
+ {
3735
+ type: "button",
3736
+ className: "agent-receipt-dialog__backdrop",
3737
+ "aria-label": "Close",
3738
+ tabIndex: -1,
3739
+ onClick: onClose
3740
+ }
3741
+ ),
3742
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3743
+ "div",
3744
+ {
3745
+ ref: cardRef,
3746
+ className: "agent-receipt-dialog__card",
3747
+ role: "dialog",
3748
+ "aria-modal": "true",
3749
+ "aria-labelledby": "agent-receipt-dialog-title",
3750
+ children: [
3751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog__header", children: [
3752
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3753
+ "p",
3754
+ {
3755
+ className: "agent-receipt-dialog__title",
3756
+ id: "agent-receipt-dialog-title",
3757
+ children: "How this answer was made"
3758
+ }
3759
+ ),
3760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3761
+ "button",
3762
+ {
3763
+ ref: closeButtonRef,
3764
+ type: "button",
3765
+ className: "agent-receipt-dialog__close",
3766
+ "aria-label": "Close",
3767
+ onClick: onClose,
3768
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
3769
+ }
3770
+ )
3771
+ ] }),
3772
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
3773
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AgentWorkSteps, { brandLabel, steps }) })
3774
+ ]
3775
+ }
3776
+ )
3777
+ ] });
3778
+ if (overlayRoot?.current) {
3779
+ return (0, import_react_dom.createPortal)(content, overlayRoot.current);
3780
+ }
3781
+ return content;
3782
+ }
3783
+
3784
+ // src/react/components/Composer/Composer.tsx
3785
+ var import_react8 = require("react");
3786
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3787
+ function SendIcon() {
3788
+ 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)(
3547
3789
  "path",
3548
3790
  {
3549
3791
  d: "M8 12V4M8 4l-3 3M8 4l3 3",
@@ -3566,21 +3808,21 @@ function Composer({
3566
3808
  form = null,
3567
3809
  onSubmit
3568
3810
  }) {
3569
- const [value, setValue] = (0, import_react6.useState)("");
3570
- const [values, setValues] = (0, import_react6.useState)(
3811
+ const [value, setValue] = (0, import_react8.useState)("");
3812
+ const [values, setValues] = (0, import_react8.useState)(
3571
3813
  () => emptyValues(form)
3572
3814
  );
3573
- const [blurred, setBlurred] = (0, import_react6.useState)({});
3574
- const inputRef = (0, import_react6.useRef)(null);
3575
- const firstFieldRef = (0, import_react6.useRef)(null);
3576
- const formId = (0, import_react6.useId)();
3815
+ const [blurred, setBlurred] = (0, import_react8.useState)({});
3816
+ const inputRef = (0, import_react8.useRef)(null);
3817
+ const firstFieldRef = (0, import_react8.useRef)(null);
3818
+ const formId = (0, import_react8.useId)();
3577
3819
  const activeForm = form;
3578
3820
  const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
3579
- (0, import_react6.useEffect)(() => {
3821
+ (0, import_react8.useEffect)(() => {
3580
3822
  setValues(emptyValues(form));
3581
3823
  setBlurred({});
3582
3824
  }, [form?.id]);
3583
- (0, import_react6.useEffect)(() => {
3825
+ (0, import_react8.useEffect)(() => {
3584
3826
  if (activeForm) firstFieldRef.current?.focus();
3585
3827
  }, [activeForm?.id]);
3586
3828
  function submitChat() {
@@ -3615,7 +3857,7 @@ function Composer({
3615
3857
  submitForm();
3616
3858
  }
3617
3859
  }
3618
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3860
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3619
3861
  "form",
3620
3862
  {
3621
3863
  className: [
@@ -3624,7 +3866,7 @@ function Composer({
3624
3866
  activeForm ? "composer--form" : ""
3625
3867
  ].filter(Boolean).join(" "),
3626
3868
  onSubmit: handleSubmit,
3627
- children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3869
+ children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3628
3870
  activeForm.fields.map((field, index) => {
3629
3871
  const fieldId = `${formId}-${field.id}`;
3630
3872
  const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
@@ -3649,7 +3891,7 @@ function Composer({
3649
3891
  },
3650
3892
  onKeyDown: handleFormKeyDown
3651
3893
  };
3652
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3894
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3653
3895
  "div",
3654
3896
  {
3655
3897
  className: [
@@ -3657,9 +3899,9 @@ function Composer({
3657
3899
  field.kind === "textarea" ? "composer__row--grow" : ""
3658
3900
  ].filter(Boolean).join(" "),
3659
3901
  children: [
3660
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3661
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "composer__sr-only", children: field.label }),
3662
- field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3902
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "composer__sr-only", children: field.label }),
3904
+ field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3663
3905
  "textarea",
3664
3906
  {
3665
3907
  ...controlProps,
@@ -3669,7 +3911,7 @@ function Composer({
3669
3911
  className: "composer__control composer__control--area",
3670
3912
  rows: 3
3671
3913
  }
3672
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3914
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3673
3915
  "input",
3674
3916
  {
3675
3917
  ...controlProps,
@@ -3682,24 +3924,24 @@ function Composer({
3682
3924
  }
3683
3925
  )
3684
3926
  ] }),
3685
- 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
3927
+ 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
3686
3928
  ]
3687
3929
  },
3688
3930
  field.id
3689
3931
  );
3690
3932
  }),
3691
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3933
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3692
3934
  "button",
3693
3935
  {
3694
3936
  type: "submit",
3695
3937
  className: "composer__send",
3696
3938
  disabled: disabled || !canSendForm,
3697
3939
  "aria-label": "Send details",
3698
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3940
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3699
3941
  }
3700
3942
  ) })
3701
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__field", children: [
3702
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3943
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
3944
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3703
3945
  "textarea",
3704
3946
  {
3705
3947
  ref: inputRef,
@@ -3714,14 +3956,14 @@ function Composer({
3714
3956
  onKeyDown: handleChatKeyDown
3715
3957
  }
3716
3958
  ),
3717
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3959
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3718
3960
  "button",
3719
3961
  {
3720
3962
  type: "submit",
3721
3963
  className: "composer__send",
3722
3964
  disabled: disabled || !value.trim(),
3723
3965
  "aria-label": "Send message",
3724
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3966
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3725
3967
  }
3726
3968
  )
3727
3969
  ] })
@@ -3730,7 +3972,7 @@ function Composer({
3730
3972
  }
3731
3973
 
3732
3974
  // src/react/components/FollowUpChips/FollowUpChips.tsx
3733
- var import_jsx_runtime3 = require("react/jsx-runtime");
3975
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3734
3976
  function FollowUpChips({
3735
3977
  suggestions,
3736
3978
  disabled = false,
@@ -3740,7 +3982,7 @@ function FollowUpChips({
3740
3982
  }) {
3741
3983
  if (suggestions.length === 0) return null;
3742
3984
  if (variant === "dock") {
3743
- 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)(
3985
+ 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)(
3744
3986
  "button",
3745
3987
  {
3746
3988
  type: "button",
@@ -3752,9 +3994,9 @@ function FollowUpChips({
3752
3994
  suggestion.id
3753
3995
  )) }) });
3754
3996
  }
3755
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "followups", children: [
3756
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "followups__label", children: label }),
3757
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3997
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
3998
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
3999
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3758
4000
  "button",
3759
4001
  {
3760
4002
  type: "button",
@@ -3769,11 +4011,11 @@ function FollowUpChips({
3769
4011
  }
3770
4012
 
3771
4013
  // src/react/components/MessageBubble/MessageBubble.tsx
3772
- var import_react8 = require("react");
4014
+ var import_react10 = require("react");
3773
4015
 
3774
4016
  // src/react/components/BookingCard/BookingCard.tsx
3775
- var import_react7 = require("react");
3776
- var import_jsx_runtime4 = require("react/jsx-runtime");
4017
+ var import_react9 = require("react");
4018
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3777
4019
  var BOOKING_STEPS = [
3778
4020
  { id: "date", label: "Date" },
3779
4021
  { id: "time", label: "Time" },
@@ -3804,34 +4046,34 @@ function calendarCells(year, month) {
3804
4046
  return cells;
3805
4047
  }
3806
4048
  function BookingCardLoader() {
3807
- 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" }) });
4049
+ 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" }) });
3808
4050
  }
3809
4051
  function BookingCard({
3810
4052
  disabled = false,
3811
4053
  offer,
3812
4054
  onBook
3813
4055
  }) {
3814
- const fieldId = (0, import_react7.useId)();
4056
+ const fieldId = (0, import_react9.useId)();
3815
4057
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
3816
- const [step, setStep] = (0, import_react7.useState)("date");
3817
- const [eventTypeUri, setEventTypeUri] = (0, import_react7.useState)(defaultType);
3818
- const [selectedDate, setSelectedDate] = (0, import_react7.useState)("");
3819
- const [startTime, setStartTime] = (0, import_react7.useState)("");
3820
- const [name, setName] = (0, import_react7.useState)("");
3821
- const [email, setEmail] = (0, import_react7.useState)("");
3822
- const activeStepRef = (0, import_react7.useRef)(null);
3823
- const previousStepRef = (0, import_react7.useRef)(step);
4058
+ const [step, setStep] = (0, import_react9.useState)("date");
4059
+ const [eventTypeUri, setEventTypeUri] = (0, import_react9.useState)(defaultType);
4060
+ const [selectedDate, setSelectedDate] = (0, import_react9.useState)("");
4061
+ const [startTime, setStartTime] = (0, import_react9.useState)("");
4062
+ const [name, setName] = (0, import_react9.useState)("");
4063
+ const [email, setEmail] = (0, import_react9.useState)("");
4064
+ const activeStepRef = (0, import_react9.useRef)(null);
4065
+ const previousStepRef = (0, import_react9.useRef)(step);
3824
4066
  const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
3825
- (0, import_react7.useEffect)(() => {
4067
+ (0, import_react9.useEffect)(() => {
3826
4068
  if (previousStepRef.current === step) return;
3827
4069
  previousStepRef.current = step;
3828
4070
  activeStepRef.current?.scrollIntoView({ block: "nearest" });
3829
4071
  }, [step]);
3830
- const slots = (0, import_react7.useMemo)(
4072
+ const slots = (0, import_react9.useMemo)(
3831
4073
  () => bookingSlotsForEventType(offer.slots, eventTypeUri),
3832
4074
  [eventTypeUri, offer.slots]
3833
4075
  );
3834
- const availableByDate = (0, import_react7.useMemo)(() => {
4076
+ const availableByDate = (0, import_react9.useMemo)(() => {
3835
4077
  const next = /* @__PURE__ */ new Map();
3836
4078
  for (const slot of slots) {
3837
4079
  const key = slotDateKey(slot.startTime);
@@ -3839,7 +4081,7 @@ function BookingCard({
3839
4081
  }
3840
4082
  return next;
3841
4083
  }, [slots]);
3842
- const [visibleMonth, setVisibleMonth] = (0, import_react7.useState)(
4084
+ const [visibleMonth, setVisibleMonth] = (0, import_react9.useState)(
3843
4085
  () => firstAvailableBookingMonth(slots)
3844
4086
  );
3845
4087
  function selectEventType(nextType) {
@@ -3852,7 +4094,7 @@ function BookingCard({
3852
4094
  )
3853
4095
  );
3854
4096
  }
3855
- const daySlots = (0, import_react7.useMemo)(
4097
+ const daySlots = (0, import_react9.useMemo)(
3856
4098
  () => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
3857
4099
  [selectedDate, slots]
3858
4100
  );
@@ -3861,7 +4103,7 @@ function BookingCard({
3861
4103
  );
3862
4104
  const selectedSample = availableByDate.get(selectedDate) ?? startTime;
3863
4105
  const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
3864
- const weekdays = (0, import_react7.useMemo)(() => weekdayLabels(), []);
4106
+ const weekdays = (0, import_react9.useMemo)(() => weekdayLabels(), []);
3865
4107
  const cells = calendarCells(visibleMonth.year, visibleMonth.month);
3866
4108
  const canPrevMonth = [...availableByDate.keys()].some((key) => {
3867
4109
  const month = monthFromKey(key);
@@ -3903,14 +4145,14 @@ function BookingCard({
3903
4145
  })
3904
4146
  });
3905
4147
  }
3906
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4148
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3907
4149
  "section",
3908
4150
  {
3909
4151
  className: "booking-card",
3910
4152
  "aria-busy": disabled || void 0,
3911
4153
  "aria-label": "Book a meeting",
3912
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3913
- /* @__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)(
4154
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
4155
+ /* @__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)(
3914
4156
  "li",
3915
4157
  {
3916
4158
  className: [
@@ -3920,40 +4162,40 @@ function BookingCard({
3920
4162
  ].filter(Boolean).join(" "),
3921
4163
  "aria-current": index === stepIndex ? "step" : void 0,
3922
4164
  children: [
3923
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
3924
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: item.label })
4165
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
4166
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: item.label })
3925
4167
  ]
3926
4168
  },
3927
4169
  item.id
3928
4170
  )) }),
3929
- step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
3930
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3931
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
4171
+ step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4172
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
4173
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
3932
4174
  "Times in ",
3933
4175
  timeZone
3934
4176
  ] }) : null,
3935
- offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4177
+ offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3936
4178
  "label",
3937
4179
  {
3938
4180
  className: "booking-card__field",
3939
4181
  htmlFor: `${fieldId}-type`,
3940
4182
  children: [
3941
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Meeting" }),
3942
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4183
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Meeting" }),
4184
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3943
4185
  "select",
3944
4186
  {
3945
4187
  id: `${fieldId}-type`,
3946
4188
  value: eventTypeUri,
3947
4189
  disabled,
3948
4190
  onChange: (event) => selectEventType(event.target.value),
3949
- children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: item.uri, children: item.name }, item.uri))
4191
+ children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: item.uri, children: item.name }, item.uri))
3950
4192
  }
3951
4193
  )
3952
4194
  ]
3953
4195
  }
3954
4196
  ) : null,
3955
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__month", children: [
3956
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4197
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__month", children: [
4198
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3957
4199
  "button",
3958
4200
  {
3959
4201
  type: "button",
@@ -3964,8 +4206,8 @@ function BookingCard({
3964
4206
  children: "\u2039"
3965
4207
  }
3966
4208
  ),
3967
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3968
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
4210
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3969
4211
  "button",
3970
4212
  {
3971
4213
  type: "button",
@@ -3977,9 +4219,9 @@ function BookingCard({
3977
4219
  }
3978
4220
  )
3979
4221
  ] }),
3980
- /* @__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)) }),
3981
- offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3982
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4222
+ /* @__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)) }),
4223
+ offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
4224
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3983
4225
  "div",
3984
4226
  {
3985
4227
  className: "booking-card__calendar",
@@ -3987,7 +4229,7 @@ function BookingCard({
3987
4229
  "aria-label": "Available dates",
3988
4230
  children: cells.map((cell, index) => {
3989
4231
  if (!cell) {
3990
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4232
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3991
4233
  "span",
3992
4234
  {
3993
4235
  className: "booking-card__day"
@@ -3997,7 +4239,7 @@ function BookingCard({
3997
4239
  }
3998
4240
  const available = availableByDate.has(cell.key);
3999
4241
  const selected = cell.key === selectedDate;
4000
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4242
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4001
4243
  "button",
4002
4244
  {
4003
4245
  type: "button",
@@ -4017,9 +4259,9 @@ function BookingCard({
4017
4259
  }
4018
4260
  )
4019
4261
  ] }, "date") : null,
4020
- step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4021
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
4022
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4262
+ step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4263
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4264
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4023
4265
  "button",
4024
4266
  {
4025
4267
  type: "button",
@@ -4030,15 +4272,15 @@ function BookingCard({
4030
4272
  children: "\u2039"
4031
4273
  }
4032
4274
  ),
4033
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
4034
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4035
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
4275
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4276
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4277
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
4036
4278
  "Times in ",
4037
4279
  timeZone
4038
4280
  ] }) : null
4039
4281
  ] })
4040
4282
  ] }),
4041
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4283
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4042
4284
  "button",
4043
4285
  {
4044
4286
  type: "button",
@@ -4050,9 +4292,9 @@ function BookingCard({
4050
4292
  slot.startTime
4051
4293
  )) })
4052
4294
  ] }, "time") : null,
4053
- step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4054
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
4055
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4295
+ step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4296
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4297
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4056
4298
  "button",
4057
4299
  {
4058
4300
  type: "button",
@@ -4063,21 +4305,21 @@ function BookingCard({
4063
4305
  children: "\u2039"
4064
4306
  }
4065
4307
  ),
4066
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
4067
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4068
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4069
- selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4308
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4309
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4310
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4311
+ selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4070
4312
  ] })
4071
4313
  ] }),
4072
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__identity", children: [
4073
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4314
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__identity", children: [
4315
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4074
4316
  "label",
4075
4317
  {
4076
4318
  className: "booking-card__field",
4077
4319
  htmlFor: `${fieldId}-name`,
4078
4320
  children: [
4079
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Name" }),
4080
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4321
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Name" }),
4322
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4081
4323
  "input",
4082
4324
  {
4083
4325
  id: `${fieldId}-name`,
@@ -4091,14 +4333,14 @@ function BookingCard({
4091
4333
  ]
4092
4334
  }
4093
4335
  ),
4094
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4336
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4095
4337
  "label",
4096
4338
  {
4097
4339
  className: "booking-card__field",
4098
4340
  htmlFor: `${fieldId}-email`,
4099
4341
  children: [
4100
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Email" }),
4101
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4342
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Email" }),
4343
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4102
4344
  "input",
4103
4345
  {
4104
4346
  id: `${fieldId}-email`,
@@ -4114,7 +4356,7 @@ function BookingCard({
4114
4356
  }
4115
4357
  )
4116
4358
  ] }),
4117
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4359
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4118
4360
  "button",
4119
4361
  {
4120
4362
  type: "submit",
@@ -4132,7 +4374,7 @@ function BookingCard({
4132
4374
  // src/react/components/MessageBubble/MessageBubble.tsx
4133
4375
  var import_streamdown = require("streamdown");
4134
4376
  var import_styles = require("streamdown/styles.css");
4135
- var import_jsx_runtime5 = require("react/jsx-runtime");
4377
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4136
4378
  function normalizeDedupeText(text) {
4137
4379
  return text.trim().replace(/\s+/g, " ").toLowerCase();
4138
4380
  }
@@ -4176,7 +4418,7 @@ function MessageBubble({
4176
4418
  onBook
4177
4419
  }) {
4178
4420
  const resolvedLogoUrl = brandLogoUrl?.trim();
4179
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react8.useState)(null);
4421
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react10.useState)(null);
4180
4422
  const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
4181
4423
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
4182
4424
  const extractedOffers = cards.filter(
@@ -4189,11 +4431,11 @@ function MessageBubble({
4189
4431
  offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
4190
4432
  );
4191
4433
  if (message.role === "visitor") {
4192
- 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 }) });
4434
+ 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 }) });
4193
4435
  }
4194
4436
  const citations = message.citations ?? [];
4195
- const agentText = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__text", children: [
4196
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4437
+ const agentText = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__text", children: [
4438
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4197
4439
  import_streamdown.Streamdown,
4198
4440
  {
4199
4441
  animated: isStreaming,
@@ -4207,8 +4449,8 @@ function MessageBubble({
4207
4449
  children: displayText
4208
4450
  }
4209
4451
  ),
4210
- 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: [
4211
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4452
+ 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: [
4453
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4212
4454
  "span",
4213
4455
  {
4214
4456
  className: "message-bubble__source-icon",
@@ -4216,12 +4458,12 @@ function MessageBubble({
4216
4458
  children: "\u25A6"
4217
4459
  }
4218
4460
  ),
4219
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: citation.label })
4461
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: citation.label })
4220
4462
  ] }) }, citation.id)) }) : null
4221
4463
  ] });
4222
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4223
- displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__agent-row", children: [
4224
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4464
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4465
+ displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__agent-row", children: [
4466
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4225
4467
  "img",
4226
4468
  {
4227
4469
  src: resolvedLogoUrl,
@@ -4233,7 +4475,7 @@ function MessageBubble({
4233
4475
  ) }),
4234
4476
  agentText
4235
4477
  ] }) : agentText : null,
4236
- offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4478
+ offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4237
4479
  BookingCard,
4238
4480
  {
4239
4481
  disabled: bookingDisabled,
@@ -4245,68 +4487,679 @@ function MessageBubble({
4245
4487
  ] });
4246
4488
  }
4247
4489
 
4248
- // src/react/components/HumanInputCard/HumanInputCard.tsx
4249
- var import_react10 = require("react");
4490
+ // src/react/components/MessageActions/MessageActions.tsx
4491
+ var import_react11 = require("react");
4492
+ var import_react_dom2 = require("react-dom");
4250
4493
 
4251
- // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4252
- var import_jsx_runtime6 = require("react/jsx-runtime");
4253
- function ConfirmationCard({
4254
- disabled = false,
4255
- request,
4256
- onRespond
4257
- }) {
4258
- const options = request.options ?? [];
4259
- const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4260
- const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4261
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4262
- "section",
4263
- {
4264
- className: "confirmation-card",
4265
- "aria-labelledby": `confirmation-${request.requestId}`,
4266
- children: [
4267
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "confirmation-card__heading", children: [
4268
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4269
- prompt ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: prompt }) : null
4270
- ] }),
4271
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4272
- "button",
4273
- {
4274
- type: "button",
4275
- className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
4276
- disabled,
4277
- onClick: () => onRespond?.({
4278
- requestId: request.requestId,
4279
- optionId: option.id
4280
- }),
4281
- children: option.label
4282
- },
4283
- option.id
4284
- )) })
4285
- ]
4494
+ // src/react/lib/speech.ts
4495
+ function toSpeechText(text) {
4496
+ let out = hideToolCardFences(text);
4497
+ out = out.replace(/```[\s\S]*?```/g, " ");
4498
+ out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
4499
+ out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
4500
+ out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
4501
+ out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
4502
+ out = out.replace(/(\*|_)(.*?)\1/g, "$2");
4503
+ out = out.replace(/~~(.*?)~~/g, "$1");
4504
+ out = out.replace(/`([^`]*)`/g, "$1");
4505
+ out = out.replace(/^\s*>\s?/gm, "");
4506
+ out = out.replace(/^\s*[-*+]\s+/gm, "");
4507
+ out = out.replace(/^\s*\d+\.\s+/gm, "");
4508
+ out = out.replace(/\|/g, " ");
4509
+ out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
4510
+ out = out.replace(/\s*\n\s*/g, ". ");
4511
+ out = out.replace(/(?:\.\s*){2,}/g, ". ");
4512
+ return out.replace(/\s{2,}/g, " ").trim();
4513
+ }
4514
+ function isSpeechSupported() {
4515
+ return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
4516
+ }
4517
+ function stopSpeech() {
4518
+ if (!isSpeechSupported()) return;
4519
+ window.speechSynthesis.cancel();
4520
+ }
4521
+ var speechInterruptListeners = /* @__PURE__ */ new Set();
4522
+ var pageListenersAttached = false;
4523
+ var lastPathname = "";
4524
+ var originalPushState = null;
4525
+ var originalReplaceState = null;
4526
+ var patchedPushState = null;
4527
+ var patchedReplaceState = null;
4528
+ function currentPathname() {
4529
+ return window.location.pathname;
4530
+ }
4531
+ function notifySpeechInterrupts() {
4532
+ if (speechInterruptListeners.size === 0) return;
4533
+ stopSpeech();
4534
+ for (const listener of speechInterruptListeners) {
4535
+ listener();
4536
+ }
4537
+ }
4538
+ function interruptIfPathChanged(nextPath) {
4539
+ if (nextPath === lastPathname) return;
4540
+ lastPathname = nextPath;
4541
+ notifySpeechInterrupts();
4542
+ }
4543
+ function patchHistoryMethod(original) {
4544
+ return function patched(data, unused, url) {
4545
+ const result = original.call(this, data, unused, url);
4546
+ interruptIfPathChanged(currentPathname());
4547
+ return result;
4548
+ };
4549
+ }
4550
+ function historyMethodState(name) {
4551
+ return name === "pushState" ? {
4552
+ original: originalPushState,
4553
+ patched: patchedPushState,
4554
+ set(original, patched) {
4555
+ originalPushState = original;
4556
+ patchedPushState = patched;
4286
4557
  }
4287
- );
4558
+ } : {
4559
+ original: originalReplaceState,
4560
+ patched: patchedReplaceState,
4561
+ set(original, patched) {
4562
+ originalReplaceState = original;
4563
+ patchedReplaceState = patched;
4564
+ }
4565
+ };
4566
+ }
4567
+ function patchHistoryNamed(name) {
4568
+ const state = historyMethodState(name);
4569
+ const current = history[name];
4570
+ if (state.patched && current === state.patched) return;
4571
+ const patched = patchHistoryMethod(current);
4572
+ state.set(current, patched);
4573
+ history[name] = patched;
4574
+ }
4575
+ function restoreHistoryMethod(name) {
4576
+ const state = historyMethodState(name);
4577
+ if (!state.patched || !state.original || typeof history === "undefined") {
4578
+ return false;
4579
+ }
4580
+ if (history[name] !== state.patched) return false;
4581
+ history[name] = state.original;
4582
+ state.set(null, null);
4583
+ return true;
4584
+ }
4585
+ function handlePageHide() {
4586
+ notifySpeechInterrupts();
4587
+ }
4588
+ function handlePopState() {
4589
+ interruptIfPathChanged(currentPathname());
4590
+ }
4591
+ function handleVisibilityChange() {
4592
+ if (document.visibilityState === "hidden") {
4593
+ notifySpeechInterrupts();
4594
+ }
4595
+ }
4596
+ function attachPageListeners() {
4597
+ if (pageListenersAttached || typeof window === "undefined") return;
4598
+ pageListenersAttached = true;
4599
+ window.addEventListener("pagehide", handlePageHide);
4600
+ window.addEventListener("popstate", handlePopState);
4601
+ document.addEventListener("visibilitychange", handleVisibilityChange);
4602
+ }
4603
+ function detachPageListeners() {
4604
+ if (!pageListenersAttached || typeof window === "undefined") return;
4605
+ window.removeEventListener("pagehide", handlePageHide);
4606
+ window.removeEventListener("popstate", handlePopState);
4607
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
4608
+ pageListenersAttached = false;
4609
+ }
4610
+ function ensureSpeechInterruptsPatched() {
4611
+ if (typeof window === "undefined") return;
4612
+ lastPathname = currentPathname();
4613
+ patchHistoryNamed("pushState");
4614
+ patchHistoryNamed("replaceState");
4615
+ attachPageListeners();
4616
+ }
4617
+ function teardownSpeechInterrupts() {
4618
+ detachPageListeners();
4619
+ restoreHistoryMethod("pushState");
4620
+ restoreHistoryMethod("replaceState");
4621
+ if (!patchedPushState && !patchedReplaceState) {
4622
+ lastPathname = "";
4623
+ }
4624
+ }
4625
+ function subscribeSpeechInterrupts(onInterrupt) {
4626
+ if (typeof window === "undefined") return () => {
4627
+ };
4628
+ ensureSpeechInterruptsPatched();
4629
+ speechInterruptListeners.add(onInterrupt);
4630
+ return () => {
4631
+ speechInterruptListeners.delete(onInterrupt);
4632
+ if (speechInterruptListeners.size === 0) {
4633
+ teardownSpeechInterrupts();
4634
+ }
4635
+ };
4288
4636
  }
4289
4637
 
4290
- // src/react/components/ToolInputCard/ToolInputCard.tsx
4291
- var import_react9 = require("react");
4638
+ // src/react/components/MessageActions/MessageActions.tsx
4292
4639
  var import_jsx_runtime7 = require("react/jsx-runtime");
4293
- function isRecord5(value) {
4294
- return value !== null && typeof value === "object" && !Array.isArray(value);
4295
- }
4296
- function pathSegments(path) {
4297
- return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
4640
+ function CopyIcon() {
4641
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4642
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4643
+ "rect",
4644
+ {
4645
+ x: "5.75",
4646
+ y: "5.75",
4647
+ width: "7.5",
4648
+ height: "7.5",
4649
+ rx: "1.5",
4650
+ stroke: "currentColor",
4651
+ strokeWidth: "1.5"
4652
+ }
4653
+ ),
4654
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4655
+ "path",
4656
+ {
4657
+ 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",
4658
+ stroke: "currentColor",
4659
+ strokeWidth: "1.5"
4660
+ }
4661
+ )
4662
+ ] });
4298
4663
  }
4299
- function valueAtPath(root, path) {
4300
- let current = root;
4301
- for (const segment of pathSegments(path)) {
4302
- if (Array.isArray(current)) {
4303
- const index = Number(segment);
4304
- current = Number.isInteger(index) ? current[index] : void 0;
4305
- continue;
4664
+ function CheckIcon() {
4665
+ 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)(
4666
+ "path",
4667
+ {
4668
+ d: "M3.5 8.5l3 3 6-7",
4669
+ stroke: "currentColor",
4670
+ strokeWidth: "1.6",
4671
+ strokeLinecap: "round",
4672
+ strokeLinejoin: "round"
4306
4673
  }
4307
- current = isRecord5(current) ? current[segment] : void 0;
4308
- }
4309
- return current;
4674
+ ) });
4675
+ }
4676
+ function ThumbUpIcon() {
4677
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4678
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4679
+ "path",
4680
+ {
4681
+ d: "M4.67 6.67v8",
4682
+ stroke: "currentColor",
4683
+ strokeWidth: "1.5",
4684
+ strokeLinecap: "round"
4685
+ }
4686
+ ),
4687
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4688
+ "path",
4689
+ {
4690
+ 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",
4691
+ stroke: "currentColor",
4692
+ strokeWidth: "1.5",
4693
+ strokeLinecap: "round",
4694
+ strokeLinejoin: "round"
4695
+ }
4696
+ )
4697
+ ] });
4698
+ }
4699
+ function ThumbDownIcon() {
4700
+ 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: [
4701
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4702
+ "path",
4703
+ {
4704
+ d: "M4.67 6.67v8",
4705
+ stroke: "currentColor",
4706
+ strokeWidth: "1.5",
4707
+ strokeLinecap: "round"
4708
+ }
4709
+ ),
4710
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4711
+ "path",
4712
+ {
4713
+ 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",
4714
+ stroke: "currentColor",
4715
+ strokeWidth: "1.5",
4716
+ strokeLinecap: "round",
4717
+ strokeLinejoin: "round"
4718
+ }
4719
+ )
4720
+ ] }) });
4721
+ }
4722
+ function RegenerateIcon() {
4723
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4724
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4725
+ "path",
4726
+ {
4727
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
4728
+ stroke: "currentColor",
4729
+ strokeWidth: "1.5",
4730
+ strokeLinecap: "round"
4731
+ }
4732
+ ),
4733
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4734
+ "path",
4735
+ {
4736
+ d: "M14 2v3.33h-3.33",
4737
+ stroke: "currentColor",
4738
+ strokeWidth: "1.5",
4739
+ strokeLinecap: "round",
4740
+ strokeLinejoin: "round"
4741
+ }
4742
+ ),
4743
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4744
+ "path",
4745
+ {
4746
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
4747
+ stroke: "currentColor",
4748
+ strokeWidth: "1.5",
4749
+ strokeLinecap: "round"
4750
+ }
4751
+ ),
4752
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4753
+ "path",
4754
+ {
4755
+ d: "M5.33 10.67H2V14",
4756
+ stroke: "currentColor",
4757
+ strokeWidth: "1.5",
4758
+ strokeLinecap: "round",
4759
+ strokeLinejoin: "round"
4760
+ }
4761
+ )
4762
+ ] });
4763
+ }
4764
+ function MoreIcon() {
4765
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4766
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
4767
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
4768
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
4769
+ ] });
4770
+ }
4771
+ function SourcesIcon() {
4772
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4773
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4774
+ "path",
4775
+ {
4776
+ 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",
4777
+ stroke: "currentColor",
4778
+ strokeWidth: "1.4",
4779
+ strokeLinecap: "round",
4780
+ strokeLinejoin: "round"
4781
+ }
4782
+ ),
4783
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4784
+ "path",
4785
+ {
4786
+ d: "M8 4.5v9",
4787
+ stroke: "currentColor",
4788
+ strokeWidth: "1.4",
4789
+ strokeLinecap: "round"
4790
+ }
4791
+ )
4792
+ ] });
4793
+ }
4794
+ function ReadAloudIcon() {
4795
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4796
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4797
+ "path",
4798
+ {
4799
+ 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",
4800
+ stroke: "currentColor",
4801
+ strokeWidth: "1.4",
4802
+ strokeLinecap: "round",
4803
+ strokeLinejoin: "round"
4804
+ }
4805
+ ),
4806
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4807
+ "path",
4808
+ {
4809
+ 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",
4810
+ stroke: "currentColor",
4811
+ strokeWidth: "1.4",
4812
+ strokeLinecap: "round"
4813
+ }
4814
+ )
4815
+ ] });
4816
+ }
4817
+ function StopIcon() {
4818
+ 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)(
4819
+ "rect",
4820
+ {
4821
+ x: "4",
4822
+ y: "4",
4823
+ width: "8",
4824
+ height: "8",
4825
+ rx: "1.5",
4826
+ stroke: "currentColor",
4827
+ strokeWidth: "1.5"
4828
+ }
4829
+ ) });
4830
+ }
4831
+ async function writeToClipboard(text) {
4832
+ try {
4833
+ await navigator.clipboard.writeText(text);
4834
+ } catch {
4835
+ const textarea = document.createElement("textarea");
4836
+ textarea.value = text;
4837
+ textarea.style.position = "fixed";
4838
+ textarea.style.opacity = "0";
4839
+ document.body.appendChild(textarea);
4840
+ textarea.select();
4841
+ document.execCommand("copy");
4842
+ textarea.remove();
4843
+ }
4844
+ }
4845
+ function formatAnsweredAt(answeredAt) {
4846
+ if (!answeredAt) return null;
4847
+ const date = new Date(answeredAt);
4848
+ if (Number.isNaN(date.getTime())) return null;
4849
+ return new Intl.DateTimeFormat(void 0, {
4850
+ dateStyle: "medium",
4851
+ timeStyle: "short"
4852
+ }).format(date);
4853
+ }
4854
+ function resolveMenuPosition(input) {
4855
+ const padding = 8;
4856
+ const { button, menuHeight, menuWidth, rail } = input;
4857
+ if (!rail) {
4858
+ return {
4859
+ left: button.left,
4860
+ top: button.top - menuHeight - 6
4861
+ };
4862
+ }
4863
+ let left = button.left - rail.left;
4864
+ let top = button.top - rail.top - menuHeight - 6;
4865
+ left = Math.min(
4866
+ Math.max(left, padding),
4867
+ rail.width - menuWidth - padding
4868
+ );
4869
+ if (top < padding) {
4870
+ top = button.bottom - rail.top + 6;
4871
+ }
4872
+ top = Math.min(top, rail.height - menuHeight - padding);
4873
+ return { left, top };
4874
+ }
4875
+ function MessageActions({
4876
+ answeredAt,
4877
+ copyText,
4878
+ disabled = false,
4879
+ onOpenReceipt,
4880
+ onRegenerate,
4881
+ onFeedback,
4882
+ readAloud = false,
4883
+ receiptSteps,
4884
+ speechText
4885
+ }) {
4886
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
4887
+ const [copied, setCopied] = (0, import_react11.useState)(false);
4888
+ const [rating, setRating] = (0, import_react11.useState)(null);
4889
+ const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4890
+ const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4891
+ const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4892
+ const [speechSupported, setSpeechSupported] = (0, import_react11.useState)(null);
4893
+ const copyTimerRef = (0, import_react11.useRef)(null);
4894
+ const menuRef = (0, import_react11.useRef)(null);
4895
+ const portaledMenuRef = (0, import_react11.useRef)(null);
4896
+ const moreButtonRef = (0, import_react11.useRef)(null);
4897
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4898
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4899
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4900
+ const readAloudEligible = Boolean(readAloud && resolvedSpeechText);
4901
+ const canReadAloud = readAloudEligible && speechSupported === true;
4902
+ const showMenu = canOpenReceipt || (speechSupported === null ? readAloudEligible : canReadAloud);
4903
+ (0, import_react11.useLayoutEffect)(() => {
4904
+ setSpeechSupported(isSpeechSupported());
4905
+ }, []);
4906
+ (0, import_react11.useLayoutEffect)(() => {
4907
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4908
+ setMenuPosition(null);
4909
+ return;
4910
+ }
4911
+ const button = moreButtonRef.current.getBoundingClientRect();
4912
+ const menu2 = portaledMenuRef.current;
4913
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
4914
+ setMenuPosition(
4915
+ resolveMenuPosition({
4916
+ button,
4917
+ menuHeight: menu2.offsetHeight,
4918
+ menuWidth: menu2.offsetWidth || 190,
4919
+ rail
4920
+ })
4921
+ );
4922
+ }, [menuOpen, menuPortalRoot]);
4923
+ (0, import_react11.useEffect)(() => {
4924
+ const unsubscribe = subscribeSpeechInterrupts(() => setSpeaking(false));
4925
+ return () => {
4926
+ unsubscribe();
4927
+ if (copyTimerRef.current !== null) {
4928
+ window.clearTimeout(copyTimerRef.current);
4929
+ }
4930
+ stopSpeech();
4931
+ };
4932
+ }, []);
4933
+ (0, import_react11.useEffect)(() => {
4934
+ if (!menuOpen) return;
4935
+ const handlePointerDown = (event) => {
4936
+ const target = event.target;
4937
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
4938
+ setMenuOpen(false);
4939
+ }
4940
+ };
4941
+ const handleKeyDown = (event) => {
4942
+ if (event.key !== "Escape") return;
4943
+ event.preventDefault();
4944
+ event.stopPropagation();
4945
+ setMenuOpen(false);
4946
+ };
4947
+ document.addEventListener("pointerdown", handlePointerDown);
4948
+ document.addEventListener("keydown", handleKeyDown);
4949
+ return () => {
4950
+ document.removeEventListener("pointerdown", handlePointerDown);
4951
+ document.removeEventListener("keydown", handleKeyDown);
4952
+ };
4953
+ }, [menuOpen]);
4954
+ function handleCopy() {
4955
+ void writeToClipboard(copyText);
4956
+ setCopied(true);
4957
+ if (copyTimerRef.current !== null) {
4958
+ window.clearTimeout(copyTimerRef.current);
4959
+ }
4960
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
4961
+ }
4962
+ function handleFeedback(next) {
4963
+ const resolved = rating === next ? null : next;
4964
+ setRating(resolved);
4965
+ if (resolved) onFeedback?.(resolved);
4966
+ }
4967
+ function handleReadAloud() {
4968
+ if (!canReadAloud) return;
4969
+ setMenuOpen(false);
4970
+ if (speaking) {
4971
+ stopSpeech();
4972
+ setSpeaking(false);
4973
+ return;
4974
+ }
4975
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4976
+ utterance.onend = () => setSpeaking(false);
4977
+ utterance.onerror = () => setSpeaking(false);
4978
+ stopSpeech();
4979
+ window.speechSynthesis.speak(utterance);
4980
+ setSpeaking(true);
4981
+ }
4982
+ const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4983
+ "div",
4984
+ {
4985
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
4986
+ ref: portaledMenuRef,
4987
+ role: "menu",
4988
+ style: menuPosition ? {
4989
+ left: `${menuPosition.left}px`,
4990
+ top: `${menuPosition.top}px`
4991
+ } : { visibility: "hidden" },
4992
+ children: [
4993
+ answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
4994
+ "Answered ",
4995
+ answeredLabel
4996
+ ] }) : null,
4997
+ canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4998
+ "button",
4999
+ {
5000
+ type: "button",
5001
+ className: "agent-message-actions__menu-item",
5002
+ role: "menuitem",
5003
+ onClick: () => {
5004
+ setMenuOpen(false);
5005
+ onOpenReceipt?.();
5006
+ },
5007
+ children: [
5008
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
5009
+ "View sources"
5010
+ ]
5011
+ }
5012
+ ) : null,
5013
+ canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5014
+ "button",
5015
+ {
5016
+ type: "button",
5017
+ className: "agent-message-actions__menu-item",
5018
+ role: "menuitem",
5019
+ onClick: handleReadAloud,
5020
+ children: [
5021
+ speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
5022
+ speaking ? "Stop reading" : "Read aloud"
5023
+ ]
5024
+ }
5025
+ ) : null
5026
+ ]
5027
+ }
5028
+ ) : null;
5029
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
5030
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5031
+ "button",
5032
+ {
5033
+ type: "button",
5034
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
5035
+ "aria-label": copied ? "Copied" : "Copy answer",
5036
+ title: copied ? "Copied" : "Copy answer",
5037
+ disabled,
5038
+ onClick: handleCopy,
5039
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
5040
+ }
5041
+ ),
5042
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5043
+ "button",
5044
+ {
5045
+ type: "button",
5046
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
5047
+ "aria-label": "Good answer",
5048
+ "aria-pressed": rating === "positive",
5049
+ title: "Good answer",
5050
+ disabled,
5051
+ onClick: () => handleFeedback("positive"),
5052
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
5053
+ }
5054
+ ),
5055
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5056
+ "button",
5057
+ {
5058
+ type: "button",
5059
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
5060
+ "aria-label": "Bad answer",
5061
+ "aria-pressed": rating === "negative",
5062
+ title: "Bad answer",
5063
+ disabled,
5064
+ onClick: () => handleFeedback("negative"),
5065
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
5066
+ }
5067
+ ),
5068
+ onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5069
+ "button",
5070
+ {
5071
+ type: "button",
5072
+ className: "agent-message-actions__button",
5073
+ "aria-label": "Regenerate answer",
5074
+ title: "Regenerate answer",
5075
+ disabled,
5076
+ onClick: onRegenerate,
5077
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
5078
+ }
5079
+ ) : null,
5080
+ showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
5081
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5082
+ "button",
5083
+ {
5084
+ ref: moreButtonRef,
5085
+ type: "button",
5086
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
5087
+ "aria-label": "More actions",
5088
+ "aria-haspopup": "menu",
5089
+ "aria-expanded": menuOpen,
5090
+ title: "More actions",
5091
+ disabled,
5092
+ onClick: () => setMenuOpen((open) => !open),
5093
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
5094
+ }
5095
+ ),
5096
+ menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
5097
+ ] }) : null
5098
+ ] });
5099
+ }
5100
+
5101
+ // src/react/components/HumanInputCard/HumanInputCard.tsx
5102
+ var import_react13 = require("react");
5103
+
5104
+ // src/react/components/ConfirmationCard/ConfirmationCard.tsx
5105
+ var import_jsx_runtime8 = require("react/jsx-runtime");
5106
+ function ConfirmationCard({
5107
+ disabled = false,
5108
+ request,
5109
+ onRespond
5110
+ }) {
5111
+ const options = request.options ?? [];
5112
+ const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
5113
+ const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
5114
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5115
+ "section",
5116
+ {
5117
+ className: "confirmation-card",
5118
+ "aria-labelledby": `confirmation-${request.requestId}`,
5119
+ children: [
5120
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
5121
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
5122
+ prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
5123
+ ] }),
5124
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5125
+ "button",
5126
+ {
5127
+ type: "button",
5128
+ className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
5129
+ disabled,
5130
+ onClick: () => onRespond?.({
5131
+ requestId: request.requestId,
5132
+ optionId: option.id
5133
+ }),
5134
+ children: option.label
5135
+ },
5136
+ option.id
5137
+ )) })
5138
+ ]
5139
+ }
5140
+ );
5141
+ }
5142
+
5143
+ // src/react/components/ToolInputCard/ToolInputCard.tsx
5144
+ var import_react12 = require("react");
5145
+ var import_jsx_runtime9 = require("react/jsx-runtime");
5146
+ function isRecord5(value) {
5147
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5148
+ }
5149
+ function pathSegments(path) {
5150
+ return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
5151
+ }
5152
+ function valueAtPath(root, path) {
5153
+ let current = root;
5154
+ for (const segment of pathSegments(path)) {
5155
+ if (Array.isArray(current)) {
5156
+ const index = Number(segment);
5157
+ current = Number.isInteger(index) ? current[index] : void 0;
5158
+ continue;
5159
+ }
5160
+ current = isRecord5(current) ? current[segment] : void 0;
5161
+ }
5162
+ return current;
4310
5163
  }
4311
5164
  function initialFieldValue(field, surface) {
4312
5165
  const supplied = valueAtPath(surface.values, field.path);
@@ -4413,7 +5266,7 @@ function FieldDescription({
4413
5266
  field,
4414
5267
  id
4415
5268
  }) {
4416
- return field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5269
+ return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4417
5270
  }
4418
5271
  function ChoiceField({
4419
5272
  field,
@@ -4432,7 +5285,7 @@ function ChoiceField({
4432
5285
  const selectedIndex = options.findIndex(
4433
5286
  (option) => valuesMatch(option.value, value)
4434
5287
  );
4435
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5288
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4436
5289
  "select",
4437
5290
  {
4438
5291
  id,
@@ -4447,13 +5300,13 @@ function ChoiceField({
4447
5300
  if (option) onChange(option.value);
4448
5301
  },
4449
5302
  children: [
4450
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
4451
- options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: index, children: option.label }, optionKey(option)))
5303
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
5304
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
4452
5305
  ]
4453
5306
  }
4454
5307
  );
4455
5308
  }
4456
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5309
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4457
5310
  "div",
4458
5311
  {
4459
5312
  className: "tool-input-card__choices",
@@ -4464,8 +5317,8 @@ function ChoiceField({
4464
5317
  "aria-required": field.required,
4465
5318
  children: options.map((option, index) => {
4466
5319
  const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
4467
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__choice", children: [
4468
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5320
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
5321
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4469
5322
  "input",
4470
5323
  {
4471
5324
  type: multiple ? "checkbox" : "radio",
@@ -4487,7 +5340,7 @@ function ChoiceField({
4487
5340
  }
4488
5341
  }
4489
5342
  ),
4490
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
5343
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
4491
5344
  ] }, optionKey(option));
4492
5345
  })
4493
5346
  }
@@ -4507,9 +5360,9 @@ function ToolField({
4507
5360
  error ? `${id}-error` : ""
4508
5361
  ].filter(Boolean).join(" ");
4509
5362
  if (field.kind === "checkbox" || field.kind === "confirmation") {
4510
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
4511
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
4512
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5363
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
5364
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
5365
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4513
5366
  "input",
4514
5367
  {
4515
5368
  id,
@@ -4522,17 +5375,17 @@ function ToolField({
4522
5375
  onChange: (event) => onChange(event.target.checked)
4523
5376
  }
4524
5377
  ),
4525
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
4526
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: field.label }),
4527
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-description`, children: field.description }) : null
5378
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
5379
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
5380
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
4528
5381
  ] })
4529
5382
  ] }),
4530
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5383
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4531
5384
  ] });
4532
5385
  }
4533
- const label = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
5386
+ const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
4534
5387
  field.label,
4535
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5388
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4536
5389
  ] });
4537
5390
  const common = {
4538
5391
  id,
@@ -4544,7 +5397,7 @@ function ToolField({
4544
5397
  };
4545
5398
  let control;
4546
5399
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4547
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5400
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4548
5401
  ChoiceField,
4549
5402
  {
4550
5403
  field,
@@ -4558,7 +5411,7 @@ function ToolField({
4558
5411
  }
4559
5412
  );
4560
5413
  } else if (field.kind === "textarea" || field.kind === "json") {
4561
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5414
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4562
5415
  "textarea",
4563
5416
  {
4564
5417
  ...common,
@@ -4572,8 +5425,8 @@ function ToolField({
4572
5425
  );
4573
5426
  } else if (field.kind === "range") {
4574
5427
  const numericValue = typeof value === "number" ? value : field.min ?? 0;
4575
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__range", children: [
4576
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5428
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
5429
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4577
5430
  "input",
4578
5431
  {
4579
5432
  ...common,
@@ -4585,11 +5438,11 @@ function ToolField({
4585
5438
  onChange: (event) => onChange(Number(event.target.value))
4586
5439
  }
4587
5440
  ),
4588
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("output", { htmlFor: id, children: numericValue })
5441
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
4589
5442
  ] });
4590
5443
  } else {
4591
5444
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4592
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5445
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4593
5446
  "input",
4594
5447
  {
4595
5448
  ...common,
@@ -4607,11 +5460,11 @@ function ToolField({
4607
5460
  }
4608
5461
  );
4609
5462
  }
4610
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
5463
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
4611
5464
  label,
4612
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldDescription, { field, id: `${id}-description` }),
5465
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
4613
5466
  control,
4614
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5467
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4615
5468
  ] });
4616
5469
  }
4617
5470
  function ToolInputCard({
@@ -4619,11 +5472,11 @@ function ToolInputCard({
4619
5472
  surface,
4620
5473
  onSubmit
4621
5474
  }) {
4622
- const [values, setValues] = (0, import_react9.useState)(
5475
+ const [values, setValues] = (0, import_react12.useState)(
4623
5476
  () => initialValues(surface)
4624
5477
  );
4625
- const [touched, setTouched] = (0, import_react9.useState)(() => /* @__PURE__ */ new Set());
4626
- const [submitted, setSubmitted] = (0, import_react9.useState)(false);
5478
+ const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
5479
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
4627
5480
  const errors = Object.fromEntries(
4628
5481
  surface.fields.map((field) => [
4629
5482
  field.path,
@@ -4648,14 +5501,14 @@ function ToolInputCard({
4648
5501
  onSubmit?.(surface, result);
4649
5502
  }
4650
5503
  if (submitted) {
4651
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5504
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4652
5505
  "section",
4653
5506
  {
4654
5507
  className: "tool-input-card tool-input-card--submitted",
4655
5508
  role: "status",
4656
5509
  children: [
4657
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
4658
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5510
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
5511
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
4659
5512
  surface.title,
4660
5513
  " submitted"
4661
5514
  ] })
@@ -4663,18 +5516,18 @@ function ToolInputCard({
4663
5516
  }
4664
5517
  );
4665
5518
  }
4666
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5519
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4667
5520
  "section",
4668
5521
  {
4669
5522
  className: "tool-input-card",
4670
5523
  "aria-labelledby": `tool-input-${surface.id}`,
4671
5524
  children: [
4672
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__heading", children: [
4673
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
4674
- surface.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: surface.description }) : null
5525
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
5526
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5527
+ surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
4675
5528
  ] }),
4676
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
4677
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5529
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
5530
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4678
5531
  ToolField,
4679
5532
  {
4680
5533
  disabled,
@@ -4687,8 +5540,8 @@ function ToolInputCard({
4687
5540
  },
4688
5541
  field.path
4689
5542
  )) }),
4690
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__actions", children: [
4691
- surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5543
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
5544
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4692
5545
  "button",
4693
5546
  {
4694
5547
  type: "button",
@@ -4701,7 +5554,7 @@ function ToolInputCard({
4701
5554
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4702
5555
  }
4703
5556
  ) : null,
4704
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5557
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4705
5558
  ] })
4706
5559
  ] })
4707
5560
  ]
@@ -4710,17 +5563,17 @@ function ToolInputCard({
4710
5563
  }
4711
5564
 
4712
5565
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4713
- var import_jsx_runtime8 = require("react/jsx-runtime");
5566
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4714
5567
  function HumanInputCard({
4715
5568
  disabled = false,
4716
5569
  request,
4717
5570
  onRespond
4718
5571
  }) {
4719
- const [text, setText] = (0, import_react10.useState)("");
5572
+ const [text, setText] = (0, import_react13.useState)("");
4720
5573
  const options = request.options ?? [];
4721
5574
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4722
5575
  if (request.ui) {
4723
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5576
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4724
5577
  ToolInputCard,
4725
5578
  {
4726
5579
  disabled,
@@ -4730,7 +5583,7 @@ function HumanInputCard({
4730
5583
  );
4731
5584
  }
4732
5585
  if (options.length > 0) {
4733
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5586
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4734
5587
  ConfirmationCard,
4735
5588
  {
4736
5589
  disabled,
@@ -4745,17 +5598,17 @@ function HumanInputCard({
4745
5598
  if (!value || disabled) return;
4746
5599
  onRespond?.({ requestId: request.requestId, text: value });
4747
5600
  }
4748
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5601
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4749
5602
  "section",
4750
5603
  {
4751
5604
  className: "human-input-card",
4752
5605
  "aria-labelledby": `human-input-${request.requestId}`,
4753
5606
  children: [
4754
- /* @__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 }) }),
4755
- showText ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: submitText, children: [
4756
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
4757
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
4758
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5607
+ /* @__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 }) }),
5608
+ showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
5609
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5610
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
5611
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4759
5612
  "input",
4760
5613
  {
4761
5614
  id: `human-input-text-${request.requestId}`,
@@ -4764,39 +5617,39 @@ function HumanInputCard({
4764
5617
  onChange: (event) => setText(event.target.value)
4765
5618
  }
4766
5619
  ),
4767
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5620
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4768
5621
  ] })
4769
5622
  ] }) : null,
4770
- !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
5623
+ !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
4771
5624
  ]
4772
5625
  }
4773
5626
  );
4774
5627
  }
4775
5628
 
4776
5629
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4777
- var import_jsx_runtime9 = require("react/jsx-runtime");
5630
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4778
5631
  function CollectionResultCard({
4779
5632
  result
4780
5633
  }) {
4781
5634
  const empty = result.items.length === 0;
4782
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5635
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4783
5636
  "section",
4784
5637
  {
4785
5638
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4786
5639
  "aria-label": result.title,
4787
5640
  children: [
4788
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-result-card__heading", children: [
4789
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4790
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: result.title })
5641
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
5642
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5643
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
4791
5644
  ] }),
4792
- 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: [
4793
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
4794
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: item.description }) : null,
4795
- item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
4796
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: detail.label }),
4797
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: detail.value })
5645
+ 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: [
5646
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
5647
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
5648
+ item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
5649
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
5650
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
4798
5651
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4799
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
5652
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4800
5653
  ] }, item.title)) })
4801
5654
  ]
4802
5655
  }
@@ -4804,26 +5657,26 @@ function CollectionResultCard({
4804
5657
  }
4805
5658
 
4806
5659
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4807
- var import_jsx_runtime10 = require("react/jsx-runtime");
5660
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4808
5661
  function EntityResultCard({
4809
5662
  result
4810
5663
  }) {
4811
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5664
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4812
5665
  "section",
4813
5666
  {
4814
5667
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4815
5668
  "aria-label": result.title,
4816
5669
  children: [
4817
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "tool-result-card__heading", children: [
4818
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4819
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: result.title })
5670
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
5671
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5672
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
4820
5673
  ] }),
4821
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: result.description }) : null,
4822
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
4823
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dt", { children: detail.label }),
4824
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dd", { children: detail.value })
5674
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
5675
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
5676
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
5677
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
4825
5678
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4826
- 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)(
5679
+ 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)(
4827
5680
  "a",
4828
5681
  {
4829
5682
  href: link.href,
@@ -4839,24 +5692,24 @@ function EntityResultCard({
4839
5692
  }
4840
5693
 
4841
5694
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4842
- var import_jsx_runtime11 = require("react/jsx-runtime");
5695
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4843
5696
  function SignatureResultCard({
4844
5697
  result
4845
5698
  }) {
4846
5699
  const primaryLink = result.links?.[0];
4847
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5700
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4848
5701
  "section",
4849
5702
  {
4850
5703
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4851
5704
  "aria-label": result.title,
4852
5705
  children: [
4853
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
4854
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4855
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
5706
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
5707
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5708
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
4856
5709
  ] }),
4857
- result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
4858
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: result.description }) : null,
4859
- primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5710
+ result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5711
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
5712
+ primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4860
5713
  "a",
4861
5714
  {
4862
5715
  className: "signature-result-card__cta",
@@ -4872,26 +5725,26 @@ function SignatureResultCard({
4872
5725
  }
4873
5726
 
4874
5727
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4875
- var import_jsx_runtime12 = require("react/jsx-runtime");
5728
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4876
5729
  function ToolResultCard({
4877
5730
  result
4878
5731
  }) {
4879
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5732
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4880
5733
  "section",
4881
5734
  {
4882
5735
  className: `tool-result-card tool-result-card--${result.status}`,
4883
5736
  "aria-label": result.title,
4884
5737
  children: [
4885
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
4886
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4887
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
5738
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
5739
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5740
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
4888
5741
  ] }),
4889
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
4890
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
4891
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
4892
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
5742
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
5743
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5744
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
5745
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
4893
5746
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4894
- 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)(
5747
+ 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)(
4895
5748
  "a",
4896
5749
  {
4897
5750
  href: link.href,
@@ -4907,14 +5760,14 @@ function ToolResultCard({
4907
5760
  }
4908
5761
 
4909
5762
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4910
- var import_jsx_runtime13 = require("react/jsx-runtime");
5763
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4911
5764
  function VisitorToolResultView({
4912
5765
  disabled = false,
4913
5766
  onToolInput,
4914
5767
  result
4915
5768
  }) {
4916
5769
  if (result.kind === "input") {
4917
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5770
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4918
5771
  ToolInputCard,
4919
5772
  {
4920
5773
  disabled,
@@ -4924,16 +5777,16 @@ function VisitorToolResultView({
4924
5777
  );
4925
5778
  }
4926
5779
  if (result.kind === "entity") {
4927
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EntityResultCard, { result });
5780
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
4928
5781
  }
4929
5782
  if (result.kind === "collection") {
4930
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollectionResultCard, { result });
5783
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
4931
5784
  }
4932
5785
  if (result.kind === "signature") {
4933
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SignatureResultCard, { result });
5786
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
4934
5787
  }
4935
5788
  if (result.kind === "summary") {
4936
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResultCard, { result });
5789
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
4937
5790
  }
4938
5791
  return null;
4939
5792
  }
@@ -4942,9 +5795,9 @@ function isRenderableVisitorToolResult(result) {
4942
5795
  }
4943
5796
 
4944
5797
  // src/react/components/AgentRail/AgentRail.tsx
4945
- var import_jsx_runtime14 = require("react/jsx-runtime");
5798
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4946
5799
  function MinimizeIcon() {
4947
- 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)(
5800
+ 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)(
4948
5801
  "path",
4949
5802
  {
4950
5803
  d: "M3.5 8h9",
@@ -4954,8 +5807,8 @@ function MinimizeIcon() {
4954
5807
  }
4955
5808
  ) });
4956
5809
  }
4957
- function CloseIcon() {
4958
- 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)(
5810
+ function CloseIcon2() {
5811
+ 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)(
4959
5812
  "path",
4960
5813
  {
4961
5814
  d: "M4 4l8 8M12 4l-8 8",
@@ -4966,7 +5819,7 @@ function CloseIcon() {
4966
5819
  ) });
4967
5820
  }
4968
5821
  function NewChatIcon() {
4969
- 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)(
5822
+ 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)(
4970
5823
  "path",
4971
5824
  {
4972
5825
  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",
@@ -4978,7 +5831,7 @@ function NewChatIcon() {
4978
5831
  ) });
4979
5832
  }
4980
5833
  function ExpandIcon() {
4981
- 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)(
5834
+ 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)(
4982
5835
  "path",
4983
5836
  {
4984
5837
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4990,7 +5843,7 @@ function ExpandIcon() {
4990
5843
  ) });
4991
5844
  }
4992
5845
  function RestoreIcon() {
4993
- 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)(
5846
+ 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)(
4994
5847
  "path",
4995
5848
  {
4996
5849
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -5001,13 +5854,30 @@ function RestoreIcon() {
5001
5854
  }
5002
5855
  ) });
5003
5856
  }
5857
+ function ChevronDownIcon() {
5858
+ 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)(
5859
+ "path",
5860
+ {
5861
+ d: "M4 6.5l4 4 4-4",
5862
+ stroke: "currentColor",
5863
+ strokeWidth: "1.6",
5864
+ strokeLinecap: "round",
5865
+ strokeLinejoin: "round"
5866
+ }
5867
+ ) });
5868
+ }
5869
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
5004
5870
  function AgentRail({
5005
5871
  state,
5006
5872
  theme,
5007
5873
  colorScheme = "auto",
5008
5874
  brandLabel = "",
5009
5875
  brandLogoUrl,
5010
- poweredByLabel = "Powered by Webless",
5876
+ poweredByLabel,
5877
+ disclaimerLabel,
5878
+ disclaimerLink,
5879
+ answerReceipt = false,
5880
+ readAloud = false,
5011
5881
  composerPlaceholder = "Ask anything\u2026",
5012
5882
  mobileFullscreen = false,
5013
5883
  expanded = false,
@@ -5016,16 +5886,26 @@ function AgentRail({
5016
5886
  onExpandToggle,
5017
5887
  onReset,
5018
5888
  onRetry,
5889
+ onRegenerate,
5890
+ onFeedback,
5019
5891
  onSubmit,
5020
5892
  onFollowUpSelect,
5021
5893
  onBook,
5022
5894
  onInputResponse,
5023
5895
  onToolInput
5024
5896
  }) {
5025
- const transcriptRef = (0, import_react11.useRef)(null);
5897
+ const railRef = (0, import_react14.useRef)(null);
5898
+ const overlayRef = (0, import_react14.useRef)(null);
5899
+ const transcriptRef = (0, import_react14.useRef)(null);
5900
+ const pinnedToBottomRef = (0, import_react14.useRef)(true);
5901
+ const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
5902
+ const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
5903
+ const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
5904
+ const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
5026
5905
  const resolvedBrandLabel = brandLabel.trim();
5027
5906
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
5028
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react11.useState)(null);
5907
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5908
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
5029
5909
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
5030
5910
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
5031
5911
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -5076,10 +5956,15 @@ function AgentRail({
5076
5956
  );
5077
5957
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
5078
5958
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
5079
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5959
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5960
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
5080
5961
  const hasVisitorMessages2 = state.messages.some(
5081
5962
  (message) => message.role === "visitor"
5082
5963
  );
5964
+ const hasAgentResponseAfterVisitor = state.messages.some(
5965
+ (message) => message.role === "agent" && message.id !== "greeting"
5966
+ );
5967
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
5083
5968
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
5084
5969
  const greeting = state.messages.find(
5085
5970
  (message) => message.role === "agent" && message.id === "greeting"
@@ -5101,6 +5986,7 @@ function AgentRail({
5101
5986
  }
5102
5987
  }
5103
5988
  const lastIsAgent = lastMessage?.role === "agent";
5989
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
5104
5990
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
5105
5991
  createdAt: 0,
5106
5992
  id: "streaming-response",
@@ -5127,10 +6013,36 @@ function AgentRail({
5127
6013
  hasPendingConfirmation,
5128
6014
  enabled: lastIsAgent && !isBusy
5129
6015
  });
5130
- (0, import_react11.useEffect)(() => {
6016
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
6017
+ (0, import_react14.useEffect)(() => {
6018
+ if (state.phase !== "complete") {
6019
+ setReceiptOpen(false);
6020
+ }
6021
+ }, [state.phase]);
6022
+ function handleSubmit(message) {
6023
+ setReceiptOpen(false);
6024
+ onSubmit?.(message);
6025
+ }
6026
+ function handleRegenerate() {
6027
+ setReceiptOpen(false);
6028
+ onRegenerate?.();
6029
+ }
6030
+ function handleReset() {
6031
+ setReceiptOpen(false);
6032
+ onReset?.();
6033
+ }
6034
+ function handleFollowUpSelect(label) {
6035
+ setReceiptOpen(false);
6036
+ onFollowUpSelect?.(label);
6037
+ }
6038
+ (0, import_react14.useEffect)(() => {
5131
6039
  const node = transcriptRef.current;
5132
6040
  if (!node) return;
5133
- node.scrollTop = node.scrollHeight;
6041
+ const lastMessage2 = state.messages.at(-1);
6042
+ const visitorJustSent = lastMessage2?.role === "visitor";
6043
+ if (pinnedToBottomRef.current || visitorJustSent) {
6044
+ node.scrollTop = node.scrollHeight;
6045
+ }
5134
6046
  }, [
5135
6047
  state.messages,
5136
6048
  state.toolSteps,
@@ -5138,10 +6050,75 @@ function AgentRail({
5138
6050
  state.followUps,
5139
6051
  state.journey
5140
6052
  ]);
5141
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
6053
+ (0, import_react14.useEffect)(() => {
6054
+ const node = transcriptRef.current;
6055
+ if (!node) return;
6056
+ const handleScroll = () => {
6057
+ if (node.clientHeight === 0) return;
6058
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
6059
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
6060
+ pinnedToBottomRef.current = pinned;
6061
+ setShowJumpToLatest(!pinned);
6062
+ };
6063
+ node.addEventListener("scroll", handleScroll, { passive: true });
6064
+ handleScroll();
6065
+ return () => node.removeEventListener("scroll", handleScroll);
6066
+ }, []);
6067
+ (0, import_react14.useEffect)(() => {
6068
+ const node = transcriptRef.current;
6069
+ if (!node) return;
6070
+ const observer = new ResizeObserver(() => {
6071
+ if (node.clientHeight === 0) return;
6072
+ if (pinnedToBottomRef.current) {
6073
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
6074
+ }
6075
+ });
6076
+ observer.observe(node);
6077
+ return () => observer.disconnect();
6078
+ }, []);
6079
+ (0, import_react14.useEffect)(() => {
6080
+ if (!receiptOpen) {
6081
+ lockedTranscriptScrollTopRef.current = null;
6082
+ return;
6083
+ }
6084
+ const node = transcriptRef.current;
6085
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
6086
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
6087
+ }, [receiptOpen]);
6088
+ function openReceipt() {
6089
+ const node = transcriptRef.current;
6090
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
6091
+ setReceiptOpen(true);
6092
+ }
6093
+ function scrollToLatest() {
6094
+ const node = transcriptRef.current;
6095
+ if (!node) return;
6096
+ pinnedToBottomRef.current = true;
6097
+ setShowJumpToLatest(false);
6098
+ const reduceMotion = window.matchMedia(
6099
+ "(prefers-reduced-motion: reduce)"
6100
+ ).matches;
6101
+ if (reduceMotion) {
6102
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
6103
+ return;
6104
+ }
6105
+ smoothScrollToLatestRef.current = true;
6106
+ const settle = () => {
6107
+ smoothScrollToLatestRef.current = false;
6108
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
6109
+ const pinned = distanceFromBottom < 48;
6110
+ pinnedToBottomRef.current = pinned;
6111
+ setShowJumpToLatest(!pinned);
6112
+ };
6113
+ node.addEventListener("scrollend", settle, { once: true });
6114
+ window.setTimeout(settle, 900);
6115
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
6116
+ }
6117
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5142
6118
  "aside",
5143
6119
  {
5144
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
6120
+ ref: railRef,
6121
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
5145
6122
  "data-not-typeset": "",
5146
6123
  "data-color-scheme": resolvedColorScheme,
5147
6124
  spellCheck: false,
@@ -5151,196 +6128,242 @@ function AgentRail({
5151
6128
  autoFocus: mobileFullscreen || expanded,
5152
6129
  role: mobileFullscreen || expanded ? "dialog" : void 0,
5153
6130
  tabIndex: mobileFullscreen || expanded ? -1 : void 0,
5154
- children: [
5155
- /* @__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: [
5156
- onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5157
- "button",
5158
- {
5159
- type: "button",
5160
- className: "agent-rail__collapse",
5161
- "aria-label": "Collapse assist",
5162
- onClick: onCollapse,
5163
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MinimizeIcon, {})
5164
- }
5165
- ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5166
- "button",
5167
- {
5168
- type: "button",
5169
- className: "agent-rail__close",
5170
- "aria-label": "Close agent",
5171
- onClick: onClose,
5172
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {})
5173
- }
5174
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
5175
- resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__identity", children: [
5176
- showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5177
- "img",
5178
- {
5179
- className: "agent-rail__brand-logo",
5180
- src: resolvedBrandLogoUrl,
5181
- alt: "",
5182
- onError: () => {
5183
- setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6131
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6132
+ AgentRailOverlayContext.Provider,
6133
+ {
6134
+ value: { railRef, overlayRef },
6135
+ children: [
6136
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
6137
+ /* @__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: [
6138
+ onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6139
+ "button",
6140
+ {
6141
+ type: "button",
6142
+ className: "agent-rail__collapse",
6143
+ "aria-label": "Collapse assist",
6144
+ onClick: onCollapse,
6145
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
6146
+ }
6147
+ ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6148
+ "button",
6149
+ {
6150
+ type: "button",
6151
+ className: "agent-rail__close",
6152
+ "aria-label": "Close agent",
6153
+ onClick: onClose,
6154
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
6155
+ }
6156
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
6157
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
6158
+ showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6159
+ "img",
6160
+ {
6161
+ className: "agent-rail__brand-logo",
6162
+ src: resolvedBrandLogoUrl,
6163
+ alt: "",
6164
+ onError: () => {
6165
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6166
+ }
6167
+ }
6168
+ ) }) : null,
6169
+ resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
6170
+ ] }) : null,
6171
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
6172
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6173
+ "button",
6174
+ {
6175
+ type: "button",
6176
+ className: "agent-rail__new-chat",
6177
+ "aria-label": "Start a new conversation",
6178
+ disabled: !hasVisitorMessages2,
6179
+ onClick: handleReset,
6180
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
6181
+ }
6182
+ ) : null,
6183
+ onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6184
+ "button",
6185
+ {
6186
+ type: "button",
6187
+ className: "agent-rail__expand",
6188
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
6189
+ onClick: onExpandToggle,
6190
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
6191
+ }
6192
+ ) : null
6193
+ ] })
6194
+ ] }) }),
6195
+ /* @__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: [
6196
+ !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
6197
+ greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6198
+ MessageBubble,
6199
+ {
6200
+ message: greeting,
6201
+ bookingDisabled: isBusy,
6202
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6203
+ onBook
6204
+ }
6205
+ ) : null,
6206
+ showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6207
+ FollowUpChips,
6208
+ {
6209
+ suggestions: state.followUps,
6210
+ disabled: isBusy,
6211
+ label: "Start here",
6212
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
6213
+ }
6214
+ ) }) : null,
6215
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6216
+ AgentActivityBubble,
6217
+ {
6218
+ brandLabel: resolvedBrandLabel,
6219
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6220
+ failed: state.phase === "error",
6221
+ steps: state.toolSteps
6222
+ }
6223
+ ) : null,
6224
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6225
+ VisitorToolResultView,
6226
+ {
6227
+ result,
6228
+ disabled: semanticSurfaceDisabled,
6229
+ onToolInput
6230
+ },
6231
+ result.id
6232
+ )),
6233
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6234
+ HumanInputCard,
6235
+ {
6236
+ request,
6237
+ onRespond: onInputResponse
6238
+ },
6239
+ request.requestId
6240
+ ))
6241
+ ] }) : null,
6242
+ visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
6243
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6244
+ MessageBubble,
6245
+ {
6246
+ message,
6247
+ bookingDisabled: isBusy,
6248
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6249
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6250
+ onBook
6251
+ }
6252
+ ),
6253
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6254
+ MessageActions,
6255
+ {
6256
+ answeredAt: message.createdAt,
6257
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6258
+ readAloud,
6259
+ receiptSteps,
6260
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6261
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6262
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6263
+ }
6264
+ ) : null,
6265
+ index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
6266
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6267
+ AgentActivityBubble,
6268
+ {
6269
+ brandLabel: resolvedBrandLabel,
6270
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6271
+ failed: state.phase === "error",
6272
+ steps: state.toolSteps
6273
+ }
6274
+ ) : null,
6275
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6276
+ VisitorToolResultView,
6277
+ {
6278
+ result,
6279
+ disabled: semanticSurfaceDisabled,
6280
+ onToolInput
6281
+ },
6282
+ result.id
6283
+ )),
6284
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6285
+ HumanInputCard,
6286
+ {
6287
+ request,
6288
+ onRespond: onInputResponse
6289
+ },
6290
+ request.requestId
6291
+ ))
6292
+ ] }) : null
6293
+ ] }, message.id)),
6294
+ streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6295
+ MessageBubble,
6296
+ {
6297
+ message: streamingMessage,
6298
+ bookingDisabled: isBusy,
6299
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6300
+ offer: state.pendingOffer,
6301
+ onBook
6302
+ }
6303
+ ) : null,
6304
+ waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
6305
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
6306
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
6307
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
6308
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
6309
+ ] }),
6310
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6311
+ ] }) : null
6312
+ ] }) }),
6313
+ 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)(
6314
+ "a",
6315
+ {
6316
+ href: disclaimerLink,
6317
+ rel: "noopener noreferrer",
6318
+ target: "_blank",
6319
+ children: resolvedDisclaimerLabel
5184
6320
  }
5185
- }
5186
- ) }) : null,
5187
- resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
5188
- ] }) : null,
5189
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__actions", children: [
5190
- onReset ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5191
- "button",
5192
- {
5193
- type: "button",
5194
- className: "agent-rail__new-chat",
5195
- "aria-label": "Start a new conversation",
5196
- disabled: !hasVisitorMessages2,
5197
- onClick: onReset,
5198
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NewChatIcon, {})
5199
- }
5200
- ) : null,
5201
- onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5202
- "button",
5203
- {
5204
- type: "button",
5205
- className: "agent-rail__expand",
5206
- "aria-label": expanded ? "Exit full screen" : "Open full screen",
5207
- onClick: onExpandToggle,
5208
- children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ExpandIcon, {})
5209
- }
5210
- ) : null
5211
- ] })
5212
- ] }) }),
5213
- /* @__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: [
5214
- !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
5215
- greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5216
- MessageBubble,
5217
- {
5218
- message: greeting,
5219
- bookingDisabled: isBusy,
5220
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5221
- onBook
5222
- }
5223
- ) : null,
5224
- showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5225
- FollowUpChips,
5226
- {
5227
- suggestions: state.followUps,
5228
- disabled: isBusy,
5229
- label: "Start here",
5230
- onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
5231
- }
5232
- ) }) : null,
5233
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5234
- AgentActivityBubble,
6321
+ ) : resolvedDisclaimerLabel }) }) : null,
6322
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6323
+ showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6324
+ "button",
6325
+ {
6326
+ type: "button",
6327
+ className: "agent-rail__jump-to-latest",
6328
+ "aria-label": "Jump to the latest message",
6329
+ title: "Jump to the latest message",
6330
+ onClick: scrollToLatest,
6331
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
6332
+ }
6333
+ ) : null,
6334
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6335
+ Composer,
6336
+ {
6337
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6338
+ disabled: isBusy,
6339
+ form: composerForm,
6340
+ placeholder: composerPlaceholder,
6341
+ onSubmit: handleSubmit
6342
+ }
6343
+ ),
6344
+ 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
6345
+ ] })
6346
+ ] }),
6347
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6348
+ receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6349
+ AnswerReceiptDialog,
5235
6350
  {
5236
6351
  brandLabel: resolvedBrandLabel,
5237
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5238
- failed: state.phase === "error",
5239
- steps: state.toolSteps
6352
+ onClose: () => setReceiptOpen(false),
6353
+ steps: receiptSteps
5240
6354
  }
5241
- ) : null,
5242
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5243
- VisitorToolResultView,
5244
- {
5245
- result,
5246
- disabled: semanticSurfaceDisabled,
5247
- onToolInput
5248
- },
5249
- result.id
5250
- )),
5251
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5252
- HumanInputCard,
5253
- {
5254
- request,
5255
- onRespond: onInputResponse
5256
- },
5257
- request.requestId
5258
- ))
5259
- ] }) : null,
5260
- visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__turn-block", children: [
5261
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5262
- MessageBubble,
5263
- {
5264
- message,
5265
- bookingDisabled: isBusy,
5266
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5267
- offer: index === lastAgentIndex ? state.pendingOffer : void 0,
5268
- onBook
5269
- }
5270
- ),
5271
- index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
5272
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5273
- AgentActivityBubble,
5274
- {
5275
- brandLabel: resolvedBrandLabel,
5276
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5277
- failed: state.phase === "error",
5278
- steps: state.toolSteps
5279
- }
5280
- ) : null,
5281
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5282
- VisitorToolResultView,
5283
- {
5284
- result,
5285
- disabled: semanticSurfaceDisabled,
5286
- onToolInput
5287
- },
5288
- result.id
5289
- )),
5290
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5291
- HumanInputCard,
5292
- {
5293
- request,
5294
- onRespond: onInputResponse
5295
- },
5296
- request.requestId
5297
- ))
5298
- ] }) : null
5299
- ] }, message.id)),
5300
- streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5301
- MessageBubble,
5302
- {
5303
- message: streamingMessage,
5304
- bookingDisabled: isBusy,
5305
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5306
- offer: state.pendingOffer,
5307
- onBook
5308
- }
5309
- ) : null,
5310
- waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BookingCardLoader, {}) : null,
5311
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
5312
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5313
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: "Something went wrong" }),
5314
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: state.error })
5315
- ] }),
5316
- onRetry ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
5317
- ] }) : null
5318
- ] }) }),
5319
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
5320
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5321
- Composer,
5322
- {
5323
- variant: expanded || mobileFullscreen ? "dock" : "default",
5324
- disabled: isBusy,
5325
- form: composerForm,
5326
- placeholder: composerPlaceholder,
5327
- onSubmit
5328
- }
5329
- ),
5330
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
5331
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "AI can make mistakes. Check important info." }),
5332
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: poweredByLabel })
5333
- ] }) })
5334
- ] })
5335
- ]
6355
+ ) : null
6356
+ ]
6357
+ }
6358
+ )
5336
6359
  }
5337
6360
  );
5338
6361
  }
5339
6362
 
5340
6363
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5341
- var import_jsx_runtime15 = require("react/jsx-runtime");
6364
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5342
6365
  function SparklesIcon() {
5343
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6366
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5344
6367
  "svg",
5345
6368
  {
5346
6369
  className: "assist-edge-tab__sparkles",
@@ -5348,21 +6371,21 @@ function SparklesIcon() {
5348
6371
  fill: "none",
5349
6372
  "aria-hidden": "true",
5350
6373
  children: [
5351
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6374
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5352
6375
  "path",
5353
6376
  {
5354
6377
  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",
5355
6378
  fill: "currentColor"
5356
6379
  }
5357
6380
  ),
5358
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6381
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5359
6382
  "path",
5360
6383
  {
5361
6384
  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",
5362
6385
  fill: "currentColor"
5363
6386
  }
5364
6387
  ),
5365
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6388
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5366
6389
  "path",
5367
6390
  {
5368
6391
  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",
@@ -5376,7 +6399,7 @@ function SparklesIcon() {
5376
6399
  function TabMarkIcon({ customIconUrl }) {
5377
6400
  const url = customIconUrl?.trim();
5378
6401
  if (url) {
5379
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6402
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5380
6403
  "img",
5381
6404
  {
5382
6405
  alt: "",
@@ -5386,10 +6409,10 @@ function TabMarkIcon({ customIconUrl }) {
5386
6409
  }
5387
6410
  );
5388
6411
  }
5389
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SparklesIcon, {});
6412
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
5390
6413
  }
5391
6414
  function ChevronLeftIcon() {
5392
- 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)(
6415
+ 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)(
5393
6416
  "path",
5394
6417
  {
5395
6418
  d: "M10 4L6 8l4 4",
@@ -5400,8 +6423,8 @@ function ChevronLeftIcon() {
5400
6423
  }
5401
6424
  ) });
5402
6425
  }
5403
- function ChevronDownIcon() {
5404
- 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)(
6426
+ function ChevronDownIcon2() {
6427
+ 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)(
5405
6428
  "path",
5406
6429
  {
5407
6430
  d: "M4 6l4 4 4-4",
@@ -5413,7 +6436,7 @@ function ChevronDownIcon() {
5413
6436
  ) });
5414
6437
  }
5415
6438
  function DragDots() {
5416
- 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)) });
6439
+ 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)) });
5417
6440
  }
5418
6441
  var VARIANT_COPY = {
5419
6442
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5459,7 +6482,7 @@ function AssistEdgeTab({
5459
6482
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5460
6483
  colorScheme: resolvedColorScheme
5461
6484
  };
5462
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6485
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5463
6486
  "button",
5464
6487
  {
5465
6488
  type: "button",
@@ -5471,15 +6494,15 @@ function AssistEdgeTab({
5471
6494
  tabIndex: visible ? 0 : -1,
5472
6495
  onClick: onOpen,
5473
6496
  children: [
5474
- mobile ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5475
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6497
+ mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6498
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5476
6499
  "span",
5477
6500
  {
5478
6501
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5479
6502
  "aria-hidden": "true",
5480
6503
  children: [
5481
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5482
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6504
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6505
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5483
6506
  "img",
5484
6507
  {
5485
6508
  className: "assist-edge-tab__logo",
@@ -5493,11 +6516,11 @@ function AssistEdgeTab({
5493
6516
  ]
5494
6517
  }
5495
6518
  ),
5496
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
5497
- ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5498
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5499
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5500
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6519
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
6520
+ ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6521
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6522
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6523
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5501
6524
  "img",
5502
6525
  {
5503
6526
  className: "assist-edge-tab__logo",
@@ -5509,18 +6532,18 @@ function AssistEdgeTab({
5509
6532
  }
5510
6533
  ) : null
5511
6534
  ] }),
5512
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5513
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronDownIcon, {})
6535
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6536
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
5514
6537
  ] }) : null,
5515
- variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5516
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {}),
5517
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5518
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DragDots, {})
6538
+ variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6539
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
6540
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6541
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
5519
6542
  ] }) : null,
5520
- variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5521
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5522
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5523
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6543
+ variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6544
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6545
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6546
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5524
6547
  "img",
5525
6548
  {
5526
6549
  className: "assist-edge-tab__logo",
@@ -5532,16 +6555,72 @@ function AssistEdgeTab({
5532
6555
  }
5533
6556
  ) : null
5534
6557
  ] }),
5535
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5536
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {})
6558
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6559
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
5537
6560
  ] }) : null
5538
6561
  ]
5539
6562
  }
5540
6563
  );
5541
6564
  }
5542
6565
 
6566
+ // src/react/lib/agent-feedback.ts
6567
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6568
+ function findPrecedingVisitorText(messages, agentMessageId) {
6569
+ const agentIndex = messages.findIndex(
6570
+ (message) => message.id === agentMessageId && message.role === "agent"
6571
+ );
6572
+ if (agentIndex < 0) return void 0;
6573
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6574
+ const message = messages[index];
6575
+ if (message?.role === "visitor") {
6576
+ return message.text.trim() || void 0;
6577
+ }
6578
+ }
6579
+ return void 0;
6580
+ }
6581
+ function normalizeAgentFeedbackAnswerText(text) {
6582
+ const normalized = text.replace(/\s+/g, " ").trim();
6583
+ if (!normalized) return void 0;
6584
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6585
+ }
6586
+ function buildAgentAnswerFeedbackEvent(input) {
6587
+ const positive = input.rating === "positive";
6588
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6589
+ return {
6590
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6591
+ company: input.analytics.companyIndex,
6592
+ session_id: input.visitorSessionId,
6593
+ page: input.page,
6594
+ timestamp: Date.now(),
6595
+ tracking_consent: input.analytics.trackingConsent,
6596
+ feedback_value: positive ? 1 : -1,
6597
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6598
+ feedback_rating: positive ? "helpful" : "not_helpful",
6599
+ surface: "agent_panel",
6600
+ index_id: input.indexId,
6601
+ index_version: input.version,
6602
+ message_id: input.messageId,
6603
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6604
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6605
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6606
+ };
6607
+ }
6608
+ function sendAgentAnswerFeedback(eventUrl, event) {
6609
+ try {
6610
+ void fetch(eventUrl, {
6611
+ body: JSON.stringify(event),
6612
+ credentials: "omit",
6613
+ headers: { "Content-Type": "application/json" },
6614
+ keepalive: true,
6615
+ method: "POST"
6616
+ }).catch(() => {
6617
+ });
6618
+ } catch {
6619
+ }
6620
+ }
6621
+
5543
6622
  // src/react/components/AgentWidget/AgentWidget.tsx
5544
- var import_jsx_runtime16 = require("react/jsx-runtime");
6623
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5545
6624
  function AgentWidget({
5546
6625
  indexId,
5547
6626
  customerId,
@@ -5555,13 +6634,14 @@ function AgentWidget({
5555
6634
  registerPanelController = false,
5556
6635
  colorScheme = "auto",
5557
6636
  branding,
6637
+ analytics,
5558
6638
  toolResultRegistry
5559
6639
  }) {
5560
6640
  const isMobile = useIsMobile();
5561
6641
  const placement = normalizeAgentPlacement(placementInput);
5562
- const railSlotRef = (0, import_react12.useRef)(null);
5563
- const [railCollapsed, setRailCollapsed] = (0, import_react12.useState)(defaultCollapsed);
5564
- const [railExpanded, setRailExpanded] = (0, import_react12.useState)(false);
6642
+ const railSlotRef = (0, import_react15.useRef)(null);
6643
+ const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
6644
+ const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
5565
6645
  const pageShiftActive = shouldApplyPageShift({
5566
6646
  pageShift,
5567
6647
  isMobile,
@@ -5572,7 +6652,17 @@ function AgentWidget({
5572
6652
  active: pageShiftActive,
5573
6653
  railSlotRef
5574
6654
  });
5575
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6655
+ const {
6656
+ state,
6657
+ reset,
6658
+ retry,
6659
+ regenerate,
6660
+ respondToInput,
6661
+ respondToToolInput,
6662
+ submit,
6663
+ visitorSessionId,
6664
+ sessionId
6665
+ } = useAgentChat({
5576
6666
  customerId,
5577
6667
  getUnpublishedPreviewGrant,
5578
6668
  indexId,
@@ -5604,7 +6694,7 @@ function AgentWidget({
5604
6694
  } : {},
5605
6695
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5606
6696
  };
5607
- (0, import_react12.useEffect)(() => {
6697
+ (0, import_react15.useEffect)(() => {
5608
6698
  if (!registerPanelController) return;
5609
6699
  registerAgentPanelController(customerId, {
5610
6700
  open: () => setRailCollapsed(false),
@@ -5621,7 +6711,25 @@ function AgentWidget({
5621
6711
  if (isMobile) setRailCollapsed(false);
5622
6712
  await submit(message);
5623
6713
  }
5624
- (0, import_react12.useEffect)(() => {
6714
+ function handleFeedback(rating, message) {
6715
+ if (!analytics) return;
6716
+ sendAgentAnswerFeedback(
6717
+ analytics.eventUrl,
6718
+ buildAgentAnswerFeedbackEvent({
6719
+ agentSessionId: sessionId,
6720
+ analytics,
6721
+ indexId,
6722
+ messageId: message.id,
6723
+ page: window.location.href,
6724
+ query: findPrecedingVisitorText(state.messages, message.id),
6725
+ answer: message.text,
6726
+ rating,
6727
+ version: version ?? "published",
6728
+ visitorSessionId
6729
+ })
6730
+ );
6731
+ }
6732
+ (0, import_react15.useEffect)(() => {
5625
6733
  if (railCollapsed) return;
5626
6734
  const handleKeyDown = (event) => {
5627
6735
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5655,19 +6763,19 @@ function AgentWidget({
5655
6763
  window.addEventListener("keydown", handleKeyDown);
5656
6764
  return () => window.removeEventListener("keydown", handleKeyDown);
5657
6765
  }, [isMobile, railCollapsed, railExpanded]);
5658
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "webless-agent-root", children: [
5659
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6766
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
6767
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5660
6768
  "div",
5661
6769
  {
5662
6770
  className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
5663
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6771
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5664
6772
  "div",
5665
6773
  {
5666
6774
  ref: railSlotRef,
5667
6775
  className: "webless-agent-root__rail-slot",
5668
6776
  inert: railCollapsed || void 0,
5669
6777
  "aria-hidden": railCollapsed,
5670
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6778
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5671
6779
  AgentRail,
5672
6780
  {
5673
6781
  theme,
@@ -5675,7 +6783,11 @@ function AgentWidget({
5675
6783
  brandLabel: agentName,
5676
6784
  brandLogoUrl: branding?.logoUrl,
5677
6785
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5678
- poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6786
+ poweredByLabel: branding?.poweredByLabel,
6787
+ disclaimerLabel: branding?.disclaimer,
6788
+ disclaimerLink: branding?.disclaimerLink,
6789
+ answerReceipt: branding?.answerReceipt,
6790
+ readAloud: branding?.readAloud,
5679
6791
  state,
5680
6792
  mobileFullscreen: isMobile && !railCollapsed,
5681
6793
  expanded: railExpanded,
@@ -5685,6 +6797,8 @@ function AgentWidget({
5685
6797
  onSubmit: handleSubmit,
5686
6798
  onReset: reset,
5687
6799
  onRetry: () => void retry(),
6800
+ onRegenerate: () => void regenerate(),
6801
+ onFeedback: analytics ? handleFeedback : void 0,
5688
6802
  onInputResponse: (response) => void respondToInput(response),
5689
6803
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5690
6804
  onFollowUpSelect: (label) => void handleSubmit(label),
@@ -5698,7 +6812,7 @@ function AgentWidget({
5698
6812
  )
5699
6813
  }
5700
6814
  ),
5701
- railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6815
+ railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5702
6816
  AssistEdgeTab,
5703
6817
  {
5704
6818
  variant: placement.variant,
@@ -5724,21 +6838,26 @@ function AgentWidget({
5724
6838
  }
5725
6839
  // Annotate the CommonJS export names for ESM import in node:
5726
6840
  0 && (module.exports = {
6841
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
5727
6842
  AGENT_STRUCTURED_TOOL_INPUT_HEADER,
5728
6843
  AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
5729
6844
  AgentRail,
5730
6845
  AgentWidget,
5731
6846
  AssistEdgeTab,
5732
6847
  DEFAULT_AGENT_PLACEMENT,
6848
+ MessageActions,
6849
+ buildAgentAnswerFeedbackEvent,
5733
6850
  builtInVisitorToolResultRegistry,
5734
6851
  createIdleSuggestions,
5735
6852
  defaultAgentRailTheme,
5736
6853
  defaultDarkAgentRailTheme,
6854
+ findPrecedingVisitorText,
5737
6855
  formatAgentStructuredToolInput,
5738
6856
  hasVisitorMessages,
5739
6857
  isAgentBusy,
5740
6858
  normalizeAgentPlacement,
5741
6859
  presentVisitorToolResult,
6860
+ sendAgentAnswerFeedback,
5742
6861
  useAgentChat
5743
6862
  });
5744
6863
  //# sourceMappingURL=react.cjs.map