@webless/agent 0.6.10 → 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.
@@ -780,6 +780,30 @@ function bookingPresenter(kind) {
780
780
  }
781
781
  };
782
782
  }
783
+ function providerErrorPresenter() {
784
+ return {
785
+ kind: "provider_error",
786
+ present: ({ envelope }) => {
787
+ const output = asRecord3(envelope.output);
788
+ const providerError = asRecord3(output?.providerError);
789
+ const message = safeText(providerError?.message);
790
+ const action = safeText(providerError?.action);
791
+ if (!message || !action) return null;
792
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
793
+ return {
794
+ kind: "summary",
795
+ status: "failed",
796
+ title: message,
797
+ description: action,
798
+ ...resourceLabels.length ? {
799
+ details: [
800
+ { label: "Affected", value: resourceLabels.join(", ") }
801
+ ]
802
+ } : {}
803
+ };
804
+ }
805
+ };
806
+ }
783
807
  function asRecord3(value) {
784
808
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
785
809
  }
@@ -897,6 +921,7 @@ function fallbackTitleFromKind(kind) {
897
921
  return "Saved";
898
922
  }
899
923
  var builtInVisitorToolResultRegistry = [
924
+ providerErrorPresenter(),
900
925
  bookingPresenter("booking_offer"),
901
926
  bookingPresenter("booking_confirmed"),
902
927
  bookingPresenter("booking_canceled"),
@@ -946,7 +971,7 @@ function finalizeSummaryPresentation(result, proposed) {
946
971
  return {
947
972
  id: result.callId,
948
973
  toolName: result.toolName,
949
- status: result.status,
974
+ status: proposed.status ?? result.status,
950
975
  kind: "summary",
951
976
  title,
952
977
  ...description && description !== title ? { description } : {},
@@ -955,7 +980,7 @@ function finalizeSummaryPresentation(result, proposed) {
955
980
  };
956
981
  }
957
982
  function presentVisitorToolResult(result, registry = []) {
958
- const envelope = parseAgentToolResultEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
983
+ const envelope = parseAgentToolResultEnvelope(result.output) ?? providerErrorEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
959
984
  const proposed = envelope ? resolvePresenterOutput(result, envelope, registry) : null;
960
985
  if (proposed?.kind === "booking") {
961
986
  return {
@@ -1018,6 +1043,25 @@ function presentVisitorToolResult(result, registry = []) {
1018
1043
  }
1019
1044
  return finalizeSummaryPresentation(result, proposed);
1020
1045
  }
1046
+ function providerErrorEnvelope(output) {
1047
+ const record = asRecord3(output);
1048
+ const providerError = asRecord3(record?.providerError);
1049
+ const message = safeText(providerError?.message);
1050
+ const action = safeText(providerError?.action);
1051
+ if (!message || !action) return null;
1052
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
1053
+ return {
1054
+ schemaVersion: "webless.tool-result.v1",
1055
+ output: {
1056
+ providerError: {
1057
+ action,
1058
+ message,
1059
+ ...resourceLabels.length ? { resourceLabels } : {}
1060
+ }
1061
+ },
1062
+ presentationKinds: ["provider_error"]
1063
+ };
1064
+ }
1021
1065
  function legacyBookingEnvelope(output) {
1022
1066
  const card = bookingCardFromActionOutput(output);
1023
1067
  return card ? {
@@ -1573,6 +1617,20 @@ function latestTurnEvents(events) {
1573
1617
  }
1574
1618
  return startIndex >= 0 ? events.slice(startIndex) : [];
1575
1619
  }
1620
+ function streamIndexBeforeLastTurn(input) {
1621
+ let turnStart = -1;
1622
+ for (let index = input.events.length - 1; index >= 0; index -= 1) {
1623
+ if (input.events[index]?.type === "message.received") {
1624
+ turnStart = index;
1625
+ break;
1626
+ }
1627
+ }
1628
+ if (turnStart < 0) return null;
1629
+ return Math.max(
1630
+ 0,
1631
+ input.currentStreamIndex - (input.events.length - turnStart)
1632
+ );
1633
+ }
1576
1634
  function renderTurn(events) {
1577
1635
  let rendered = "";
1578
1636
  for (const event of events) {
@@ -1757,6 +1815,40 @@ var AgentSession = class {
1757
1815
  this.storeOptions
1758
1816
  );
1759
1817
  }
1818
+ async rewindBeforeLastTurn(signal) {
1819
+ const persisted = loadPersistedAgentSession(
1820
+ this.visitorSessionId,
1821
+ this.storeOptions
1822
+ );
1823
+ if (!persisted?.sessionId) return false;
1824
+ const client = this.ensureClient();
1825
+ const attached = client.sessions.attach(persisted.sessionId, {
1826
+ streamIndex: persisted.streamIndex
1827
+ });
1828
+ const snapshot = await withCapabilityRefresh(
1829
+ this.capability,
1830
+ () => attached.snapshot({ signal })
1831
+ );
1832
+ const rewindStreamIndex = streamIndexBeforeLastTurn({
1833
+ currentStreamIndex: snapshot.session.streamIndex,
1834
+ events: snapshot.events
1835
+ });
1836
+ if (rewindStreamIndex === null) return false;
1837
+ this.session = client.sessions.attach(persisted.sessionId, {
1838
+ streamIndex: rewindStreamIndex
1839
+ });
1840
+ savePersistedAgentSession(
1841
+ this.visitorSessionId,
1842
+ persisted.sessionId,
1843
+ rewindStreamIndex,
1844
+ this.storeOptions
1845
+ );
1846
+ return true;
1847
+ }
1848
+ async regenerateTurn(message, signal, handlers) {
1849
+ await this.rewindBeforeLastTurn(signal);
1850
+ return this.sendTurn(message, signal, handlers);
1851
+ }
1760
1852
  ensureClient() {
1761
1853
  const config = resolveAgentRuntimeConfig({
1762
1854
  indexId: this.indexId,
@@ -2092,6 +2184,11 @@ function createAgentClient(options) {
2092
2184
  respondOptions.signal ?? new AbortController().signal,
2093
2185
  respondOptions.handlers
2094
2186
  ),
2187
+ regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
2188
+ message,
2189
+ regenerateOptions.signal ?? new AbortController().signal,
2190
+ regenerateOptions.handlers
2191
+ ),
2095
2192
  reset: () => session.reset(),
2096
2193
  cancelActive: () => session.cancelActive(),
2097
2194
  getActiveSessionId: () => session.getActiveSessionId()
@@ -2692,6 +2789,7 @@ function useAgentChat({
2692
2789
  const {
2693
2790
  controller,
2694
2791
  initialText = "",
2792
+ regenerate: regenerate2 = false,
2695
2793
  responses,
2696
2794
  resume,
2697
2795
  visitorText
@@ -2702,6 +2800,7 @@ function useAgentChat({
2702
2800
  let streamStarted = Boolean(initialText);
2703
2801
  let streamed = initialText;
2704
2802
  const capturedOffers = [];
2803
+ let bookingConfirmed = false;
2705
2804
  let capturedInputCount = 0;
2706
2805
  const handlers = {
2707
2806
  onWork: (item) => {
@@ -2726,6 +2825,7 @@ function useAgentChat({
2726
2825
  }
2727
2826
  if (!isActiveRun()) return;
2728
2827
  if (card.type === "booking_confirmed") {
2828
+ bookingConfirmed = true;
2729
2829
  pendingBookingRef.current = card;
2730
2830
  savePendingWidgetBooking(
2731
2831
  resolvedStorageKeyPrefix,
@@ -2801,7 +2901,13 @@ function useAgentChat({
2801
2901
  initialText,
2802
2902
  message: visitorText,
2803
2903
  signal
2804
- }) : await clientRef.current.sendTurn(visitorText, { handlers, signal });
2904
+ }) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
2905
+ handlers,
2906
+ signal
2907
+ }) : await clientRef.current.sendTurn(visitorText, {
2908
+ handlers,
2909
+ signal
2910
+ });
2805
2911
  if (resume && finalText === null) {
2806
2912
  finalText = await clientRef.current.sendTurn(visitorText, {
2807
2913
  handlers,
@@ -2820,6 +2926,7 @@ function useAgentChat({
2820
2926
  const parsedCards = extractToolCards(displayText);
2821
2927
  for (const card of parsedCards) {
2822
2928
  if (card.type === "booking_confirmed") {
2929
+ bookingConfirmed = true;
2823
2930
  pendingBookingRef.current = card;
2824
2931
  savePendingWidgetBooking(resolvedStorageKeyPrefix, visitorId, card);
2825
2932
  }
@@ -2834,7 +2941,7 @@ function useAgentChat({
2834
2941
  messages: appendAgentTurnMessage(prev.messages, displayText),
2835
2942
  toolSteps: completeActivePlanning(prev.toolSteps),
2836
2943
  streamingText: "",
2837
- pendingOffer: capturedOffers.at(-1) ?? prev.pendingOffer,
2944
+ pendingOffer: bookingConfirmed ? null : capturedOffers.at(-1) ?? prev.pendingOffer,
2838
2945
  pendingInputs: (prev.pendingInputs ?? []).filter(
2839
2946
  isChatCollectibleInputRequest
2840
2947
  ),
@@ -2860,7 +2967,6 @@ function useAgentChat({
2860
2967
  } : step
2861
2968
  ),
2862
2969
  streamingText: "",
2863
- pendingOffer: null,
2864
2970
  error: message
2865
2971
  }));
2866
2972
  runRef.current = null;
@@ -2968,7 +3074,7 @@ ${outgoing}` : outgoing;
2968
3074
  journey: null,
2969
3075
  followUps: [],
2970
3076
  streamingText: "",
2971
- pendingOffer: null,
3077
+ pendingOffer: options?.preservePendingOffer ? prev.pendingOffer : null,
2972
3078
  pendingInputs: [],
2973
3079
  toolResults: [],
2974
3080
  error: null
@@ -3004,7 +3110,6 @@ ${outgoing}` : outgoing;
3004
3110
  journey: null,
3005
3111
  followUps: [],
3006
3112
  streamingText: "",
3007
- pendingOffer: null,
3008
3113
  pendingInputs: [],
3009
3114
  toolResults: [],
3010
3115
  error: null
@@ -3015,6 +3120,49 @@ ${outgoing}` : outgoing;
3015
3120
  visitorText: visitorTurnText(visitorMessage)
3016
3121
  });
3017
3122
  }, [runTurn, state.messages]);
3123
+ const regenerate = useCallback(async () => {
3124
+ let lastVisitorIndex = -1;
3125
+ for (let index = state.messages.length - 1; index >= 0; index -= 1) {
3126
+ if (state.messages[index]?.role === "visitor") {
3127
+ lastVisitorIndex = index;
3128
+ break;
3129
+ }
3130
+ }
3131
+ const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
3132
+ if (!visitorMessage) return null;
3133
+ if (runRef.current) {
3134
+ runRef.current.abort();
3135
+ clientRef.current.cancelActive();
3136
+ }
3137
+ const controller = new AbortController();
3138
+ runRef.current = controller;
3139
+ setState((prev) => ({
3140
+ ...prev,
3141
+ phase: "thinking",
3142
+ messages: prev.messages.slice(0, lastVisitorIndex + 1),
3143
+ toolSteps: [
3144
+ {
3145
+ id: "planning",
3146
+ kind: "planning",
3147
+ label: "Understanding your question",
3148
+ state: "active"
3149
+ }
3150
+ ],
3151
+ journey: null,
3152
+ followUps: [],
3153
+ streamingText: "",
3154
+ pendingOffer: null,
3155
+ pendingInputs: [],
3156
+ toolResults: [],
3157
+ error: null
3158
+ }));
3159
+ return await runTurn({
3160
+ controller,
3161
+ regenerate: true,
3162
+ resume: false,
3163
+ visitorText: visitorTurnText(visitorMessage)
3164
+ });
3165
+ }, [runTurn, state.messages]);
3018
3166
  const respondToToolInput = useCallback(
3019
3167
  async (surface, values) => {
3020
3168
  await submit(`${surface.title} submitted`, {
@@ -3091,6 +3239,7 @@ ${outgoing}` : outgoing;
3091
3239
  state,
3092
3240
  reset,
3093
3241
  retry,
3242
+ regenerate,
3094
3243
  respondToInput,
3095
3244
  respondToToolInput,
3096
3245
  submit,
@@ -3196,8 +3345,505 @@ var defaultDarkAgentRailTheme = {
3196
3345
  danger: "#ff8da1"
3197
3346
  };
3198
3347
 
3348
+ // src/react/components/MessageActions/MessageActions.tsx
3349
+ import { useEffect as useEffect2, useLayoutEffect, useRef as useRef2, useState as useState2 } from "react";
3350
+ import { createPortal } from "react-dom";
3351
+
3352
+ // src/react/lib/speech.ts
3353
+ function toSpeechText(text) {
3354
+ let out = hideToolCardFences(text);
3355
+ out = out.replace(/```[\s\S]*?```/g, " ");
3356
+ out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
3357
+ out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
3358
+ out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
3359
+ out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
3360
+ out = out.replace(/(\*|_)(.*?)\1/g, "$2");
3361
+ out = out.replace(/~~(.*?)~~/g, "$1");
3362
+ out = out.replace(/`([^`]*)`/g, "$1");
3363
+ out = out.replace(/^\s*>\s?/gm, "");
3364
+ out = out.replace(/^\s*[-*+]\s+/gm, "");
3365
+ out = out.replace(/^\s*\d+\.\s+/gm, "");
3366
+ out = out.replace(/\|/g, " ");
3367
+ out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
3368
+ out = out.replace(/\s*\n\s*/g, ". ");
3369
+ out = out.replace(/(?:\.\s*){2,}/g, ". ");
3370
+ return out.replace(/\s{2,}/g, " ").trim();
3371
+ }
3372
+ function isSpeechSupported() {
3373
+ return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
3374
+ }
3375
+
3376
+ // src/react/components/AgentRail/AgentRailOverlayContext.tsx
3377
+ import { createContext, useContext } from "react";
3378
+ var AgentRailOverlayContext = createContext(null);
3379
+ function useAgentRailPortalRoots() {
3380
+ return useContext(AgentRailOverlayContext);
3381
+ }
3382
+ function useAgentRailMenuPortalRoot() {
3383
+ return useContext(AgentRailOverlayContext)?.railRef ?? null;
3384
+ }
3385
+
3386
+ // src/react/components/MessageActions/MessageActions.tsx
3387
+ import { jsx, jsxs } from "react/jsx-runtime";
3388
+ function CopyIcon() {
3389
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3390
+ /* @__PURE__ */ jsx(
3391
+ "rect",
3392
+ {
3393
+ x: "5.75",
3394
+ y: "5.75",
3395
+ width: "7.5",
3396
+ height: "7.5",
3397
+ rx: "1.5",
3398
+ stroke: "currentColor",
3399
+ strokeWidth: "1.5"
3400
+ }
3401
+ ),
3402
+ /* @__PURE__ */ jsx(
3403
+ "path",
3404
+ {
3405
+ 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",
3406
+ stroke: "currentColor",
3407
+ strokeWidth: "1.5"
3408
+ }
3409
+ )
3410
+ ] });
3411
+ }
3412
+ function CheckIcon() {
3413
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
3414
+ "path",
3415
+ {
3416
+ d: "M3.5 8.5l3 3 6-7",
3417
+ stroke: "currentColor",
3418
+ strokeWidth: "1.6",
3419
+ strokeLinecap: "round",
3420
+ strokeLinejoin: "round"
3421
+ }
3422
+ ) });
3423
+ }
3424
+ function ThumbUpIcon() {
3425
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3426
+ /* @__PURE__ */ jsx(
3427
+ "path",
3428
+ {
3429
+ d: "M4.67 6.67v8",
3430
+ stroke: "currentColor",
3431
+ strokeWidth: "1.5",
3432
+ strokeLinecap: "round"
3433
+ }
3434
+ ),
3435
+ /* @__PURE__ */ jsx(
3436
+ "path",
3437
+ {
3438
+ 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",
3439
+ stroke: "currentColor",
3440
+ strokeWidth: "1.5",
3441
+ strokeLinecap: "round",
3442
+ strokeLinejoin: "round"
3443
+ }
3444
+ )
3445
+ ] });
3446
+ }
3447
+ function ThumbDownIcon() {
3448
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("g", { transform: "rotate(180 8 8)", children: [
3449
+ /* @__PURE__ */ jsx(
3450
+ "path",
3451
+ {
3452
+ d: "M4.67 6.67v8",
3453
+ stroke: "currentColor",
3454
+ strokeWidth: "1.5",
3455
+ strokeLinecap: "round"
3456
+ }
3457
+ ),
3458
+ /* @__PURE__ */ jsx(
3459
+ "path",
3460
+ {
3461
+ 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",
3462
+ stroke: "currentColor",
3463
+ strokeWidth: "1.5",
3464
+ strokeLinecap: "round",
3465
+ strokeLinejoin: "round"
3466
+ }
3467
+ )
3468
+ ] }) });
3469
+ }
3470
+ function RegenerateIcon() {
3471
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3472
+ /* @__PURE__ */ jsx(
3473
+ "path",
3474
+ {
3475
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
3476
+ stroke: "currentColor",
3477
+ strokeWidth: "1.5",
3478
+ strokeLinecap: "round"
3479
+ }
3480
+ ),
3481
+ /* @__PURE__ */ jsx(
3482
+ "path",
3483
+ {
3484
+ d: "M14 2v3.33h-3.33",
3485
+ stroke: "currentColor",
3486
+ strokeWidth: "1.5",
3487
+ strokeLinecap: "round",
3488
+ strokeLinejoin: "round"
3489
+ }
3490
+ ),
3491
+ /* @__PURE__ */ jsx(
3492
+ "path",
3493
+ {
3494
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
3495
+ stroke: "currentColor",
3496
+ strokeWidth: "1.5",
3497
+ strokeLinecap: "round"
3498
+ }
3499
+ ),
3500
+ /* @__PURE__ */ jsx(
3501
+ "path",
3502
+ {
3503
+ d: "M5.33 10.67H2V14",
3504
+ stroke: "currentColor",
3505
+ strokeWidth: "1.5",
3506
+ strokeLinecap: "round",
3507
+ strokeLinejoin: "round"
3508
+ }
3509
+ )
3510
+ ] });
3511
+ }
3512
+ function MoreIcon() {
3513
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3514
+ /* @__PURE__ */ jsx("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
3515
+ /* @__PURE__ */ jsx("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
3516
+ /* @__PURE__ */ jsx("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
3517
+ ] });
3518
+ }
3519
+ function SourcesIcon() {
3520
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3521
+ /* @__PURE__ */ jsx(
3522
+ "path",
3523
+ {
3524
+ 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",
3525
+ stroke: "currentColor",
3526
+ strokeWidth: "1.4",
3527
+ strokeLinecap: "round",
3528
+ strokeLinejoin: "round"
3529
+ }
3530
+ ),
3531
+ /* @__PURE__ */ jsx(
3532
+ "path",
3533
+ {
3534
+ d: "M8 4.5v9",
3535
+ stroke: "currentColor",
3536
+ strokeWidth: "1.4",
3537
+ strokeLinecap: "round"
3538
+ }
3539
+ )
3540
+ ] });
3541
+ }
3542
+ function ReadAloudIcon() {
3543
+ return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
3544
+ /* @__PURE__ */ jsx(
3545
+ "path",
3546
+ {
3547
+ 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",
3548
+ stroke: "currentColor",
3549
+ strokeWidth: "1.4",
3550
+ strokeLinecap: "round",
3551
+ strokeLinejoin: "round"
3552
+ }
3553
+ ),
3554
+ /* @__PURE__ */ jsx(
3555
+ "path",
3556
+ {
3557
+ 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",
3558
+ stroke: "currentColor",
3559
+ strokeWidth: "1.4",
3560
+ strokeLinecap: "round"
3561
+ }
3562
+ )
3563
+ ] });
3564
+ }
3565
+ function StopIcon() {
3566
+ return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
3567
+ "rect",
3568
+ {
3569
+ x: "4",
3570
+ y: "4",
3571
+ width: "8",
3572
+ height: "8",
3573
+ rx: "1.5",
3574
+ stroke: "currentColor",
3575
+ strokeWidth: "1.5"
3576
+ }
3577
+ ) });
3578
+ }
3579
+ async function writeToClipboard(text) {
3580
+ try {
3581
+ await navigator.clipboard.writeText(text);
3582
+ } catch {
3583
+ const textarea = document.createElement("textarea");
3584
+ textarea.value = text;
3585
+ textarea.style.position = "fixed";
3586
+ textarea.style.opacity = "0";
3587
+ document.body.appendChild(textarea);
3588
+ textarea.select();
3589
+ document.execCommand("copy");
3590
+ textarea.remove();
3591
+ }
3592
+ }
3593
+ function formatAnsweredAt(answeredAt) {
3594
+ if (!answeredAt) return null;
3595
+ const date = new Date(answeredAt);
3596
+ if (Number.isNaN(date.getTime())) return null;
3597
+ return new Intl.DateTimeFormat(void 0, {
3598
+ dateStyle: "medium",
3599
+ timeStyle: "short"
3600
+ }).format(date);
3601
+ }
3602
+ function resolveMenuPosition(input) {
3603
+ const padding = 8;
3604
+ const { button, menuHeight, menuWidth, rail } = input;
3605
+ if (!rail) {
3606
+ return {
3607
+ left: button.left,
3608
+ top: button.top - menuHeight - 6
3609
+ };
3610
+ }
3611
+ let left = button.left - rail.left;
3612
+ let top = button.top - rail.top - menuHeight - 6;
3613
+ left = Math.min(
3614
+ Math.max(left, padding),
3615
+ rail.width - menuWidth - padding
3616
+ );
3617
+ if (top < padding) {
3618
+ top = button.bottom - rail.top + 6;
3619
+ }
3620
+ top = Math.min(top, rail.height - menuHeight - padding);
3621
+ return { left, top };
3622
+ }
3623
+ function MessageActions({
3624
+ answeredAt,
3625
+ copyText,
3626
+ disabled = false,
3627
+ onOpenReceipt,
3628
+ onRegenerate,
3629
+ onFeedback,
3630
+ readAloud = false,
3631
+ receiptSteps,
3632
+ speechText
3633
+ }) {
3634
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
3635
+ const [copied, setCopied] = useState2(false);
3636
+ const [rating, setRating] = useState2(null);
3637
+ const [menuOpen, setMenuOpen] = useState2(false);
3638
+ const [menuPosition, setMenuPosition] = useState2(null);
3639
+ const [speaking, setSpeaking] = useState2(false);
3640
+ const copyTimerRef = useRef2(null);
3641
+ const menuRef = useRef2(null);
3642
+ const portaledMenuRef = useRef2(null);
3643
+ const moreButtonRef = useRef2(null);
3644
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
3645
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
3646
+ const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
3647
+ const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
3648
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
3649
+ useLayoutEffect(() => {
3650
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
3651
+ setMenuPosition(null);
3652
+ return;
3653
+ }
3654
+ const button = moreButtonRef.current.getBoundingClientRect();
3655
+ const menu2 = portaledMenuRef.current;
3656
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
3657
+ setMenuPosition(
3658
+ resolveMenuPosition({
3659
+ button,
3660
+ menuHeight: menu2.offsetHeight,
3661
+ menuWidth: menu2.offsetWidth || 190,
3662
+ rail
3663
+ })
3664
+ );
3665
+ }, [menuOpen, menuPortalRoot]);
3666
+ useEffect2(
3667
+ () => () => {
3668
+ if (copyTimerRef.current !== null) {
3669
+ window.clearTimeout(copyTimerRef.current);
3670
+ }
3671
+ if (speaking) window.speechSynthesis.cancel();
3672
+ },
3673
+ // Cancel speech only when this answer's actions unmount.
3674
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3675
+ []
3676
+ );
3677
+ useEffect2(() => {
3678
+ if (!menuOpen) return;
3679
+ const handlePointerDown = (event) => {
3680
+ const target = event.target;
3681
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
3682
+ setMenuOpen(false);
3683
+ }
3684
+ };
3685
+ const handleKeyDown = (event) => {
3686
+ if (event.key !== "Escape") return;
3687
+ event.preventDefault();
3688
+ event.stopPropagation();
3689
+ setMenuOpen(false);
3690
+ };
3691
+ document.addEventListener("pointerdown", handlePointerDown);
3692
+ document.addEventListener("keydown", handleKeyDown);
3693
+ return () => {
3694
+ document.removeEventListener("pointerdown", handlePointerDown);
3695
+ document.removeEventListener("keydown", handleKeyDown);
3696
+ };
3697
+ }, [menuOpen]);
3698
+ function handleCopy() {
3699
+ void writeToClipboard(copyText);
3700
+ setCopied(true);
3701
+ if (copyTimerRef.current !== null) {
3702
+ window.clearTimeout(copyTimerRef.current);
3703
+ }
3704
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
3705
+ }
3706
+ function handleFeedback(next) {
3707
+ const resolved = rating === next ? null : next;
3708
+ setRating(resolved);
3709
+ if (resolved) onFeedback?.(resolved);
3710
+ }
3711
+ function handleReadAloud() {
3712
+ if (!canReadAloud) return;
3713
+ setMenuOpen(false);
3714
+ if (speaking) {
3715
+ window.speechSynthesis.cancel();
3716
+ setSpeaking(false);
3717
+ return;
3718
+ }
3719
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
3720
+ utterance.onend = () => setSpeaking(false);
3721
+ utterance.onerror = () => setSpeaking(false);
3722
+ window.speechSynthesis.cancel();
3723
+ window.speechSynthesis.speak(utterance);
3724
+ setSpeaking(true);
3725
+ }
3726
+ const menu = menuOpen ? /* @__PURE__ */ jsxs(
3727
+ "div",
3728
+ {
3729
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
3730
+ ref: portaledMenuRef,
3731
+ role: "menu",
3732
+ style: menuPosition ? {
3733
+ left: `${menuPosition.left}px`,
3734
+ top: `${menuPosition.top}px`
3735
+ } : { visibility: "hidden" },
3736
+ children: [
3737
+ answeredLabel ? /* @__PURE__ */ jsxs("p", { className: "agent-message-actions__menu-meta", children: [
3738
+ "Answered ",
3739
+ answeredLabel
3740
+ ] }) : null,
3741
+ canOpenReceipt ? /* @__PURE__ */ jsxs(
3742
+ "button",
3743
+ {
3744
+ type: "button",
3745
+ className: "agent-message-actions__menu-item",
3746
+ role: "menuitem",
3747
+ onClick: () => {
3748
+ setMenuOpen(false);
3749
+ onOpenReceipt?.();
3750
+ },
3751
+ children: [
3752
+ /* @__PURE__ */ jsx(SourcesIcon, {}),
3753
+ "View sources"
3754
+ ]
3755
+ }
3756
+ ) : null,
3757
+ canReadAloud ? /* @__PURE__ */ jsxs(
3758
+ "button",
3759
+ {
3760
+ type: "button",
3761
+ className: "agent-message-actions__menu-item",
3762
+ role: "menuitem",
3763
+ onClick: handleReadAloud,
3764
+ children: [
3765
+ speaking ? /* @__PURE__ */ jsx(StopIcon, {}) : /* @__PURE__ */ jsx(ReadAloudIcon, {}),
3766
+ speaking ? "Stop reading" : "Read aloud"
3767
+ ]
3768
+ }
3769
+ ) : null
3770
+ ]
3771
+ }
3772
+ ) : null;
3773
+ return /* @__PURE__ */ jsxs("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
3774
+ /* @__PURE__ */ jsx(
3775
+ "button",
3776
+ {
3777
+ type: "button",
3778
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
3779
+ "aria-label": copied ? "Copied" : "Copy answer",
3780
+ title: copied ? "Copied" : "Copy answer",
3781
+ disabled,
3782
+ onClick: handleCopy,
3783
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
3784
+ }
3785
+ ),
3786
+ /* @__PURE__ */ jsx(
3787
+ "button",
3788
+ {
3789
+ type: "button",
3790
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
3791
+ "aria-label": "Good answer",
3792
+ "aria-pressed": rating === "positive",
3793
+ title: "Good answer",
3794
+ disabled,
3795
+ onClick: () => handleFeedback("positive"),
3796
+ children: /* @__PURE__ */ jsx(ThumbUpIcon, {})
3797
+ }
3798
+ ),
3799
+ /* @__PURE__ */ jsx(
3800
+ "button",
3801
+ {
3802
+ type: "button",
3803
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
3804
+ "aria-label": "Bad answer",
3805
+ "aria-pressed": rating === "negative",
3806
+ title: "Bad answer",
3807
+ disabled,
3808
+ onClick: () => handleFeedback("negative"),
3809
+ children: /* @__PURE__ */ jsx(ThumbDownIcon, {})
3810
+ }
3811
+ ),
3812
+ onRegenerate ? /* @__PURE__ */ jsx(
3813
+ "button",
3814
+ {
3815
+ type: "button",
3816
+ className: "agent-message-actions__button",
3817
+ "aria-label": "Regenerate answer",
3818
+ title: "Regenerate answer",
3819
+ disabled,
3820
+ onClick: onRegenerate,
3821
+ children: /* @__PURE__ */ jsx(RegenerateIcon, {})
3822
+ }
3823
+ ) : null,
3824
+ showMenu ? /* @__PURE__ */ jsxs("div", { className: "agent-message-actions__more", ref: menuRef, children: [
3825
+ /* @__PURE__ */ jsx(
3826
+ "button",
3827
+ {
3828
+ ref: moreButtonRef,
3829
+ type: "button",
3830
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
3831
+ "aria-label": "More actions",
3832
+ "aria-haspopup": "menu",
3833
+ "aria-expanded": menuOpen,
3834
+ title: "More actions",
3835
+ disabled,
3836
+ onClick: () => setMenuOpen((open) => !open),
3837
+ children: /* @__PURE__ */ jsx(MoreIcon, {})
3838
+ }
3839
+ ),
3840
+ menuPortalRoot?.current && menu ? createPortal(menu, menuPortalRoot.current) : menu
3841
+ ] }) : null
3842
+ ] });
3843
+ }
3844
+
3199
3845
  // src/react/components/AgentRail/AgentRail.tsx
3200
- import { useEffect as useEffect4, useRef as useRef4, useState as useState8 } from "react";
3846
+ import { useEffect as useEffect6, useRef as useRef6, useState as useState9 } from "react";
3201
3847
 
3202
3848
  // src/react/hooks/useAgentColorScheme.ts
3203
3849
  import { useSyncExternalStore } from "react";
@@ -3230,8 +3876,8 @@ function resolveAgentColorScheme(colorScheme = "auto", prefersDarkMode) {
3230
3876
  }
3231
3877
 
3232
3878
  // src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
3233
- import { useState as useState2 } from "react";
3234
- import { jsx, jsxs } from "react/jsx-runtime";
3879
+ import { useState as useState3 } from "react";
3880
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
3235
3881
  function joinLabels(labels) {
3236
3882
  if (labels.length <= 1) return labels[0] ?? "";
3237
3883
  if (labels.length === 2) return `${labels[0]} and ${labels[1]}`;
@@ -3281,18 +3927,11 @@ function stepDetail(step, steps) {
3281
3927
  return "Searched this site";
3282
3928
  return step.detail;
3283
3929
  }
3284
- function AgentActivityBubble({
3930
+ function AgentWorkSteps({
3285
3931
  brandLabel = "",
3286
- failed = false,
3287
- steps,
3288
- onRetryStep
3932
+ onRetryStep,
3933
+ steps
3289
3934
  }) {
3290
- const active = steps.some((step) => step.state === "active");
3291
- const receiptId = steps.map((step) => step.id).join(":");
3292
- const [expandedReceiptId, setExpandedReceiptId] = useState2(
3293
- null
3294
- );
3295
- const detailsOpen = active || expandedReceiptId === receiptId;
3296
3935
  const delegationCount = steps.filter(
3297
3936
  (step) => step.kind === "specialist"
3298
3937
  ).length;
@@ -3300,26 +3939,80 @@ function AgentActivityBubble({
3300
3939
  const visibleSteps = steps.filter(
3301
3940
  (step) => step.kind !== "planning" || Boolean(brandLabel)
3302
3941
  );
3303
- return /* @__PURE__ */ jsxs("article", { className: "agent-activity-bubble", children: [
3304
- /* @__PURE__ */ jsxs("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
3305
- /* @__PURE__ */ jsx(
3306
- "span",
3942
+ return /* @__PURE__ */ jsx2("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3943
+ const detail = stepDetail(step, steps);
3944
+ const child = delegated && step.kind === "specialist";
3945
+ return /* @__PURE__ */ jsxs2(
3946
+ "li",
3947
+ {
3948
+ className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3949
+ "data-kind": step.kind,
3950
+ "data-state": step.state,
3951
+ children: [
3952
+ /* @__PURE__ */ jsx2(
3953
+ "span",
3954
+ {
3955
+ className: "agent-activity-bubble__step-icon",
3956
+ "aria-hidden": "true"
3957
+ }
3958
+ ),
3959
+ /* @__PURE__ */ jsxs2("span", { className: "agent-activity-bubble__step-copy", children: [
3960
+ /* @__PURE__ */ jsx2("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ jsx2("strong", { children: stepLabel(step, brandLabel) }) }),
3961
+ detail ? /* @__PURE__ */ jsx2("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3962
+ delegated && step.kind === "planning" ? /* @__PURE__ */ jsxs2("span", { className: "agent-activity-bubble__delegation", children: [
3963
+ "Delegated ",
3964
+ delegationCount,
3965
+ " ",
3966
+ delegationCount === 1 ? "task" : "tasks"
3967
+ ] }) : null,
3968
+ step.state === "error" && onRetryStep ? /* @__PURE__ */ jsx2(
3969
+ "button",
3970
+ {
3971
+ type: "button",
3972
+ className: "agent-activity-bubble__step-retry",
3973
+ onClick: () => onRetryStep(step),
3974
+ children: "Retry"
3975
+ }
3976
+ ) : null
3977
+ ] })
3978
+ ]
3979
+ },
3980
+ step.id
3981
+ );
3982
+ }) });
3983
+ }
3984
+ function AgentActivityBubble({
3985
+ brandLabel = "",
3986
+ failed = false,
3987
+ steps,
3988
+ onRetryStep
3989
+ }) {
3990
+ const active = steps.some((step) => step.state === "active");
3991
+ const receiptId = steps.map((step) => step.id).join(":");
3992
+ const [expandedReceiptId, setExpandedReceiptId] = useState3(
3993
+ null
3994
+ );
3995
+ const detailsOpen = !active && expandedReceiptId === receiptId;
3996
+ return /* @__PURE__ */ jsxs2("article", { className: "agent-activity-bubble", children: [
3997
+ /* @__PURE__ */ jsxs2("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
3998
+ /* @__PURE__ */ jsx2(
3999
+ "span",
3307
4000
  {
3308
4001
  className: `agent-activity-bubble__pulse${active ? " is-active" : failed ? " is-error" : ""}`,
3309
4002
  "aria-hidden": "true"
3310
4003
  }
3311
4004
  ),
3312
- workSummary(steps, failed, brandLabel)
4005
+ workSummary(steps, failed, brandLabel),
4006
+ active ? "\u2026" : ""
3313
4007
  ] }),
3314
- /* @__PURE__ */ jsxs("div", { className: "agent-activity-bubble__details", children: [
3315
- /* @__PURE__ */ jsx(
4008
+ !active ? /* @__PURE__ */ jsxs2("div", { className: "agent-activity-bubble__details", children: [
4009
+ /* @__PURE__ */ jsx2(
3316
4010
  "button",
3317
4011
  {
3318
4012
  type: "button",
3319
4013
  className: "agent-activity-bubble__summary",
3320
4014
  "aria-expanded": detailsOpen,
3321
4015
  onClick: () => {
3322
- if (active) return;
3323
4016
  setExpandedReceiptId(
3324
4017
  (current) => current === receiptId ? null : receiptId
3325
4018
  );
@@ -3327,61 +4020,138 @@ function AgentActivityBubble({
3327
4020
  children: "How this answer was made"
3328
4021
  }
3329
4022
  ),
3330
- detailsOpen ? /* @__PURE__ */ jsx("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3331
- const detail = stepDetail(step, steps);
3332
- const child = delegated && step.kind === "specialist";
3333
- return /* @__PURE__ */ jsxs(
3334
- "li",
3335
- {
3336
- className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3337
- "data-kind": step.kind,
3338
- "data-state": step.state,
3339
- children: [
3340
- /* @__PURE__ */ jsx(
3341
- "span",
3342
- {
3343
- className: "agent-activity-bubble__step-icon",
3344
- "aria-hidden": "true"
3345
- }
3346
- ),
3347
- /* @__PURE__ */ jsxs("span", { className: "agent-activity-bubble__step-copy", children: [
3348
- /* @__PURE__ */ jsx("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ jsx("strong", { children: stepLabel(step, brandLabel) }) }),
3349
- detail ? /* @__PURE__ */ jsx("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3350
- delegated && step.kind === "planning" ? /* @__PURE__ */ jsxs("span", { className: "agent-activity-bubble__delegation", children: [
3351
- "Delegated ",
3352
- delegationCount,
3353
- " ",
3354
- delegationCount === 1 ? "task" : "tasks"
3355
- ] }) : null,
3356
- step.state === "error" && onRetryStep ? /* @__PURE__ */ jsx(
3357
- "button",
3358
- {
3359
- type: "button",
3360
- className: "agent-activity-bubble__step-retry",
3361
- onClick: () => onRetryStep(step),
3362
- children: "Retry"
3363
- }
3364
- ) : null
3365
- ] })
3366
- ]
3367
- },
3368
- step.id
3369
- );
3370
- }) }) : null
3371
- ] })
4023
+ detailsOpen ? /* @__PURE__ */ jsx2(
4024
+ AgentWorkSteps,
4025
+ {
4026
+ brandLabel,
4027
+ onRetryStep,
4028
+ steps
4029
+ }
4030
+ ) : null
4031
+ ] }) : null
4032
+ ] });
4033
+ }
4034
+
4035
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
4036
+ import { useEffect as useEffect3, useRef as useRef3 } from "react";
4037
+ import { createPortal as createPortal2 } from "react-dom";
4038
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
4039
+ var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
4040
+ function CloseIcon() {
4041
+ return /* @__PURE__ */ jsx3("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
4042
+ "path",
4043
+ {
4044
+ d: "M4 4l8 8M12 4l-8 8",
4045
+ stroke: "currentColor",
4046
+ strokeWidth: "1.5",
4047
+ strokeLinecap: "round"
4048
+ }
4049
+ ) });
4050
+ }
4051
+ function AnswerReceiptDialog({
4052
+ brandLabel = "",
4053
+ onClose,
4054
+ steps
4055
+ }) {
4056
+ const portalRoots = useAgentRailPortalRoots();
4057
+ const overlayRoot = portalRoots?.overlayRef ?? null;
4058
+ const cardRef = useRef3(null);
4059
+ const closeButtonRef = useRef3(null);
4060
+ const previouslyFocusedRef = useRef3(null);
4061
+ useEffect3(() => {
4062
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
4063
+ closeButtonRef.current?.focus({ preventScroll: true });
4064
+ const handleKeyDown = (event) => {
4065
+ if (event.key === "Escape") {
4066
+ event.preventDefault();
4067
+ event.stopPropagation();
4068
+ onClose();
4069
+ return;
4070
+ }
4071
+ if (event.key !== "Tab" || !cardRef.current) return;
4072
+ const focusable = cardRef.current.querySelectorAll(
4073
+ FOCUSABLE_SELECTOR
4074
+ );
4075
+ if (focusable.length === 0) return;
4076
+ const first = focusable.item(0);
4077
+ const last = focusable.item(focusable.length - 1);
4078
+ if (event.shiftKey && document.activeElement === first) {
4079
+ event.preventDefault();
4080
+ last.focus({ preventScroll: true });
4081
+ } else if (!event.shiftKey && document.activeElement === last) {
4082
+ event.preventDefault();
4083
+ first.focus({ preventScroll: true });
4084
+ }
4085
+ };
4086
+ document.addEventListener("keydown", handleKeyDown);
4087
+ return () => {
4088
+ document.removeEventListener("keydown", handleKeyDown);
4089
+ previouslyFocusedRef.current?.focus({ preventScroll: true });
4090
+ };
4091
+ }, [onClose]);
4092
+ const content = /* @__PURE__ */ jsxs3("div", { className: "agent-receipt-dialog", children: [
4093
+ /* @__PURE__ */ jsx3(
4094
+ "button",
4095
+ {
4096
+ type: "button",
4097
+ className: "agent-receipt-dialog__backdrop",
4098
+ "aria-label": "Close",
4099
+ tabIndex: -1,
4100
+ onClick: onClose
4101
+ }
4102
+ ),
4103
+ /* @__PURE__ */ jsxs3(
4104
+ "div",
4105
+ {
4106
+ ref: cardRef,
4107
+ className: "agent-receipt-dialog__card",
4108
+ role: "dialog",
4109
+ "aria-modal": "true",
4110
+ "aria-labelledby": "agent-receipt-dialog-title",
4111
+ children: [
4112
+ /* @__PURE__ */ jsxs3("div", { className: "agent-receipt-dialog__header", children: [
4113
+ /* @__PURE__ */ jsx3(
4114
+ "p",
4115
+ {
4116
+ className: "agent-receipt-dialog__title",
4117
+ id: "agent-receipt-dialog-title",
4118
+ children: "How this answer was made"
4119
+ }
4120
+ ),
4121
+ /* @__PURE__ */ jsx3(
4122
+ "button",
4123
+ {
4124
+ ref: closeButtonRef,
4125
+ type: "button",
4126
+ className: "agent-receipt-dialog__close",
4127
+ "aria-label": "Close",
4128
+ onClick: onClose,
4129
+ children: /* @__PURE__ */ jsx3(CloseIcon, {})
4130
+ }
4131
+ )
4132
+ ] }),
4133
+ /* @__PURE__ */ jsx3("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
4134
+ /* @__PURE__ */ jsx3("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ jsx3(AgentWorkSteps, { brandLabel, steps }) })
4135
+ ]
4136
+ }
4137
+ )
3372
4138
  ] });
4139
+ if (overlayRoot?.current) {
4140
+ return createPortal2(content, overlayRoot.current);
4141
+ }
4142
+ return content;
3373
4143
  }
3374
4144
 
3375
4145
  // src/react/components/Composer/Composer.tsx
3376
4146
  import {
3377
- useEffect as useEffect2,
4147
+ useEffect as useEffect4,
3378
4148
  useId,
3379
- useRef as useRef2,
3380
- useState as useState3
4149
+ useRef as useRef4,
4150
+ useState as useState4
3381
4151
  } from "react";
3382
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
4152
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
3383
4153
  function SendIcon() {
3384
- return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
4154
+ return /* @__PURE__ */ jsx4("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(
3385
4155
  "path",
3386
4156
  {
3387
4157
  d: "M8 12V4M8 4l-3 3M8 4l3 3",
@@ -3404,21 +4174,21 @@ function Composer({
3404
4174
  form = null,
3405
4175
  onSubmit
3406
4176
  }) {
3407
- const [value, setValue] = useState3("");
3408
- const [values, setValues] = useState3(
4177
+ const [value, setValue] = useState4("");
4178
+ const [values, setValues] = useState4(
3409
4179
  () => emptyValues(form)
3410
4180
  );
3411
- const [blurred, setBlurred] = useState3({});
3412
- const inputRef = useRef2(null);
3413
- const firstFieldRef = useRef2(null);
4181
+ const [blurred, setBlurred] = useState4({});
4182
+ const inputRef = useRef4(null);
4183
+ const firstFieldRef = useRef4(null);
3414
4184
  const formId = useId();
3415
4185
  const activeForm = form;
3416
4186
  const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
3417
- useEffect2(() => {
4187
+ useEffect4(() => {
3418
4188
  setValues(emptyValues(form));
3419
4189
  setBlurred({});
3420
4190
  }, [form?.id]);
3421
- useEffect2(() => {
4191
+ useEffect4(() => {
3422
4192
  if (activeForm) firstFieldRef.current?.focus();
3423
4193
  }, [activeForm?.id]);
3424
4194
  function submitChat() {
@@ -3453,7 +4223,7 @@ function Composer({
3453
4223
  submitForm();
3454
4224
  }
3455
4225
  }
3456
- return /* @__PURE__ */ jsx2(
4226
+ return /* @__PURE__ */ jsx4(
3457
4227
  "form",
3458
4228
  {
3459
4229
  className: [
@@ -3462,7 +4232,7 @@ function Composer({
3462
4232
  activeForm ? "composer--form" : ""
3463
4233
  ].filter(Boolean).join(" "),
3464
4234
  onSubmit: handleSubmit,
3465
- children: activeForm ? /* @__PURE__ */ jsxs2("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
4235
+ children: activeForm ? /* @__PURE__ */ jsxs4("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3466
4236
  activeForm.fields.map((field, index) => {
3467
4237
  const fieldId = `${formId}-${field.id}`;
3468
4238
  const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
@@ -3487,7 +4257,7 @@ function Composer({
3487
4257
  },
3488
4258
  onKeyDown: handleFormKeyDown
3489
4259
  };
3490
- return /* @__PURE__ */ jsxs2(
4260
+ return /* @__PURE__ */ jsxs4(
3491
4261
  "div",
3492
4262
  {
3493
4263
  className: [
@@ -3495,9 +4265,9 @@ function Composer({
3495
4265
  field.kind === "textarea" ? "composer__row--grow" : ""
3496
4266
  ].filter(Boolean).join(" "),
3497
4267
  children: [
3498
- /* @__PURE__ */ jsxs2("label", { className: "composer__label", htmlFor: fieldId, children: [
3499
- /* @__PURE__ */ jsx2("span", { className: "composer__sr-only", children: field.label }),
3500
- field.kind === "textarea" ? /* @__PURE__ */ jsx2(
4268
+ /* @__PURE__ */ jsxs4("label", { className: "composer__label", htmlFor: fieldId, children: [
4269
+ /* @__PURE__ */ jsx4("span", { className: "composer__sr-only", children: field.label }),
4270
+ field.kind === "textarea" ? /* @__PURE__ */ jsx4(
3501
4271
  "textarea",
3502
4272
  {
3503
4273
  ...controlProps,
@@ -3507,7 +4277,7 @@ function Composer({
3507
4277
  className: "composer__control composer__control--area",
3508
4278
  rows: 3
3509
4279
  }
3510
- ) : /* @__PURE__ */ jsx2(
4280
+ ) : /* @__PURE__ */ jsx4(
3511
4281
  "input",
3512
4282
  {
3513
4283
  ...controlProps,
@@ -3520,24 +4290,24 @@ function Composer({
3520
4290
  }
3521
4291
  )
3522
4292
  ] }),
3523
- invalid ? /* @__PURE__ */ jsx2("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
4293
+ invalid ? /* @__PURE__ */ jsx4("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
3524
4294
  ]
3525
4295
  },
3526
4296
  field.id
3527
4297
  );
3528
4298
  }),
3529
- /* @__PURE__ */ jsx2("div", { className: "composer__toolbar", children: /* @__PURE__ */ jsx2(
4299
+ /* @__PURE__ */ jsx4("div", { className: "composer__toolbar", children: /* @__PURE__ */ jsx4(
3530
4300
  "button",
3531
4301
  {
3532
4302
  type: "submit",
3533
4303
  className: "composer__send",
3534
4304
  disabled: disabled || !canSendForm,
3535
4305
  "aria-label": "Send details",
3536
- children: /* @__PURE__ */ jsx2(SendIcon, {})
4306
+ children: /* @__PURE__ */ jsx4(SendIcon, {})
3537
4307
  }
3538
4308
  ) })
3539
- ] }) : /* @__PURE__ */ jsxs2("div", { className: "composer__field", children: [
3540
- /* @__PURE__ */ jsx2(
4309
+ ] }) : /* @__PURE__ */ jsxs4("div", { className: "composer__field", children: [
4310
+ /* @__PURE__ */ jsx4(
3541
4311
  "textarea",
3542
4312
  {
3543
4313
  ref: inputRef,
@@ -3552,14 +4322,14 @@ function Composer({
3552
4322
  onKeyDown: handleChatKeyDown
3553
4323
  }
3554
4324
  ),
3555
- /* @__PURE__ */ jsx2(
4325
+ /* @__PURE__ */ jsx4(
3556
4326
  "button",
3557
4327
  {
3558
4328
  type: "submit",
3559
4329
  className: "composer__send",
3560
4330
  disabled: disabled || !value.trim(),
3561
4331
  "aria-label": "Send message",
3562
- children: /* @__PURE__ */ jsx2(SendIcon, {})
4332
+ children: /* @__PURE__ */ jsx4(SendIcon, {})
3563
4333
  }
3564
4334
  )
3565
4335
  ] })
@@ -3568,7 +4338,7 @@ function Composer({
3568
4338
  }
3569
4339
 
3570
4340
  // src/react/components/FollowUpChips/FollowUpChips.tsx
3571
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
4341
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
3572
4342
  function FollowUpChips({
3573
4343
  suggestions,
3574
4344
  disabled = false,
@@ -3578,7 +4348,7 @@ function FollowUpChips({
3578
4348
  }) {
3579
4349
  if (suggestions.length === 0) return null;
3580
4350
  if (variant === "dock") {
3581
- return /* @__PURE__ */ jsx3("div", { className: "followups followups--dock", children: /* @__PURE__ */ jsx3("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx3(
4351
+ return /* @__PURE__ */ jsx5("div", { className: "followups followups--dock", children: /* @__PURE__ */ jsx5("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx5(
3582
4352
  "button",
3583
4353
  {
3584
4354
  type: "button",
@@ -3590,9 +4360,9 @@ function FollowUpChips({
3590
4360
  suggestion.id
3591
4361
  )) }) });
3592
4362
  }
3593
- return /* @__PURE__ */ jsxs3("div", { className: "followups", children: [
3594
- /* @__PURE__ */ jsx3("span", { className: "followups__label", children: label }),
3595
- /* @__PURE__ */ jsx3("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx3(
4363
+ return /* @__PURE__ */ jsxs5("div", { className: "followups", children: [
4364
+ /* @__PURE__ */ jsx5("span", { className: "followups__label", children: label }),
4365
+ /* @__PURE__ */ jsx5("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx5(
3596
4366
  "button",
3597
4367
  {
3598
4368
  type: "button",
@@ -3607,17 +4377,17 @@ function FollowUpChips({
3607
4377
  }
3608
4378
 
3609
4379
  // src/react/components/MessageBubble/MessageBubble.tsx
3610
- import { useState as useState5 } from "react";
4380
+ import { useState as useState6 } from "react";
3611
4381
 
3612
4382
  // src/react/components/BookingCard/BookingCard.tsx
3613
4383
  import {
3614
- useEffect as useEffect3,
4384
+ useEffect as useEffect5,
3615
4385
  useId as useId2,
3616
4386
  useMemo as useMemo2,
3617
- useRef as useRef3,
3618
- useState as useState4
4387
+ useRef as useRef5,
4388
+ useState as useState5
3619
4389
  } from "react";
3620
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
4390
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
3621
4391
  var BOOKING_STEPS = [
3622
4392
  { id: "date", label: "Date" },
3623
4393
  { id: "time", label: "Time" },
@@ -3648,24 +4418,25 @@ function calendarCells(year, month) {
3648
4418
  return cells;
3649
4419
  }
3650
4420
  function BookingCardLoader() {
3651
- return /* @__PURE__ */ jsx4("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsx4("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
4421
+ return /* @__PURE__ */ jsx6("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsx6("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
3652
4422
  }
3653
4423
  function BookingCard({
4424
+ disabled = false,
3654
4425
  offer,
3655
4426
  onBook
3656
4427
  }) {
3657
4428
  const fieldId = useId2();
3658
4429
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
3659
- const [step, setStep] = useState4("date");
3660
- const [eventTypeUri, setEventTypeUri] = useState4(defaultType);
3661
- const [selectedDate, setSelectedDate] = useState4("");
3662
- const [startTime, setStartTime] = useState4("");
3663
- const [name, setName] = useState4("");
3664
- const [email, setEmail] = useState4("");
3665
- const activeStepRef = useRef3(null);
3666
- const previousStepRef = useRef3(step);
4430
+ const [step, setStep] = useState5("date");
4431
+ const [eventTypeUri, setEventTypeUri] = useState5(defaultType);
4432
+ const [selectedDate, setSelectedDate] = useState5("");
4433
+ const [startTime, setStartTime] = useState5("");
4434
+ const [name, setName] = useState5("");
4435
+ const [email, setEmail] = useState5("");
4436
+ const activeStepRef = useRef5(null);
4437
+ const previousStepRef = useRef5(step);
3667
4438
  const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
3668
- useEffect3(() => {
4439
+ useEffect5(() => {
3669
4440
  if (previousStepRef.current === step) return;
3670
4441
  previousStepRef.current = step;
3671
4442
  activeStepRef.current?.scrollIntoView({ block: "nearest" });
@@ -3682,7 +4453,7 @@ function BookingCard({
3682
4453
  }
3683
4454
  return next;
3684
4455
  }, [slots]);
3685
- const [visibleMonth, setVisibleMonth] = useState4(
4456
+ const [visibleMonth, setVisibleMonth] = useState5(
3686
4457
  () => firstAvailableBookingMonth(slots)
3687
4458
  );
3688
4459
  function selectEventType(nextType) {
@@ -3746,222 +4517,236 @@ function BookingCard({
3746
4517
  })
3747
4518
  });
3748
4519
  }
3749
- return /* @__PURE__ */ jsx4("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsxs4("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3750
- /* @__PURE__ */ jsx4("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ jsxs4(
3751
- "li",
3752
- {
3753
- className: [
3754
- "booking-card__step-indicator",
3755
- index === stepIndex ? "booking-card__step-indicator--active" : "",
3756
- index < stepIndex ? "booking-card__step-indicator--complete" : ""
3757
- ].filter(Boolean).join(" "),
3758
- "aria-current": index === stepIndex ? "step" : void 0,
3759
- children: [
3760
- /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: index + 1 }),
3761
- /* @__PURE__ */ jsx4("span", { children: item.label })
3762
- ]
3763
- },
3764
- item.id
3765
- )) }),
3766
- step === "date" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3767
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3768
- timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3769
- "Times in ",
3770
- timeZone
3771
- ] }) : null,
3772
- offer.eventTypes.length > 1 ? /* @__PURE__ */ jsxs4(
3773
- "label",
3774
- {
3775
- className: "booking-card__field",
3776
- htmlFor: `${fieldId}-type`,
3777
- children: [
3778
- /* @__PURE__ */ jsx4("span", { children: "Meeting" }),
3779
- /* @__PURE__ */ jsx4(
3780
- "select",
4520
+ return /* @__PURE__ */ jsx6(
4521
+ "section",
4522
+ {
4523
+ className: "booking-card",
4524
+ "aria-busy": disabled || void 0,
4525
+ "aria-label": "Book a meeting",
4526
+ children: /* @__PURE__ */ jsxs6("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
4527
+ /* @__PURE__ */ jsx6("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ jsxs6(
4528
+ "li",
4529
+ {
4530
+ className: [
4531
+ "booking-card__step-indicator",
4532
+ index === stepIndex ? "booking-card__step-indicator--active" : "",
4533
+ index < stepIndex ? "booking-card__step-indicator--complete" : ""
4534
+ ].filter(Boolean).join(" "),
4535
+ "aria-current": index === stepIndex ? "step" : void 0,
4536
+ children: [
4537
+ /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", children: index + 1 }),
4538
+ /* @__PURE__ */ jsx6("span", { children: item.label })
4539
+ ]
4540
+ },
4541
+ item.id
4542
+ )) }),
4543
+ step === "date" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
4544
+ /* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
4545
+ timeZone ? /* @__PURE__ */ jsxs6("p", { className: "booking-card__tz", children: [
4546
+ "Times in ",
4547
+ timeZone
4548
+ ] }) : null,
4549
+ offer.eventTypes.length > 1 ? /* @__PURE__ */ jsxs6(
4550
+ "label",
4551
+ {
4552
+ className: "booking-card__field",
4553
+ htmlFor: `${fieldId}-type`,
4554
+ children: [
4555
+ /* @__PURE__ */ jsx6("span", { children: "Meeting" }),
4556
+ /* @__PURE__ */ jsx6(
4557
+ "select",
4558
+ {
4559
+ id: `${fieldId}-type`,
4560
+ value: eventTypeUri,
4561
+ disabled,
4562
+ onChange: (event) => selectEventType(event.target.value),
4563
+ children: offer.eventTypes.map((item) => /* @__PURE__ */ jsx6("option", { value: item.uri, children: item.name }, item.uri))
4564
+ }
4565
+ )
4566
+ ]
4567
+ }
4568
+ ) : null,
4569
+ /* @__PURE__ */ jsxs6("div", { className: "booking-card__month", children: [
4570
+ /* @__PURE__ */ jsx6(
4571
+ "button",
3781
4572
  {
3782
- id: `${fieldId}-type`,
3783
- value: eventTypeUri,
3784
- onChange: (event) => selectEventType(event.target.value),
3785
- children: offer.eventTypes.map((item) => /* @__PURE__ */ jsx4("option", { value: item.uri, children: item.name }, item.uri))
4573
+ type: "button",
4574
+ className: "booking-card__nav",
4575
+ "aria-label": "Previous month",
4576
+ disabled: disabled || !canPrevMonth,
4577
+ onClick: () => goToMonth(-1),
4578
+ children: "\u2039"
4579
+ }
4580
+ ),
4581
+ /* @__PURE__ */ jsx6("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
4582
+ /* @__PURE__ */ jsx6(
4583
+ "button",
4584
+ {
4585
+ type: "button",
4586
+ className: "booking-card__nav",
4587
+ "aria-label": "Next month",
4588
+ disabled: disabled || !canNextMonth,
4589
+ onClick: () => goToMonth(1),
4590
+ children: "\u203A"
3786
4591
  }
3787
4592
  )
3788
- ]
3789
- }
3790
- ) : null,
3791
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__month", children: [
3792
- /* @__PURE__ */ jsx4(
3793
- "button",
3794
- {
3795
- type: "button",
3796
- className: "booking-card__nav",
3797
- "aria-label": "Previous month",
3798
- disabled: !canPrevMonth,
3799
- onClick: () => goToMonth(-1),
3800
- children: "\u2039"
3801
- }
3802
- ),
3803
- /* @__PURE__ */ jsx4("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3804
- /* @__PURE__ */ jsx4(
3805
- "button",
3806
- {
3807
- type: "button",
3808
- className: "booking-card__nav",
3809
- "aria-label": "Next month",
3810
- disabled: !canNextMonth,
3811
- onClick: () => goToMonth(1),
3812
- children: "\u203A"
3813
- }
3814
- )
3815
- ] }),
3816
- /* @__PURE__ */ jsx4("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ jsx4("span", { children: label }, label)) }),
3817
- offer.slots.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3818
- /* @__PURE__ */ jsx4(
3819
- "div",
3820
- {
3821
- className: "booking-card__calendar",
3822
- role: "grid",
3823
- "aria-label": "Available dates",
3824
- children: cells.map((cell, index) => {
3825
- if (!cell) {
3826
- return /* @__PURE__ */ jsx4(
3827
- "span",
3828
- {
3829
- className: "booking-card__day"
3830
- },
3831
- `empty-${index}`
3832
- );
4593
+ ] }),
4594
+ /* @__PURE__ */ jsx6("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ jsx6("span", { children: label }, label)) }),
4595
+ offer.slots.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
4596
+ /* @__PURE__ */ jsx6(
4597
+ "div",
4598
+ {
4599
+ className: "booking-card__calendar",
4600
+ role: "grid",
4601
+ "aria-label": "Available dates",
4602
+ children: cells.map((cell, index) => {
4603
+ if (!cell) {
4604
+ return /* @__PURE__ */ jsx6(
4605
+ "span",
4606
+ {
4607
+ className: "booking-card__day"
4608
+ },
4609
+ `empty-${index}`
4610
+ );
4611
+ }
4612
+ const available = availableByDate.has(cell.key);
4613
+ const selected = cell.key === selectedDate;
4614
+ return /* @__PURE__ */ jsx6(
4615
+ "button",
4616
+ {
4617
+ type: "button",
4618
+ className: [
4619
+ "booking-card__day",
4620
+ available ? "booking-card__day--available" : "",
4621
+ selected ? "booking-card__day--selected" : ""
4622
+ ].filter(Boolean).join(" "),
4623
+ disabled: disabled || !available,
4624
+ "aria-pressed": selected,
4625
+ onClick: () => selectDate(cell.key),
4626
+ children: cell.day
4627
+ },
4628
+ cell.key
4629
+ );
4630
+ })
3833
4631
  }
3834
- const available = availableByDate.has(cell.key);
3835
- const selected = cell.key === selectedDate;
3836
- return /* @__PURE__ */ jsx4(
4632
+ )
4633
+ ] }, "date") : null,
4634
+ step === "time" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
4635
+ /* @__PURE__ */ jsxs6("div", { className: "booking-card__step-bar", children: [
4636
+ /* @__PURE__ */ jsx6(
3837
4637
  "button",
3838
4638
  {
3839
4639
  type: "button",
3840
- className: [
3841
- "booking-card__day",
3842
- available ? "booking-card__day--available" : "",
3843
- selected ? "booking-card__day--selected" : ""
3844
- ].filter(Boolean).join(" "),
3845
- disabled: !available,
3846
- "aria-pressed": selected,
3847
- onClick: () => selectDate(cell.key),
3848
- children: cell.day
3849
- },
3850
- cell.key
3851
- );
3852
- })
3853
- }
3854
- )
3855
- ] }, "date") : null,
3856
- step === "time" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3857
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3858
- /* @__PURE__ */ jsx4(
3859
- "button",
3860
- {
3861
- type: "button",
3862
- className: "booking-card__nav",
3863
- "aria-label": "Back to dates",
3864
- onClick: () => setStep("date"),
3865
- children: "\u2039"
3866
- }
3867
- ),
3868
- /* @__PURE__ */ jsxs4("div", { children: [
3869
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
3870
- timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3871
- "Times in ",
3872
- timeZone
3873
- ] }) : null
3874
- ] })
3875
- ] }),
3876
- /* @__PURE__ */ jsx4("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ jsx4(
3877
- "button",
3878
- {
3879
- type: "button",
3880
- className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
3881
- onClick: () => selectTime(slot.startTime),
3882
- children: formatTimeChip(slot.startTime)
3883
- },
3884
- slot.startTime
3885
- )) })
3886
- ] }, "time") : null,
3887
- step === "details" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3888
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3889
- /* @__PURE__ */ jsx4(
3890
- "button",
3891
- {
3892
- type: "button",
3893
- className: "booking-card__nav",
3894
- "aria-label": "Back to times",
3895
- onClick: () => setStep("time"),
3896
- children: "\u2039"
3897
- }
3898
- ),
3899
- /* @__PURE__ */ jsxs4("div", { children: [
3900
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: "Enter details" }),
3901
- /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
3902
- selectedType?.location ? /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: selectedType.location }) : null
3903
- ] })
3904
- ] }),
3905
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__identity", children: [
3906
- /* @__PURE__ */ jsxs4(
3907
- "label",
3908
- {
3909
- className: "booking-card__field",
3910
- htmlFor: `${fieldId}-name`,
3911
- children: [
3912
- /* @__PURE__ */ jsx4("span", { children: "Name" }),
3913
- /* @__PURE__ */ jsx4(
3914
- "input",
3915
- {
3916
- id: `${fieldId}-name`,
3917
- autoComplete: "name",
3918
- value: name,
3919
- onChange: (event) => setName(event.target.value),
3920
- required: true
3921
- }
3922
- )
3923
- ]
3924
- }
3925
- ),
3926
- /* @__PURE__ */ jsxs4(
3927
- "label",
3928
- {
3929
- className: "booking-card__field",
3930
- htmlFor: `${fieldId}-email`,
3931
- children: [
3932
- /* @__PURE__ */ jsx4("span", { children: "Email" }),
3933
- /* @__PURE__ */ jsx4(
3934
- "input",
3935
- {
3936
- id: `${fieldId}-email`,
3937
- type: "email",
3938
- autoComplete: "email",
3939
- value: email,
3940
- onChange: (event) => setEmail(event.target.value),
3941
- required: true
3942
- }
3943
- )
3944
- ]
3945
- }
3946
- )
3947
- ] }),
3948
- /* @__PURE__ */ jsx4(
3949
- "button",
3950
- {
3951
- type: "submit",
3952
- className: "booking-card__submit",
3953
- disabled: !name.trim() || !email.trim(),
3954
- children: "Book this time"
3955
- }
3956
- )
3957
- ] }, "details") : null
3958
- ] }) });
4640
+ className: "booking-card__nav",
4641
+ "aria-label": "Back to dates",
4642
+ disabled,
4643
+ onClick: () => setStep("date"),
4644
+ children: "\u2039"
4645
+ }
4646
+ ),
4647
+ /* @__PURE__ */ jsxs6("div", { children: [
4648
+ /* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4649
+ timeZone ? /* @__PURE__ */ jsxs6("p", { className: "booking-card__tz", children: [
4650
+ "Times in ",
4651
+ timeZone
4652
+ ] }) : null
4653
+ ] })
4654
+ ] }),
4655
+ /* @__PURE__ */ jsx6("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ jsx6(
4656
+ "button",
4657
+ {
4658
+ type: "button",
4659
+ className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
4660
+ disabled,
4661
+ onClick: () => selectTime(slot.startTime),
4662
+ children: formatTimeChip(slot.startTime)
4663
+ },
4664
+ slot.startTime
4665
+ )) })
4666
+ ] }, "time") : null,
4667
+ step === "details" ? /* @__PURE__ */ jsxs6("div", { className: "booking-card__step", ref: activeStepRef, children: [
4668
+ /* @__PURE__ */ jsxs6("div", { className: "booking-card__step-bar", children: [
4669
+ /* @__PURE__ */ jsx6(
4670
+ "button",
4671
+ {
4672
+ type: "button",
4673
+ className: "booking-card__nav",
4674
+ "aria-label": "Back to times",
4675
+ disabled,
4676
+ onClick: () => setStep("time"),
4677
+ children: "\u2039"
4678
+ }
4679
+ ),
4680
+ /* @__PURE__ */ jsxs6("div", { children: [
4681
+ /* @__PURE__ */ jsx6("p", { className: "booking-card__title", children: "Enter details" }),
4682
+ /* @__PURE__ */ jsx6("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4683
+ selectedType?.location ? /* @__PURE__ */ jsx6("p", { className: "booking-card__tz", children: selectedType.location }) : null
4684
+ ] })
4685
+ ] }),
4686
+ /* @__PURE__ */ jsxs6("div", { className: "booking-card__identity", children: [
4687
+ /* @__PURE__ */ jsxs6(
4688
+ "label",
4689
+ {
4690
+ className: "booking-card__field",
4691
+ htmlFor: `${fieldId}-name`,
4692
+ children: [
4693
+ /* @__PURE__ */ jsx6("span", { children: "Name" }),
4694
+ /* @__PURE__ */ jsx6(
4695
+ "input",
4696
+ {
4697
+ id: `${fieldId}-name`,
4698
+ autoComplete: "name",
4699
+ disabled,
4700
+ value: name,
4701
+ onChange: (event) => setName(event.target.value),
4702
+ required: true
4703
+ }
4704
+ )
4705
+ ]
4706
+ }
4707
+ ),
4708
+ /* @__PURE__ */ jsxs6(
4709
+ "label",
4710
+ {
4711
+ className: "booking-card__field",
4712
+ htmlFor: `${fieldId}-email`,
4713
+ children: [
4714
+ /* @__PURE__ */ jsx6("span", { children: "Email" }),
4715
+ /* @__PURE__ */ jsx6(
4716
+ "input",
4717
+ {
4718
+ id: `${fieldId}-email`,
4719
+ type: "email",
4720
+ autoComplete: "email",
4721
+ disabled,
4722
+ value: email,
4723
+ onChange: (event) => setEmail(event.target.value),
4724
+ required: true
4725
+ }
4726
+ )
4727
+ ]
4728
+ }
4729
+ )
4730
+ ] }),
4731
+ /* @__PURE__ */ jsx6(
4732
+ "button",
4733
+ {
4734
+ type: "submit",
4735
+ className: "booking-card__submit",
4736
+ disabled: disabled || !name.trim() || !email.trim(),
4737
+ children: disabled ? "Booking\u2026" : "Book this time"
4738
+ }
4739
+ )
4740
+ ] }, "details") : null
4741
+ ] })
4742
+ }
4743
+ );
3959
4744
  }
3960
4745
 
3961
4746
  // src/react/components/MessageBubble/MessageBubble.tsx
3962
4747
  import { Streamdown } from "streamdown";
3963
4748
  import "streamdown/styles.css";
3964
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
4749
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3965
4750
  function normalizeDedupeText(text) {
3966
4751
  return text.trim().replace(/\s+/g, " ").toLowerCase();
3967
4752
  }
@@ -3972,9 +4757,7 @@ function paragraphsAreNearDuplicates(first, second) {
3972
4757
  if (left === right) return true;
3973
4758
  const shorter = left.length <= right.length ? left : right;
3974
4759
  const longer = left.length <= right.length ? right : left;
3975
- return longer.startsWith(
3976
- shorter.slice(0, Math.floor(shorter.length * 0.85))
3977
- );
4760
+ return longer.startsWith(shorter.slice(0, Math.floor(shorter.length * 0.85)));
3978
4761
  }
3979
4762
  function paragraphsShareOpening(first, second) {
3980
4763
  const opening = first.split("\n")[0]?.trim();
@@ -4002,11 +4785,12 @@ function collapseRepeatedText(text) {
4002
4785
  function MessageBubble({
4003
4786
  message,
4004
4787
  brandLogoUrl,
4788
+ bookingDisabled = false,
4005
4789
  offer,
4006
4790
  onBook
4007
4791
  }) {
4008
4792
  const resolvedLogoUrl = brandLogoUrl?.trim();
4009
- const [failedLogoUrl, setFailedLogoUrl] = useState5(null);
4793
+ const [failedLogoUrl, setFailedLogoUrl] = useState6(null);
4010
4794
  const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
4011
4795
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
4012
4796
  const extractedOffers = cards.filter(
@@ -4019,11 +4803,11 @@ function MessageBubble({
4019
4803
  offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
4020
4804
  );
4021
4805
  if (message.role === "visitor") {
4022
- return /* @__PURE__ */ jsx5("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ jsx5("p", { className: "message-bubble__text", children: message.text }) });
4806
+ return /* @__PURE__ */ jsx7("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ jsx7("p", { className: "message-bubble__text", children: message.text }) });
4023
4807
  }
4024
4808
  const citations = message.citations ?? [];
4025
- const agentText = /* @__PURE__ */ jsxs5("div", { className: "message-bubble__text", children: [
4026
- /* @__PURE__ */ jsx5(
4809
+ const agentText = /* @__PURE__ */ jsxs7("div", { className: "message-bubble__text", children: [
4810
+ /* @__PURE__ */ jsx7(
4027
4811
  Streamdown,
4028
4812
  {
4029
4813
  animated: isStreaming,
@@ -4037,22 +4821,21 @@ function MessageBubble({
4037
4821
  children: displayText
4038
4822
  }
4039
4823
  ),
4040
- citations.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsxs5(
4041
- "a",
4042
- {
4043
- href: citation.url,
4044
- target: "_blank",
4045
- rel: "noreferrer",
4046
- children: [
4047
- /* @__PURE__ */ jsx5("span", { className: "message-bubble__source-icon", "aria-hidden": "true", children: "\u25A6" }),
4048
- /* @__PURE__ */ jsx5("span", { children: citation.label })
4049
- ]
4050
- }
4051
- ) }, citation.id)) }) : null
4824
+ citations.length > 0 ? /* @__PURE__ */ jsx7("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsxs7("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
4825
+ /* @__PURE__ */ jsx7(
4826
+ "span",
4827
+ {
4828
+ className: "message-bubble__source-icon",
4829
+ "aria-hidden": "true",
4830
+ children: "\u25A6"
4831
+ }
4832
+ ),
4833
+ /* @__PURE__ */ jsx7("span", { children: citation.label })
4834
+ ] }) }, citation.id)) }) : null
4052
4835
  ] });
4053
- return /* @__PURE__ */ jsxs5("article", { className: "message-bubble message-bubble--agent", children: [
4054
- displayText ? showBrandLogo ? /* @__PURE__ */ jsxs5("div", { className: "message-bubble__agent-row", children: [
4055
- /* @__PURE__ */ jsx5("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(
4836
+ return /* @__PURE__ */ jsxs7("article", { className: "message-bubble message-bubble--agent", children: [
4837
+ displayText ? showBrandLogo ? /* @__PURE__ */ jsxs7("div", { className: "message-bubble__agent-row", children: [
4838
+ /* @__PURE__ */ jsx7("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ jsx7(
4056
4839
  "img",
4057
4840
  {
4058
4841
  src: resolvedLogoUrl,
@@ -4064,9 +4847,10 @@ function MessageBubble({
4064
4847
  ) }),
4065
4848
  agentText
4066
4849
  ] }) : agentText : null,
4067
- offers.map((nextOffer, index) => /* @__PURE__ */ jsx5(
4850
+ offers.map((nextOffer, index) => /* @__PURE__ */ jsx7(
4068
4851
  BookingCard,
4069
4852
  {
4853
+ disabled: bookingDisabled,
4070
4854
  offer: nextOffer,
4071
4855
  onBook
4072
4856
  },
@@ -4076,10 +4860,10 @@ function MessageBubble({
4076
4860
  }
4077
4861
 
4078
4862
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4079
- import { useState as useState7 } from "react";
4863
+ import { useState as useState8 } from "react";
4080
4864
 
4081
4865
  // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4082
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
4866
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
4083
4867
  function ConfirmationCard({
4084
4868
  disabled = false,
4085
4869
  request,
@@ -4088,17 +4872,17 @@ function ConfirmationCard({
4088
4872
  const options = request.options ?? [];
4089
4873
  const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4090
4874
  const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4091
- return /* @__PURE__ */ jsxs6(
4875
+ return /* @__PURE__ */ jsxs8(
4092
4876
  "section",
4093
4877
  {
4094
4878
  className: "confirmation-card",
4095
4879
  "aria-labelledby": `confirmation-${request.requestId}`,
4096
4880
  children: [
4097
- /* @__PURE__ */ jsxs6("div", { className: "confirmation-card__heading", children: [
4098
- /* @__PURE__ */ jsx6("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4099
- prompt ? /* @__PURE__ */ jsx6("p", { children: prompt }) : null
4881
+ /* @__PURE__ */ jsxs8("div", { className: "confirmation-card__heading", children: [
4882
+ /* @__PURE__ */ jsx8("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4883
+ prompt ? /* @__PURE__ */ jsx8("p", { children: prompt }) : null
4100
4884
  ] }),
4101
- /* @__PURE__ */ jsx6("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ jsx6(
4885
+ /* @__PURE__ */ jsx8("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ jsx8(
4102
4886
  "button",
4103
4887
  {
4104
4888
  type: "button",
@@ -4118,8 +4902,8 @@ function ConfirmationCard({
4118
4902
  }
4119
4903
 
4120
4904
  // src/react/components/ToolInputCard/ToolInputCard.tsx
4121
- import { useState as useState6 } from "react";
4122
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
4905
+ import { useState as useState7 } from "react";
4906
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
4123
4907
  function isRecord5(value) {
4124
4908
  return value !== null && typeof value === "object" && !Array.isArray(value);
4125
4909
  }
@@ -4243,7 +5027,7 @@ function FieldDescription({
4243
5027
  field,
4244
5028
  id
4245
5029
  }) {
4246
- return field.description ? /* @__PURE__ */ jsx7("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5030
+ return field.description ? /* @__PURE__ */ jsx9("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4247
5031
  }
4248
5032
  function ChoiceField({
4249
5033
  field,
@@ -4262,7 +5046,7 @@ function ChoiceField({
4262
5046
  const selectedIndex = options.findIndex(
4263
5047
  (option) => valuesMatch(option.value, value)
4264
5048
  );
4265
- return /* @__PURE__ */ jsxs7(
5049
+ return /* @__PURE__ */ jsxs9(
4266
5050
  "select",
4267
5051
  {
4268
5052
  id,
@@ -4277,13 +5061,13 @@ function ChoiceField({
4277
5061
  if (option) onChange(option.value);
4278
5062
  },
4279
5063
  children: [
4280
- /* @__PURE__ */ jsx7("option", { value: "", disabled: field.required, children: "Choose an option" }),
4281
- options.map((option, index) => /* @__PURE__ */ jsx7("option", { value: index, children: option.label }, optionKey(option)))
5064
+ /* @__PURE__ */ jsx9("option", { value: "", disabled: field.required, children: "Choose an option" }),
5065
+ options.map((option, index) => /* @__PURE__ */ jsx9("option", { value: index, children: option.label }, optionKey(option)))
4282
5066
  ]
4283
5067
  }
4284
5068
  );
4285
5069
  }
4286
- return /* @__PURE__ */ jsx7(
5070
+ return /* @__PURE__ */ jsx9(
4287
5071
  "div",
4288
5072
  {
4289
5073
  className: "tool-input-card__choices",
@@ -4294,8 +5078,8 @@ function ChoiceField({
4294
5078
  "aria-required": field.required,
4295
5079
  children: options.map((option, index) => {
4296
5080
  const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
4297
- return /* @__PURE__ */ jsxs7("label", { className: "tool-input-card__choice", children: [
4298
- /* @__PURE__ */ jsx7(
5081
+ return /* @__PURE__ */ jsxs9("label", { className: "tool-input-card__choice", children: [
5082
+ /* @__PURE__ */ jsx9(
4299
5083
  "input",
4300
5084
  {
4301
5085
  type: multiple ? "checkbox" : "radio",
@@ -4317,7 +5101,7 @@ function ChoiceField({
4317
5101
  }
4318
5102
  }
4319
5103
  ),
4320
- /* @__PURE__ */ jsx7("span", { children: option.label })
5104
+ /* @__PURE__ */ jsx9("span", { children: option.label })
4321
5105
  ] }, optionKey(option));
4322
5106
  })
4323
5107
  }
@@ -4337,9 +5121,9 @@ function ToolField({
4337
5121
  error ? `${id}-error` : ""
4338
5122
  ].filter(Boolean).join(" ");
4339
5123
  if (field.kind === "checkbox" || field.kind === "confirmation") {
4340
- return /* @__PURE__ */ jsxs7("div", { className: "tool-input-card__field", children: [
4341
- /* @__PURE__ */ jsxs7("label", { className: "tool-input-card__check", htmlFor: id, children: [
4342
- /* @__PURE__ */ jsx7(
5124
+ return /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__field", children: [
5125
+ /* @__PURE__ */ jsxs9("label", { className: "tool-input-card__check", htmlFor: id, children: [
5126
+ /* @__PURE__ */ jsx9(
4343
5127
  "input",
4344
5128
  {
4345
5129
  id,
@@ -4352,17 +5136,17 @@ function ToolField({
4352
5136
  onChange: (event) => onChange(event.target.checked)
4353
5137
  }
4354
5138
  ),
4355
- /* @__PURE__ */ jsxs7("span", { children: [
4356
- /* @__PURE__ */ jsx7("strong", { children: field.label }),
4357
- field.description ? /* @__PURE__ */ jsx7("span", { id: `${id}-description`, children: field.description }) : null
5139
+ /* @__PURE__ */ jsxs9("span", { children: [
5140
+ /* @__PURE__ */ jsx9("strong", { children: field.label }),
5141
+ field.description ? /* @__PURE__ */ jsx9("span", { id: `${id}-description`, children: field.description }) : null
4358
5142
  ] })
4359
5143
  ] }),
4360
- error ? /* @__PURE__ */ jsx7("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5144
+ error ? /* @__PURE__ */ jsx9("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4361
5145
  ] });
4362
5146
  }
4363
- const label = /* @__PURE__ */ jsxs7("label", { id: `${id}-label`, htmlFor: id, children: [
5147
+ const label = /* @__PURE__ */ jsxs9("label", { id: `${id}-label`, htmlFor: id, children: [
4364
5148
  field.label,
4365
- field.required ? /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: " *" }) : null
5149
+ field.required ? /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: " *" }) : null
4366
5150
  ] });
4367
5151
  const common = {
4368
5152
  id,
@@ -4374,7 +5158,7 @@ function ToolField({
4374
5158
  };
4375
5159
  let control;
4376
5160
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4377
- control = /* @__PURE__ */ jsx7(
5161
+ control = /* @__PURE__ */ jsx9(
4378
5162
  ChoiceField,
4379
5163
  {
4380
5164
  field,
@@ -4388,7 +5172,7 @@ function ToolField({
4388
5172
  }
4389
5173
  );
4390
5174
  } else if (field.kind === "textarea" || field.kind === "json") {
4391
- control = /* @__PURE__ */ jsx7(
5175
+ control = /* @__PURE__ */ jsx9(
4392
5176
  "textarea",
4393
5177
  {
4394
5178
  ...common,
@@ -4402,8 +5186,8 @@ function ToolField({
4402
5186
  );
4403
5187
  } else if (field.kind === "range") {
4404
5188
  const numericValue = typeof value === "number" ? value : field.min ?? 0;
4405
- control = /* @__PURE__ */ jsxs7("div", { className: "tool-input-card__range", children: [
4406
- /* @__PURE__ */ jsx7(
5189
+ control = /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__range", children: [
5190
+ /* @__PURE__ */ jsx9(
4407
5191
  "input",
4408
5192
  {
4409
5193
  ...common,
@@ -4415,11 +5199,11 @@ function ToolField({
4415
5199
  onChange: (event) => onChange(Number(event.target.value))
4416
5200
  }
4417
5201
  ),
4418
- /* @__PURE__ */ jsx7("output", { htmlFor: id, children: numericValue })
5202
+ /* @__PURE__ */ jsx9("output", { htmlFor: id, children: numericValue })
4419
5203
  ] });
4420
5204
  } else {
4421
5205
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4422
- control = /* @__PURE__ */ jsx7(
5206
+ control = /* @__PURE__ */ jsx9(
4423
5207
  "input",
4424
5208
  {
4425
5209
  ...common,
@@ -4437,11 +5221,11 @@ function ToolField({
4437
5221
  }
4438
5222
  );
4439
5223
  }
4440
- return /* @__PURE__ */ jsxs7("div", { className: "tool-input-card__field", children: [
5224
+ return /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__field", children: [
4441
5225
  label,
4442
- /* @__PURE__ */ jsx7(FieldDescription, { field, id: `${id}-description` }),
5226
+ /* @__PURE__ */ jsx9(FieldDescription, { field, id: `${id}-description` }),
4443
5227
  control,
4444
- error ? /* @__PURE__ */ jsx7("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5228
+ error ? /* @__PURE__ */ jsx9("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4445
5229
  ] });
4446
5230
  }
4447
5231
  function ToolInputCard({
@@ -4449,11 +5233,11 @@ function ToolInputCard({
4449
5233
  surface,
4450
5234
  onSubmit
4451
5235
  }) {
4452
- const [values, setValues] = useState6(
5236
+ const [values, setValues] = useState7(
4453
5237
  () => initialValues(surface)
4454
5238
  );
4455
- const [touched, setTouched] = useState6(() => /* @__PURE__ */ new Set());
4456
- const [submitted, setSubmitted] = useState6(false);
5239
+ const [touched, setTouched] = useState7(() => /* @__PURE__ */ new Set());
5240
+ const [submitted, setSubmitted] = useState7(false);
4457
5241
  const errors = Object.fromEntries(
4458
5242
  surface.fields.map((field) => [
4459
5243
  field.path,
@@ -4478,14 +5262,14 @@ function ToolInputCard({
4478
5262
  onSubmit?.(surface, result);
4479
5263
  }
4480
5264
  if (submitted) {
4481
- return /* @__PURE__ */ jsxs7(
5265
+ return /* @__PURE__ */ jsxs9(
4482
5266
  "section",
4483
5267
  {
4484
5268
  className: "tool-input-card tool-input-card--submitted",
4485
5269
  role: "status",
4486
5270
  children: [
4487
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u2713" }),
4488
- /* @__PURE__ */ jsxs7("strong", { children: [
5271
+ /* @__PURE__ */ jsx9("span", { "aria-hidden": "true", children: "\u2713" }),
5272
+ /* @__PURE__ */ jsxs9("strong", { children: [
4489
5273
  surface.title,
4490
5274
  " submitted"
4491
5275
  ] })
@@ -4493,18 +5277,18 @@ function ToolInputCard({
4493
5277
  }
4494
5278
  );
4495
5279
  }
4496
- return /* @__PURE__ */ jsxs7(
5280
+ return /* @__PURE__ */ jsxs9(
4497
5281
  "section",
4498
5282
  {
4499
5283
  className: "tool-input-card",
4500
5284
  "aria-labelledby": `tool-input-${surface.id}`,
4501
5285
  children: [
4502
- /* @__PURE__ */ jsxs7("div", { className: "tool-input-card__heading", children: [
4503
- /* @__PURE__ */ jsx7("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
4504
- surface.description ? /* @__PURE__ */ jsx7("p", { children: surface.description }) : null
5286
+ /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__heading", children: [
5287
+ /* @__PURE__ */ jsx9("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5288
+ surface.description ? /* @__PURE__ */ jsx9("p", { children: surface.description }) : null
4505
5289
  ] }),
4506
- /* @__PURE__ */ jsxs7("form", { noValidate: true, onSubmit: submit, children: [
4507
- /* @__PURE__ */ jsx7("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ jsx7(
5290
+ /* @__PURE__ */ jsxs9("form", { noValidate: true, onSubmit: submit, children: [
5291
+ /* @__PURE__ */ jsx9("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ jsx9(
4508
5292
  ToolField,
4509
5293
  {
4510
5294
  disabled,
@@ -4517,8 +5301,8 @@ function ToolInputCard({
4517
5301
  },
4518
5302
  field.path
4519
5303
  )) }),
4520
- /* @__PURE__ */ jsxs7("div", { className: "tool-input-card__actions", children: [
4521
- surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ jsx7(
5304
+ /* @__PURE__ */ jsxs9("div", { className: "tool-input-card__actions", children: [
5305
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ jsx9(
4522
5306
  "button",
4523
5307
  {
4524
5308
  type: "button",
@@ -4531,7 +5315,7 @@ function ToolInputCard({
4531
5315
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4532
5316
  }
4533
5317
  ) : null,
4534
- /* @__PURE__ */ jsx7("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5318
+ /* @__PURE__ */ jsx9("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4535
5319
  ] })
4536
5320
  ] })
4537
5321
  ]
@@ -4540,17 +5324,17 @@ function ToolInputCard({
4540
5324
  }
4541
5325
 
4542
5326
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4543
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
5327
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
4544
5328
  function HumanInputCard({
4545
5329
  disabled = false,
4546
5330
  request,
4547
5331
  onRespond
4548
5332
  }) {
4549
- const [text, setText] = useState7("");
5333
+ const [text, setText] = useState8("");
4550
5334
  const options = request.options ?? [];
4551
5335
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4552
5336
  if (request.ui) {
4553
- return /* @__PURE__ */ jsx8(
5337
+ return /* @__PURE__ */ jsx10(
4554
5338
  ToolInputCard,
4555
5339
  {
4556
5340
  disabled,
@@ -4560,7 +5344,7 @@ function HumanInputCard({
4560
5344
  );
4561
5345
  }
4562
5346
  if (options.length > 0) {
4563
- return /* @__PURE__ */ jsx8(
5347
+ return /* @__PURE__ */ jsx10(
4564
5348
  ConfirmationCard,
4565
5349
  {
4566
5350
  disabled,
@@ -4575,17 +5359,17 @@ function HumanInputCard({
4575
5359
  if (!value || disabled) return;
4576
5360
  onRespond?.({ requestId: request.requestId, text: value });
4577
5361
  }
4578
- return /* @__PURE__ */ jsxs8(
5362
+ return /* @__PURE__ */ jsxs10(
4579
5363
  "section",
4580
5364
  {
4581
5365
  className: "human-input-card",
4582
5366
  "aria-labelledby": `human-input-${request.requestId}`,
4583
5367
  children: [
4584
- /* @__PURE__ */ jsx8("div", { className: "human-input-card__heading", children: /* @__PURE__ */ jsx8("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
4585
- showText ? /* @__PURE__ */ jsxs8("form", { onSubmit: submitText, children: [
4586
- /* @__PURE__ */ jsx8("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
4587
- /* @__PURE__ */ jsxs8("div", { children: [
4588
- /* @__PURE__ */ jsx8(
5368
+ /* @__PURE__ */ jsx10("div", { className: "human-input-card__heading", children: /* @__PURE__ */ jsx10("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
5369
+ showText ? /* @__PURE__ */ jsxs10("form", { onSubmit: submitText, children: [
5370
+ /* @__PURE__ */ jsx10("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5371
+ /* @__PURE__ */ jsxs10("div", { children: [
5372
+ /* @__PURE__ */ jsx10(
4589
5373
  "input",
4590
5374
  {
4591
5375
  id: `human-input-text-${request.requestId}`,
@@ -4594,39 +5378,39 @@ function HumanInputCard({
4594
5378
  onChange: (event) => setText(event.target.value)
4595
5379
  }
4596
5380
  ),
4597
- /* @__PURE__ */ jsx8("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5381
+ /* @__PURE__ */ jsx10("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4598
5382
  ] })
4599
5383
  ] }) : null,
4600
- !showText && options.length === 0 ? /* @__PURE__ */ jsx8("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
5384
+ !showText && options.length === 0 ? /* @__PURE__ */ jsx10("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
4601
5385
  ]
4602
5386
  }
4603
5387
  );
4604
5388
  }
4605
5389
 
4606
5390
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4607
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
5391
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
4608
5392
  function CollectionResultCard({
4609
5393
  result
4610
5394
  }) {
4611
5395
  const empty = result.items.length === 0;
4612
- return /* @__PURE__ */ jsxs9(
5396
+ return /* @__PURE__ */ jsxs11(
4613
5397
  "section",
4614
5398
  {
4615
5399
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4616
5400
  "aria-label": result.title,
4617
5401
  children: [
4618
- /* @__PURE__ */ jsxs9("div", { className: "tool-result-card__heading", children: [
4619
- /* @__PURE__ */ jsx9("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4620
- /* @__PURE__ */ jsx9("strong", { children: result.title })
5402
+ /* @__PURE__ */ jsxs11("div", { className: "tool-result-card__heading", children: [
5403
+ /* @__PURE__ */ jsx11("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5404
+ /* @__PURE__ */ jsx11("strong", { children: result.title })
4621
5405
  ] }),
4622
- empty ? /* @__PURE__ */ jsx9("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ jsx9("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ jsxs9("li", { children: [
4623
- /* @__PURE__ */ jsx9("div", { className: "collection-result-card__item-title", children: item.title }),
4624
- item.description ? /* @__PURE__ */ jsx9("p", { children: item.description }) : null,
4625
- item.details?.length ? /* @__PURE__ */ jsx9("dl", { children: item.details.map((detail) => /* @__PURE__ */ jsxs9("div", { children: [
4626
- /* @__PURE__ */ jsx9("dt", { children: detail.label }),
4627
- /* @__PURE__ */ jsx9("dd", { children: detail.value })
5406
+ empty ? /* @__PURE__ */ jsx11("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ jsx11("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ jsxs11("li", { children: [
5407
+ /* @__PURE__ */ jsx11("div", { className: "collection-result-card__item-title", children: item.title }),
5408
+ item.description ? /* @__PURE__ */ jsx11("p", { children: item.description }) : null,
5409
+ item.details?.length ? /* @__PURE__ */ jsx11("dl", { children: item.details.map((detail) => /* @__PURE__ */ jsxs11("div", { children: [
5410
+ /* @__PURE__ */ jsx11("dt", { children: detail.label }),
5411
+ /* @__PURE__ */ jsx11("dd", { children: detail.value })
4628
5412
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4629
- item.href ? /* @__PURE__ */ jsx9("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
5413
+ item.href ? /* @__PURE__ */ jsx11("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4630
5414
  ] }, item.title)) })
4631
5415
  ]
4632
5416
  }
@@ -4634,26 +5418,26 @@ function CollectionResultCard({
4634
5418
  }
4635
5419
 
4636
5420
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4637
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
5421
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
4638
5422
  function EntityResultCard({
4639
5423
  result
4640
5424
  }) {
4641
- return /* @__PURE__ */ jsxs10(
5425
+ return /* @__PURE__ */ jsxs12(
4642
5426
  "section",
4643
5427
  {
4644
5428
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4645
5429
  "aria-label": result.title,
4646
5430
  children: [
4647
- /* @__PURE__ */ jsxs10("div", { className: "tool-result-card__heading", children: [
4648
- /* @__PURE__ */ jsx10("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4649
- /* @__PURE__ */ jsx10("strong", { children: result.title })
5431
+ /* @__PURE__ */ jsxs12("div", { className: "tool-result-card__heading", children: [
5432
+ /* @__PURE__ */ jsx12("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5433
+ /* @__PURE__ */ jsx12("strong", { children: result.title })
4650
5434
  ] }),
4651
- result.description ? /* @__PURE__ */ jsx10("p", { children: result.description }) : null,
4652
- result.details?.length ? /* @__PURE__ */ jsx10("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs10("div", { children: [
4653
- /* @__PURE__ */ jsx10("dt", { children: detail.label }),
4654
- /* @__PURE__ */ jsx10("dd", { children: detail.value })
5435
+ result.description ? /* @__PURE__ */ jsx12("p", { children: result.description }) : null,
5436
+ result.details?.length ? /* @__PURE__ */ jsx12("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs12("div", { children: [
5437
+ /* @__PURE__ */ jsx12("dt", { children: detail.label }),
5438
+ /* @__PURE__ */ jsx12("dd", { children: detail.value })
4655
5439
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4656
- result.links?.length ? /* @__PURE__ */ jsx10("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx10(
5440
+ result.links?.length ? /* @__PURE__ */ jsx12("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx12(
4657
5441
  "a",
4658
5442
  {
4659
5443
  href: link.href,
@@ -4669,24 +5453,24 @@ function EntityResultCard({
4669
5453
  }
4670
5454
 
4671
5455
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4672
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
5456
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
4673
5457
  function SignatureResultCard({
4674
5458
  result
4675
5459
  }) {
4676
5460
  const primaryLink = result.links?.[0];
4677
- return /* @__PURE__ */ jsxs11(
5461
+ return /* @__PURE__ */ jsxs13(
4678
5462
  "section",
4679
5463
  {
4680
5464
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4681
5465
  "aria-label": result.title,
4682
5466
  children: [
4683
- /* @__PURE__ */ jsxs11("div", { className: "tool-result-card__heading", children: [
4684
- /* @__PURE__ */ jsx11("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4685
- /* @__PURE__ */ jsx11("strong", { children: result.title })
5467
+ /* @__PURE__ */ jsxs13("div", { className: "tool-result-card__heading", children: [
5468
+ /* @__PURE__ */ jsx13("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5469
+ /* @__PURE__ */ jsx13("strong", { children: result.title })
4686
5470
  ] }),
4687
- result.statusLabel ? /* @__PURE__ */ jsx11("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
4688
- result.description ? /* @__PURE__ */ jsx11("p", { children: result.description }) : null,
4689
- primaryLink ? /* @__PURE__ */ jsx11(
5471
+ result.statusLabel ? /* @__PURE__ */ jsx13("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5472
+ result.description ? /* @__PURE__ */ jsx13("p", { children: result.description }) : null,
5473
+ primaryLink ? /* @__PURE__ */ jsx13(
4690
5474
  "a",
4691
5475
  {
4692
5476
  className: "signature-result-card__cta",
@@ -4702,26 +5486,26 @@ function SignatureResultCard({
4702
5486
  }
4703
5487
 
4704
5488
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4705
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
5489
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
4706
5490
  function ToolResultCard({
4707
5491
  result
4708
5492
  }) {
4709
- return /* @__PURE__ */ jsxs12(
5493
+ return /* @__PURE__ */ jsxs14(
4710
5494
  "section",
4711
5495
  {
4712
5496
  className: `tool-result-card tool-result-card--${result.status}`,
4713
5497
  "aria-label": result.title,
4714
5498
  children: [
4715
- /* @__PURE__ */ jsxs12("div", { className: "tool-result-card__heading", children: [
4716
- /* @__PURE__ */ jsx12("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4717
- /* @__PURE__ */ jsx12("strong", { children: result.title })
5499
+ /* @__PURE__ */ jsxs14("div", { className: "tool-result-card__heading", children: [
5500
+ /* @__PURE__ */ jsx14("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5501
+ /* @__PURE__ */ jsx14("strong", { children: result.title })
4718
5502
  ] }),
4719
- result.description ? /* @__PURE__ */ jsx12("p", { children: result.description }) : null,
4720
- result.details?.length ? /* @__PURE__ */ jsx12("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs12("div", { children: [
4721
- /* @__PURE__ */ jsx12("dt", { children: detail.label }),
4722
- /* @__PURE__ */ jsx12("dd", { children: detail.value })
5503
+ result.description ? /* @__PURE__ */ jsx14("p", { children: result.description }) : null,
5504
+ result.details?.length ? /* @__PURE__ */ jsx14("dl", { children: result.details.map((detail) => /* @__PURE__ */ jsxs14("div", { children: [
5505
+ /* @__PURE__ */ jsx14("dt", { children: detail.label }),
5506
+ /* @__PURE__ */ jsx14("dd", { children: detail.value })
4723
5507
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4724
- result.links?.length ? /* @__PURE__ */ jsx12("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx12(
5508
+ result.links?.length ? /* @__PURE__ */ jsx14("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ jsx14(
4725
5509
  "a",
4726
5510
  {
4727
5511
  href: link.href,
@@ -4737,14 +5521,14 @@ function ToolResultCard({
4737
5521
  }
4738
5522
 
4739
5523
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4740
- import { jsx as jsx13 } from "react/jsx-runtime";
5524
+ import { jsx as jsx15 } from "react/jsx-runtime";
4741
5525
  function VisitorToolResultView({
4742
5526
  disabled = false,
4743
5527
  onToolInput,
4744
5528
  result
4745
5529
  }) {
4746
5530
  if (result.kind === "input") {
4747
- return /* @__PURE__ */ jsx13(
5531
+ return /* @__PURE__ */ jsx15(
4748
5532
  ToolInputCard,
4749
5533
  {
4750
5534
  disabled,
@@ -4754,16 +5538,16 @@ function VisitorToolResultView({
4754
5538
  );
4755
5539
  }
4756
5540
  if (result.kind === "entity") {
4757
- return /* @__PURE__ */ jsx13(EntityResultCard, { result });
5541
+ return /* @__PURE__ */ jsx15(EntityResultCard, { result });
4758
5542
  }
4759
5543
  if (result.kind === "collection") {
4760
- return /* @__PURE__ */ jsx13(CollectionResultCard, { result });
5544
+ return /* @__PURE__ */ jsx15(CollectionResultCard, { result });
4761
5545
  }
4762
5546
  if (result.kind === "signature") {
4763
- return /* @__PURE__ */ jsx13(SignatureResultCard, { result });
5547
+ return /* @__PURE__ */ jsx15(SignatureResultCard, { result });
4764
5548
  }
4765
5549
  if (result.kind === "summary") {
4766
- return /* @__PURE__ */ jsx13(ToolResultCard, { result });
5550
+ return /* @__PURE__ */ jsx15(ToolResultCard, { result });
4767
5551
  }
4768
5552
  return null;
4769
5553
  }
@@ -4772,9 +5556,9 @@ function isRenderableVisitorToolResult(result) {
4772
5556
  }
4773
5557
 
4774
5558
  // src/react/components/AgentRail/AgentRail.tsx
4775
- import { Fragment, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
5559
+ import { Fragment, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
4776
5560
  function MinimizeIcon() {
4777
- return /* @__PURE__ */ jsx14("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5561
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
4778
5562
  "path",
4779
5563
  {
4780
5564
  d: "M3.5 8h9",
@@ -4784,8 +5568,8 @@ function MinimizeIcon() {
4784
5568
  }
4785
5569
  ) });
4786
5570
  }
4787
- function CloseIcon() {
4788
- return /* @__PURE__ */ jsx14("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5571
+ function CloseIcon2() {
5572
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
4789
5573
  "path",
4790
5574
  {
4791
5575
  d: "M4 4l8 8M12 4l-8 8",
@@ -4796,7 +5580,7 @@ function CloseIcon() {
4796
5580
  ) });
4797
5581
  }
4798
5582
  function NewChatIcon() {
4799
- return /* @__PURE__ */ jsx14("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5583
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
4800
5584
  "path",
4801
5585
  {
4802
5586
  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",
@@ -4808,7 +5592,7 @@ function NewChatIcon() {
4808
5592
  ) });
4809
5593
  }
4810
5594
  function ExpandIcon() {
4811
- return /* @__PURE__ */ jsx14("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5595
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
4812
5596
  "path",
4813
5597
  {
4814
5598
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4820,7 +5604,7 @@ function ExpandIcon() {
4820
5604
  ) });
4821
5605
  }
4822
5606
  function RestoreIcon() {
4823
- return /* @__PURE__ */ jsx14("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5607
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
4824
5608
  "path",
4825
5609
  {
4826
5610
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -4831,6 +5615,19 @@ function RestoreIcon() {
4831
5615
  }
4832
5616
  ) });
4833
5617
  }
5618
+ function ChevronDownIcon() {
5619
+ return /* @__PURE__ */ jsx16("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
5620
+ "path",
5621
+ {
5622
+ d: "M4 6.5l4 4 4-4",
5623
+ stroke: "currentColor",
5624
+ strokeWidth: "1.6",
5625
+ strokeLinecap: "round",
5626
+ strokeLinejoin: "round"
5627
+ }
5628
+ ) });
5629
+ }
5630
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
4834
5631
  function AgentRail({
4835
5632
  state,
4836
5633
  theme,
@@ -4838,6 +5635,9 @@ function AgentRail({
4838
5635
  brandLabel = "",
4839
5636
  brandLogoUrl,
4840
5637
  poweredByLabel = "Powered by Webless",
5638
+ disclaimerLabel,
5639
+ answerReceipt = false,
5640
+ readAloud = false,
4841
5641
  composerPlaceholder = "Ask anything\u2026",
4842
5642
  mobileFullscreen = false,
4843
5643
  expanded = false,
@@ -4846,16 +5646,26 @@ function AgentRail({
4846
5646
  onExpandToggle,
4847
5647
  onReset,
4848
5648
  onRetry,
5649
+ onRegenerate,
5650
+ onFeedback,
4849
5651
  onSubmit,
4850
5652
  onFollowUpSelect,
4851
5653
  onBook,
4852
5654
  onInputResponse,
4853
5655
  onToolInput
4854
5656
  }) {
4855
- const transcriptRef = useRef4(null);
5657
+ const railRef = useRef6(null);
5658
+ const overlayRef = useRef6(null);
5659
+ const transcriptRef = useRef6(null);
5660
+ const pinnedToBottomRef = useRef6(true);
5661
+ const smoothScrollToLatestRef = useRef6(false);
5662
+ const lockedTranscriptScrollTopRef = useRef6(null);
5663
+ const [showJumpToLatest, setShowJumpToLatest] = useState9(false);
5664
+ const [receiptOpen, setReceiptOpen] = useState9(false);
4856
5665
  const resolvedBrandLabel = brandLabel.trim();
4857
5666
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
4858
- const [failedLogoUrl, setFailedLogoUrl] = useState8(null);
5667
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5668
+ const [failedLogoUrl, setFailedLogoUrl] = useState9(null);
4859
5669
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
4860
5670
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
4861
5671
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -4906,10 +5716,15 @@ function AgentRail({
4906
5716
  );
4907
5717
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
4908
5718
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
4909
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5719
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5720
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
4910
5721
  const hasVisitorMessages2 = state.messages.some(
4911
5722
  (message) => message.role === "visitor"
4912
5723
  );
5724
+ const hasAgentResponseAfterVisitor = state.messages.some(
5725
+ (message) => message.role === "agent" && message.id !== "greeting"
5726
+ );
5727
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
4913
5728
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
4914
5729
  const greeting = state.messages.find(
4915
5730
  (message) => message.role === "agent" && message.id === "greeting"
@@ -4931,6 +5746,7 @@ function AgentRail({
4931
5746
  }
4932
5747
  }
4933
5748
  const lastIsAgent = lastMessage?.role === "agent";
5749
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
4934
5750
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
4935
5751
  createdAt: 0,
4936
5752
  id: "streaming-response",
@@ -4957,10 +5773,36 @@ function AgentRail({
4957
5773
  hasPendingConfirmation,
4958
5774
  enabled: lastIsAgent && !isBusy
4959
5775
  });
4960
- useEffect4(() => {
5776
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
5777
+ useEffect6(() => {
5778
+ if (state.phase !== "complete") {
5779
+ setReceiptOpen(false);
5780
+ }
5781
+ }, [state.phase]);
5782
+ function handleSubmit(message) {
5783
+ setReceiptOpen(false);
5784
+ onSubmit?.(message);
5785
+ }
5786
+ function handleRegenerate() {
5787
+ setReceiptOpen(false);
5788
+ onRegenerate?.();
5789
+ }
5790
+ function handleReset() {
5791
+ setReceiptOpen(false);
5792
+ onReset?.();
5793
+ }
5794
+ function handleFollowUpSelect(label) {
5795
+ setReceiptOpen(false);
5796
+ onFollowUpSelect?.(label);
5797
+ }
5798
+ useEffect6(() => {
4961
5799
  const node = transcriptRef.current;
4962
5800
  if (!node) return;
4963
- node.scrollTop = node.scrollHeight;
5801
+ const lastMessage2 = state.messages.at(-1);
5802
+ const visitorJustSent = lastMessage2?.role === "visitor";
5803
+ if (pinnedToBottomRef.current || visitorJustSent) {
5804
+ node.scrollTop = node.scrollHeight;
5805
+ }
4964
5806
  }, [
4965
5807
  state.messages,
4966
5808
  state.toolSteps,
@@ -4968,10 +5810,75 @@ function AgentRail({
4968
5810
  state.followUps,
4969
5811
  state.journey
4970
5812
  ]);
4971
- return /* @__PURE__ */ jsxs13(
5813
+ useEffect6(() => {
5814
+ const node = transcriptRef.current;
5815
+ if (!node) return;
5816
+ const handleScroll = () => {
5817
+ if (node.clientHeight === 0) return;
5818
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5819
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
5820
+ pinnedToBottomRef.current = pinned;
5821
+ setShowJumpToLatest(!pinned);
5822
+ };
5823
+ node.addEventListener("scroll", handleScroll, { passive: true });
5824
+ handleScroll();
5825
+ return () => node.removeEventListener("scroll", handleScroll);
5826
+ }, []);
5827
+ useEffect6(() => {
5828
+ const node = transcriptRef.current;
5829
+ if (!node) return;
5830
+ const observer = new ResizeObserver(() => {
5831
+ if (node.clientHeight === 0) return;
5832
+ if (pinnedToBottomRef.current) {
5833
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5834
+ }
5835
+ });
5836
+ observer.observe(node);
5837
+ return () => observer.disconnect();
5838
+ }, []);
5839
+ useEffect6(() => {
5840
+ if (!receiptOpen) {
5841
+ lockedTranscriptScrollTopRef.current = null;
5842
+ return;
5843
+ }
5844
+ const node = transcriptRef.current;
5845
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
5846
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
5847
+ }, [receiptOpen]);
5848
+ function openReceipt() {
5849
+ const node = transcriptRef.current;
5850
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
5851
+ setReceiptOpen(true);
5852
+ }
5853
+ function scrollToLatest() {
5854
+ const node = transcriptRef.current;
5855
+ if (!node) return;
5856
+ pinnedToBottomRef.current = true;
5857
+ setShowJumpToLatest(false);
5858
+ const reduceMotion = window.matchMedia(
5859
+ "(prefers-reduced-motion: reduce)"
5860
+ ).matches;
5861
+ if (reduceMotion) {
5862
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5863
+ return;
5864
+ }
5865
+ smoothScrollToLatestRef.current = true;
5866
+ const settle = () => {
5867
+ smoothScrollToLatestRef.current = false;
5868
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5869
+ const pinned = distanceFromBottom < 48;
5870
+ pinnedToBottomRef.current = pinned;
5871
+ setShowJumpToLatest(!pinned);
5872
+ };
5873
+ node.addEventListener("scrollend", settle, { once: true });
5874
+ window.setTimeout(settle, 900);
5875
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
5876
+ }
5877
+ return /* @__PURE__ */ jsx16(
4972
5878
  "aside",
4973
5879
  {
4974
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
5880
+ ref: railRef,
5881
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
4975
5882
  "data-not-typeset": "",
4976
5883
  "data-color-scheme": resolvedColorScheme,
4977
5884
  spellCheck: false,
@@ -4981,193 +5888,234 @@ function AgentRail({
4981
5888
  autoFocus: mobileFullscreen || expanded,
4982
5889
  role: mobileFullscreen || expanded ? "dialog" : void 0,
4983
5890
  tabIndex: mobileFullscreen || expanded ? -1 : void 0,
4984
- children: [
4985
- /* @__PURE__ */ jsx14("header", { className: "agent-rail__header", children: /* @__PURE__ */ jsxs13("div", { className: "agent-rail__brand-row", children: [
4986
- onCollapse ? /* @__PURE__ */ jsx14(
4987
- "button",
4988
- {
4989
- type: "button",
4990
- className: "agent-rail__collapse",
4991
- "aria-label": "Collapse assist",
4992
- onClick: onCollapse,
4993
- children: /* @__PURE__ */ jsx14(MinimizeIcon, {})
4994
- }
4995
- ) : onClose ? /* @__PURE__ */ jsx14(
4996
- "button",
4997
- {
4998
- type: "button",
4999
- className: "agent-rail__close",
5000
- "aria-label": "Close agent",
5001
- onClick: onClose,
5002
- children: /* @__PURE__ */ jsx14(CloseIcon, {})
5003
- }
5004
- ) : /* @__PURE__ */ jsx14("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
5005
- resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ jsxs13("span", { className: "agent-rail__identity", children: [
5006
- showBrandLogo ? /* @__PURE__ */ jsx14("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx14(
5007
- "img",
5008
- {
5009
- className: "agent-rail__brand-logo",
5010
- src: resolvedBrandLogoUrl,
5011
- alt: "",
5012
- onError: () => {
5013
- setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
5014
- }
5015
- }
5016
- ) }) : null,
5017
- resolvedBrandLabel ? /* @__PURE__ */ jsx14("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
5018
- ] }) : null,
5019
- /* @__PURE__ */ jsxs13("span", { className: "agent-rail__actions", children: [
5020
- onReset ? /* @__PURE__ */ jsx14(
5021
- "button",
5022
- {
5023
- type: "button",
5024
- className: "agent-rail__new-chat",
5025
- "aria-label": "Start a new conversation",
5026
- disabled: !hasVisitorMessages2,
5027
- onClick: onReset,
5028
- children: /* @__PURE__ */ jsx14(NewChatIcon, {})
5029
- }
5030
- ) : null,
5031
- onExpandToggle ? /* @__PURE__ */ jsx14(
5032
- "button",
5033
- {
5034
- type: "button",
5035
- className: "agent-rail__expand",
5036
- "aria-label": expanded ? "Exit full screen" : "Open full screen",
5037
- onClick: onExpandToggle,
5038
- children: expanded ? /* @__PURE__ */ jsx14(RestoreIcon, {}) : /* @__PURE__ */ jsx14(ExpandIcon, {})
5039
- }
5040
- ) : null
5041
- ] })
5042
- ] }) }),
5043
- /* @__PURE__ */ jsx14("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ jsxs13("div", { className: "agent-rail__thread", children: [
5044
- !hasVisitorMessages2 ? /* @__PURE__ */ jsxs13("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
5045
- greeting?.role === "agent" ? /* @__PURE__ */ jsx14(
5046
- MessageBubble,
5047
- {
5048
- message: greeting,
5049
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5050
- onBook
5051
- }
5052
- ) : null,
5053
- showIdleFollowUps ? /* @__PURE__ */ jsx14("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ jsx14(
5054
- FollowUpChips,
5055
- {
5056
- suggestions: state.followUps,
5057
- disabled: isBusy,
5058
- label: "Start here",
5059
- onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
5060
- }
5061
- ) }) : null,
5062
- showActivity ? /* @__PURE__ */ jsx14(
5063
- AgentActivityBubble,
5891
+ children: /* @__PURE__ */ jsxs15(
5892
+ AgentRailOverlayContext.Provider,
5893
+ {
5894
+ value: { railRef, overlayRef },
5895
+ children: [
5896
+ /* @__PURE__ */ jsxs15("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
5897
+ /* @__PURE__ */ jsx16("header", { className: "agent-rail__header", children: /* @__PURE__ */ jsxs15("div", { className: "agent-rail__brand-row", children: [
5898
+ onCollapse ? /* @__PURE__ */ jsx16(
5899
+ "button",
5900
+ {
5901
+ type: "button",
5902
+ className: "agent-rail__collapse",
5903
+ "aria-label": "Collapse assist",
5904
+ onClick: onCollapse,
5905
+ children: /* @__PURE__ */ jsx16(MinimizeIcon, {})
5906
+ }
5907
+ ) : onClose ? /* @__PURE__ */ jsx16(
5908
+ "button",
5909
+ {
5910
+ type: "button",
5911
+ className: "agent-rail__close",
5912
+ "aria-label": "Close agent",
5913
+ onClick: onClose,
5914
+ children: /* @__PURE__ */ jsx16(CloseIcon2, {})
5915
+ }
5916
+ ) : /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
5917
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ jsxs15("span", { className: "agent-rail__identity", children: [
5918
+ showBrandLogo ? /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(
5919
+ "img",
5920
+ {
5921
+ className: "agent-rail__brand-logo",
5922
+ src: resolvedBrandLogoUrl,
5923
+ alt: "",
5924
+ onError: () => {
5925
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
5926
+ }
5927
+ }
5928
+ ) }) : null,
5929
+ resolvedBrandLabel ? /* @__PURE__ */ jsx16("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
5930
+ ] }) : null,
5931
+ /* @__PURE__ */ jsxs15("span", { className: "agent-rail__actions", children: [
5932
+ onReset ? /* @__PURE__ */ jsx16(
5933
+ "button",
5934
+ {
5935
+ type: "button",
5936
+ className: "agent-rail__new-chat",
5937
+ "aria-label": "Start a new conversation",
5938
+ disabled: !hasVisitorMessages2,
5939
+ onClick: handleReset,
5940
+ children: /* @__PURE__ */ jsx16(NewChatIcon, {})
5941
+ }
5942
+ ) : null,
5943
+ onExpandToggle ? /* @__PURE__ */ jsx16(
5944
+ "button",
5945
+ {
5946
+ type: "button",
5947
+ className: "agent-rail__expand",
5948
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
5949
+ onClick: onExpandToggle,
5950
+ children: expanded ? /* @__PURE__ */ jsx16(RestoreIcon, {}) : /* @__PURE__ */ jsx16(ExpandIcon, {})
5951
+ }
5952
+ ) : null
5953
+ ] })
5954
+ ] }) }),
5955
+ /* @__PURE__ */ jsx16("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ jsxs15("div", { className: "agent-rail__thread", children: [
5956
+ !hasVisitorMessages2 ? /* @__PURE__ */ jsxs15("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
5957
+ greeting?.role === "agent" ? /* @__PURE__ */ jsx16(
5958
+ MessageBubble,
5959
+ {
5960
+ message: greeting,
5961
+ bookingDisabled: isBusy,
5962
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5963
+ onBook
5964
+ }
5965
+ ) : null,
5966
+ showIdleFollowUps ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ jsx16(
5967
+ FollowUpChips,
5968
+ {
5969
+ suggestions: state.followUps,
5970
+ disabled: isBusy,
5971
+ label: "Start here",
5972
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
5973
+ }
5974
+ ) }) : null,
5975
+ showActivity ? /* @__PURE__ */ jsx16(
5976
+ AgentActivityBubble,
5977
+ {
5978
+ brandLabel: resolvedBrandLabel,
5979
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5980
+ failed: state.phase === "error",
5981
+ steps: state.toolSteps
5982
+ }
5983
+ ) : null,
5984
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx16(
5985
+ VisitorToolResultView,
5986
+ {
5987
+ result,
5988
+ disabled: semanticSurfaceDisabled,
5989
+ onToolInput
5990
+ },
5991
+ result.id
5992
+ )),
5993
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx16(
5994
+ HumanInputCard,
5995
+ {
5996
+ request,
5997
+ onRespond: onInputResponse
5998
+ },
5999
+ request.requestId
6000
+ ))
6001
+ ] }) : null,
6002
+ visibleMessages.map((message, index) => /* @__PURE__ */ jsxs15("div", { className: "agent-rail__turn-block", children: [
6003
+ /* @__PURE__ */ jsx16(
6004
+ MessageBubble,
6005
+ {
6006
+ message,
6007
+ bookingDisabled: isBusy,
6008
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6009
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6010
+ onBook
6011
+ }
6012
+ ),
6013
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ jsx16(
6014
+ MessageActions,
6015
+ {
6016
+ answeredAt: message.createdAt,
6017
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6018
+ readAloud,
6019
+ receiptSteps,
6020
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6021
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6022
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6023
+ }
6024
+ ) : null,
6025
+ index === lastVisitorIndex ? /* @__PURE__ */ jsxs15(Fragment, { children: [
6026
+ showActivity ? /* @__PURE__ */ jsx16(
6027
+ AgentActivityBubble,
6028
+ {
6029
+ brandLabel: resolvedBrandLabel,
6030
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6031
+ failed: state.phase === "error",
6032
+ steps: state.toolSteps
6033
+ }
6034
+ ) : null,
6035
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx16(
6036
+ VisitorToolResultView,
6037
+ {
6038
+ result,
6039
+ disabled: semanticSurfaceDisabled,
6040
+ onToolInput
6041
+ },
6042
+ result.id
6043
+ )),
6044
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx16(
6045
+ HumanInputCard,
6046
+ {
6047
+ request,
6048
+ onRespond: onInputResponse
6049
+ },
6050
+ request.requestId
6051
+ ))
6052
+ ] }) : null
6053
+ ] }, message.id)),
6054
+ streamingMessage ? /* @__PURE__ */ jsx16(
6055
+ MessageBubble,
6056
+ {
6057
+ message: streamingMessage,
6058
+ bookingDisabled: isBusy,
6059
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6060
+ offer: state.pendingOffer,
6061
+ onBook
6062
+ }
6063
+ ) : null,
6064
+ waitingForBooking ? /* @__PURE__ */ jsx16(BookingCardLoader, {}) : null,
6065
+ state.error ? /* @__PURE__ */ jsxs15("section", { className: "agent-rail__error", role: "alert", children: [
6066
+ /* @__PURE__ */ jsxs15("div", { children: [
6067
+ /* @__PURE__ */ jsx16("strong", { children: "Something went wrong" }),
6068
+ /* @__PURE__ */ jsx16("p", { children: state.error })
6069
+ ] }),
6070
+ onRetry ? /* @__PURE__ */ jsx16("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6071
+ ] }) : null
6072
+ ] }) }),
6073
+ showDisclaimerLabel ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ jsx16("p", { children: resolvedDisclaimerLabel }) }) : null,
6074
+ /* @__PURE__ */ jsxs15("div", { className: "agent-rail__composer-wrap", children: [
6075
+ showJumpToLatest ? /* @__PURE__ */ jsx16(
6076
+ "button",
6077
+ {
6078
+ type: "button",
6079
+ className: "agent-rail__jump-to-latest",
6080
+ "aria-label": "Jump to the latest message",
6081
+ title: "Jump to the latest message",
6082
+ onClick: scrollToLatest,
6083
+ children: /* @__PURE__ */ jsx16(ChevronDownIcon, {})
6084
+ }
6085
+ ) : null,
6086
+ /* @__PURE__ */ jsx16(
6087
+ Composer,
6088
+ {
6089
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6090
+ disabled: isBusy,
6091
+ form: composerForm,
6092
+ placeholder: composerPlaceholder,
6093
+ onSubmit: handleSubmit
6094
+ }
6095
+ ),
6096
+ poweredByLabel ? /* @__PURE__ */ jsx16("div", { className: "agent-rail__footer", children: /* @__PURE__ */ jsx16("p", { children: /* @__PURE__ */ jsx16("span", { children: poweredByLabel }) }) }) : null
6097
+ ] })
6098
+ ] }),
6099
+ /* @__PURE__ */ jsx16("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6100
+ receiptOpen && receiptSteps ? /* @__PURE__ */ jsx16(
6101
+ AnswerReceiptDialog,
5064
6102
  {
5065
6103
  brandLabel: resolvedBrandLabel,
5066
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5067
- failed: state.phase === "error",
5068
- steps: state.toolSteps
6104
+ onClose: () => setReceiptOpen(false),
6105
+ steps: receiptSteps
5069
6106
  }
5070
- ) : null,
5071
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx14(
5072
- VisitorToolResultView,
5073
- {
5074
- result,
5075
- disabled: semanticSurfaceDisabled,
5076
- onToolInput
5077
- },
5078
- result.id
5079
- )),
5080
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx14(
5081
- HumanInputCard,
5082
- {
5083
- request,
5084
- onRespond: onInputResponse
5085
- },
5086
- request.requestId
5087
- ))
5088
- ] }) : null,
5089
- visibleMessages.map((message, index) => /* @__PURE__ */ jsxs13("div", { className: "agent-rail__turn-block", children: [
5090
- /* @__PURE__ */ jsx14(
5091
- MessageBubble,
5092
- {
5093
- message,
5094
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5095
- offer: index === lastAgentIndex ? state.pendingOffer : void 0,
5096
- onBook
5097
- }
5098
- ),
5099
- index === lastVisitorIndex ? /* @__PURE__ */ jsxs13(Fragment, { children: [
5100
- showActivity ? /* @__PURE__ */ jsx14(
5101
- AgentActivityBubble,
5102
- {
5103
- brandLabel: resolvedBrandLabel,
5104
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5105
- failed: state.phase === "error",
5106
- steps: state.toolSteps
5107
- }
5108
- ) : null,
5109
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ jsx14(
5110
- VisitorToolResultView,
5111
- {
5112
- result,
5113
- disabled: semanticSurfaceDisabled,
5114
- onToolInput
5115
- },
5116
- result.id
5117
- )),
5118
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ jsx14(
5119
- HumanInputCard,
5120
- {
5121
- request,
5122
- onRespond: onInputResponse
5123
- },
5124
- request.requestId
5125
- ))
5126
- ] }) : null
5127
- ] }, message.id)),
5128
- streamingMessage ? /* @__PURE__ */ jsx14(
5129
- MessageBubble,
5130
- {
5131
- message: streamingMessage,
5132
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5133
- offer: state.pendingOffer,
5134
- onBook
5135
- }
5136
- ) : null,
5137
- waitingForBooking ? /* @__PURE__ */ jsx14(BookingCardLoader, {}) : null,
5138
- state.error ? /* @__PURE__ */ jsxs13("section", { className: "agent-rail__error", role: "alert", children: [
5139
- /* @__PURE__ */ jsxs13("div", { children: [
5140
- /* @__PURE__ */ jsx14("strong", { children: "Something went wrong" }),
5141
- /* @__PURE__ */ jsx14("p", { children: state.error })
5142
- ] }),
5143
- onRetry ? /* @__PURE__ */ jsx14("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
5144
- ] }) : null
5145
- ] }) }),
5146
- /* @__PURE__ */ jsxs13("div", { className: "agent-rail__composer-wrap", children: [
5147
- /* @__PURE__ */ jsx14(
5148
- Composer,
5149
- {
5150
- variant: expanded || mobileFullscreen ? "dock" : "default",
5151
- disabled: isBusy,
5152
- form: composerForm,
5153
- placeholder: composerPlaceholder,
5154
- onSubmit
5155
- }
5156
- ),
5157
- /* @__PURE__ */ jsx14("div", { className: "agent-rail__footer", children: /* @__PURE__ */ jsxs13("p", { children: [
5158
- /* @__PURE__ */ jsx14("span", { children: "AI can make mistakes. Check important info." }),
5159
- /* @__PURE__ */ jsx14("span", { children: poweredByLabel })
5160
- ] }) })
5161
- ] })
5162
- ]
6107
+ ) : null
6108
+ ]
6109
+ }
6110
+ )
5163
6111
  }
5164
6112
  );
5165
6113
  }
5166
6114
 
5167
6115
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5168
- import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
6116
+ import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
5169
6117
  function SparklesIcon() {
5170
- return /* @__PURE__ */ jsxs14(
6118
+ return /* @__PURE__ */ jsxs16(
5171
6119
  "svg",
5172
6120
  {
5173
6121
  className: "assist-edge-tab__sparkles",
@@ -5175,21 +6123,21 @@ function SparklesIcon() {
5175
6123
  fill: "none",
5176
6124
  "aria-hidden": "true",
5177
6125
  children: [
5178
- /* @__PURE__ */ jsx15(
6126
+ /* @__PURE__ */ jsx17(
5179
6127
  "path",
5180
6128
  {
5181
6129
  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",
5182
6130
  fill: "currentColor"
5183
6131
  }
5184
6132
  ),
5185
- /* @__PURE__ */ jsx15(
6133
+ /* @__PURE__ */ jsx17(
5186
6134
  "path",
5187
6135
  {
5188
6136
  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",
5189
6137
  fill: "currentColor"
5190
6138
  }
5191
6139
  ),
5192
- /* @__PURE__ */ jsx15(
6140
+ /* @__PURE__ */ jsx17(
5193
6141
  "path",
5194
6142
  {
5195
6143
  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",
@@ -5203,7 +6151,7 @@ function SparklesIcon() {
5203
6151
  function TabMarkIcon({ customIconUrl }) {
5204
6152
  const url = customIconUrl?.trim();
5205
6153
  if (url) {
5206
- return /* @__PURE__ */ jsx15(
6154
+ return /* @__PURE__ */ jsx17(
5207
6155
  "img",
5208
6156
  {
5209
6157
  alt: "",
@@ -5213,10 +6161,10 @@ function TabMarkIcon({ customIconUrl }) {
5213
6161
  }
5214
6162
  );
5215
6163
  }
5216
- return /* @__PURE__ */ jsx15(SparklesIcon, {});
6164
+ return /* @__PURE__ */ jsx17(SparklesIcon, {});
5217
6165
  }
5218
6166
  function ChevronLeftIcon() {
5219
- return /* @__PURE__ */ jsx15("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx15(
6167
+ return /* @__PURE__ */ jsx17("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(
5220
6168
  "path",
5221
6169
  {
5222
6170
  d: "M10 4L6 8l4 4",
@@ -5227,8 +6175,8 @@ function ChevronLeftIcon() {
5227
6175
  }
5228
6176
  ) });
5229
6177
  }
5230
- function ChevronDownIcon() {
5231
- return /* @__PURE__ */ jsx15("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx15(
6178
+ function ChevronDownIcon2() {
6179
+ return /* @__PURE__ */ jsx17("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx17(
5232
6180
  "path",
5233
6181
  {
5234
6182
  d: "M4 6l4 4 4-4",
@@ -5240,7 +6188,7 @@ function ChevronDownIcon() {
5240
6188
  ) });
5241
6189
  }
5242
6190
  function DragDots() {
5243
- return /* @__PURE__ */ jsx15("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ jsx15("i", {}, index)) });
6191
+ return /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ jsx17("i", {}, index)) });
5244
6192
  }
5245
6193
  var VARIANT_COPY = {
5246
6194
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5286,7 +6234,7 @@ function AssistEdgeTab({
5286
6234
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5287
6235
  colorScheme: resolvedColorScheme
5288
6236
  };
5289
- return /* @__PURE__ */ jsxs14(
6237
+ return /* @__PURE__ */ jsxs16(
5290
6238
  "button",
5291
6239
  {
5292
6240
  type: "button",
@@ -5298,15 +6246,15 @@ function AssistEdgeTab({
5298
6246
  tabIndex: visible ? 0 : -1,
5299
6247
  onClick: onOpen,
5300
6248
  children: [
5301
- mobile ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
5302
- /* @__PURE__ */ jsxs14(
6249
+ mobile ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
6250
+ /* @__PURE__ */ jsxs16(
5303
6251
  "span",
5304
6252
  {
5305
6253
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5306
6254
  "aria-hidden": "true",
5307
6255
  children: [
5308
- /* @__PURE__ */ jsx15(TabMarkIcon, { customIconUrl }),
5309
- showLogo ? /* @__PURE__ */ jsx15(
6256
+ /* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
6257
+ showLogo ? /* @__PURE__ */ jsx17(
5310
6258
  "img",
5311
6259
  {
5312
6260
  className: "assist-edge-tab__logo",
@@ -5320,11 +6268,11 @@ function AssistEdgeTab({
5320
6268
  ]
5321
6269
  }
5322
6270
  ),
5323
- /* @__PURE__ */ jsx15("span", { className: "assist-edge-tab__label", children: visibleLabel })
5324
- ] }) : variant === "outline" ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
5325
- /* @__PURE__ */ jsxs14("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5326
- /* @__PURE__ */ jsx15(TabMarkIcon, { customIconUrl }),
5327
- showLogo ? /* @__PURE__ */ jsx15(
6271
+ /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel })
6272
+ ] }) : variant === "outline" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
6273
+ /* @__PURE__ */ jsxs16("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6274
+ /* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
6275
+ showLogo ? /* @__PURE__ */ jsx17(
5328
6276
  "img",
5329
6277
  {
5330
6278
  className: "assist-edge-tab__logo",
@@ -5336,18 +6284,18 @@ function AssistEdgeTab({
5336
6284
  }
5337
6285
  ) : null
5338
6286
  ] }),
5339
- /* @__PURE__ */ jsx15("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5340
- /* @__PURE__ */ jsx15(ChevronDownIcon, {})
6287
+ /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6288
+ /* @__PURE__ */ jsx17(ChevronDownIcon2, {})
5341
6289
  ] }) : null,
5342
- variant === "ask" ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
5343
- /* @__PURE__ */ jsx15(ChevronLeftIcon, {}),
5344
- /* @__PURE__ */ jsx15("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5345
- /* @__PURE__ */ jsx15(DragDots, {})
6290
+ variant === "ask" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
6291
+ /* @__PURE__ */ jsx17(ChevronLeftIcon, {}),
6292
+ /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6293
+ /* @__PURE__ */ jsx17(DragDots, {})
5346
6294
  ] }) : null,
5347
- variant === "fill" ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
5348
- /* @__PURE__ */ jsxs14("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5349
- /* @__PURE__ */ jsx15(TabMarkIcon, { customIconUrl }),
5350
- showLogo ? /* @__PURE__ */ jsx15(
6295
+ variant === "fill" ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
6296
+ /* @__PURE__ */ jsxs16("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6297
+ /* @__PURE__ */ jsx17(TabMarkIcon, { customIconUrl }),
6298
+ showLogo ? /* @__PURE__ */ jsx17(
5351
6299
  "img",
5352
6300
  {
5353
6301
  className: "assist-edge-tab__logo",
@@ -5359,19 +6307,75 @@ function AssistEdgeTab({
5359
6307
  }
5360
6308
  ) : null
5361
6309
  ] }),
5362
- /* @__PURE__ */ jsx15("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5363
- /* @__PURE__ */ jsx15(ChevronLeftIcon, {})
6310
+ /* @__PURE__ */ jsx17("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6311
+ /* @__PURE__ */ jsx17(ChevronLeftIcon, {})
5364
6312
  ] }) : null
5365
6313
  ]
5366
6314
  }
5367
6315
  );
5368
6316
  }
5369
6317
 
6318
+ // src/react/lib/agent-feedback.ts
6319
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6320
+ function findPrecedingVisitorText(messages, agentMessageId) {
6321
+ const agentIndex = messages.findIndex(
6322
+ (message) => message.id === agentMessageId && message.role === "agent"
6323
+ );
6324
+ if (agentIndex < 0) return void 0;
6325
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6326
+ const message = messages[index];
6327
+ if (message?.role === "visitor") {
6328
+ return message.text.trim() || void 0;
6329
+ }
6330
+ }
6331
+ return void 0;
6332
+ }
6333
+ function normalizeAgentFeedbackAnswerText(text) {
6334
+ const normalized = text.replace(/\s+/g, " ").trim();
6335
+ if (!normalized) return void 0;
6336
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6337
+ }
6338
+ function buildAgentAnswerFeedbackEvent(input) {
6339
+ const positive = input.rating === "positive";
6340
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6341
+ return {
6342
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6343
+ company: input.analytics.companyIndex,
6344
+ session_id: input.visitorSessionId,
6345
+ page: input.page,
6346
+ timestamp: Date.now(),
6347
+ tracking_consent: input.analytics.trackingConsent,
6348
+ feedback_value: positive ? 1 : -1,
6349
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6350
+ feedback_rating: positive ? "helpful" : "not_helpful",
6351
+ surface: "agent_panel",
6352
+ index_id: input.indexId,
6353
+ index_version: input.version,
6354
+ message_id: input.messageId,
6355
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6356
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6357
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6358
+ };
6359
+ }
6360
+ function sendAgentAnswerFeedback(eventUrl, event) {
6361
+ try {
6362
+ void fetch(eventUrl, {
6363
+ body: JSON.stringify(event),
6364
+ credentials: "omit",
6365
+ headers: { "Content-Type": "application/json" },
6366
+ keepalive: true,
6367
+ method: "POST"
6368
+ }).catch(() => {
6369
+ });
6370
+ } catch {
6371
+ }
6372
+ }
6373
+
5370
6374
  // src/react/components/AgentWidget/AgentWidget.tsx
5371
- import { useEffect as useEffect7, useRef as useRef5, useState as useState10 } from "react";
6375
+ import { useEffect as useEffect9, useRef as useRef7, useState as useState11 } from "react";
5372
6376
 
5373
6377
  // src/react/page-shift.ts
5374
- import { useEffect as useEffect5 } from "react";
6378
+ import { useEffect as useEffect7 } from "react";
5375
6379
  var PAGE_SHIFT_CLASS = "webless-agent-page-shift";
5376
6380
  var DEFAULT_RAIL_WIDTH_PX = 450;
5377
6381
  function shouldApplyPageShift(input) {
@@ -5423,7 +6427,7 @@ function clearPageMargin() {
5423
6427
  }
5424
6428
  function usePageShift(input) {
5425
6429
  const { active, railSlotRef } = input;
5426
- useEffect5(() => {
6430
+ useEffect7(() => {
5427
6431
  if (typeof document === "undefined") {
5428
6432
  return;
5429
6433
  }
@@ -5451,12 +6455,12 @@ function usePageShift(input) {
5451
6455
  }
5452
6456
 
5453
6457
  // src/react/hooks/useIsMobile.ts
5454
- import { useEffect as useEffect6, useState as useState9 } from "react";
6458
+ import { useEffect as useEffect8, useState as useState10 } from "react";
5455
6459
  function useIsMobile(breakpoint = 767) {
5456
- const [isMobile, setIsMobile] = useState9(
6460
+ const [isMobile, setIsMobile] = useState10(
5457
6461
  () => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
5458
6462
  );
5459
- useEffect6(() => {
6463
+ useEffect8(() => {
5460
6464
  const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
5461
6465
  const onChange = () => setIsMobile(media.matches);
5462
6466
  onChange();
@@ -5467,7 +6471,7 @@ function useIsMobile(breakpoint = 767) {
5467
6471
  }
5468
6472
 
5469
6473
  // src/react/components/AgentWidget/AgentWidget.tsx
5470
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
6474
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
5471
6475
  function AgentWidget({
5472
6476
  indexId,
5473
6477
  customerId,
@@ -5481,13 +6485,14 @@ function AgentWidget({
5481
6485
  registerPanelController = false,
5482
6486
  colorScheme = "auto",
5483
6487
  branding,
6488
+ analytics,
5484
6489
  toolResultRegistry
5485
6490
  }) {
5486
6491
  const isMobile = useIsMobile();
5487
6492
  const placement = normalizeAgentPlacement(placementInput);
5488
- const railSlotRef = useRef5(null);
5489
- const [railCollapsed, setRailCollapsed] = useState10(defaultCollapsed);
5490
- const [railExpanded, setRailExpanded] = useState10(false);
6493
+ const railSlotRef = useRef7(null);
6494
+ const [railCollapsed, setRailCollapsed] = useState11(defaultCollapsed);
6495
+ const [railExpanded, setRailExpanded] = useState11(false);
5491
6496
  const pageShiftActive = shouldApplyPageShift({
5492
6497
  pageShift,
5493
6498
  isMobile,
@@ -5498,7 +6503,17 @@ function AgentWidget({
5498
6503
  active: pageShiftActive,
5499
6504
  railSlotRef
5500
6505
  });
5501
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6506
+ const {
6507
+ state,
6508
+ reset,
6509
+ retry,
6510
+ regenerate,
6511
+ respondToInput,
6512
+ respondToToolInput,
6513
+ submit,
6514
+ visitorSessionId,
6515
+ sessionId
6516
+ } = useAgentChat({
5502
6517
  customerId,
5503
6518
  getUnpublishedPreviewGrant,
5504
6519
  indexId,
@@ -5530,7 +6545,7 @@ function AgentWidget({
5530
6545
  } : {},
5531
6546
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5532
6547
  };
5533
- useEffect7(() => {
6548
+ useEffect9(() => {
5534
6549
  if (!registerPanelController) return;
5535
6550
  registerAgentPanelController(customerId, {
5536
6551
  open: () => setRailCollapsed(false),
@@ -5547,7 +6562,25 @@ function AgentWidget({
5547
6562
  if (isMobile) setRailCollapsed(false);
5548
6563
  await submit(message);
5549
6564
  }
5550
- useEffect7(() => {
6565
+ function handleFeedback(rating, message) {
6566
+ if (!analytics) return;
6567
+ sendAgentAnswerFeedback(
6568
+ analytics.eventUrl,
6569
+ buildAgentAnswerFeedbackEvent({
6570
+ agentSessionId: sessionId,
6571
+ analytics,
6572
+ indexId,
6573
+ messageId: message.id,
6574
+ page: window.location.href,
6575
+ query: findPrecedingVisitorText(state.messages, message.id),
6576
+ answer: message.text,
6577
+ rating,
6578
+ version: version ?? "published",
6579
+ visitorSessionId
6580
+ })
6581
+ );
6582
+ }
6583
+ useEffect9(() => {
5551
6584
  if (railCollapsed) return;
5552
6585
  const handleKeyDown = (event) => {
5553
6586
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5581,19 +6614,19 @@ function AgentWidget({
5581
6614
  window.addEventListener("keydown", handleKeyDown);
5582
6615
  return () => window.removeEventListener("keydown", handleKeyDown);
5583
6616
  }, [isMobile, railCollapsed, railExpanded]);
5584
- return /* @__PURE__ */ jsxs15("div", { className: "webless-agent-root", children: [
5585
- /* @__PURE__ */ jsx16(
6617
+ return /* @__PURE__ */ jsxs17("div", { className: "webless-agent-root", children: [
6618
+ /* @__PURE__ */ jsx18(
5586
6619
  "div",
5587
6620
  {
5588
6621
  className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
5589
- children: /* @__PURE__ */ jsx16(
6622
+ children: /* @__PURE__ */ jsx18(
5590
6623
  "div",
5591
6624
  {
5592
6625
  ref: railSlotRef,
5593
6626
  className: "webless-agent-root__rail-slot",
5594
6627
  inert: railCollapsed || void 0,
5595
6628
  "aria-hidden": railCollapsed,
5596
- children: /* @__PURE__ */ jsx16(
6629
+ children: /* @__PURE__ */ jsx18(
5597
6630
  AgentRail,
5598
6631
  {
5599
6632
  theme,
@@ -5602,6 +6635,9 @@ function AgentWidget({
5602
6635
  brandLogoUrl: branding?.logoUrl,
5603
6636
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5604
6637
  poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6638
+ disclaimerLabel: branding?.disclaimer,
6639
+ answerReceipt: branding?.answerReceipt,
6640
+ readAloud: branding?.readAloud,
5605
6641
  state,
5606
6642
  mobileFullscreen: isMobile && !railCollapsed,
5607
6643
  expanded: railExpanded,
@@ -5611,17 +6647,22 @@ function AgentWidget({
5611
6647
  onSubmit: handleSubmit,
5612
6648
  onReset: reset,
5613
6649
  onRetry: () => void retry(),
6650
+ onRegenerate: () => void regenerate(),
6651
+ onFeedback: analytics ? handleFeedback : void 0,
5614
6652
  onInputResponse: (response) => void respondToInput(response),
5615
6653
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5616
6654
  onFollowUpSelect: (label) => void handleSubmit(label),
5617
- onBook: (input) => void submit(input.displayText, { runtimeText: input.runtimeText })
6655
+ onBook: (input) => void submit(input.displayText, {
6656
+ preservePendingOffer: true,
6657
+ runtimeText: input.runtimeText
6658
+ })
5618
6659
  }
5619
6660
  )
5620
6661
  }
5621
6662
  )
5622
6663
  }
5623
6664
  ),
5624
- railCollapsed ? /* @__PURE__ */ jsx16(
6665
+ railCollapsed ? /* @__PURE__ */ jsx18(
5625
6666
  AssistEdgeTab,
5626
6667
  {
5627
6668
  variant: placement.variant,
@@ -5666,8 +6707,13 @@ export {
5666
6707
  submitAgentPanel,
5667
6708
  defaultAgentRailTheme,
5668
6709
  defaultDarkAgentRailTheme,
6710
+ MessageActions,
5669
6711
  AgentRail,
5670
6712
  AssistEdgeTab,
6713
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6714
+ findPrecedingVisitorText,
6715
+ buildAgentAnswerFeedbackEvent,
6716
+ sendAgentAnswerFeedback,
5671
6717
  AgentWidget
5672
6718
  };
5673
- //# sourceMappingURL=chunk-NEI5GKGH.js.map
6719
+ //# sourceMappingURL=chunk-CYI3OSWG.js.map