@webless/agent 0.6.11 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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,77 +4487,564 @@ 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
- ]
4286
- }
4287
- );
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";
4288
4516
  }
4289
4517
 
4290
- // src/react/components/ToolInputCard/ToolInputCard.tsx
4291
- var import_react9 = require("react");
4518
+ // src/react/components/MessageActions/MessageActions.tsx
4292
4519
  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);
4520
+ function CopyIcon() {
4521
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4522
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4523
+ "rect",
4524
+ {
4525
+ x: "5.75",
4526
+ y: "5.75",
4527
+ width: "7.5",
4528
+ height: "7.5",
4529
+ rx: "1.5",
4530
+ stroke: "currentColor",
4531
+ strokeWidth: "1.5"
4532
+ }
4533
+ ),
4534
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4535
+ "path",
4536
+ {
4537
+ 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",
4538
+ stroke: "currentColor",
4539
+ strokeWidth: "1.5"
4540
+ }
4541
+ )
4542
+ ] });
4298
4543
  }
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;
4544
+ function CheckIcon() {
4545
+ 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)(
4546
+ "path",
4547
+ {
4548
+ d: "M3.5 8.5l3 3 6-7",
4549
+ stroke: "currentColor",
4550
+ strokeWidth: "1.6",
4551
+ strokeLinecap: "round",
4552
+ strokeLinejoin: "round"
4306
4553
  }
4307
- current = isRecord5(current) ? current[segment] : void 0;
4308
- }
4309
- return current;
4310
- }
4311
- function initialFieldValue(field, surface) {
4312
- const supplied = valueAtPath(surface.values, field.path);
4313
- if (supplied !== void 0) return supplied;
4314
- if (field.defaultValue !== void 0) return field.defaultValue;
4315
- if (field.kind === "checkbox" || field.kind === "confirmation") return false;
4316
- if (field.kind === "multi-select") return [];
4317
- if (field.kind === "range") return field.min ?? 0;
4318
- return "";
4554
+ ) });
4555
+ }
4556
+ function ThumbUpIcon() {
4557
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4558
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4559
+ "path",
4560
+ {
4561
+ d: "M4.67 6.67v8",
4562
+ stroke: "currentColor",
4563
+ strokeWidth: "1.5",
4564
+ strokeLinecap: "round"
4565
+ }
4566
+ ),
4567
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4568
+ "path",
4569
+ {
4570
+ 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",
4571
+ stroke: "currentColor",
4572
+ strokeWidth: "1.5",
4573
+ strokeLinecap: "round",
4574
+ strokeLinejoin: "round"
4575
+ }
4576
+ )
4577
+ ] });
4578
+ }
4579
+ function ThumbDownIcon() {
4580
+ 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: [
4581
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4582
+ "path",
4583
+ {
4584
+ d: "M4.67 6.67v8",
4585
+ stroke: "currentColor",
4586
+ strokeWidth: "1.5",
4587
+ strokeLinecap: "round"
4588
+ }
4589
+ ),
4590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4591
+ "path",
4592
+ {
4593
+ 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",
4594
+ stroke: "currentColor",
4595
+ strokeWidth: "1.5",
4596
+ strokeLinecap: "round",
4597
+ strokeLinejoin: "round"
4598
+ }
4599
+ )
4600
+ ] }) });
4601
+ }
4602
+ function RegenerateIcon() {
4603
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4604
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4605
+ "path",
4606
+ {
4607
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
4608
+ stroke: "currentColor",
4609
+ strokeWidth: "1.5",
4610
+ strokeLinecap: "round"
4611
+ }
4612
+ ),
4613
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4614
+ "path",
4615
+ {
4616
+ d: "M14 2v3.33h-3.33",
4617
+ stroke: "currentColor",
4618
+ strokeWidth: "1.5",
4619
+ strokeLinecap: "round",
4620
+ strokeLinejoin: "round"
4621
+ }
4622
+ ),
4623
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4624
+ "path",
4625
+ {
4626
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
4627
+ stroke: "currentColor",
4628
+ strokeWidth: "1.5",
4629
+ strokeLinecap: "round"
4630
+ }
4631
+ ),
4632
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4633
+ "path",
4634
+ {
4635
+ d: "M5.33 10.67H2V14",
4636
+ stroke: "currentColor",
4637
+ strokeWidth: "1.5",
4638
+ strokeLinecap: "round",
4639
+ strokeLinejoin: "round"
4640
+ }
4641
+ )
4642
+ ] });
4643
+ }
4644
+ function MoreIcon() {
4645
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4646
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
4647
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
4648
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
4649
+ ] });
4650
+ }
4651
+ function SourcesIcon() {
4652
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4653
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4654
+ "path",
4655
+ {
4656
+ 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",
4657
+ stroke: "currentColor",
4658
+ strokeWidth: "1.4",
4659
+ strokeLinecap: "round",
4660
+ strokeLinejoin: "round"
4661
+ }
4662
+ ),
4663
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4664
+ "path",
4665
+ {
4666
+ d: "M8 4.5v9",
4667
+ stroke: "currentColor",
4668
+ strokeWidth: "1.4",
4669
+ strokeLinecap: "round"
4670
+ }
4671
+ )
4672
+ ] });
4673
+ }
4674
+ function ReadAloudIcon() {
4675
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4676
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4677
+ "path",
4678
+ {
4679
+ 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",
4680
+ stroke: "currentColor",
4681
+ strokeWidth: "1.4",
4682
+ strokeLinecap: "round",
4683
+ strokeLinejoin: "round"
4684
+ }
4685
+ ),
4686
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4687
+ "path",
4688
+ {
4689
+ 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",
4690
+ stroke: "currentColor",
4691
+ strokeWidth: "1.4",
4692
+ strokeLinecap: "round"
4693
+ }
4694
+ )
4695
+ ] });
4696
+ }
4697
+ function StopIcon() {
4698
+ 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)(
4699
+ "rect",
4700
+ {
4701
+ x: "4",
4702
+ y: "4",
4703
+ width: "8",
4704
+ height: "8",
4705
+ rx: "1.5",
4706
+ stroke: "currentColor",
4707
+ strokeWidth: "1.5"
4708
+ }
4709
+ ) });
4710
+ }
4711
+ async function writeToClipboard(text) {
4712
+ try {
4713
+ await navigator.clipboard.writeText(text);
4714
+ } catch {
4715
+ const textarea = document.createElement("textarea");
4716
+ textarea.value = text;
4717
+ textarea.style.position = "fixed";
4718
+ textarea.style.opacity = "0";
4719
+ document.body.appendChild(textarea);
4720
+ textarea.select();
4721
+ document.execCommand("copy");
4722
+ textarea.remove();
4723
+ }
4724
+ }
4725
+ function formatAnsweredAt(answeredAt) {
4726
+ if (!answeredAt) return null;
4727
+ const date = new Date(answeredAt);
4728
+ if (Number.isNaN(date.getTime())) return null;
4729
+ return new Intl.DateTimeFormat(void 0, {
4730
+ dateStyle: "medium",
4731
+ timeStyle: "short"
4732
+ }).format(date);
4733
+ }
4734
+ function resolveMenuPosition(input) {
4735
+ const padding = 8;
4736
+ const { button, menuHeight, menuWidth, rail } = input;
4737
+ if (!rail) {
4738
+ return {
4739
+ left: button.left,
4740
+ top: button.top - menuHeight - 6
4741
+ };
4742
+ }
4743
+ let left = button.left - rail.left;
4744
+ let top = button.top - rail.top - menuHeight - 6;
4745
+ left = Math.min(
4746
+ Math.max(left, padding),
4747
+ rail.width - menuWidth - padding
4748
+ );
4749
+ if (top < padding) {
4750
+ top = button.bottom - rail.top + 6;
4751
+ }
4752
+ top = Math.min(top, rail.height - menuHeight - padding);
4753
+ return { left, top };
4754
+ }
4755
+ function MessageActions({
4756
+ answeredAt,
4757
+ copyText,
4758
+ disabled = false,
4759
+ onOpenReceipt,
4760
+ onRegenerate,
4761
+ onFeedback,
4762
+ readAloud = false,
4763
+ receiptSteps,
4764
+ speechText
4765
+ }) {
4766
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
4767
+ const [copied, setCopied] = (0, import_react11.useState)(false);
4768
+ const [rating, setRating] = (0, import_react11.useState)(null);
4769
+ const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4770
+ const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4771
+ const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4772
+ const copyTimerRef = (0, import_react11.useRef)(null);
4773
+ const menuRef = (0, import_react11.useRef)(null);
4774
+ const portaledMenuRef = (0, import_react11.useRef)(null);
4775
+ const moreButtonRef = (0, import_react11.useRef)(null);
4776
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4777
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4778
+ const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
4779
+ const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
4780
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4781
+ (0, import_react11.useLayoutEffect)(() => {
4782
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4783
+ setMenuPosition(null);
4784
+ return;
4785
+ }
4786
+ const button = moreButtonRef.current.getBoundingClientRect();
4787
+ const menu2 = portaledMenuRef.current;
4788
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
4789
+ setMenuPosition(
4790
+ resolveMenuPosition({
4791
+ button,
4792
+ menuHeight: menu2.offsetHeight,
4793
+ menuWidth: menu2.offsetWidth || 190,
4794
+ rail
4795
+ })
4796
+ );
4797
+ }, [menuOpen, menuPortalRoot]);
4798
+ (0, import_react11.useEffect)(
4799
+ () => () => {
4800
+ if (copyTimerRef.current !== null) {
4801
+ window.clearTimeout(copyTimerRef.current);
4802
+ }
4803
+ if (speaking) window.speechSynthesis.cancel();
4804
+ },
4805
+ // Cancel speech only when this answer's actions unmount.
4806
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4807
+ []
4808
+ );
4809
+ (0, import_react11.useEffect)(() => {
4810
+ if (!menuOpen) return;
4811
+ const handlePointerDown = (event) => {
4812
+ const target = event.target;
4813
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
4814
+ setMenuOpen(false);
4815
+ }
4816
+ };
4817
+ const handleKeyDown = (event) => {
4818
+ if (event.key !== "Escape") return;
4819
+ event.preventDefault();
4820
+ event.stopPropagation();
4821
+ setMenuOpen(false);
4822
+ };
4823
+ document.addEventListener("pointerdown", handlePointerDown);
4824
+ document.addEventListener("keydown", handleKeyDown);
4825
+ return () => {
4826
+ document.removeEventListener("pointerdown", handlePointerDown);
4827
+ document.removeEventListener("keydown", handleKeyDown);
4828
+ };
4829
+ }, [menuOpen]);
4830
+ function handleCopy() {
4831
+ void writeToClipboard(copyText);
4832
+ setCopied(true);
4833
+ if (copyTimerRef.current !== null) {
4834
+ window.clearTimeout(copyTimerRef.current);
4835
+ }
4836
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
4837
+ }
4838
+ function handleFeedback(next) {
4839
+ const resolved = rating === next ? null : next;
4840
+ setRating(resolved);
4841
+ if (resolved) onFeedback?.(resolved);
4842
+ }
4843
+ function handleReadAloud() {
4844
+ if (!canReadAloud) return;
4845
+ setMenuOpen(false);
4846
+ if (speaking) {
4847
+ window.speechSynthesis.cancel();
4848
+ setSpeaking(false);
4849
+ return;
4850
+ }
4851
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4852
+ utterance.onend = () => setSpeaking(false);
4853
+ utterance.onerror = () => setSpeaking(false);
4854
+ window.speechSynthesis.cancel();
4855
+ window.speechSynthesis.speak(utterance);
4856
+ setSpeaking(true);
4857
+ }
4858
+ const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4859
+ "div",
4860
+ {
4861
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
4862
+ ref: portaledMenuRef,
4863
+ role: "menu",
4864
+ style: menuPosition ? {
4865
+ left: `${menuPosition.left}px`,
4866
+ top: `${menuPosition.top}px`
4867
+ } : { visibility: "hidden" },
4868
+ children: [
4869
+ answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
4870
+ "Answered ",
4871
+ answeredLabel
4872
+ ] }) : null,
4873
+ canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4874
+ "button",
4875
+ {
4876
+ type: "button",
4877
+ className: "agent-message-actions__menu-item",
4878
+ role: "menuitem",
4879
+ onClick: () => {
4880
+ setMenuOpen(false);
4881
+ onOpenReceipt?.();
4882
+ },
4883
+ children: [
4884
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
4885
+ "View sources"
4886
+ ]
4887
+ }
4888
+ ) : null,
4889
+ canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4890
+ "button",
4891
+ {
4892
+ type: "button",
4893
+ className: "agent-message-actions__menu-item",
4894
+ role: "menuitem",
4895
+ onClick: handleReadAloud,
4896
+ children: [
4897
+ speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
4898
+ speaking ? "Stop reading" : "Read aloud"
4899
+ ]
4900
+ }
4901
+ ) : null
4902
+ ]
4903
+ }
4904
+ ) : null;
4905
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
4906
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4907
+ "button",
4908
+ {
4909
+ type: "button",
4910
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
4911
+ "aria-label": copied ? "Copied" : "Copy answer",
4912
+ title: copied ? "Copied" : "Copy answer",
4913
+ disabled,
4914
+ onClick: handleCopy,
4915
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
4916
+ }
4917
+ ),
4918
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4919
+ "button",
4920
+ {
4921
+ type: "button",
4922
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
4923
+ "aria-label": "Good answer",
4924
+ "aria-pressed": rating === "positive",
4925
+ title: "Good answer",
4926
+ disabled,
4927
+ onClick: () => handleFeedback("positive"),
4928
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
4929
+ }
4930
+ ),
4931
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4932
+ "button",
4933
+ {
4934
+ type: "button",
4935
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
4936
+ "aria-label": "Bad answer",
4937
+ "aria-pressed": rating === "negative",
4938
+ title: "Bad answer",
4939
+ disabled,
4940
+ onClick: () => handleFeedback("negative"),
4941
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
4942
+ }
4943
+ ),
4944
+ onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4945
+ "button",
4946
+ {
4947
+ type: "button",
4948
+ className: "agent-message-actions__button",
4949
+ "aria-label": "Regenerate answer",
4950
+ title: "Regenerate answer",
4951
+ disabled,
4952
+ onClick: onRegenerate,
4953
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
4954
+ }
4955
+ ) : null,
4956
+ showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
4957
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4958
+ "button",
4959
+ {
4960
+ ref: moreButtonRef,
4961
+ type: "button",
4962
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
4963
+ "aria-label": "More actions",
4964
+ "aria-haspopup": "menu",
4965
+ "aria-expanded": menuOpen,
4966
+ title: "More actions",
4967
+ disabled,
4968
+ onClick: () => setMenuOpen((open) => !open),
4969
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
4970
+ }
4971
+ ),
4972
+ menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
4973
+ ] }) : null
4974
+ ] });
4975
+ }
4976
+
4977
+ // src/react/components/HumanInputCard/HumanInputCard.tsx
4978
+ var import_react13 = require("react");
4979
+
4980
+ // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4981
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4982
+ function ConfirmationCard({
4983
+ disabled = false,
4984
+ request,
4985
+ onRespond
4986
+ }) {
4987
+ const options = request.options ?? [];
4988
+ const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4989
+ const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4990
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
4991
+ "section",
4992
+ {
4993
+ className: "confirmation-card",
4994
+ "aria-labelledby": `confirmation-${request.requestId}`,
4995
+ children: [
4996
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
4997
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4998
+ prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
4999
+ ] }),
5000
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5001
+ "button",
5002
+ {
5003
+ type: "button",
5004
+ className: `confirmation-card__action confirmation-card__action--${option.style ?? "default"}`,
5005
+ disabled,
5006
+ onClick: () => onRespond?.({
5007
+ requestId: request.requestId,
5008
+ optionId: option.id
5009
+ }),
5010
+ children: option.label
5011
+ },
5012
+ option.id
5013
+ )) })
5014
+ ]
5015
+ }
5016
+ );
5017
+ }
5018
+
5019
+ // src/react/components/ToolInputCard/ToolInputCard.tsx
5020
+ var import_react12 = require("react");
5021
+ var import_jsx_runtime9 = require("react/jsx-runtime");
5022
+ function isRecord5(value) {
5023
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5024
+ }
5025
+ function pathSegments(path) {
5026
+ return path.replace(/\[(\d+)\]/gu, ".$1").split(".").filter(Boolean);
5027
+ }
5028
+ function valueAtPath(root, path) {
5029
+ let current = root;
5030
+ for (const segment of pathSegments(path)) {
5031
+ if (Array.isArray(current)) {
5032
+ const index = Number(segment);
5033
+ current = Number.isInteger(index) ? current[index] : void 0;
5034
+ continue;
5035
+ }
5036
+ current = isRecord5(current) ? current[segment] : void 0;
5037
+ }
5038
+ return current;
5039
+ }
5040
+ function initialFieldValue(field, surface) {
5041
+ const supplied = valueAtPath(surface.values, field.path);
5042
+ if (supplied !== void 0) return supplied;
5043
+ if (field.defaultValue !== void 0) return field.defaultValue;
5044
+ if (field.kind === "checkbox" || field.kind === "confirmation") return false;
5045
+ if (field.kind === "multi-select") return [];
5046
+ if (field.kind === "range") return field.min ?? 0;
5047
+ return "";
4319
5048
  }
4320
5049
  function initialValues(surface) {
4321
5050
  return Object.fromEntries(
@@ -4413,7 +5142,7 @@ function FieldDescription({
4413
5142
  field,
4414
5143
  id
4415
5144
  }) {
4416
- return field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5145
+ return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4417
5146
  }
4418
5147
  function ChoiceField({
4419
5148
  field,
@@ -4432,7 +5161,7 @@ function ChoiceField({
4432
5161
  const selectedIndex = options.findIndex(
4433
5162
  (option) => valuesMatch(option.value, value)
4434
5163
  );
4435
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5164
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4436
5165
  "select",
4437
5166
  {
4438
5167
  id,
@@ -4447,13 +5176,13 @@ function ChoiceField({
4447
5176
  if (option) onChange(option.value);
4448
5177
  },
4449
5178
  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)))
5179
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
5180
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
4452
5181
  ]
4453
5182
  }
4454
5183
  );
4455
5184
  }
4456
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5185
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4457
5186
  "div",
4458
5187
  {
4459
5188
  className: "tool-input-card__choices",
@@ -4464,8 +5193,8 @@ function ChoiceField({
4464
5193
  "aria-required": field.required,
4465
5194
  children: options.map((option, index) => {
4466
5195
  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)(
5196
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
5197
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4469
5198
  "input",
4470
5199
  {
4471
5200
  type: multiple ? "checkbox" : "radio",
@@ -4487,7 +5216,7 @@ function ChoiceField({
4487
5216
  }
4488
5217
  }
4489
5218
  ),
4490
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
5219
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
4491
5220
  ] }, optionKey(option));
4492
5221
  })
4493
5222
  }
@@ -4507,9 +5236,9 @@ function ToolField({
4507
5236
  error ? `${id}-error` : ""
4508
5237
  ].filter(Boolean).join(" ");
4509
5238
  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)(
5239
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
5240
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
5241
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4513
5242
  "input",
4514
5243
  {
4515
5244
  id,
@@ -4522,17 +5251,17 @@ function ToolField({
4522
5251
  onChange: (event) => onChange(event.target.checked)
4523
5252
  }
4524
5253
  ),
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
5254
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
5255
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
5256
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
4528
5257
  ] })
4529
5258
  ] }),
4530
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5259
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4531
5260
  ] });
4532
5261
  }
4533
- const label = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
5262
+ const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
4534
5263
  field.label,
4535
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5264
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4536
5265
  ] });
4537
5266
  const common = {
4538
5267
  id,
@@ -4544,7 +5273,7 @@ function ToolField({
4544
5273
  };
4545
5274
  let control;
4546
5275
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4547
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5276
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4548
5277
  ChoiceField,
4549
5278
  {
4550
5279
  field,
@@ -4558,7 +5287,7 @@ function ToolField({
4558
5287
  }
4559
5288
  );
4560
5289
  } else if (field.kind === "textarea" || field.kind === "json") {
4561
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5290
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4562
5291
  "textarea",
4563
5292
  {
4564
5293
  ...common,
@@ -4572,8 +5301,8 @@ function ToolField({
4572
5301
  );
4573
5302
  } else if (field.kind === "range") {
4574
5303
  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)(
5304
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
5305
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4577
5306
  "input",
4578
5307
  {
4579
5308
  ...common,
@@ -4585,11 +5314,11 @@ function ToolField({
4585
5314
  onChange: (event) => onChange(Number(event.target.value))
4586
5315
  }
4587
5316
  ),
4588
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("output", { htmlFor: id, children: numericValue })
5317
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
4589
5318
  ] });
4590
5319
  } else {
4591
5320
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4592
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5321
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4593
5322
  "input",
4594
5323
  {
4595
5324
  ...common,
@@ -4607,11 +5336,11 @@ function ToolField({
4607
5336
  }
4608
5337
  );
4609
5338
  }
4610
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
5339
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
4611
5340
  label,
4612
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldDescription, { field, id: `${id}-description` }),
5341
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
4613
5342
  control,
4614
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5343
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4615
5344
  ] });
4616
5345
  }
4617
5346
  function ToolInputCard({
@@ -4619,11 +5348,11 @@ function ToolInputCard({
4619
5348
  surface,
4620
5349
  onSubmit
4621
5350
  }) {
4622
- const [values, setValues] = (0, import_react9.useState)(
5351
+ const [values, setValues] = (0, import_react12.useState)(
4623
5352
  () => initialValues(surface)
4624
5353
  );
4625
- const [touched, setTouched] = (0, import_react9.useState)(() => /* @__PURE__ */ new Set());
4626
- const [submitted, setSubmitted] = (0, import_react9.useState)(false);
5354
+ const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
5355
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
4627
5356
  const errors = Object.fromEntries(
4628
5357
  surface.fields.map((field) => [
4629
5358
  field.path,
@@ -4648,14 +5377,14 @@ function ToolInputCard({
4648
5377
  onSubmit?.(surface, result);
4649
5378
  }
4650
5379
  if (submitted) {
4651
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5380
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4652
5381
  "section",
4653
5382
  {
4654
5383
  className: "tool-input-card tool-input-card--submitted",
4655
5384
  role: "status",
4656
5385
  children: [
4657
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
4658
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5386
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
5387
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
4659
5388
  surface.title,
4660
5389
  " submitted"
4661
5390
  ] })
@@ -4663,18 +5392,18 @@ function ToolInputCard({
4663
5392
  }
4664
5393
  );
4665
5394
  }
4666
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5395
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4667
5396
  "section",
4668
5397
  {
4669
5398
  className: "tool-input-card",
4670
5399
  "aria-labelledby": `tool-input-${surface.id}`,
4671
5400
  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
5401
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
5402
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5403
+ surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
4675
5404
  ] }),
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)(
5405
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
5406
+ /* @__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
5407
  ToolField,
4679
5408
  {
4680
5409
  disabled,
@@ -4687,8 +5416,8 @@ function ToolInputCard({
4687
5416
  },
4688
5417
  field.path
4689
5418
  )) }),
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)(
5419
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
5420
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4692
5421
  "button",
4693
5422
  {
4694
5423
  type: "button",
@@ -4701,7 +5430,7 @@ function ToolInputCard({
4701
5430
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4702
5431
  }
4703
5432
  ) : null,
4704
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5433
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4705
5434
  ] })
4706
5435
  ] })
4707
5436
  ]
@@ -4710,17 +5439,17 @@ function ToolInputCard({
4710
5439
  }
4711
5440
 
4712
5441
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4713
- var import_jsx_runtime8 = require("react/jsx-runtime");
5442
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4714
5443
  function HumanInputCard({
4715
5444
  disabled = false,
4716
5445
  request,
4717
5446
  onRespond
4718
5447
  }) {
4719
- const [text, setText] = (0, import_react10.useState)("");
5448
+ const [text, setText] = (0, import_react13.useState)("");
4720
5449
  const options = request.options ?? [];
4721
5450
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4722
5451
  if (request.ui) {
4723
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5452
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4724
5453
  ToolInputCard,
4725
5454
  {
4726
5455
  disabled,
@@ -4730,7 +5459,7 @@ function HumanInputCard({
4730
5459
  );
4731
5460
  }
4732
5461
  if (options.length > 0) {
4733
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5462
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4734
5463
  ConfirmationCard,
4735
5464
  {
4736
5465
  disabled,
@@ -4745,17 +5474,17 @@ function HumanInputCard({
4745
5474
  if (!value || disabled) return;
4746
5475
  onRespond?.({ requestId: request.requestId, text: value });
4747
5476
  }
4748
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5477
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4749
5478
  "section",
4750
5479
  {
4751
5480
  className: "human-input-card",
4752
5481
  "aria-labelledby": `human-input-${request.requestId}`,
4753
5482
  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)(
5483
+ /* @__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 }) }),
5484
+ showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
5485
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5486
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
5487
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4759
5488
  "input",
4760
5489
  {
4761
5490
  id: `human-input-text-${request.requestId}`,
@@ -4764,39 +5493,39 @@ function HumanInputCard({
4764
5493
  onChange: (event) => setText(event.target.value)
4765
5494
  }
4766
5495
  ),
4767
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5496
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4768
5497
  ] })
4769
5498
  ] }) : 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
5499
+ !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
5500
  ]
4772
5501
  }
4773
5502
  );
4774
5503
  }
4775
5504
 
4776
5505
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4777
- var import_jsx_runtime9 = require("react/jsx-runtime");
5506
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4778
5507
  function CollectionResultCard({
4779
5508
  result
4780
5509
  }) {
4781
5510
  const empty = result.items.length === 0;
4782
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5511
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4783
5512
  "section",
4784
5513
  {
4785
5514
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4786
5515
  "aria-label": result.title,
4787
5516
  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 })
5517
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
5518
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5519
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
4791
5520
  ] }),
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 })
5521
+ 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: [
5522
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
5523
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
5524
+ item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
5526
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
4798
5527
  ] }, `${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
5528
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4800
5529
  ] }, item.title)) })
4801
5530
  ]
4802
5531
  }
@@ -4804,26 +5533,26 @@ function CollectionResultCard({
4804
5533
  }
4805
5534
 
4806
5535
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4807
- var import_jsx_runtime10 = require("react/jsx-runtime");
5536
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4808
5537
  function EntityResultCard({
4809
5538
  result
4810
5539
  }) {
4811
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5540
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4812
5541
  "section",
4813
5542
  {
4814
5543
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4815
5544
  "aria-label": result.title,
4816
5545
  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 })
5546
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
5547
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5548
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
4820
5549
  ] }),
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 })
5550
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
5551
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
5552
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
5553
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
4825
5554
  ] }, `${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)(
5555
+ 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
5556
  "a",
4828
5557
  {
4829
5558
  href: link.href,
@@ -4839,24 +5568,24 @@ function EntityResultCard({
4839
5568
  }
4840
5569
 
4841
5570
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4842
- var import_jsx_runtime11 = require("react/jsx-runtime");
5571
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4843
5572
  function SignatureResultCard({
4844
5573
  result
4845
5574
  }) {
4846
5575
  const primaryLink = result.links?.[0];
4847
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5576
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4848
5577
  "section",
4849
5578
  {
4850
5579
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4851
5580
  "aria-label": result.title,
4852
5581
  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 })
5582
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
5583
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5584
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
4856
5585
  ] }),
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)(
5586
+ result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5587
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
5588
+ primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4860
5589
  "a",
4861
5590
  {
4862
5591
  className: "signature-result-card__cta",
@@ -4872,26 +5601,26 @@ function SignatureResultCard({
4872
5601
  }
4873
5602
 
4874
5603
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4875
- var import_jsx_runtime12 = require("react/jsx-runtime");
5604
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4876
5605
  function ToolResultCard({
4877
5606
  result
4878
5607
  }) {
4879
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5608
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4880
5609
  "section",
4881
5610
  {
4882
5611
  className: `tool-result-card tool-result-card--${result.status}`,
4883
5612
  "aria-label": result.title,
4884
5613
  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 })
5614
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
5615
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5616
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
4888
5617
  ] }),
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 })
5618
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
5619
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5620
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
5621
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
4893
5622
  ] }, `${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)(
5623
+ 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
5624
  "a",
4896
5625
  {
4897
5626
  href: link.href,
@@ -4907,14 +5636,14 @@ function ToolResultCard({
4907
5636
  }
4908
5637
 
4909
5638
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4910
- var import_jsx_runtime13 = require("react/jsx-runtime");
5639
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4911
5640
  function VisitorToolResultView({
4912
5641
  disabled = false,
4913
5642
  onToolInput,
4914
5643
  result
4915
5644
  }) {
4916
5645
  if (result.kind === "input") {
4917
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5646
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4918
5647
  ToolInputCard,
4919
5648
  {
4920
5649
  disabled,
@@ -4924,16 +5653,16 @@ function VisitorToolResultView({
4924
5653
  );
4925
5654
  }
4926
5655
  if (result.kind === "entity") {
4927
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EntityResultCard, { result });
5656
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
4928
5657
  }
4929
5658
  if (result.kind === "collection") {
4930
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollectionResultCard, { result });
5659
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
4931
5660
  }
4932
5661
  if (result.kind === "signature") {
4933
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SignatureResultCard, { result });
5662
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
4934
5663
  }
4935
5664
  if (result.kind === "summary") {
4936
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResultCard, { result });
5665
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
4937
5666
  }
4938
5667
  return null;
4939
5668
  }
@@ -4942,9 +5671,9 @@ function isRenderableVisitorToolResult(result) {
4942
5671
  }
4943
5672
 
4944
5673
  // src/react/components/AgentRail/AgentRail.tsx
4945
- var import_jsx_runtime14 = require("react/jsx-runtime");
5674
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4946
5675
  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)(
5676
+ 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
5677
  "path",
4949
5678
  {
4950
5679
  d: "M3.5 8h9",
@@ -4954,8 +5683,8 @@ function MinimizeIcon() {
4954
5683
  }
4955
5684
  ) });
4956
5685
  }
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)(
5686
+ function CloseIcon2() {
5687
+ 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
5688
  "path",
4960
5689
  {
4961
5690
  d: "M4 4l8 8M12 4l-8 8",
@@ -4966,7 +5695,7 @@ function CloseIcon() {
4966
5695
  ) });
4967
5696
  }
4968
5697
  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)(
5698
+ 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
5699
  "path",
4971
5700
  {
4972
5701
  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 +5707,7 @@ function NewChatIcon() {
4978
5707
  ) });
4979
5708
  }
4980
5709
  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)(
5710
+ 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
5711
  "path",
4983
5712
  {
4984
5713
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4990,7 +5719,7 @@ function ExpandIcon() {
4990
5719
  ) });
4991
5720
  }
4992
5721
  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)(
5722
+ 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
5723
  "path",
4995
5724
  {
4996
5725
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -5001,6 +5730,19 @@ function RestoreIcon() {
5001
5730
  }
5002
5731
  ) });
5003
5732
  }
5733
+ function ChevronDownIcon() {
5734
+ 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)(
5735
+ "path",
5736
+ {
5737
+ d: "M4 6.5l4 4 4-4",
5738
+ stroke: "currentColor",
5739
+ strokeWidth: "1.6",
5740
+ strokeLinecap: "round",
5741
+ strokeLinejoin: "round"
5742
+ }
5743
+ ) });
5744
+ }
5745
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
5004
5746
  function AgentRail({
5005
5747
  state,
5006
5748
  theme,
@@ -5008,6 +5750,9 @@ function AgentRail({
5008
5750
  brandLabel = "",
5009
5751
  brandLogoUrl,
5010
5752
  poweredByLabel = "Powered by Webless",
5753
+ disclaimerLabel,
5754
+ answerReceipt = false,
5755
+ readAloud = false,
5011
5756
  composerPlaceholder = "Ask anything\u2026",
5012
5757
  mobileFullscreen = false,
5013
5758
  expanded = false,
@@ -5016,16 +5761,26 @@ function AgentRail({
5016
5761
  onExpandToggle,
5017
5762
  onReset,
5018
5763
  onRetry,
5764
+ onRegenerate,
5765
+ onFeedback,
5019
5766
  onSubmit,
5020
5767
  onFollowUpSelect,
5021
5768
  onBook,
5022
5769
  onInputResponse,
5023
5770
  onToolInput
5024
5771
  }) {
5025
- const transcriptRef = (0, import_react11.useRef)(null);
5772
+ const railRef = (0, import_react14.useRef)(null);
5773
+ const overlayRef = (0, import_react14.useRef)(null);
5774
+ const transcriptRef = (0, import_react14.useRef)(null);
5775
+ const pinnedToBottomRef = (0, import_react14.useRef)(true);
5776
+ const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
5777
+ const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
5778
+ const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
5779
+ const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
5026
5780
  const resolvedBrandLabel = brandLabel.trim();
5027
5781
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
5028
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react11.useState)(null);
5782
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5783
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
5029
5784
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
5030
5785
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
5031
5786
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -5076,10 +5831,15 @@ function AgentRail({
5076
5831
  );
5077
5832
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
5078
5833
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
5079
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5834
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5835
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
5080
5836
  const hasVisitorMessages2 = state.messages.some(
5081
5837
  (message) => message.role === "visitor"
5082
5838
  );
5839
+ const hasAgentResponseAfterVisitor = state.messages.some(
5840
+ (message) => message.role === "agent" && message.id !== "greeting"
5841
+ );
5842
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
5083
5843
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
5084
5844
  const greeting = state.messages.find(
5085
5845
  (message) => message.role === "agent" && message.id === "greeting"
@@ -5101,6 +5861,7 @@ function AgentRail({
5101
5861
  }
5102
5862
  }
5103
5863
  const lastIsAgent = lastMessage?.role === "agent";
5864
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
5104
5865
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
5105
5866
  createdAt: 0,
5106
5867
  id: "streaming-response",
@@ -5127,10 +5888,36 @@ function AgentRail({
5127
5888
  hasPendingConfirmation,
5128
5889
  enabled: lastIsAgent && !isBusy
5129
5890
  });
5130
- (0, import_react11.useEffect)(() => {
5891
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
5892
+ (0, import_react14.useEffect)(() => {
5893
+ if (state.phase !== "complete") {
5894
+ setReceiptOpen(false);
5895
+ }
5896
+ }, [state.phase]);
5897
+ function handleSubmit(message) {
5898
+ setReceiptOpen(false);
5899
+ onSubmit?.(message);
5900
+ }
5901
+ function handleRegenerate() {
5902
+ setReceiptOpen(false);
5903
+ onRegenerate?.();
5904
+ }
5905
+ function handleReset() {
5906
+ setReceiptOpen(false);
5907
+ onReset?.();
5908
+ }
5909
+ function handleFollowUpSelect(label) {
5910
+ setReceiptOpen(false);
5911
+ onFollowUpSelect?.(label);
5912
+ }
5913
+ (0, import_react14.useEffect)(() => {
5131
5914
  const node = transcriptRef.current;
5132
5915
  if (!node) return;
5133
- node.scrollTop = node.scrollHeight;
5916
+ const lastMessage2 = state.messages.at(-1);
5917
+ const visitorJustSent = lastMessage2?.role === "visitor";
5918
+ if (pinnedToBottomRef.current || visitorJustSent) {
5919
+ node.scrollTop = node.scrollHeight;
5920
+ }
5134
5921
  }, [
5135
5922
  state.messages,
5136
5923
  state.toolSteps,
@@ -5138,10 +5925,75 @@ function AgentRail({
5138
5925
  state.followUps,
5139
5926
  state.journey
5140
5927
  ]);
5141
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5928
+ (0, import_react14.useEffect)(() => {
5929
+ const node = transcriptRef.current;
5930
+ if (!node) return;
5931
+ const handleScroll = () => {
5932
+ if (node.clientHeight === 0) return;
5933
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5934
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
5935
+ pinnedToBottomRef.current = pinned;
5936
+ setShowJumpToLatest(!pinned);
5937
+ };
5938
+ node.addEventListener("scroll", handleScroll, { passive: true });
5939
+ handleScroll();
5940
+ return () => node.removeEventListener("scroll", handleScroll);
5941
+ }, []);
5942
+ (0, import_react14.useEffect)(() => {
5943
+ const node = transcriptRef.current;
5944
+ if (!node) return;
5945
+ const observer = new ResizeObserver(() => {
5946
+ if (node.clientHeight === 0) return;
5947
+ if (pinnedToBottomRef.current) {
5948
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5949
+ }
5950
+ });
5951
+ observer.observe(node);
5952
+ return () => observer.disconnect();
5953
+ }, []);
5954
+ (0, import_react14.useEffect)(() => {
5955
+ if (!receiptOpen) {
5956
+ lockedTranscriptScrollTopRef.current = null;
5957
+ return;
5958
+ }
5959
+ const node = transcriptRef.current;
5960
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
5961
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
5962
+ }, [receiptOpen]);
5963
+ function openReceipt() {
5964
+ const node = transcriptRef.current;
5965
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
5966
+ setReceiptOpen(true);
5967
+ }
5968
+ function scrollToLatest() {
5969
+ const node = transcriptRef.current;
5970
+ if (!node) return;
5971
+ pinnedToBottomRef.current = true;
5972
+ setShowJumpToLatest(false);
5973
+ const reduceMotion = window.matchMedia(
5974
+ "(prefers-reduced-motion: reduce)"
5975
+ ).matches;
5976
+ if (reduceMotion) {
5977
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5978
+ return;
5979
+ }
5980
+ smoothScrollToLatestRef.current = true;
5981
+ const settle = () => {
5982
+ smoothScrollToLatestRef.current = false;
5983
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5984
+ const pinned = distanceFromBottom < 48;
5985
+ pinnedToBottomRef.current = pinned;
5986
+ setShowJumpToLatest(!pinned);
5987
+ };
5988
+ node.addEventListener("scrollend", settle, { once: true });
5989
+ window.setTimeout(settle, 900);
5990
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
5991
+ }
5992
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5142
5993
  "aside",
5143
5994
  {
5144
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
5995
+ ref: railRef,
5996
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
5145
5997
  "data-not-typeset": "",
5146
5998
  "data-color-scheme": resolvedColorScheme,
5147
5999
  spellCheck: false,
@@ -5151,196 +6003,234 @@ function AgentRail({
5151
6003
  autoFocus: mobileFullscreen || expanded,
5152
6004
  role: mobileFullscreen || expanded ? "dialog" : void 0,
5153
6005
  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);
5184
- }
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,
6006
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6007
+ AgentRailOverlayContext.Provider,
6008
+ {
6009
+ value: { railRef, overlayRef },
6010
+ children: [
6011
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
6012
+ /* @__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: [
6013
+ onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6014
+ "button",
6015
+ {
6016
+ type: "button",
6017
+ className: "agent-rail__collapse",
6018
+ "aria-label": "Collapse assist",
6019
+ onClick: onCollapse,
6020
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
6021
+ }
6022
+ ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6023
+ "button",
6024
+ {
6025
+ type: "button",
6026
+ className: "agent-rail__close",
6027
+ "aria-label": "Close agent",
6028
+ onClick: onClose,
6029
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
6030
+ }
6031
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
6032
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
6033
+ showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6034
+ "img",
6035
+ {
6036
+ className: "agent-rail__brand-logo",
6037
+ src: resolvedBrandLogoUrl,
6038
+ alt: "",
6039
+ onError: () => {
6040
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6041
+ }
6042
+ }
6043
+ ) }) : null,
6044
+ resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
6045
+ ] }) : null,
6046
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
6047
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6048
+ "button",
6049
+ {
6050
+ type: "button",
6051
+ className: "agent-rail__new-chat",
6052
+ "aria-label": "Start a new conversation",
6053
+ disabled: !hasVisitorMessages2,
6054
+ onClick: handleReset,
6055
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
6056
+ }
6057
+ ) : null,
6058
+ onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6059
+ "button",
6060
+ {
6061
+ type: "button",
6062
+ className: "agent-rail__expand",
6063
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
6064
+ onClick: onExpandToggle,
6065
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
6066
+ }
6067
+ ) : null
6068
+ ] })
6069
+ ] }) }),
6070
+ /* @__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: [
6071
+ !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
6072
+ greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6073
+ MessageBubble,
6074
+ {
6075
+ message: greeting,
6076
+ bookingDisabled: isBusy,
6077
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6078
+ onBook
6079
+ }
6080
+ ) : null,
6081
+ showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6082
+ FollowUpChips,
6083
+ {
6084
+ suggestions: state.followUps,
6085
+ disabled: isBusy,
6086
+ label: "Start here",
6087
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
6088
+ }
6089
+ ) }) : null,
6090
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6091
+ AgentActivityBubble,
6092
+ {
6093
+ brandLabel: resolvedBrandLabel,
6094
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6095
+ failed: state.phase === "error",
6096
+ steps: state.toolSteps
6097
+ }
6098
+ ) : null,
6099
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6100
+ VisitorToolResultView,
6101
+ {
6102
+ result,
6103
+ disabled: semanticSurfaceDisabled,
6104
+ onToolInput
6105
+ },
6106
+ result.id
6107
+ )),
6108
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6109
+ HumanInputCard,
6110
+ {
6111
+ request,
6112
+ onRespond: onInputResponse
6113
+ },
6114
+ request.requestId
6115
+ ))
6116
+ ] }) : null,
6117
+ visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
6118
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6119
+ MessageBubble,
6120
+ {
6121
+ message,
6122
+ bookingDisabled: isBusy,
6123
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6124
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6125
+ onBook
6126
+ }
6127
+ ),
6128
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6129
+ MessageActions,
6130
+ {
6131
+ answeredAt: message.createdAt,
6132
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6133
+ readAloud,
6134
+ receiptSteps,
6135
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6136
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6137
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6138
+ }
6139
+ ) : null,
6140
+ index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
6141
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6142
+ AgentActivityBubble,
6143
+ {
6144
+ brandLabel: resolvedBrandLabel,
6145
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6146
+ failed: state.phase === "error",
6147
+ steps: state.toolSteps
6148
+ }
6149
+ ) : null,
6150
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6151
+ VisitorToolResultView,
6152
+ {
6153
+ result,
6154
+ disabled: semanticSurfaceDisabled,
6155
+ onToolInput
6156
+ },
6157
+ result.id
6158
+ )),
6159
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6160
+ HumanInputCard,
6161
+ {
6162
+ request,
6163
+ onRespond: onInputResponse
6164
+ },
6165
+ request.requestId
6166
+ ))
6167
+ ] }) : null
6168
+ ] }, message.id)),
6169
+ streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6170
+ MessageBubble,
6171
+ {
6172
+ message: streamingMessage,
6173
+ bookingDisabled: isBusy,
6174
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6175
+ offer: state.pendingOffer,
6176
+ onBook
6177
+ }
6178
+ ) : null,
6179
+ waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
6180
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
6181
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
6182
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
6183
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
6184
+ ] }),
6185
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6186
+ ] }) : null
6187
+ ] }) }),
6188
+ showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: resolvedDisclaimerLabel }) }) : null,
6189
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6190
+ showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6191
+ "button",
6192
+ {
6193
+ type: "button",
6194
+ className: "agent-rail__jump-to-latest",
6195
+ "aria-label": "Jump to the latest message",
6196
+ title: "Jump to the latest message",
6197
+ onClick: scrollToLatest,
6198
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
6199
+ }
6200
+ ) : null,
6201
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6202
+ Composer,
6203
+ {
6204
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6205
+ disabled: isBusy,
6206
+ form: composerForm,
6207
+ placeholder: composerPlaceholder,
6208
+ onSubmit: handleSubmit
6209
+ }
6210
+ ),
6211
+ 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
6212
+ ] })
6213
+ ] }),
6214
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6215
+ receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6216
+ AnswerReceiptDialog,
5235
6217
  {
5236
6218
  brandLabel: resolvedBrandLabel,
5237
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5238
- failed: state.phase === "error",
5239
- steps: state.toolSteps
6219
+ onClose: () => setReceiptOpen(false),
6220
+ steps: receiptSteps
5240
6221
  }
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
- ]
6222
+ ) : null
6223
+ ]
6224
+ }
6225
+ )
5336
6226
  }
5337
6227
  );
5338
6228
  }
5339
6229
 
5340
6230
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5341
- var import_jsx_runtime15 = require("react/jsx-runtime");
6231
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5342
6232
  function SparklesIcon() {
5343
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6233
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5344
6234
  "svg",
5345
6235
  {
5346
6236
  className: "assist-edge-tab__sparkles",
@@ -5348,21 +6238,21 @@ function SparklesIcon() {
5348
6238
  fill: "none",
5349
6239
  "aria-hidden": "true",
5350
6240
  children: [
5351
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6241
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5352
6242
  "path",
5353
6243
  {
5354
6244
  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
6245
  fill: "currentColor"
5356
6246
  }
5357
6247
  ),
5358
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6248
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5359
6249
  "path",
5360
6250
  {
5361
6251
  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
6252
  fill: "currentColor"
5363
6253
  }
5364
6254
  ),
5365
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6255
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5366
6256
  "path",
5367
6257
  {
5368
6258
  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 +6266,7 @@ function SparklesIcon() {
5376
6266
  function TabMarkIcon({ customIconUrl }) {
5377
6267
  const url = customIconUrl?.trim();
5378
6268
  if (url) {
5379
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6269
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5380
6270
  "img",
5381
6271
  {
5382
6272
  alt: "",
@@ -5386,10 +6276,10 @@ function TabMarkIcon({ customIconUrl }) {
5386
6276
  }
5387
6277
  );
5388
6278
  }
5389
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SparklesIcon, {});
6279
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
5390
6280
  }
5391
6281
  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)(
6282
+ 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
6283
  "path",
5394
6284
  {
5395
6285
  d: "M10 4L6 8l4 4",
@@ -5400,8 +6290,8 @@ function ChevronLeftIcon() {
5400
6290
  }
5401
6291
  ) });
5402
6292
  }
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)(
6293
+ function ChevronDownIcon2() {
6294
+ 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
6295
  "path",
5406
6296
  {
5407
6297
  d: "M4 6l4 4 4-4",
@@ -5413,7 +6303,7 @@ function ChevronDownIcon() {
5413
6303
  ) });
5414
6304
  }
5415
6305
  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)) });
6306
+ 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
6307
  }
5418
6308
  var VARIANT_COPY = {
5419
6309
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5459,7 +6349,7 @@ function AssistEdgeTab({
5459
6349
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5460
6350
  colorScheme: resolvedColorScheme
5461
6351
  };
5462
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6352
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5463
6353
  "button",
5464
6354
  {
5465
6355
  type: "button",
@@ -5471,15 +6361,15 @@ function AssistEdgeTab({
5471
6361
  tabIndex: visible ? 0 : -1,
5472
6362
  onClick: onOpen,
5473
6363
  children: [
5474
- mobile ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5475
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6364
+ mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6365
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5476
6366
  "span",
5477
6367
  {
5478
6368
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5479
6369
  "aria-hidden": "true",
5480
6370
  children: [
5481
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5482
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6371
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6372
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5483
6373
  "img",
5484
6374
  {
5485
6375
  className: "assist-edge-tab__logo",
@@ -5493,11 +6383,11 @@ function AssistEdgeTab({
5493
6383
  ]
5494
6384
  }
5495
6385
  ),
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)(
6386
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
6387
+ ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6388
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6390
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5501
6391
  "img",
5502
6392
  {
5503
6393
  className: "assist-edge-tab__logo",
@@ -5509,18 +6399,18 @@ function AssistEdgeTab({
5509
6399
  }
5510
6400
  ) : null
5511
6401
  ] }),
5512
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5513
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronDownIcon, {})
6402
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6403
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
5514
6404
  ] }) : 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, {})
6405
+ variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6406
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
6407
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6408
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
5519
6409
  ] }) : 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)(
6410
+ variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6411
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6412
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6413
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5524
6414
  "img",
5525
6415
  {
5526
6416
  className: "assist-edge-tab__logo",
@@ -5532,16 +6422,72 @@ function AssistEdgeTab({
5532
6422
  }
5533
6423
  ) : null
5534
6424
  ] }),
5535
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5536
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {})
6425
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6426
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
5537
6427
  ] }) : null
5538
6428
  ]
5539
6429
  }
5540
6430
  );
5541
6431
  }
5542
6432
 
6433
+ // src/react/lib/agent-feedback.ts
6434
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6435
+ function findPrecedingVisitorText(messages, agentMessageId) {
6436
+ const agentIndex = messages.findIndex(
6437
+ (message) => message.id === agentMessageId && message.role === "agent"
6438
+ );
6439
+ if (agentIndex < 0) return void 0;
6440
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6441
+ const message = messages[index];
6442
+ if (message?.role === "visitor") {
6443
+ return message.text.trim() || void 0;
6444
+ }
6445
+ }
6446
+ return void 0;
6447
+ }
6448
+ function normalizeAgentFeedbackAnswerText(text) {
6449
+ const normalized = text.replace(/\s+/g, " ").trim();
6450
+ if (!normalized) return void 0;
6451
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6452
+ }
6453
+ function buildAgentAnswerFeedbackEvent(input) {
6454
+ const positive = input.rating === "positive";
6455
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6456
+ return {
6457
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6458
+ company: input.analytics.companyIndex,
6459
+ session_id: input.visitorSessionId,
6460
+ page: input.page,
6461
+ timestamp: Date.now(),
6462
+ tracking_consent: input.analytics.trackingConsent,
6463
+ feedback_value: positive ? 1 : -1,
6464
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6465
+ feedback_rating: positive ? "helpful" : "not_helpful",
6466
+ surface: "agent_panel",
6467
+ index_id: input.indexId,
6468
+ index_version: input.version,
6469
+ message_id: input.messageId,
6470
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6471
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6472
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6473
+ };
6474
+ }
6475
+ function sendAgentAnswerFeedback(eventUrl, event) {
6476
+ try {
6477
+ void fetch(eventUrl, {
6478
+ body: JSON.stringify(event),
6479
+ credentials: "omit",
6480
+ headers: { "Content-Type": "application/json" },
6481
+ keepalive: true,
6482
+ method: "POST"
6483
+ }).catch(() => {
6484
+ });
6485
+ } catch {
6486
+ }
6487
+ }
6488
+
5543
6489
  // src/react/components/AgentWidget/AgentWidget.tsx
5544
- var import_jsx_runtime16 = require("react/jsx-runtime");
6490
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5545
6491
  function AgentWidget({
5546
6492
  indexId,
5547
6493
  customerId,
@@ -5555,13 +6501,14 @@ function AgentWidget({
5555
6501
  registerPanelController = false,
5556
6502
  colorScheme = "auto",
5557
6503
  branding,
6504
+ analytics,
5558
6505
  toolResultRegistry
5559
6506
  }) {
5560
6507
  const isMobile = useIsMobile();
5561
6508
  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);
6509
+ const railSlotRef = (0, import_react15.useRef)(null);
6510
+ const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
6511
+ const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
5565
6512
  const pageShiftActive = shouldApplyPageShift({
5566
6513
  pageShift,
5567
6514
  isMobile,
@@ -5572,7 +6519,17 @@ function AgentWidget({
5572
6519
  active: pageShiftActive,
5573
6520
  railSlotRef
5574
6521
  });
5575
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6522
+ const {
6523
+ state,
6524
+ reset,
6525
+ retry,
6526
+ regenerate,
6527
+ respondToInput,
6528
+ respondToToolInput,
6529
+ submit,
6530
+ visitorSessionId,
6531
+ sessionId
6532
+ } = useAgentChat({
5576
6533
  customerId,
5577
6534
  getUnpublishedPreviewGrant,
5578
6535
  indexId,
@@ -5604,7 +6561,7 @@ function AgentWidget({
5604
6561
  } : {},
5605
6562
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5606
6563
  };
5607
- (0, import_react12.useEffect)(() => {
6564
+ (0, import_react15.useEffect)(() => {
5608
6565
  if (!registerPanelController) return;
5609
6566
  registerAgentPanelController(customerId, {
5610
6567
  open: () => setRailCollapsed(false),
@@ -5621,7 +6578,25 @@ function AgentWidget({
5621
6578
  if (isMobile) setRailCollapsed(false);
5622
6579
  await submit(message);
5623
6580
  }
5624
- (0, import_react12.useEffect)(() => {
6581
+ function handleFeedback(rating, message) {
6582
+ if (!analytics) return;
6583
+ sendAgentAnswerFeedback(
6584
+ analytics.eventUrl,
6585
+ buildAgentAnswerFeedbackEvent({
6586
+ agentSessionId: sessionId,
6587
+ analytics,
6588
+ indexId,
6589
+ messageId: message.id,
6590
+ page: window.location.href,
6591
+ query: findPrecedingVisitorText(state.messages, message.id),
6592
+ answer: message.text,
6593
+ rating,
6594
+ version: version ?? "published",
6595
+ visitorSessionId
6596
+ })
6597
+ );
6598
+ }
6599
+ (0, import_react15.useEffect)(() => {
5625
6600
  if (railCollapsed) return;
5626
6601
  const handleKeyDown = (event) => {
5627
6602
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5655,19 +6630,19 @@ function AgentWidget({
5655
6630
  window.addEventListener("keydown", handleKeyDown);
5656
6631
  return () => window.removeEventListener("keydown", handleKeyDown);
5657
6632
  }, [isMobile, railCollapsed, railExpanded]);
5658
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "webless-agent-root", children: [
5659
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6633
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
6634
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5660
6635
  "div",
5661
6636
  {
5662
6637
  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)(
6638
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5664
6639
  "div",
5665
6640
  {
5666
6641
  ref: railSlotRef,
5667
6642
  className: "webless-agent-root__rail-slot",
5668
6643
  inert: railCollapsed || void 0,
5669
6644
  "aria-hidden": railCollapsed,
5670
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6645
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5671
6646
  AgentRail,
5672
6647
  {
5673
6648
  theme,
@@ -5676,6 +6651,9 @@ function AgentWidget({
5676
6651
  brandLogoUrl: branding?.logoUrl,
5677
6652
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5678
6653
  poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6654
+ disclaimerLabel: branding?.disclaimer,
6655
+ answerReceipt: branding?.answerReceipt,
6656
+ readAloud: branding?.readAloud,
5679
6657
  state,
5680
6658
  mobileFullscreen: isMobile && !railCollapsed,
5681
6659
  expanded: railExpanded,
@@ -5685,6 +6663,8 @@ function AgentWidget({
5685
6663
  onSubmit: handleSubmit,
5686
6664
  onReset: reset,
5687
6665
  onRetry: () => void retry(),
6666
+ onRegenerate: () => void regenerate(),
6667
+ onFeedback: analytics ? handleFeedback : void 0,
5688
6668
  onInputResponse: (response) => void respondToInput(response),
5689
6669
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5690
6670
  onFollowUpSelect: (label) => void handleSubmit(label),
@@ -5698,7 +6678,7 @@ function AgentWidget({
5698
6678
  )
5699
6679
  }
5700
6680
  ),
5701
- railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6681
+ railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5702
6682
  AssistEdgeTab,
5703
6683
  {
5704
6684
  variant: placement.variant,
@@ -5724,21 +6704,26 @@ function AgentWidget({
5724
6704
  }
5725
6705
  // Annotate the CommonJS export names for ESM import in node:
5726
6706
  0 && (module.exports = {
6707
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
5727
6708
  AGENT_STRUCTURED_TOOL_INPUT_HEADER,
5728
6709
  AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
5729
6710
  AgentRail,
5730
6711
  AgentWidget,
5731
6712
  AssistEdgeTab,
5732
6713
  DEFAULT_AGENT_PLACEMENT,
6714
+ MessageActions,
6715
+ buildAgentAnswerFeedbackEvent,
5733
6716
  builtInVisitorToolResultRegistry,
5734
6717
  createIdleSuggestions,
5735
6718
  defaultAgentRailTheme,
5736
6719
  defaultDarkAgentRailTheme,
6720
+ findPrecedingVisitorText,
5737
6721
  formatAgentStructuredToolInput,
5738
6722
  hasVisitorMessages,
5739
6723
  isAgentBusy,
5740
6724
  normalizeAgentPlacement,
5741
6725
  presentVisitorToolResult,
6726
+ sendAgentAnswerFeedback,
5742
6727
  useAgentChat
5743
6728
  });
5744
6729
  //# sourceMappingURL=react.cjs.map