@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.
package/dist/react.cjs CHANGED
@@ -20,27 +20,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/react/index.ts
21
21
  var react_exports = {};
22
22
  __export(react_exports, {
23
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE: () => AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
23
24
  AGENT_STRUCTURED_TOOL_INPUT_HEADER: () => AGENT_STRUCTURED_TOOL_INPUT_HEADER,
24
25
  AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION: () => AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
25
26
  AgentRail: () => AgentRail,
26
27
  AgentWidget: () => AgentWidget,
27
28
  AssistEdgeTab: () => AssistEdgeTab,
28
29
  DEFAULT_AGENT_PLACEMENT: () => DEFAULT_AGENT_PLACEMENT,
30
+ MessageActions: () => MessageActions,
31
+ buildAgentAnswerFeedbackEvent: () => buildAgentAnswerFeedbackEvent,
29
32
  builtInVisitorToolResultRegistry: () => builtInVisitorToolResultRegistry,
30
33
  createIdleSuggestions: () => createIdleSuggestions,
31
34
  defaultAgentRailTheme: () => defaultAgentRailTheme,
32
35
  defaultDarkAgentRailTheme: () => defaultDarkAgentRailTheme,
36
+ findPrecedingVisitorText: () => findPrecedingVisitorText,
33
37
  formatAgentStructuredToolInput: () => formatAgentStructuredToolInput,
34
38
  hasVisitorMessages: () => hasVisitorMessages,
35
39
  isAgentBusy: () => isAgentBusy,
36
40
  normalizeAgentPlacement: () => normalizeAgentPlacement,
37
41
  presentVisitorToolResult: () => presentVisitorToolResult,
42
+ sendAgentAnswerFeedback: () => sendAgentAnswerFeedback,
38
43
  useAgentChat: () => useAgentChat
39
44
  });
40
45
  module.exports = __toCommonJS(react_exports);
41
46
 
42
47
  // src/react/components/AgentWidget/AgentWidget.tsx
43
- var import_react12 = require("react");
48
+ var import_react15 = require("react");
44
49
 
45
50
  // src/react/page-shift.ts
46
51
  var import_react = require("react");
@@ -896,6 +901,20 @@ function latestTurnEvents(events) {
896
901
  }
897
902
  return startIndex >= 0 ? events.slice(startIndex) : [];
898
903
  }
904
+ function streamIndexBeforeLastTurn(input) {
905
+ let turnStart = -1;
906
+ for (let index = input.events.length - 1; index >= 0; index -= 1) {
907
+ if (input.events[index]?.type === "message.received") {
908
+ turnStart = index;
909
+ break;
910
+ }
911
+ }
912
+ if (turnStart < 0) return null;
913
+ return Math.max(
914
+ 0,
915
+ input.currentStreamIndex - (input.events.length - turnStart)
916
+ );
917
+ }
899
918
  function renderTurn(events) {
900
919
  let rendered = "";
901
920
  for (const event of events) {
@@ -1080,6 +1099,40 @@ var AgentSession = class {
1080
1099
  this.storeOptions
1081
1100
  );
1082
1101
  }
1102
+ async rewindBeforeLastTurn(signal) {
1103
+ const persisted = loadPersistedAgentSession(
1104
+ this.visitorSessionId,
1105
+ this.storeOptions
1106
+ );
1107
+ if (!persisted?.sessionId) return false;
1108
+ const client = this.ensureClient();
1109
+ const attached = client.sessions.attach(persisted.sessionId, {
1110
+ streamIndex: persisted.streamIndex
1111
+ });
1112
+ const snapshot = await withCapabilityRefresh(
1113
+ this.capability,
1114
+ () => attached.snapshot({ signal })
1115
+ );
1116
+ const rewindStreamIndex = streamIndexBeforeLastTurn({
1117
+ currentStreamIndex: snapshot.session.streamIndex,
1118
+ events: snapshot.events
1119
+ });
1120
+ if (rewindStreamIndex === null) return false;
1121
+ this.session = client.sessions.attach(persisted.sessionId, {
1122
+ streamIndex: rewindStreamIndex
1123
+ });
1124
+ savePersistedAgentSession(
1125
+ this.visitorSessionId,
1126
+ persisted.sessionId,
1127
+ rewindStreamIndex,
1128
+ this.storeOptions
1129
+ );
1130
+ return true;
1131
+ }
1132
+ async regenerateTurn(message, signal, handlers) {
1133
+ await this.rewindBeforeLastTurn(signal);
1134
+ return this.sendTurn(message, signal, handlers);
1135
+ }
1083
1136
  ensureClient() {
1084
1137
  const config = resolveAgentRuntimeConfig({
1085
1138
  indexId: this.indexId,
@@ -1415,6 +1468,11 @@ function createAgentClient(options) {
1415
1468
  respondOptions.signal ?? new AbortController().signal,
1416
1469
  respondOptions.handlers
1417
1470
  ),
1471
+ regenerateTurn: (message, regenerateOptions) => session.regenerateTurn(
1472
+ message,
1473
+ regenerateOptions.signal ?? new AbortController().signal,
1474
+ regenerateOptions.handlers
1475
+ ),
1418
1476
  reset: () => session.reset(),
1419
1477
  cancelActive: () => session.cancelActive(),
1420
1478
  getActiveSessionId: () => session.getActiveSessionId()
@@ -2278,6 +2336,30 @@ function bookingPresenter(kind) {
2278
2336
  }
2279
2337
  };
2280
2338
  }
2339
+ function providerErrorPresenter() {
2340
+ return {
2341
+ kind: "provider_error",
2342
+ present: ({ envelope }) => {
2343
+ const output = asRecord3(envelope.output);
2344
+ const providerError = asRecord3(output?.providerError);
2345
+ const message = safeText(providerError?.message);
2346
+ const action = safeText(providerError?.action);
2347
+ if (!message || !action) return null;
2348
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
2349
+ return {
2350
+ kind: "summary",
2351
+ status: "failed",
2352
+ title: message,
2353
+ description: action,
2354
+ ...resourceLabels.length ? {
2355
+ details: [
2356
+ { label: "Affected", value: resourceLabels.join(", ") }
2357
+ ]
2358
+ } : {}
2359
+ };
2360
+ }
2361
+ };
2362
+ }
2281
2363
  function asRecord3(value) {
2282
2364
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
2283
2365
  }
@@ -2395,6 +2477,7 @@ function fallbackTitleFromKind(kind) {
2395
2477
  return "Saved";
2396
2478
  }
2397
2479
  var builtInVisitorToolResultRegistry = [
2480
+ providerErrorPresenter(),
2398
2481
  bookingPresenter("booking_offer"),
2399
2482
  bookingPresenter("booking_confirmed"),
2400
2483
  bookingPresenter("booking_canceled"),
@@ -2444,7 +2527,7 @@ function finalizeSummaryPresentation(result, proposed) {
2444
2527
  return {
2445
2528
  id: result.callId,
2446
2529
  toolName: result.toolName,
2447
- status: result.status,
2530
+ status: proposed.status ?? result.status,
2448
2531
  kind: "summary",
2449
2532
  title,
2450
2533
  ...description && description !== title ? { description } : {},
@@ -2453,7 +2536,7 @@ function finalizeSummaryPresentation(result, proposed) {
2453
2536
  };
2454
2537
  }
2455
2538
  function presentVisitorToolResult(result, registry = []) {
2456
- const envelope = parseAgentToolResultEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
2539
+ const envelope = parseAgentToolResultEnvelope(result.output) ?? providerErrorEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
2457
2540
  const proposed = envelope ? resolvePresenterOutput(result, envelope, registry) : null;
2458
2541
  if (proposed?.kind === "booking") {
2459
2542
  return {
@@ -2516,6 +2599,25 @@ function presentVisitorToolResult(result, registry = []) {
2516
2599
  }
2517
2600
  return finalizeSummaryPresentation(result, proposed);
2518
2601
  }
2602
+ function providerErrorEnvelope(output) {
2603
+ const record = asRecord3(output);
2604
+ const providerError = asRecord3(record?.providerError);
2605
+ const message = safeText(providerError?.message);
2606
+ const action = safeText(providerError?.action);
2607
+ if (!message || !action) return null;
2608
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
2609
+ return {
2610
+ schemaVersion: "webless.tool-result.v1",
2611
+ output: {
2612
+ providerError: {
2613
+ action,
2614
+ message,
2615
+ ...resourceLabels.length ? { resourceLabels } : {}
2616
+ }
2617
+ },
2618
+ presentationKinds: ["provider_error"]
2619
+ };
2620
+ }
2519
2621
  function legacyBookingEnvelope(output) {
2520
2622
  const card = bookingCardFromActionOutput(output);
2521
2623
  return card ? {
@@ -2813,6 +2915,7 @@ function useAgentChat({
2813
2915
  const {
2814
2916
  controller,
2815
2917
  initialText = "",
2918
+ regenerate: regenerate2 = false,
2816
2919
  responses,
2817
2920
  resume,
2818
2921
  visitorText
@@ -2823,6 +2926,7 @@ function useAgentChat({
2823
2926
  let streamStarted = Boolean(initialText);
2824
2927
  let streamed = initialText;
2825
2928
  const capturedOffers = [];
2929
+ let bookingConfirmed = false;
2826
2930
  let capturedInputCount = 0;
2827
2931
  const handlers = {
2828
2932
  onWork: (item) => {
@@ -2847,6 +2951,7 @@ function useAgentChat({
2847
2951
  }
2848
2952
  if (!isActiveRun()) return;
2849
2953
  if (card.type === "booking_confirmed") {
2954
+ bookingConfirmed = true;
2850
2955
  pendingBookingRef.current = card;
2851
2956
  savePendingWidgetBooking(
2852
2957
  resolvedStorageKeyPrefix,
@@ -2922,7 +3027,13 @@ function useAgentChat({
2922
3027
  initialText,
2923
3028
  message: visitorText,
2924
3029
  signal
2925
- }) : await clientRef.current.sendTurn(visitorText, { handlers, signal });
3030
+ }) : regenerate2 ? await clientRef.current.regenerateTurn(visitorText, {
3031
+ handlers,
3032
+ signal
3033
+ }) : await clientRef.current.sendTurn(visitorText, {
3034
+ handlers,
3035
+ signal
3036
+ });
2926
3037
  if (resume && finalText === null) {
2927
3038
  finalText = await clientRef.current.sendTurn(visitorText, {
2928
3039
  handlers,
@@ -2941,6 +3052,7 @@ function useAgentChat({
2941
3052
  const parsedCards = extractToolCards(displayText);
2942
3053
  for (const card of parsedCards) {
2943
3054
  if (card.type === "booking_confirmed") {
3055
+ bookingConfirmed = true;
2944
3056
  pendingBookingRef.current = card;
2945
3057
  savePendingWidgetBooking(resolvedStorageKeyPrefix, visitorId, card);
2946
3058
  }
@@ -2955,7 +3067,7 @@ function useAgentChat({
2955
3067
  messages: appendAgentTurnMessage(prev.messages, displayText),
2956
3068
  toolSteps: completeActivePlanning(prev.toolSteps),
2957
3069
  streamingText: "",
2958
- pendingOffer: capturedOffers.at(-1) ?? prev.pendingOffer,
3070
+ pendingOffer: bookingConfirmed ? null : capturedOffers.at(-1) ?? prev.pendingOffer,
2959
3071
  pendingInputs: (prev.pendingInputs ?? []).filter(
2960
3072
  isChatCollectibleInputRequest
2961
3073
  ),
@@ -2981,7 +3093,6 @@ function useAgentChat({
2981
3093
  } : step
2982
3094
  ),
2983
3095
  streamingText: "",
2984
- pendingOffer: null,
2985
3096
  error: message
2986
3097
  }));
2987
3098
  runRef.current = null;
@@ -3089,7 +3200,7 @@ ${outgoing}` : outgoing;
3089
3200
  journey: null,
3090
3201
  followUps: [],
3091
3202
  streamingText: "",
3092
- pendingOffer: null,
3203
+ pendingOffer: options?.preservePendingOffer ? prev.pendingOffer : null,
3093
3204
  pendingInputs: [],
3094
3205
  toolResults: [],
3095
3206
  error: null
@@ -3125,7 +3236,6 @@ ${outgoing}` : outgoing;
3125
3236
  journey: null,
3126
3237
  followUps: [],
3127
3238
  streamingText: "",
3128
- pendingOffer: null,
3129
3239
  pendingInputs: [],
3130
3240
  toolResults: [],
3131
3241
  error: null
@@ -3136,6 +3246,49 @@ ${outgoing}` : outgoing;
3136
3246
  visitorText: visitorTurnText(visitorMessage)
3137
3247
  });
3138
3248
  }, [runTurn, state.messages]);
3249
+ const regenerate = (0, import_react2.useCallback)(async () => {
3250
+ let lastVisitorIndex = -1;
3251
+ for (let index = state.messages.length - 1; index >= 0; index -= 1) {
3252
+ if (state.messages[index]?.role === "visitor") {
3253
+ lastVisitorIndex = index;
3254
+ break;
3255
+ }
3256
+ }
3257
+ const visitorMessage = lastVisitorIndex >= 0 ? state.messages[lastVisitorIndex] : void 0;
3258
+ if (!visitorMessage) return null;
3259
+ if (runRef.current) {
3260
+ runRef.current.abort();
3261
+ clientRef.current.cancelActive();
3262
+ }
3263
+ const controller = new AbortController();
3264
+ runRef.current = controller;
3265
+ setState((prev) => ({
3266
+ ...prev,
3267
+ phase: "thinking",
3268
+ messages: prev.messages.slice(0, lastVisitorIndex + 1),
3269
+ toolSteps: [
3270
+ {
3271
+ id: "planning",
3272
+ kind: "planning",
3273
+ label: "Understanding your question",
3274
+ state: "active"
3275
+ }
3276
+ ],
3277
+ journey: null,
3278
+ followUps: [],
3279
+ streamingText: "",
3280
+ pendingOffer: null,
3281
+ pendingInputs: [],
3282
+ toolResults: [],
3283
+ error: null
3284
+ }));
3285
+ return await runTurn({
3286
+ controller,
3287
+ regenerate: true,
3288
+ resume: false,
3289
+ visitorText: visitorTurnText(visitorMessage)
3290
+ });
3291
+ }, [runTurn, state.messages]);
3139
3292
  const respondToToolInput = (0, import_react2.useCallback)(
3140
3293
  async (surface, values) => {
3141
3294
  await submit(`${surface.title} submitted`, {
@@ -3212,6 +3365,7 @@ ${outgoing}` : outgoing;
3212
3365
  state,
3213
3366
  reset,
3214
3367
  retry,
3368
+ regenerate,
3215
3369
  respondToInput,
3216
3370
  respondToToolInput,
3217
3371
  submit,
@@ -3278,7 +3432,7 @@ function unregisterAgentPanelController(customerId) {
3278
3432
  }
3279
3433
 
3280
3434
  // src/react/components/AgentRail/AgentRail.tsx
3281
- var import_react11 = require("react");
3435
+ var import_react14 = require("react");
3282
3436
 
3283
3437
  // src/react/types/conversation.ts
3284
3438
  var defaultAgentRailTheme = {
@@ -3400,6 +3554,60 @@ function stepDetail(step, steps) {
3400
3554
  return "Searched this site";
3401
3555
  return step.detail;
3402
3556
  }
3557
+ function AgentWorkSteps({
3558
+ brandLabel = "",
3559
+ onRetryStep,
3560
+ steps
3561
+ }) {
3562
+ const delegationCount = steps.filter(
3563
+ (step) => step.kind === "specialist"
3564
+ ).length;
3565
+ const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3566
+ const visibleSteps = steps.filter(
3567
+ (step) => step.kind !== "planning" || Boolean(brandLabel)
3568
+ );
3569
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3570
+ const detail = stepDetail(step, steps);
3571
+ const child = delegated && step.kind === "specialist";
3572
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3573
+ "li",
3574
+ {
3575
+ className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3576
+ "data-kind": step.kind,
3577
+ "data-state": step.state,
3578
+ children: [
3579
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3580
+ "span",
3581
+ {
3582
+ className: "agent-activity-bubble__step-icon",
3583
+ "aria-hidden": "true"
3584
+ }
3585
+ ),
3586
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3587
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
3588
+ detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3589
+ delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3590
+ "Delegated ",
3591
+ delegationCount,
3592
+ " ",
3593
+ delegationCount === 1 ? "task" : "tasks"
3594
+ ] }) : null,
3595
+ step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3596
+ "button",
3597
+ {
3598
+ type: "button",
3599
+ className: "agent-activity-bubble__step-retry",
3600
+ onClick: () => onRetryStep(step),
3601
+ children: "Retry"
3602
+ }
3603
+ ) : null
3604
+ ] })
3605
+ ]
3606
+ },
3607
+ step.id
3608
+ );
3609
+ }) });
3610
+ }
3403
3611
  function AgentActivityBubble({
3404
3612
  brandLabel = "",
3405
3613
  failed = false,
@@ -3411,14 +3619,7 @@ function AgentActivityBubble({
3411
3619
  const [expandedReceiptId, setExpandedReceiptId] = (0, import_react5.useState)(
3412
3620
  null
3413
3621
  );
3414
- const detailsOpen = active || expandedReceiptId === receiptId;
3415
- const delegationCount = steps.filter(
3416
- (step) => step.kind === "specialist"
3417
- ).length;
3418
- const delegated = delegationCount > 0 && steps.some((step) => step.kind === "planning");
3419
- const visibleSteps = steps.filter(
3420
- (step) => step.kind !== "planning" || Boolean(brandLabel)
3421
- );
3622
+ const detailsOpen = !active && expandedReceiptId === receiptId;
3422
3623
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
3423
3624
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
3424
3625
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -3428,9 +3629,10 @@ function AgentActivityBubble({
3428
3629
  "aria-hidden": "true"
3429
3630
  }
3430
3631
  ),
3431
- workSummary(steps, failed, brandLabel)
3632
+ workSummary(steps, failed, brandLabel),
3633
+ active ? "\u2026" : ""
3432
3634
  ] }),
3433
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3635
+ !active ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-activity-bubble__details", children: [
3434
3636
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3435
3637
  "button",
3436
3638
  {
@@ -3438,7 +3640,6 @@ function AgentActivityBubble({
3438
3640
  className: "agent-activity-bubble__summary",
3439
3641
  "aria-expanded": detailsOpen,
3440
3642
  onClick: () => {
3441
- if (active) return;
3442
3643
  setExpandedReceiptId(
3443
3644
  (current) => current === receiptId ? null : receiptId
3444
3645
  );
@@ -3446,56 +3647,145 @@ function AgentActivityBubble({
3446
3647
  children: "How this answer was made"
3447
3648
  }
3448
3649
  ),
3449
- detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "agent-activity-bubble__steps", children: visibleSteps.map((step) => {
3450
- const detail = stepDetail(step, steps);
3451
- const child = delegated && step.kind === "specialist";
3452
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3453
- "li",
3454
- {
3455
- className: `agent-activity-bubble__step${child ? " agent-activity-bubble__step--child" : ""}`,
3456
- "data-kind": step.kind,
3457
- "data-state": step.state,
3458
- children: [
3459
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3460
- "span",
3461
- {
3462
- className: "agent-activity-bubble__step-icon",
3463
- "aria-hidden": "true"
3464
- }
3465
- ),
3466
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__step-copy", children: [
3467
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-heading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: stepLabel(step, brandLabel) }) }),
3468
- detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-activity-bubble__step-detail", children: detail }) : null,
3469
- delegated && step.kind === "planning" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "agent-activity-bubble__delegation", children: [
3470
- "Delegated ",
3471
- delegationCount,
3472
- " ",
3473
- delegationCount === 1 ? "task" : "tasks"
3474
- ] }) : null,
3475
- step.state === "error" && onRetryStep ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3476
- "button",
3477
- {
3478
- type: "button",
3479
- className: "agent-activity-bubble__step-retry",
3480
- onClick: () => onRetryStep(step),
3481
- children: "Retry"
3482
- }
3483
- ) : null
3484
- ] })
3485
- ]
3486
- },
3487
- step.id
3488
- );
3489
- }) }) : null
3490
- ] })
3650
+ detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3651
+ AgentWorkSteps,
3652
+ {
3653
+ brandLabel,
3654
+ onRetryStep,
3655
+ steps
3656
+ }
3657
+ ) : null
3658
+ ] }) : null
3491
3659
  ] });
3492
3660
  }
3493
3661
 
3494
- // src/react/components/Composer/Composer.tsx
3662
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3663
+ var import_react7 = require("react");
3664
+ var import_react_dom = require("react-dom");
3665
+
3666
+ // src/react/components/AgentRail/AgentRailOverlayContext.tsx
3495
3667
  var import_react6 = require("react");
3668
+ var AgentRailOverlayContext = (0, import_react6.createContext)(null);
3669
+ function useAgentRailPortalRoots() {
3670
+ return (0, import_react6.useContext)(AgentRailOverlayContext);
3671
+ }
3672
+ function useAgentRailMenuPortalRoot() {
3673
+ return (0, import_react6.useContext)(AgentRailOverlayContext)?.railRef ?? null;
3674
+ }
3675
+
3676
+ // src/react/components/AnswerReceiptDialog/AnswerReceiptDialog.tsx
3496
3677
  var import_jsx_runtime2 = require("react/jsx-runtime");
3497
- function SendIcon() {
3678
+ var FOCUSABLE_SELECTOR = 'button:not(:disabled), a[href], textarea:not(:disabled), input:not(:disabled), [tabindex]:not([tabindex="-1"])';
3679
+ function CloseIcon() {
3498
3680
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3681
+ "path",
3682
+ {
3683
+ d: "M4 4l8 8M12 4l-8 8",
3684
+ stroke: "currentColor",
3685
+ strokeWidth: "1.5",
3686
+ strokeLinecap: "round"
3687
+ }
3688
+ ) });
3689
+ }
3690
+ function AnswerReceiptDialog({
3691
+ brandLabel = "",
3692
+ onClose,
3693
+ steps
3694
+ }) {
3695
+ const portalRoots = useAgentRailPortalRoots();
3696
+ const overlayRoot = portalRoots?.overlayRef ?? null;
3697
+ const cardRef = (0, import_react7.useRef)(null);
3698
+ const closeButtonRef = (0, import_react7.useRef)(null);
3699
+ const previouslyFocusedRef = (0, import_react7.useRef)(null);
3700
+ (0, import_react7.useEffect)(() => {
3701
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
3702
+ closeButtonRef.current?.focus({ preventScroll: true });
3703
+ const handleKeyDown = (event) => {
3704
+ if (event.key === "Escape") {
3705
+ event.preventDefault();
3706
+ event.stopPropagation();
3707
+ onClose();
3708
+ return;
3709
+ }
3710
+ if (event.key !== "Tab" || !cardRef.current) return;
3711
+ const focusable = cardRef.current.querySelectorAll(
3712
+ FOCUSABLE_SELECTOR
3713
+ );
3714
+ if (focusable.length === 0) return;
3715
+ const first = focusable.item(0);
3716
+ const last = focusable.item(focusable.length - 1);
3717
+ if (event.shiftKey && document.activeElement === first) {
3718
+ event.preventDefault();
3719
+ last.focus({ preventScroll: true });
3720
+ } else if (!event.shiftKey && document.activeElement === last) {
3721
+ event.preventDefault();
3722
+ first.focus({ preventScroll: true });
3723
+ }
3724
+ };
3725
+ document.addEventListener("keydown", handleKeyDown);
3726
+ return () => {
3727
+ document.removeEventListener("keydown", handleKeyDown);
3728
+ previouslyFocusedRef.current?.focus({ preventScroll: true });
3729
+ };
3730
+ }, [onClose]);
3731
+ const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog", children: [
3732
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3733
+ "button",
3734
+ {
3735
+ type: "button",
3736
+ className: "agent-receipt-dialog__backdrop",
3737
+ "aria-label": "Close",
3738
+ tabIndex: -1,
3739
+ onClick: onClose
3740
+ }
3741
+ ),
3742
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3743
+ "div",
3744
+ {
3745
+ ref: cardRef,
3746
+ className: "agent-receipt-dialog__card",
3747
+ role: "dialog",
3748
+ "aria-modal": "true",
3749
+ "aria-labelledby": "agent-receipt-dialog-title",
3750
+ children: [
3751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "agent-receipt-dialog__header", children: [
3752
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3753
+ "p",
3754
+ {
3755
+ className: "agent-receipt-dialog__title",
3756
+ id: "agent-receipt-dialog-title",
3757
+ children: "How this answer was made"
3758
+ }
3759
+ ),
3760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3761
+ "button",
3762
+ {
3763
+ ref: closeButtonRef,
3764
+ type: "button",
3765
+ className: "agent-receipt-dialog__close",
3766
+ "aria-label": "Close",
3767
+ onClick: onClose,
3768
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
3769
+ }
3770
+ )
3771
+ ] }),
3772
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "agent-receipt-dialog__summary", children: workSummary(steps, false, brandLabel) }),
3773
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-receipt-dialog__body", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AgentWorkSteps, { brandLabel, steps }) })
3774
+ ]
3775
+ }
3776
+ )
3777
+ ] });
3778
+ if (overlayRoot?.current) {
3779
+ return (0, import_react_dom.createPortal)(content, overlayRoot.current);
3780
+ }
3781
+ return content;
3782
+ }
3783
+
3784
+ // src/react/components/Composer/Composer.tsx
3785
+ var import_react8 = require("react");
3786
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3787
+ function SendIcon() {
3788
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3499
3789
  "path",
3500
3790
  {
3501
3791
  d: "M8 12V4M8 4l-3 3M8 4l3 3",
@@ -3518,21 +3808,21 @@ function Composer({
3518
3808
  form = null,
3519
3809
  onSubmit
3520
3810
  }) {
3521
- const [value, setValue] = (0, import_react6.useState)("");
3522
- const [values, setValues] = (0, import_react6.useState)(
3811
+ const [value, setValue] = (0, import_react8.useState)("");
3812
+ const [values, setValues] = (0, import_react8.useState)(
3523
3813
  () => emptyValues(form)
3524
3814
  );
3525
- const [blurred, setBlurred] = (0, import_react6.useState)({});
3526
- const inputRef = (0, import_react6.useRef)(null);
3527
- const firstFieldRef = (0, import_react6.useRef)(null);
3528
- const formId = (0, import_react6.useId)();
3815
+ const [blurred, setBlurred] = (0, import_react8.useState)({});
3816
+ const inputRef = (0, import_react8.useRef)(null);
3817
+ const firstFieldRef = (0, import_react8.useRef)(null);
3818
+ const formId = (0, import_react8.useId)();
3529
3819
  const activeForm = form;
3530
3820
  const canSendForm = activeForm ? isComposerFormComplete(activeForm, values) : Boolean(value.trim());
3531
- (0, import_react6.useEffect)(() => {
3821
+ (0, import_react8.useEffect)(() => {
3532
3822
  setValues(emptyValues(form));
3533
3823
  setBlurred({});
3534
3824
  }, [form?.id]);
3535
- (0, import_react6.useEffect)(() => {
3825
+ (0, import_react8.useEffect)(() => {
3536
3826
  if (activeForm) firstFieldRef.current?.focus();
3537
3827
  }, [activeForm?.id]);
3538
3828
  function submitChat() {
@@ -3567,7 +3857,7 @@ function Composer({
3567
3857
  submitForm();
3568
3858
  }
3569
3859
  }
3570
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3860
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3571
3861
  "form",
3572
3862
  {
3573
3863
  className: [
@@ -3576,7 +3866,7 @@ function Composer({
3576
3866
  activeForm ? "composer--form" : ""
3577
3867
  ].filter(Boolean).join(" "),
3578
3868
  onSubmit: handleSubmit,
3579
- children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3869
+ children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__sheet", role: "group", "aria-label": "Required details", children: [
3580
3870
  activeForm.fields.map((field, index) => {
3581
3871
  const fieldId = `${formId}-${field.id}`;
3582
3872
  const invalid = Boolean(blurred[field.id]) && !isValidComposerFieldValue(field, values[field.id] ?? "");
@@ -3601,7 +3891,7 @@ function Composer({
3601
3891
  },
3602
3892
  onKeyDown: handleFormKeyDown
3603
3893
  };
3604
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
3894
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3605
3895
  "div",
3606
3896
  {
3607
3897
  className: [
@@ -3609,9 +3899,9 @@ function Composer({
3609
3899
  field.kind === "textarea" ? "composer__row--grow" : ""
3610
3900
  ].filter(Boolean).join(" "),
3611
3901
  children: [
3612
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3613
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "composer__sr-only", children: field.label }),
3614
- field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3902
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
3903
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "composer__sr-only", children: field.label }),
3904
+ field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3615
3905
  "textarea",
3616
3906
  {
3617
3907
  ...controlProps,
@@ -3621,7 +3911,7 @@ function Composer({
3621
3911
  className: "composer__control composer__control--area",
3622
3912
  rows: 3
3623
3913
  }
3624
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3914
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3625
3915
  "input",
3626
3916
  {
3627
3917
  ...controlProps,
@@ -3634,24 +3924,24 @@ function Composer({
3634
3924
  }
3635
3925
  )
3636
3926
  ] }),
3637
- invalid ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to continue." : `Add your ${field.label.toLowerCase()} to continue.` }) : null
3927
+ invalid ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to continue." : `Add your ${field.label.toLowerCase()} to continue.` }) : null
3638
3928
  ]
3639
3929
  },
3640
3930
  field.id
3641
3931
  );
3642
3932
  }),
3643
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3933
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3644
3934
  "button",
3645
3935
  {
3646
3936
  type: "submit",
3647
3937
  className: "composer__send",
3648
3938
  disabled: disabled || !canSendForm,
3649
3939
  "aria-label": "Send details",
3650
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3940
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3651
3941
  }
3652
3942
  ) })
3653
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "composer__field", children: [
3654
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3943
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
3944
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3655
3945
  "textarea",
3656
3946
  {
3657
3947
  ref: inputRef,
@@ -3666,14 +3956,14 @@ function Composer({
3666
3956
  onKeyDown: handleChatKeyDown
3667
3957
  }
3668
3958
  ),
3669
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3959
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3670
3960
  "button",
3671
3961
  {
3672
3962
  type: "submit",
3673
3963
  className: "composer__send",
3674
3964
  disabled: disabled || !value.trim(),
3675
3965
  "aria-label": "Send message",
3676
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
3966
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
3677
3967
  }
3678
3968
  )
3679
3969
  ] })
@@ -3682,7 +3972,7 @@ function Composer({
3682
3972
  }
3683
3973
 
3684
3974
  // src/react/components/FollowUpChips/FollowUpChips.tsx
3685
- var import_jsx_runtime3 = require("react/jsx-runtime");
3975
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3686
3976
  function FollowUpChips({
3687
3977
  suggestions,
3688
3978
  disabled = false,
@@ -3692,7 +3982,7 @@ function FollowUpChips({
3692
3982
  }) {
3693
3983
  if (suggestions.length === 0) return null;
3694
3984
  if (variant === "dock") {
3695
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3985
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3696
3986
  "button",
3697
3987
  {
3698
3988
  type: "button",
@@ -3704,9 +3994,9 @@ function FollowUpChips({
3704
3994
  suggestion.id
3705
3995
  )) }) });
3706
3996
  }
3707
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "followups", children: [
3708
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "followups__label", children: label }),
3709
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3997
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
3998
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
3999
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3710
4000
  "button",
3711
4001
  {
3712
4002
  type: "button",
@@ -3721,11 +4011,11 @@ function FollowUpChips({
3721
4011
  }
3722
4012
 
3723
4013
  // src/react/components/MessageBubble/MessageBubble.tsx
3724
- var import_react8 = require("react");
4014
+ var import_react10 = require("react");
3725
4015
 
3726
4016
  // src/react/components/BookingCard/BookingCard.tsx
3727
- var import_react7 = require("react");
3728
- var import_jsx_runtime4 = require("react/jsx-runtime");
4017
+ var import_react9 = require("react");
4018
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3729
4019
  var BOOKING_STEPS = [
3730
4020
  { id: "date", label: "Date" },
3731
4021
  { id: "time", label: "Time" },
@@ -3756,33 +4046,34 @@ function calendarCells(year, month) {
3756
4046
  return cells;
3757
4047
  }
3758
4048
  function BookingCardLoader() {
3759
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
4049
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
3760
4050
  }
3761
4051
  function BookingCard({
4052
+ disabled = false,
3762
4053
  offer,
3763
4054
  onBook
3764
4055
  }) {
3765
- const fieldId = (0, import_react7.useId)();
4056
+ const fieldId = (0, import_react9.useId)();
3766
4057
  const defaultType = offer.eventTypes[0]?.uri ?? offer.slots[0]?.eventTypeUri ?? "";
3767
- const [step, setStep] = (0, import_react7.useState)("date");
3768
- const [eventTypeUri, setEventTypeUri] = (0, import_react7.useState)(defaultType);
3769
- const [selectedDate, setSelectedDate] = (0, import_react7.useState)("");
3770
- const [startTime, setStartTime] = (0, import_react7.useState)("");
3771
- const [name, setName] = (0, import_react7.useState)("");
3772
- const [email, setEmail] = (0, import_react7.useState)("");
3773
- const activeStepRef = (0, import_react7.useRef)(null);
3774
- const previousStepRef = (0, import_react7.useRef)(step);
4058
+ const [step, setStep] = (0, import_react9.useState)("date");
4059
+ const [eventTypeUri, setEventTypeUri] = (0, import_react9.useState)(defaultType);
4060
+ const [selectedDate, setSelectedDate] = (0, import_react9.useState)("");
4061
+ const [startTime, setStartTime] = (0, import_react9.useState)("");
4062
+ const [name, setName] = (0, import_react9.useState)("");
4063
+ const [email, setEmail] = (0, import_react9.useState)("");
4064
+ const activeStepRef = (0, import_react9.useRef)(null);
4065
+ const previousStepRef = (0, import_react9.useRef)(step);
3775
4066
  const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
3776
- (0, import_react7.useEffect)(() => {
4067
+ (0, import_react9.useEffect)(() => {
3777
4068
  if (previousStepRef.current === step) return;
3778
4069
  previousStepRef.current = step;
3779
4070
  activeStepRef.current?.scrollIntoView({ block: "nearest" });
3780
4071
  }, [step]);
3781
- const slots = (0, import_react7.useMemo)(
4072
+ const slots = (0, import_react9.useMemo)(
3782
4073
  () => bookingSlotsForEventType(offer.slots, eventTypeUri),
3783
4074
  [eventTypeUri, offer.slots]
3784
4075
  );
3785
- const availableByDate = (0, import_react7.useMemo)(() => {
4076
+ const availableByDate = (0, import_react9.useMemo)(() => {
3786
4077
  const next = /* @__PURE__ */ new Map();
3787
4078
  for (const slot of slots) {
3788
4079
  const key = slotDateKey(slot.startTime);
@@ -3790,7 +4081,7 @@ function BookingCard({
3790
4081
  }
3791
4082
  return next;
3792
4083
  }, [slots]);
3793
- const [visibleMonth, setVisibleMonth] = (0, import_react7.useState)(
4084
+ const [visibleMonth, setVisibleMonth] = (0, import_react9.useState)(
3794
4085
  () => firstAvailableBookingMonth(slots)
3795
4086
  );
3796
4087
  function selectEventType(nextType) {
@@ -3803,7 +4094,7 @@ function BookingCard({
3803
4094
  )
3804
4095
  );
3805
4096
  }
3806
- const daySlots = (0, import_react7.useMemo)(
4097
+ const daySlots = (0, import_react9.useMemo)(
3807
4098
  () => slots.filter((slot) => slotDateKey(slot.startTime) === selectedDate),
3808
4099
  [selectedDate, slots]
3809
4100
  );
@@ -3812,7 +4103,7 @@ function BookingCard({
3812
4103
  );
3813
4104
  const selectedSample = availableByDate.get(selectedDate) ?? startTime;
3814
4105
  const timeZone = formatSlotTimeZone(slots[0]?.startTime ?? selectedSample);
3815
- const weekdays = (0, import_react7.useMemo)(() => weekdayLabels(), []);
4106
+ const weekdays = (0, import_react9.useMemo)(() => weekdayLabels(), []);
3816
4107
  const cells = calendarCells(visibleMonth.year, visibleMonth.month);
3817
4108
  const canPrevMonth = [...availableByDate.keys()].some((key) => {
3818
4109
  const month = monthFromKey(key);
@@ -3854,222 +4145,236 @@ function BookingCard({
3854
4145
  })
3855
4146
  });
3856
4147
  }
3857
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3858
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3859
- "li",
3860
- {
3861
- className: [
3862
- "booking-card__step-indicator",
3863
- index === stepIndex ? "booking-card__step-indicator--active" : "",
3864
- index < stepIndex ? "booking-card__step-indicator--complete" : ""
3865
- ].filter(Boolean).join(" "),
3866
- "aria-current": index === stepIndex ? "step" : void 0,
3867
- children: [
3868
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
3869
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: item.label })
3870
- ]
3871
- },
3872
- item.id
3873
- )) }),
3874
- step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
3875
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3876
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
3877
- "Times in ",
3878
- timeZone
3879
- ] }) : null,
3880
- offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3881
- "label",
3882
- {
3883
- className: "booking-card__field",
3884
- htmlFor: `${fieldId}-type`,
3885
- children: [
3886
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Meeting" }),
3887
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3888
- "select",
3889
- {
3890
- id: `${fieldId}-type`,
3891
- value: eventTypeUri,
3892
- onChange: (event) => selectEventType(event.target.value),
3893
- children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: item.uri, children: item.name }, item.uri))
3894
- }
3895
- )
3896
- ]
3897
- }
3898
- ) : null,
3899
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__month", children: [
3900
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3901
- "button",
3902
- {
3903
- type: "button",
3904
- className: "booking-card__nav",
3905
- "aria-label": "Previous month",
3906
- disabled: !canPrevMonth,
3907
- onClick: () => goToMonth(-1),
3908
- children: "\u2039"
3909
- }
3910
- ),
3911
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3912
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3913
- "button",
4148
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4149
+ "section",
4150
+ {
4151
+ className: "booking-card",
4152
+ "aria-busy": disabled || void 0,
4153
+ "aria-label": "Book a meeting",
4154
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
4155
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4156
+ "li",
3914
4157
  {
3915
- type: "button",
3916
- className: "booking-card__nav",
3917
- "aria-label": "Next month",
3918
- disabled: !canNextMonth,
3919
- onClick: () => goToMonth(1),
3920
- children: "\u203A"
3921
- }
3922
- )
3923
- ] }),
3924
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: label }, label)) }),
3925
- offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3926
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3927
- "div",
3928
- {
3929
- className: "booking-card__calendar",
3930
- role: "grid",
3931
- "aria-label": "Available dates",
3932
- children: cells.map((cell, index) => {
3933
- if (!cell) {
3934
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3935
- "span",
3936
- {
3937
- className: "booking-card__day"
3938
- },
3939
- `empty-${index}`
3940
- );
4158
+ className: [
4159
+ "booking-card__step-indicator",
4160
+ index === stepIndex ? "booking-card__step-indicator--active" : "",
4161
+ index < stepIndex ? "booking-card__step-indicator--complete" : ""
4162
+ ].filter(Boolean).join(" "),
4163
+ "aria-current": index === stepIndex ? "step" : void 0,
4164
+ children: [
4165
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: index + 1 }),
4166
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: item.label })
4167
+ ]
4168
+ },
4169
+ item.id
4170
+ )) }),
4171
+ step === "date" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4172
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
4173
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
4174
+ "Times in ",
4175
+ timeZone
4176
+ ] }) : null,
4177
+ offer.eventTypes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4178
+ "label",
4179
+ {
4180
+ className: "booking-card__field",
4181
+ htmlFor: `${fieldId}-type`,
4182
+ children: [
4183
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Meeting" }),
4184
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4185
+ "select",
4186
+ {
4187
+ id: `${fieldId}-type`,
4188
+ value: eventTypeUri,
4189
+ disabled,
4190
+ onChange: (event) => selectEventType(event.target.value),
4191
+ children: offer.eventTypes.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: item.uri, children: item.name }, item.uri))
4192
+ }
4193
+ )
4194
+ ]
3941
4195
  }
3942
- const available = availableByDate.has(cell.key);
3943
- const selected = cell.key === selectedDate;
3944
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4196
+ ) : null,
4197
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__month", children: [
4198
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3945
4199
  "button",
3946
4200
  {
3947
4201
  type: "button",
3948
- className: [
3949
- "booking-card__day",
3950
- available ? "booking-card__day--available" : "",
3951
- selected ? "booking-card__day--selected" : ""
3952
- ].filter(Boolean).join(" "),
3953
- disabled: !available,
3954
- "aria-pressed": selected,
3955
- onClick: () => selectDate(cell.key),
3956
- children: cell.day
3957
- },
3958
- cell.key
3959
- );
3960
- })
3961
- }
3962
- )
3963
- ] }, "date") : null,
3964
- step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
3965
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
3966
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3967
- "button",
3968
- {
3969
- type: "button",
3970
- className: "booking-card__nav",
3971
- "aria-label": "Back to dates",
3972
- onClick: () => setStep("date"),
3973
- children: "\u2039"
3974
- }
3975
- ),
3976
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
3977
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
3978
- timeZone ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "booking-card__tz", children: [
3979
- "Times in ",
3980
- timeZone
3981
- ] }) : null
3982
- ] })
3983
- ] }),
3984
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3985
- "button",
3986
- {
3987
- type: "button",
3988
- className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
3989
- onClick: () => selectTime(slot.startTime),
3990
- children: formatTimeChip(slot.startTime)
3991
- },
3992
- slot.startTime
3993
- )) })
3994
- ] }, "time") : null,
3995
- step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
3996
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__step-bar", children: [
3997
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3998
- "button",
3999
- {
4000
- type: "button",
4001
- className: "booking-card__nav",
4002
- "aria-label": "Back to times",
4003
- onClick: () => setStep("time"),
4004
- children: "\u2039"
4005
- }
4006
- ),
4007
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
4008
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4009
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4010
- selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4011
- ] })
4012
- ] }),
4013
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "booking-card__identity", children: [
4014
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4015
- "label",
4016
- {
4017
- className: "booking-card__field",
4018
- htmlFor: `${fieldId}-name`,
4019
- children: [
4020
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Name" }),
4021
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4022
- "input",
4023
- {
4024
- id: `${fieldId}-name`,
4025
- autoComplete: "name",
4026
- value: name,
4027
- onChange: (event) => setName(event.target.value),
4028
- required: true
4029
- }
4030
- )
4031
- ]
4032
- }
4033
- ),
4034
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
4035
- "label",
4036
- {
4037
- className: "booking-card__field",
4038
- htmlFor: `${fieldId}-email`,
4039
- children: [
4040
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Email" }),
4041
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4042
- "input",
4043
- {
4044
- id: `${fieldId}-email`,
4045
- type: "email",
4046
- autoComplete: "email",
4047
- value: email,
4048
- onChange: (event) => setEmail(event.target.value),
4049
- required: true
4202
+ className: "booking-card__nav",
4203
+ "aria-label": "Previous month",
4204
+ disabled: disabled || !canPrevMonth,
4205
+ onClick: () => goToMonth(-1),
4206
+ children: "\u2039"
4207
+ }
4208
+ ),
4209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
4210
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4211
+ "button",
4212
+ {
4213
+ type: "button",
4214
+ className: "booking-card__nav",
4215
+ "aria-label": "Next month",
4216
+ disabled: disabled || !canNextMonth,
4217
+ onClick: () => goToMonth(1),
4218
+ children: "\u203A"
4219
+ }
4220
+ )
4221
+ ] }),
4222
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: label }, label)) }),
4223
+ offer.slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
4224
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4225
+ "div",
4226
+ {
4227
+ className: "booking-card__calendar",
4228
+ role: "grid",
4229
+ "aria-label": "Available dates",
4230
+ children: cells.map((cell, index) => {
4231
+ if (!cell) {
4232
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4233
+ "span",
4234
+ {
4235
+ className: "booking-card__day"
4236
+ },
4237
+ `empty-${index}`
4238
+ );
4050
4239
  }
4051
- )
4052
- ]
4053
- }
4054
- )
4055
- ] }),
4056
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4057
- "button",
4058
- {
4059
- type: "submit",
4060
- className: "booking-card__submit",
4061
- disabled: !name.trim() || !email.trim(),
4062
- children: "Book this time"
4063
- }
4064
- )
4065
- ] }, "details") : null
4066
- ] }) });
4240
+ const available = availableByDate.has(cell.key);
4241
+ const selected = cell.key === selectedDate;
4242
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4243
+ "button",
4244
+ {
4245
+ type: "button",
4246
+ className: [
4247
+ "booking-card__day",
4248
+ available ? "booking-card__day--available" : "",
4249
+ selected ? "booking-card__day--selected" : ""
4250
+ ].filter(Boolean).join(" "),
4251
+ disabled: disabled || !available,
4252
+ "aria-pressed": selected,
4253
+ onClick: () => selectDate(cell.key),
4254
+ children: cell.day
4255
+ },
4256
+ cell.key
4257
+ );
4258
+ })
4259
+ }
4260
+ )
4261
+ ] }, "date") : null,
4262
+ step === "time" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4263
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4264
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4265
+ "button",
4266
+ {
4267
+ type: "button",
4268
+ className: "booking-card__nav",
4269
+ "aria-label": "Back to dates",
4270
+ disabled,
4271
+ onClick: () => setStep("date"),
4272
+ children: "\u2039"
4273
+ }
4274
+ ),
4275
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4276
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
4277
+ timeZone ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "booking-card__tz", children: [
4278
+ "Times in ",
4279
+ timeZone
4280
+ ] }) : null
4281
+ ] })
4282
+ ] }),
4283
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4284
+ "button",
4285
+ {
4286
+ type: "button",
4287
+ className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
4288
+ disabled,
4289
+ onClick: () => selectTime(slot.startTime),
4290
+ children: formatTimeChip(slot.startTime)
4291
+ },
4292
+ slot.startTime
4293
+ )) })
4294
+ ] }, "time") : null,
4295
+ step === "details" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step", ref: activeStepRef, children: [
4296
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__step-bar", children: [
4297
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4298
+ "button",
4299
+ {
4300
+ type: "button",
4301
+ className: "booking-card__nav",
4302
+ "aria-label": "Back to times",
4303
+ disabled,
4304
+ onClick: () => setStep("time"),
4305
+ children: "\u2039"
4306
+ }
4307
+ ),
4308
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4309
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__title", children: "Enter details" }),
4310
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
4311
+ selectedType?.location ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "booking-card__tz", children: selectedType.location }) : null
4312
+ ] })
4313
+ ] }),
4314
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "booking-card__identity", children: [
4315
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4316
+ "label",
4317
+ {
4318
+ className: "booking-card__field",
4319
+ htmlFor: `${fieldId}-name`,
4320
+ children: [
4321
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Name" }),
4322
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4323
+ "input",
4324
+ {
4325
+ id: `${fieldId}-name`,
4326
+ autoComplete: "name",
4327
+ disabled,
4328
+ value: name,
4329
+ onChange: (event) => setName(event.target.value),
4330
+ required: true
4331
+ }
4332
+ )
4333
+ ]
4334
+ }
4335
+ ),
4336
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4337
+ "label",
4338
+ {
4339
+ className: "booking-card__field",
4340
+ htmlFor: `${fieldId}-email`,
4341
+ children: [
4342
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Email" }),
4343
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4344
+ "input",
4345
+ {
4346
+ id: `${fieldId}-email`,
4347
+ type: "email",
4348
+ autoComplete: "email",
4349
+ disabled,
4350
+ value: email,
4351
+ onChange: (event) => setEmail(event.target.value),
4352
+ required: true
4353
+ }
4354
+ )
4355
+ ]
4356
+ }
4357
+ )
4358
+ ] }),
4359
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4360
+ "button",
4361
+ {
4362
+ type: "submit",
4363
+ className: "booking-card__submit",
4364
+ disabled: disabled || !name.trim() || !email.trim(),
4365
+ children: disabled ? "Booking\u2026" : "Book this time"
4366
+ }
4367
+ )
4368
+ ] }, "details") : null
4369
+ ] })
4370
+ }
4371
+ );
4067
4372
  }
4068
4373
 
4069
4374
  // src/react/components/MessageBubble/MessageBubble.tsx
4070
4375
  var import_streamdown = require("streamdown");
4071
4376
  var import_styles = require("streamdown/styles.css");
4072
- var import_jsx_runtime5 = require("react/jsx-runtime");
4377
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4073
4378
  function normalizeDedupeText(text) {
4074
4379
  return text.trim().replace(/\s+/g, " ").toLowerCase();
4075
4380
  }
@@ -4080,9 +4385,7 @@ function paragraphsAreNearDuplicates(first, second) {
4080
4385
  if (left === right) return true;
4081
4386
  const shorter = left.length <= right.length ? left : right;
4082
4387
  const longer = left.length <= right.length ? right : left;
4083
- return longer.startsWith(
4084
- shorter.slice(0, Math.floor(shorter.length * 0.85))
4085
- );
4388
+ return longer.startsWith(shorter.slice(0, Math.floor(shorter.length * 0.85)));
4086
4389
  }
4087
4390
  function paragraphsShareOpening(first, second) {
4088
4391
  const opening = first.split("\n")[0]?.trim();
@@ -4110,11 +4413,12 @@ function collapseRepeatedText(text) {
4110
4413
  function MessageBubble({
4111
4414
  message,
4112
4415
  brandLogoUrl,
4416
+ bookingDisabled = false,
4113
4417
  offer,
4114
4418
  onBook
4115
4419
  }) {
4116
4420
  const resolvedLogoUrl = brandLogoUrl?.trim();
4117
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react8.useState)(null);
4421
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react10.useState)(null);
4118
4422
  const showBrandLogo = Boolean(resolvedLogoUrl) && failedLogoUrl !== resolvedLogoUrl;
4119
4423
  const cards = message.role === "agent" ? extractToolCards(message.text) : [];
4120
4424
  const extractedOffers = cards.filter(
@@ -4127,11 +4431,11 @@ function MessageBubble({
4127
4431
  offers.length > 0 ? sanitizeBookingOfferCopy(visibleText) : looksLikeBookingAvailabilityDump(visibleText) ? sanitizeBookingOfferCopy(visibleText) : visibleText || (isStreaming ? "" : message.text)
4128
4432
  );
4129
4433
  if (message.role === "visitor") {
4130
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "message-bubble__text", children: message.text }) });
4434
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "message-bubble__text", children: message.text }) });
4131
4435
  }
4132
4436
  const citations = message.citations ?? [];
4133
- const agentText = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__text", children: [
4134
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4437
+ const agentText = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__text", children: [
4438
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4135
4439
  import_streamdown.Streamdown,
4136
4440
  {
4137
4441
  animated: isStreaming,
@@ -4145,22 +4449,21 @@ function MessageBubble({
4145
4449
  children: displayText
4146
4450
  }
4147
4451
  ),
4148
- citations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4149
- "a",
4150
- {
4151
- href: citation.url,
4152
- target: "_blank",
4153
- rel: "noreferrer",
4154
- children: [
4155
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "message-bubble__source-icon", "aria-hidden": "true", children: "\u25A6" }),
4156
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: citation.label })
4157
- ]
4158
- }
4159
- ) }, citation.id)) }) : null
4452
+ citations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
4453
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4454
+ "span",
4455
+ {
4456
+ className: "message-bubble__source-icon",
4457
+ "aria-hidden": "true",
4458
+ children: "\u25A6"
4459
+ }
4460
+ ),
4461
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: citation.label })
4462
+ ] }) }, citation.id)) }) : null
4160
4463
  ] });
4161
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4162
- displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "message-bubble__agent-row", children: [
4163
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4464
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: "message-bubble message-bubble--agent", children: [
4465
+ displayText ? showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "message-bubble__agent-row", children: [
4466
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "message-bubble__agent-avatar", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4164
4467
  "img",
4165
4468
  {
4166
4469
  src: resolvedLogoUrl,
@@ -4172,9 +4475,10 @@ function MessageBubble({
4172
4475
  ) }),
4173
4476
  agentText
4174
4477
  ] }) : agentText : null,
4175
- offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4478
+ offers.map((nextOffer, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4176
4479
  BookingCard,
4177
4480
  {
4481
+ disabled: bookingDisabled,
4178
4482
  offer: nextOffer,
4179
4483
  onBook
4180
4484
  },
@@ -4183,11 +4487,498 @@ function MessageBubble({
4183
4487
  ] });
4184
4488
  }
4185
4489
 
4490
+ // src/react/components/MessageActions/MessageActions.tsx
4491
+ var import_react11 = require("react");
4492
+ var import_react_dom2 = require("react-dom");
4493
+
4494
+ // src/react/lib/speech.ts
4495
+ function toSpeechText(text) {
4496
+ let out = hideToolCardFences(text);
4497
+ out = out.replace(/```[\s\S]*?```/g, " ");
4498
+ out = out.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
4499
+ out = out.replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
4500
+ out = out.replace(/^\s{0,3}#{1,6}\s+/gm, "");
4501
+ out = out.replace(/(\*\*|__)(.*?)\1/g, "$2");
4502
+ out = out.replace(/(\*|_)(.*?)\1/g, "$2");
4503
+ out = out.replace(/~~(.*?)~~/g, "$1");
4504
+ out = out.replace(/`([^`]*)`/g, "$1");
4505
+ out = out.replace(/^\s*>\s?/gm, "");
4506
+ out = out.replace(/^\s*[-*+]\s+/gm, "");
4507
+ out = out.replace(/^\s*\d+\.\s+/gm, "");
4508
+ out = out.replace(/\|/g, " ");
4509
+ out = out.replace(/^\s*[-:]{3,}\s*$/gm, " ");
4510
+ out = out.replace(/\s*\n\s*/g, ". ");
4511
+ out = out.replace(/(?:\.\s*){2,}/g, ". ");
4512
+ return out.replace(/\s{2,}/g, " ").trim();
4513
+ }
4514
+ function isSpeechSupported() {
4515
+ return typeof window !== "undefined" && "speechSynthesis" in window && typeof window.SpeechSynthesisUtterance === "function";
4516
+ }
4517
+
4518
+ // src/react/components/MessageActions/MessageActions.tsx
4519
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4520
+ function CopyIcon() {
4521
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4522
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4523
+ "rect",
4524
+ {
4525
+ x: "5.75",
4526
+ y: "5.75",
4527
+ width: "7.5",
4528
+ height: "7.5",
4529
+ rx: "1.5",
4530
+ stroke: "currentColor",
4531
+ strokeWidth: "1.5"
4532
+ }
4533
+ ),
4534
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4535
+ "path",
4536
+ {
4537
+ d: "M10.25 5.25V4.5a1.75 1.75 0 0 0-1.75-1.75h-4A1.75 1.75 0 0 0 2.75 4.5v4c0 .97.78 1.75 1.75 1.75h.75",
4538
+ stroke: "currentColor",
4539
+ strokeWidth: "1.5"
4540
+ }
4541
+ )
4542
+ ] });
4543
+ }
4544
+ function CheckIcon() {
4545
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4546
+ "path",
4547
+ {
4548
+ d: "M3.5 8.5l3 3 6-7",
4549
+ stroke: "currentColor",
4550
+ strokeWidth: "1.6",
4551
+ strokeLinecap: "round",
4552
+ strokeLinejoin: "round"
4553
+ }
4554
+ ) });
4555
+ }
4556
+ function ThumbUpIcon() {
4557
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4558
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4559
+ "path",
4560
+ {
4561
+ d: "M4.67 6.67v8",
4562
+ stroke: "currentColor",
4563
+ strokeWidth: "1.5",
4564
+ strokeLinecap: "round"
4565
+ }
4566
+ ),
4567
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4568
+ "path",
4569
+ {
4570
+ d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
4571
+ stroke: "currentColor",
4572
+ strokeWidth: "1.5",
4573
+ strokeLinecap: "round",
4574
+ strokeLinejoin: "round"
4575
+ }
4576
+ )
4577
+ ] });
4578
+ }
4579
+ function ThumbDownIcon() {
4580
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("g", { transform: "rotate(180 8 8)", children: [
4581
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4582
+ "path",
4583
+ {
4584
+ d: "M4.67 6.67v8",
4585
+ stroke: "currentColor",
4586
+ strokeWidth: "1.5",
4587
+ strokeLinecap: "round"
4588
+ }
4589
+ ),
4590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4591
+ "path",
4592
+ {
4593
+ d: "M10 3.92 9.33 6.67h3.89a1.33 1.33 0 0 1 1.28 1.7l-1.55 5.33a1.33 1.33 0 0 1-1.28.97H2.67a1.33 1.33 0 0 1-1.34-1.34V8a1.33 1.33 0 0 1 1.34-1.33h1.84a1.33 1.33 0 0 0 1.19-.74L8 1.33a2.09 2.09 0 0 1 2 2.59Z",
4594
+ stroke: "currentColor",
4595
+ strokeWidth: "1.5",
4596
+ strokeLinecap: "round",
4597
+ strokeLinejoin: "round"
4598
+ }
4599
+ )
4600
+ ] }) });
4601
+ }
4602
+ function RegenerateIcon() {
4603
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4604
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4605
+ "path",
4606
+ {
4607
+ d: "M2 8a6 6 0 0 1 6-6 6.5 6.5 0 0 1 4.5 1.83L14 5.33",
4608
+ stroke: "currentColor",
4609
+ strokeWidth: "1.5",
4610
+ strokeLinecap: "round"
4611
+ }
4612
+ ),
4613
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4614
+ "path",
4615
+ {
4616
+ d: "M14 2v3.33h-3.33",
4617
+ stroke: "currentColor",
4618
+ strokeWidth: "1.5",
4619
+ strokeLinecap: "round",
4620
+ strokeLinejoin: "round"
4621
+ }
4622
+ ),
4623
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4624
+ "path",
4625
+ {
4626
+ d: "M14 8a6 6 0 0 1-6 6 6.5 6.5 0 0 1-4.5-1.83L2 10.67",
4627
+ stroke: "currentColor",
4628
+ strokeWidth: "1.5",
4629
+ strokeLinecap: "round"
4630
+ }
4631
+ ),
4632
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4633
+ "path",
4634
+ {
4635
+ d: "M5.33 10.67H2V14",
4636
+ stroke: "currentColor",
4637
+ strokeWidth: "1.5",
4638
+ strokeLinecap: "round",
4639
+ strokeLinejoin: "round"
4640
+ }
4641
+ )
4642
+ ] });
4643
+ }
4644
+ function MoreIcon() {
4645
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4646
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "3.5", cy: "8", r: "1.15", fill: "currentColor" }),
4647
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "8", cy: "8", r: "1.15", fill: "currentColor" }),
4648
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("circle", { cx: "12.5", cy: "8", r: "1.15", fill: "currentColor" })
4649
+ ] });
4650
+ }
4651
+ function SourcesIcon() {
4652
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4653
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4654
+ "path",
4655
+ {
4656
+ d: "M8 4.5C6.9 3.4 5.3 3 3.5 3c-.4 0-.8 0-1.2.1-.3 0-.5.3-.5.6v8.1c0 .4.4.7.8.6.3-.1.7-.1 1.1-.1 1.6 0 3.2.4 4.3 1.3 1.1-.9 2.7-1.3 4.3-1.3.4 0 .8 0 1.1.1.4.1.8-.2.8-.6V3.7c0-.3-.2-.6-.5-.6-.4-.1-.8-.1-1.2-.1-1.8 0-3.4.4-4.5 1.5Z",
4657
+ stroke: "currentColor",
4658
+ strokeWidth: "1.4",
4659
+ strokeLinecap: "round",
4660
+ strokeLinejoin: "round"
4661
+ }
4662
+ ),
4663
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4664
+ "path",
4665
+ {
4666
+ d: "M8 4.5v9",
4667
+ stroke: "currentColor",
4668
+ strokeWidth: "1.4",
4669
+ strokeLinecap: "round"
4670
+ }
4671
+ )
4672
+ ] });
4673
+ }
4674
+ function ReadAloudIcon() {
4675
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
4676
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4677
+ "path",
4678
+ {
4679
+ d: "M8.5 3.8 5.8 6H3.5c-.6 0-1 .4-1 1v2c0 .6.4 1 1 1h2.3l2.7 2.2c.4.3 1 0 1-.5V4.3c0-.5-.6-.8-1-.5Z",
4680
+ stroke: "currentColor",
4681
+ strokeWidth: "1.4",
4682
+ strokeLinecap: "round",
4683
+ strokeLinejoin: "round"
4684
+ }
4685
+ ),
4686
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4687
+ "path",
4688
+ {
4689
+ d: "M11 6.2c.5.5.8 1.1.8 1.8s-.3 1.3-.8 1.8M12.8 4.5c.9.8 1.4 2 1.4 3.5s-.5 2.7-1.4 3.5",
4690
+ stroke: "currentColor",
4691
+ strokeWidth: "1.4",
4692
+ strokeLinecap: "round"
4693
+ }
4694
+ )
4695
+ ] });
4696
+ }
4697
+ function StopIcon() {
4698
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4699
+ "rect",
4700
+ {
4701
+ x: "4",
4702
+ y: "4",
4703
+ width: "8",
4704
+ height: "8",
4705
+ rx: "1.5",
4706
+ stroke: "currentColor",
4707
+ strokeWidth: "1.5"
4708
+ }
4709
+ ) });
4710
+ }
4711
+ async function writeToClipboard(text) {
4712
+ try {
4713
+ await navigator.clipboard.writeText(text);
4714
+ } catch {
4715
+ const textarea = document.createElement("textarea");
4716
+ textarea.value = text;
4717
+ textarea.style.position = "fixed";
4718
+ textarea.style.opacity = "0";
4719
+ document.body.appendChild(textarea);
4720
+ textarea.select();
4721
+ document.execCommand("copy");
4722
+ textarea.remove();
4723
+ }
4724
+ }
4725
+ function formatAnsweredAt(answeredAt) {
4726
+ if (!answeredAt) return null;
4727
+ const date = new Date(answeredAt);
4728
+ if (Number.isNaN(date.getTime())) return null;
4729
+ return new Intl.DateTimeFormat(void 0, {
4730
+ dateStyle: "medium",
4731
+ timeStyle: "short"
4732
+ }).format(date);
4733
+ }
4734
+ function resolveMenuPosition(input) {
4735
+ const padding = 8;
4736
+ const { button, menuHeight, menuWidth, rail } = input;
4737
+ if (!rail) {
4738
+ return {
4739
+ left: button.left,
4740
+ top: button.top - menuHeight - 6
4741
+ };
4742
+ }
4743
+ let left = button.left - rail.left;
4744
+ let top = button.top - rail.top - menuHeight - 6;
4745
+ left = Math.min(
4746
+ Math.max(left, padding),
4747
+ rail.width - menuWidth - padding
4748
+ );
4749
+ if (top < padding) {
4750
+ top = button.bottom - rail.top + 6;
4751
+ }
4752
+ top = Math.min(top, rail.height - menuHeight - padding);
4753
+ return { left, top };
4754
+ }
4755
+ function MessageActions({
4756
+ answeredAt,
4757
+ copyText,
4758
+ disabled = false,
4759
+ onOpenReceipt,
4760
+ onRegenerate,
4761
+ onFeedback,
4762
+ readAloud = false,
4763
+ receiptSteps,
4764
+ speechText
4765
+ }) {
4766
+ const menuPortalRoot = useAgentRailMenuPortalRoot();
4767
+ const [copied, setCopied] = (0, import_react11.useState)(false);
4768
+ const [rating, setRating] = (0, import_react11.useState)(null);
4769
+ const [menuOpen, setMenuOpen] = (0, import_react11.useState)(false);
4770
+ const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
4771
+ const [speaking, setSpeaking] = (0, import_react11.useState)(false);
4772
+ const copyTimerRef = (0, import_react11.useRef)(null);
4773
+ const menuRef = (0, import_react11.useRef)(null);
4774
+ const portaledMenuRef = (0, import_react11.useRef)(null);
4775
+ const moreButtonRef = (0, import_react11.useRef)(null);
4776
+ const answeredLabel = formatAnsweredAt(answeredAt ?? 0);
4777
+ const resolvedSpeechText = speechText ?? toSpeechText(copyText);
4778
+ const canReadAloud = readAloud && isSpeechSupported() && resolvedSpeechText;
4779
+ const showMenu = Boolean(answeredLabel) || Boolean(receiptSteps) || canReadAloud;
4780
+ const canOpenReceipt = Boolean(receiptSteps) && Boolean(onOpenReceipt);
4781
+ (0, import_react11.useLayoutEffect)(() => {
4782
+ if (!menuOpen || !moreButtonRef.current || !portaledMenuRef.current) {
4783
+ setMenuPosition(null);
4784
+ return;
4785
+ }
4786
+ const button = moreButtonRef.current.getBoundingClientRect();
4787
+ const menu2 = portaledMenuRef.current;
4788
+ const rail = menuPortalRoot?.current?.getBoundingClientRect() ?? null;
4789
+ setMenuPosition(
4790
+ resolveMenuPosition({
4791
+ button,
4792
+ menuHeight: menu2.offsetHeight,
4793
+ menuWidth: menu2.offsetWidth || 190,
4794
+ rail
4795
+ })
4796
+ );
4797
+ }, [menuOpen, menuPortalRoot]);
4798
+ (0, import_react11.useEffect)(
4799
+ () => () => {
4800
+ if (copyTimerRef.current !== null) {
4801
+ window.clearTimeout(copyTimerRef.current);
4802
+ }
4803
+ if (speaking) window.speechSynthesis.cancel();
4804
+ },
4805
+ // Cancel speech only when this answer's actions unmount.
4806
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4807
+ []
4808
+ );
4809
+ (0, import_react11.useEffect)(() => {
4810
+ if (!menuOpen) return;
4811
+ const handlePointerDown = (event) => {
4812
+ const target = event.target;
4813
+ if (!menuRef.current?.contains(target) && !portaledMenuRef.current?.contains(target)) {
4814
+ setMenuOpen(false);
4815
+ }
4816
+ };
4817
+ const handleKeyDown = (event) => {
4818
+ if (event.key !== "Escape") return;
4819
+ event.preventDefault();
4820
+ event.stopPropagation();
4821
+ setMenuOpen(false);
4822
+ };
4823
+ document.addEventListener("pointerdown", handlePointerDown);
4824
+ document.addEventListener("keydown", handleKeyDown);
4825
+ return () => {
4826
+ document.removeEventListener("pointerdown", handlePointerDown);
4827
+ document.removeEventListener("keydown", handleKeyDown);
4828
+ };
4829
+ }, [menuOpen]);
4830
+ function handleCopy() {
4831
+ void writeToClipboard(copyText);
4832
+ setCopied(true);
4833
+ if (copyTimerRef.current !== null) {
4834
+ window.clearTimeout(copyTimerRef.current);
4835
+ }
4836
+ copyTimerRef.current = window.setTimeout(() => setCopied(false), 1600);
4837
+ }
4838
+ function handleFeedback(next) {
4839
+ const resolved = rating === next ? null : next;
4840
+ setRating(resolved);
4841
+ if (resolved) onFeedback?.(resolved);
4842
+ }
4843
+ function handleReadAloud() {
4844
+ if (!canReadAloud) return;
4845
+ setMenuOpen(false);
4846
+ if (speaking) {
4847
+ window.speechSynthesis.cancel();
4848
+ setSpeaking(false);
4849
+ return;
4850
+ }
4851
+ const utterance = new SpeechSynthesisUtterance(resolvedSpeechText);
4852
+ utterance.onend = () => setSpeaking(false);
4853
+ utterance.onerror = () => setSpeaking(false);
4854
+ window.speechSynthesis.cancel();
4855
+ window.speechSynthesis.speak(utterance);
4856
+ setSpeaking(true);
4857
+ }
4858
+ const menu = menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4859
+ "div",
4860
+ {
4861
+ className: "agent-message-actions__menu agent-message-actions__menu--portal",
4862
+ ref: portaledMenuRef,
4863
+ role: "menu",
4864
+ style: menuPosition ? {
4865
+ left: `${menuPosition.left}px`,
4866
+ top: `${menuPosition.top}px`
4867
+ } : { visibility: "hidden" },
4868
+ children: [
4869
+ answeredLabel ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "agent-message-actions__menu-meta", children: [
4870
+ "Answered ",
4871
+ answeredLabel
4872
+ ] }) : null,
4873
+ canOpenReceipt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4874
+ "button",
4875
+ {
4876
+ type: "button",
4877
+ className: "agent-message-actions__menu-item",
4878
+ role: "menuitem",
4879
+ onClick: () => {
4880
+ setMenuOpen(false);
4881
+ onOpenReceipt?.();
4882
+ },
4883
+ children: [
4884
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SourcesIcon, {}),
4885
+ "View sources"
4886
+ ]
4887
+ }
4888
+ ) : null,
4889
+ canReadAloud ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4890
+ "button",
4891
+ {
4892
+ type: "button",
4893
+ className: "agent-message-actions__menu-item",
4894
+ role: "menuitem",
4895
+ onClick: handleReadAloud,
4896
+ children: [
4897
+ speaking ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ReadAloudIcon, {}),
4898
+ speaking ? "Stop reading" : "Read aloud"
4899
+ ]
4900
+ }
4901
+ ) : null
4902
+ ]
4903
+ }
4904
+ ) : null;
4905
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions", "aria-label": "Answer actions", children: [
4906
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4907
+ "button",
4908
+ {
4909
+ type: "button",
4910
+ className: `agent-message-actions__button${copied ? " is-copied" : ""}`,
4911
+ "aria-label": copied ? "Copied" : "Copy answer",
4912
+ title: copied ? "Copied" : "Copy answer",
4913
+ disabled,
4914
+ onClick: handleCopy,
4915
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CheckIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyIcon, {})
4916
+ }
4917
+ ),
4918
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4919
+ "button",
4920
+ {
4921
+ type: "button",
4922
+ className: `agent-message-actions__button${rating === "positive" ? " is-active" : ""}`,
4923
+ "aria-label": "Good answer",
4924
+ "aria-pressed": rating === "positive",
4925
+ title: "Good answer",
4926
+ disabled,
4927
+ onClick: () => handleFeedback("positive"),
4928
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbUpIcon, {})
4929
+ }
4930
+ ),
4931
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4932
+ "button",
4933
+ {
4934
+ type: "button",
4935
+ className: `agent-message-actions__button${rating === "negative" ? " is-active" : ""}`,
4936
+ "aria-label": "Bad answer",
4937
+ "aria-pressed": rating === "negative",
4938
+ title: "Bad answer",
4939
+ disabled,
4940
+ onClick: () => handleFeedback("negative"),
4941
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThumbDownIcon, {})
4942
+ }
4943
+ ),
4944
+ onRegenerate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4945
+ "button",
4946
+ {
4947
+ type: "button",
4948
+ className: "agent-message-actions__button",
4949
+ "aria-label": "Regenerate answer",
4950
+ title: "Regenerate answer",
4951
+ disabled,
4952
+ onClick: onRegenerate,
4953
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RegenerateIcon, {})
4954
+ }
4955
+ ) : null,
4956
+ showMenu ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "agent-message-actions__more", ref: menuRef, children: [
4957
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4958
+ "button",
4959
+ {
4960
+ ref: moreButtonRef,
4961
+ type: "button",
4962
+ className: `agent-message-actions__button${menuOpen ? " is-menu-open" : ""}`,
4963
+ "aria-label": "More actions",
4964
+ "aria-haspopup": "menu",
4965
+ "aria-expanded": menuOpen,
4966
+ title: "More actions",
4967
+ disabled,
4968
+ onClick: () => setMenuOpen((open) => !open),
4969
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MoreIcon, {})
4970
+ }
4971
+ ),
4972
+ menuPortalRoot?.current && menu ? (0, import_react_dom2.createPortal)(menu, menuPortalRoot.current) : menu
4973
+ ] }) : null
4974
+ ] });
4975
+ }
4976
+
4186
4977
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4187
- var import_react10 = require("react");
4978
+ var import_react13 = require("react");
4188
4979
 
4189
4980
  // src/react/components/ConfirmationCard/ConfirmationCard.tsx
4190
- var import_jsx_runtime6 = require("react/jsx-runtime");
4981
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4191
4982
  function ConfirmationCard({
4192
4983
  disabled = false,
4193
4984
  request,
@@ -4196,17 +4987,17 @@ function ConfirmationCard({
4196
4987
  const options = request.options ?? [];
4197
4988
  const heading = request.kind === "tool-approval" ? "Confirm this action" : request.prompt;
4198
4989
  const prompt = request.kind === "tool-approval" ? request.prompt : void 0;
4199
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4990
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
4200
4991
  "section",
4201
4992
  {
4202
4993
  className: "confirmation-card",
4203
4994
  "aria-labelledby": `confirmation-${request.requestId}`,
4204
4995
  children: [
4205
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "confirmation-card__heading", children: [
4206
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4207
- prompt ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: prompt }) : null
4996
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "confirmation-card__heading", children: [
4997
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `confirmation-${request.requestId}`, children: heading }),
4998
+ prompt ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: prompt }) : null
4208
4999
  ] }),
4209
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5000
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "confirmation-card__actions", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4210
5001
  "button",
4211
5002
  {
4212
5003
  type: "button",
@@ -4226,8 +5017,8 @@ function ConfirmationCard({
4226
5017
  }
4227
5018
 
4228
5019
  // src/react/components/ToolInputCard/ToolInputCard.tsx
4229
- var import_react9 = require("react");
4230
- var import_jsx_runtime7 = require("react/jsx-runtime");
5020
+ var import_react12 = require("react");
5021
+ var import_jsx_runtime9 = require("react/jsx-runtime");
4231
5022
  function isRecord5(value) {
4232
5023
  return value !== null && typeof value === "object" && !Array.isArray(value);
4233
5024
  }
@@ -4351,7 +5142,7 @@ function FieldDescription({
4351
5142
  field,
4352
5143
  id
4353
5144
  }) {
4354
- return field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
5145
+ return field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id, className: "tool-input-card__description", children: field.description }) : null;
4355
5146
  }
4356
5147
  function ChoiceField({
4357
5148
  field,
@@ -4370,7 +5161,7 @@ function ChoiceField({
4370
5161
  const selectedIndex = options.findIndex(
4371
5162
  (option) => valuesMatch(option.value, value)
4372
5163
  );
4373
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5164
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4374
5165
  "select",
4375
5166
  {
4376
5167
  id,
@@ -4385,13 +5176,13 @@ function ChoiceField({
4385
5176
  if (option) onChange(option.value);
4386
5177
  },
4387
5178
  children: [
4388
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
4389
- options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: index, children: option.label }, optionKey(option)))
5179
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", disabled: field.required, children: "Choose an option" }),
5180
+ options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: index, children: option.label }, optionKey(option)))
4390
5181
  ]
4391
5182
  }
4392
5183
  );
4393
5184
  }
4394
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5185
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4395
5186
  "div",
4396
5187
  {
4397
5188
  className: "tool-input-card__choices",
@@ -4402,8 +5193,8 @@ function ChoiceField({
4402
5193
  "aria-required": field.required,
4403
5194
  children: options.map((option, index) => {
4404
5195
  const checked = multiple ? selected.some((item) => valuesMatch(item, option.value)) : valuesMatch(value, option.value);
4405
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__choice", children: [
4406
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5196
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__choice", children: [
5197
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4407
5198
  "input",
4408
5199
  {
4409
5200
  type: multiple ? "checkbox" : "radio",
@@ -4425,7 +5216,7 @@ function ChoiceField({
4425
5216
  }
4426
5217
  }
4427
5218
  ),
4428
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
5219
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: option.label })
4429
5220
  ] }, optionKey(option));
4430
5221
  })
4431
5222
  }
@@ -4445,9 +5236,9 @@ function ToolField({
4445
5236
  error ? `${id}-error` : ""
4446
5237
  ].filter(Boolean).join(" ");
4447
5238
  if (field.kind === "checkbox" || field.kind === "confirmation") {
4448
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
4449
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
4450
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5239
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
5240
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: "tool-input-card__check", htmlFor: id, children: [
5241
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4451
5242
  "input",
4452
5243
  {
4453
5244
  id,
@@ -4460,17 +5251,17 @@ function ToolField({
4460
5251
  onChange: (event) => onChange(event.target.checked)
4461
5252
  }
4462
5253
  ),
4463
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
4464
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: field.label }),
4465
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-description`, children: field.description }) : null
5254
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
5255
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: field.label }),
5256
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-description`, children: field.description }) : null
4466
5257
  ] })
4467
5258
  ] }),
4468
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5259
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4469
5260
  ] });
4470
5261
  }
4471
- const label = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
5262
+ const label = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { id: `${id}-label`, htmlFor: id, children: [
4472
5263
  field.label,
4473
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5264
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4474
5265
  ] });
4475
5266
  const common = {
4476
5267
  id,
@@ -4482,7 +5273,7 @@ function ToolField({
4482
5273
  };
4483
5274
  let control;
4484
5275
  if (field.kind === "select" || field.kind === "radio" || field.kind === "multi-select") {
4485
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5276
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4486
5277
  ChoiceField,
4487
5278
  {
4488
5279
  field,
@@ -4496,7 +5287,7 @@ function ToolField({
4496
5287
  }
4497
5288
  );
4498
5289
  } else if (field.kind === "textarea" || field.kind === "json") {
4499
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5290
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4500
5291
  "textarea",
4501
5292
  {
4502
5293
  ...common,
@@ -4510,8 +5301,8 @@ function ToolField({
4510
5301
  );
4511
5302
  } else if (field.kind === "range") {
4512
5303
  const numericValue = typeof value === "number" ? value : field.min ?? 0;
4513
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__range", children: [
4514
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5304
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__range", children: [
5305
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4515
5306
  "input",
4516
5307
  {
4517
5308
  ...common,
@@ -4523,11 +5314,11 @@ function ToolField({
4523
5314
  onChange: (event) => onChange(Number(event.target.value))
4524
5315
  }
4525
5316
  ),
4526
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("output", { htmlFor: id, children: numericValue })
5317
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { htmlFor: id, children: numericValue })
4527
5318
  ] });
4528
5319
  } else {
4529
5320
  const type = field.kind === "date-time" ? "datetime-local" : field.kind === "calendar" ? "date" : field.kind;
4530
- control = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5321
+ control = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4531
5322
  "input",
4532
5323
  {
4533
5324
  ...common,
@@ -4545,11 +5336,11 @@ function ToolField({
4545
5336
  }
4546
5337
  );
4547
5338
  }
4548
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__field", children: [
5339
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__field", children: [
4549
5340
  label,
4550
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FieldDescription, { field, id: `${id}-description` }),
5341
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(FieldDescription, { field, id: `${id}-description` }),
4551
5342
  control,
4552
- error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
5343
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: `${id}-error`, className: "tool-input-card__error", children: error }) : null
4553
5344
  ] });
4554
5345
  }
4555
5346
  function ToolInputCard({
@@ -4557,11 +5348,11 @@ function ToolInputCard({
4557
5348
  surface,
4558
5349
  onSubmit
4559
5350
  }) {
4560
- const [values, setValues] = (0, import_react9.useState)(
5351
+ const [values, setValues] = (0, import_react12.useState)(
4561
5352
  () => initialValues(surface)
4562
5353
  );
4563
- const [touched, setTouched] = (0, import_react9.useState)(() => /* @__PURE__ */ new Set());
4564
- const [submitted, setSubmitted] = (0, import_react9.useState)(false);
5354
+ const [touched, setTouched] = (0, import_react12.useState)(() => /* @__PURE__ */ new Set());
5355
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
4565
5356
  const errors = Object.fromEntries(
4566
5357
  surface.fields.map((field) => [
4567
5358
  field.path,
@@ -4586,14 +5377,14 @@ function ToolInputCard({
4586
5377
  onSubmit?.(surface, result);
4587
5378
  }
4588
5379
  if (submitted) {
4589
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5380
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4590
5381
  "section",
4591
5382
  {
4592
5383
  className: "tool-input-card tool-input-card--submitted",
4593
5384
  role: "status",
4594
5385
  children: [
4595
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
4596
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5386
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "aria-hidden": "true", children: "\u2713" }),
5387
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("strong", { children: [
4597
5388
  surface.title,
4598
5389
  " submitted"
4599
5390
  ] })
@@ -4601,18 +5392,18 @@ function ToolInputCard({
4601
5392
  }
4602
5393
  );
4603
5394
  }
4604
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5395
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4605
5396
  "section",
4606
5397
  {
4607
5398
  className: "tool-input-card",
4608
5399
  "aria-labelledby": `tool-input-${surface.id}`,
4609
5400
  children: [
4610
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__heading", children: [
4611
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
4612
- surface.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: surface.description }) : null
5401
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__heading", children: [
5402
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { id: `tool-input-${surface.id}`, children: surface.title }),
5403
+ surface.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: surface.description }) : null
4613
5404
  ] }),
4614
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
4615
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5405
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { noValidate: true, onSubmit: submit, children: [
5406
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "tool-input-card__fields", children: surface.fields.map((field, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4616
5407
  ToolField,
4617
5408
  {
4618
5409
  disabled,
@@ -4625,8 +5416,8 @@ function ToolInputCard({
4625
5416
  },
4626
5417
  field.path
4627
5418
  )) }),
4628
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "tool-input-card__actions", children: [
4629
- surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5419
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-input-card__actions", children: [
5420
+ surface.actions?.some((action) => action.id === "reset") ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4630
5421
  "button",
4631
5422
  {
4632
5423
  type: "button",
@@ -4639,7 +5430,7 @@ function ToolInputCard({
4639
5430
  children: surface.actions.find((action) => action.id === "reset")?.label ?? "Clear"
4640
5431
  }
4641
5432
  ) : null,
4642
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
5433
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "submit", disabled, children: surface.submitLabel ?? surface.actions?.find((action) => action.id === "submit")?.label ?? "Continue" })
4643
5434
  ] })
4644
5435
  ] })
4645
5436
  ]
@@ -4648,17 +5439,17 @@ function ToolInputCard({
4648
5439
  }
4649
5440
 
4650
5441
  // src/react/components/HumanInputCard/HumanInputCard.tsx
4651
- var import_jsx_runtime8 = require("react/jsx-runtime");
5442
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4652
5443
  function HumanInputCard({
4653
5444
  disabled = false,
4654
5445
  request,
4655
5446
  onRespond
4656
5447
  }) {
4657
- const [text, setText] = (0, import_react10.useState)("");
5448
+ const [text, setText] = (0, import_react13.useState)("");
4658
5449
  const options = request.options ?? [];
4659
5450
  const showText = request.display === "text" || request.allowFreeform && options.length === 0;
4660
5451
  if (request.ui) {
4661
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5452
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4662
5453
  ToolInputCard,
4663
5454
  {
4664
5455
  disabled,
@@ -4668,7 +5459,7 @@ function HumanInputCard({
4668
5459
  );
4669
5460
  }
4670
5461
  if (options.length > 0) {
4671
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5462
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4672
5463
  ConfirmationCard,
4673
5464
  {
4674
5465
  disabled,
@@ -4683,17 +5474,17 @@ function HumanInputCard({
4683
5474
  if (!value || disabled) return;
4684
5475
  onRespond?.({ requestId: request.requestId, text: value });
4685
5476
  }
4686
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
5477
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4687
5478
  "section",
4688
5479
  {
4689
5480
  className: "human-input-card",
4690
5481
  "aria-labelledby": `human-input-${request.requestId}`,
4691
5482
  children: [
4692
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "human-input-card__heading", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
4693
- showText ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: submitText, children: [
4694
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
4695
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
4696
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5483
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "human-input-card__heading", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { id: `human-input-${request.requestId}`, children: request.prompt }) }),
5484
+ showText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("form", { onSubmit: submitText, children: [
5485
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("label", { htmlFor: `human-input-text-${request.requestId}`, children: "Response" }),
5486
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
5487
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4697
5488
  "input",
4698
5489
  {
4699
5490
  id: `human-input-text-${request.requestId}`,
@@ -4702,39 +5493,39 @@ function HumanInputCard({
4702
5493
  onChange: (event) => setText(event.target.value)
4703
5494
  }
4704
5495
  ),
4705
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
5496
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "submit", disabled: disabled || !text.trim(), children: "Send" })
4706
5497
  ] })
4707
5498
  ] }) : null,
4708
- !showText && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
5499
+ !showText && options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "human-input-card__unavailable", role: "status", children: "This request can\u2019t be answered here." }) : null
4709
5500
  ]
4710
5501
  }
4711
5502
  );
4712
5503
  }
4713
5504
 
4714
5505
  // src/react/components/CollectionResultCard/CollectionResultCard.tsx
4715
- var import_jsx_runtime9 = require("react/jsx-runtime");
5506
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4716
5507
  function CollectionResultCard({
4717
5508
  result
4718
5509
  }) {
4719
5510
  const empty = result.items.length === 0;
4720
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5511
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4721
5512
  "section",
4722
5513
  {
4723
5514
  className: `collection-result-card tool-result-card tool-result-card--${result.status}`,
4724
5515
  "aria-label": result.title,
4725
5516
  children: [
4726
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "tool-result-card__heading", children: [
4727
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4728
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: result.title })
5517
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
5518
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5519
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
4729
5520
  ] }),
4730
- empty ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { children: [
4731
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
4732
- item.description ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { children: item.description }) : null,
4733
- item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
4734
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: detail.label }),
4735
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: detail.value })
5521
+ empty ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "collection-result-card__empty", children: "No matching record for the email you shared." }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "collection-result-card__list", children: result.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
5522
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "collection-result-card__item-title", children: item.title }),
5523
+ item.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: item.description }) : null,
5524
+ item.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { children: item.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: detail.label }),
5526
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: detail.value })
4736
5527
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4737
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
5528
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: item.href, target: "_blank", rel: "noreferrer", children: "Open record" }) : null
4738
5529
  ] }, item.title)) })
4739
5530
  ]
4740
5531
  }
@@ -4742,26 +5533,26 @@ function CollectionResultCard({
4742
5533
  }
4743
5534
 
4744
5535
  // src/react/components/EntityResultCard/EntityResultCard.tsx
4745
- var import_jsx_runtime10 = require("react/jsx-runtime");
5536
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4746
5537
  function EntityResultCard({
4747
5538
  result
4748
5539
  }) {
4749
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5540
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4750
5541
  "section",
4751
5542
  {
4752
5543
  className: `entity-result-card tool-result-card tool-result-card--${result.status}`,
4753
5544
  "aria-label": result.title,
4754
5545
  children: [
4755
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "tool-result-card__heading", children: [
4756
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4757
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: result.title })
5546
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
5547
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5548
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
4758
5549
  ] }),
4759
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: result.description }) : null,
4760
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
4761
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dt", { children: detail.label }),
4762
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dd", { children: detail.value })
5550
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
5551
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
5552
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
5553
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
4763
5554
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4764
- result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5555
+ result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4765
5556
  "a",
4766
5557
  {
4767
5558
  href: link.href,
@@ -4777,24 +5568,24 @@ function EntityResultCard({
4777
5568
  }
4778
5569
 
4779
5570
  // src/react/components/SignatureResultCard/SignatureResultCard.tsx
4780
- var import_jsx_runtime11 = require("react/jsx-runtime");
5571
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4781
5572
  function SignatureResultCard({
4782
5573
  result
4783
5574
  }) {
4784
5575
  const primaryLink = result.links?.[0];
4785
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5576
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
4786
5577
  "section",
4787
5578
  {
4788
5579
  className: `signature-result-card tool-result-card tool-result-card--${result.status}`,
4789
5580
  "aria-label": result.title,
4790
5581
  children: [
4791
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "tool-result-card__heading", children: [
4792
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4793
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("strong", { children: result.title })
5582
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "tool-result-card__heading", children: [
5583
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5584
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: result.title })
4794
5585
  ] }),
4795
- result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
4796
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: result.description }) : null,
4797
- primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5586
+ result.statusLabel ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "signature-result-card__badge", children: result.statusLabel }) : null,
5587
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: result.description }) : null,
5588
+ primaryLink ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4798
5589
  "a",
4799
5590
  {
4800
5591
  className: "signature-result-card__cta",
@@ -4810,26 +5601,26 @@ function SignatureResultCard({
4810
5601
  }
4811
5602
 
4812
5603
  // src/react/components/ToolResultCard/ToolResultCard.tsx
4813
- var import_jsx_runtime12 = require("react/jsx-runtime");
5604
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4814
5605
  function ToolResultCard({
4815
5606
  result
4816
5607
  }) {
4817
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5608
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4818
5609
  "section",
4819
5610
  {
4820
5611
  className: `tool-result-card tool-result-card--${result.status}`,
4821
5612
  "aria-label": result.title,
4822
5613
  children: [
4823
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "tool-result-card__heading", children: [
4824
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
4825
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("strong", { children: result.title })
5614
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "tool-result-card__heading", children: [
5615
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "tool-result-card__status", "aria-hidden": "true" }),
5616
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: result.title })
4826
5617
  ] }),
4827
- result.description ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: result.description }) : null,
4828
- result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
4829
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { children: detail.label }),
4830
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { children: detail.value })
5618
+ result.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: result.description }) : null,
5619
+ result.details?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dl", { children: result.details.map((detail) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5620
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: detail.label }),
5621
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: detail.value })
4831
5622
  ] }, `${detail.label}:${detail.value}`)) }) : null,
4832
- result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5623
+ result.links?.length ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "tool-result-card__links", children: result.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4833
5624
  "a",
4834
5625
  {
4835
5626
  href: link.href,
@@ -4845,14 +5636,14 @@ function ToolResultCard({
4845
5636
  }
4846
5637
 
4847
5638
  // src/react/components/VisitorToolResultView/VisitorToolResultView.tsx
4848
- var import_jsx_runtime13 = require("react/jsx-runtime");
5639
+ var import_jsx_runtime15 = require("react/jsx-runtime");
4849
5640
  function VisitorToolResultView({
4850
5641
  disabled = false,
4851
5642
  onToolInput,
4852
5643
  result
4853
5644
  }) {
4854
5645
  if (result.kind === "input") {
4855
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5646
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4856
5647
  ToolInputCard,
4857
5648
  {
4858
5649
  disabled,
@@ -4862,16 +5653,16 @@ function VisitorToolResultView({
4862
5653
  );
4863
5654
  }
4864
5655
  if (result.kind === "entity") {
4865
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(EntityResultCard, { result });
5656
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(EntityResultCard, { result });
4866
5657
  }
4867
5658
  if (result.kind === "collection") {
4868
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CollectionResultCard, { result });
5659
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CollectionResultCard, { result });
4869
5660
  }
4870
5661
  if (result.kind === "signature") {
4871
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SignatureResultCard, { result });
5662
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SignatureResultCard, { result });
4872
5663
  }
4873
5664
  if (result.kind === "summary") {
4874
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ToolResultCard, { result });
5665
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ToolResultCard, { result });
4875
5666
  }
4876
5667
  return null;
4877
5668
  }
@@ -4880,9 +5671,9 @@ function isRenderableVisitorToolResult(result) {
4880
5671
  }
4881
5672
 
4882
5673
  // src/react/components/AgentRail/AgentRail.tsx
4883
- var import_jsx_runtime14 = require("react/jsx-runtime");
5674
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4884
5675
  function MinimizeIcon() {
4885
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5676
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4886
5677
  "path",
4887
5678
  {
4888
5679
  d: "M3.5 8h9",
@@ -4892,8 +5683,8 @@ function MinimizeIcon() {
4892
5683
  }
4893
5684
  ) });
4894
5685
  }
4895
- function CloseIcon() {
4896
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5686
+ function CloseIcon2() {
5687
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4897
5688
  "path",
4898
5689
  {
4899
5690
  d: "M4 4l8 8M12 4l-8 8",
@@ -4904,7 +5695,7 @@ function CloseIcon() {
4904
5695
  ) });
4905
5696
  }
4906
5697
  function NewChatIcon() {
4907
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5698
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4908
5699
  "path",
4909
5700
  {
4910
5701
  d: "M9.5 3.5h3v3M12.25 3.75 8 8M7 4H4.5A1.5 1.5 0 0 0 3 5.5v6A1.5 1.5 0 0 0 4.5 13h6a1.5 1.5 0 0 0 1.5-1.5V9",
@@ -4916,7 +5707,7 @@ function NewChatIcon() {
4916
5707
  ) });
4917
5708
  }
4918
5709
  function ExpandIcon() {
4919
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5710
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4920
5711
  "path",
4921
5712
  {
4922
5713
  d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
@@ -4928,7 +5719,7 @@ function ExpandIcon() {
4928
5719
  ) });
4929
5720
  }
4930
5721
  function RestoreIcon() {
4931
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5722
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
4932
5723
  "path",
4933
5724
  {
4934
5725
  d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
@@ -4939,6 +5730,19 @@ function RestoreIcon() {
4939
5730
  }
4940
5731
  ) });
4941
5732
  }
5733
+ function ChevronDownIcon() {
5734
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5735
+ "path",
5736
+ {
5737
+ d: "M4 6.5l4 4 4-4",
5738
+ stroke: "currentColor",
5739
+ strokeWidth: "1.6",
5740
+ strokeLinecap: "round",
5741
+ strokeLinejoin: "round"
5742
+ }
5743
+ ) });
5744
+ }
5745
+ var DEFAULT_DISCLAIMER_LABEL = "Agent can make mistakes. Check important info.";
4942
5746
  function AgentRail({
4943
5747
  state,
4944
5748
  theme,
@@ -4946,6 +5750,9 @@ function AgentRail({
4946
5750
  brandLabel = "",
4947
5751
  brandLogoUrl,
4948
5752
  poweredByLabel = "Powered by Webless",
5753
+ disclaimerLabel,
5754
+ answerReceipt = false,
5755
+ readAloud = false,
4949
5756
  composerPlaceholder = "Ask anything\u2026",
4950
5757
  mobileFullscreen = false,
4951
5758
  expanded = false,
@@ -4954,16 +5761,26 @@ function AgentRail({
4954
5761
  onExpandToggle,
4955
5762
  onReset,
4956
5763
  onRetry,
5764
+ onRegenerate,
5765
+ onFeedback,
4957
5766
  onSubmit,
4958
5767
  onFollowUpSelect,
4959
5768
  onBook,
4960
5769
  onInputResponse,
4961
5770
  onToolInput
4962
5771
  }) {
4963
- const transcriptRef = (0, import_react11.useRef)(null);
5772
+ const railRef = (0, import_react14.useRef)(null);
5773
+ const overlayRef = (0, import_react14.useRef)(null);
5774
+ const transcriptRef = (0, import_react14.useRef)(null);
5775
+ const pinnedToBottomRef = (0, import_react14.useRef)(true);
5776
+ const smoothScrollToLatestRef = (0, import_react14.useRef)(false);
5777
+ const lockedTranscriptScrollTopRef = (0, import_react14.useRef)(null);
5778
+ const [showJumpToLatest, setShowJumpToLatest] = (0, import_react14.useState)(false);
5779
+ const [receiptOpen, setReceiptOpen] = (0, import_react14.useState)(false);
4964
5780
  const resolvedBrandLabel = brandLabel.trim();
4965
5781
  const resolvedBrandLogoUrl = brandLogoUrl?.trim();
4966
- const [failedLogoUrl, setFailedLogoUrl] = (0, import_react11.useState)(null);
5782
+ const resolvedDisclaimerLabel = disclaimerLabel === void 0 ? DEFAULT_DISCLAIMER_LABEL : disclaimerLabel;
5783
+ const [failedLogoUrl, setFailedLogoUrl] = (0, import_react14.useState)(null);
4967
5784
  const showBrandLogo = Boolean(resolvedBrandLogoUrl) && failedLogoUrl !== resolvedBrandLogoUrl;
4968
5785
  const resolvedColorScheme = useAgentColorScheme(colorScheme);
4969
5786
  const brandedTheme = { ...defaultAgentRailTheme, ...theme };
@@ -5014,10 +5831,15 @@ function AgentRail({
5014
5831
  );
5015
5832
  const activeVisitorToolInput = [...visitorToolResults].reverse().find((result) => result.kind === "input");
5016
5833
  const visibleVisitorToolResults = activeVisitorToolInput ? [activeVisitorToolInput] : visitorToolResults;
5017
- const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer;
5834
+ const activityActive = state.toolSteps.some((step) => step.state === "active");
5835
+ const showActivity = state.toolSteps.length > 0 && visibleVisitorToolResults.length === 0 && pendingInputRequests.length === 0 && !state.pendingOffer && activityActive;
5018
5836
  const hasVisitorMessages2 = state.messages.some(
5019
5837
  (message) => message.role === "visitor"
5020
5838
  );
5839
+ const hasAgentResponseAfterVisitor = state.messages.some(
5840
+ (message) => message.role === "agent" && message.id !== "greeting"
5841
+ );
5842
+ const showDisclaimerLabel = Boolean(resolvedDisclaimerLabel) && hasVisitorMessages2 && (hasAgentResponseAfterVisitor || state.phase === "streaming" && Boolean(state.streamingText));
5021
5843
  const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
5022
5844
  const greeting = state.messages.find(
5023
5845
  (message) => message.role === "agent" && message.id === "greeting"
@@ -5039,6 +5861,7 @@ function AgentRail({
5039
5861
  }
5040
5862
  }
5041
5863
  const lastIsAgent = lastMessage?.role === "agent";
5864
+ const showMessageActions = state.phase === "complete" && lastIsAgent && hasVisitorMessages2;
5042
5865
  const streamingMessage = state.phase === "streaming" && state.streamingText && !lastIsAgent ? {
5043
5866
  createdAt: 0,
5044
5867
  id: "streaming-response",
@@ -5065,10 +5888,36 @@ function AgentRail({
5065
5888
  hasPendingConfirmation,
5066
5889
  enabled: lastIsAgent && !isBusy
5067
5890
  });
5068
- (0, import_react11.useEffect)(() => {
5891
+ const receiptSteps = answerReceipt && state.toolSteps.length > 0 ? state.toolSteps : void 0;
5892
+ (0, import_react14.useEffect)(() => {
5893
+ if (state.phase !== "complete") {
5894
+ setReceiptOpen(false);
5895
+ }
5896
+ }, [state.phase]);
5897
+ function handleSubmit(message) {
5898
+ setReceiptOpen(false);
5899
+ onSubmit?.(message);
5900
+ }
5901
+ function handleRegenerate() {
5902
+ setReceiptOpen(false);
5903
+ onRegenerate?.();
5904
+ }
5905
+ function handleReset() {
5906
+ setReceiptOpen(false);
5907
+ onReset?.();
5908
+ }
5909
+ function handleFollowUpSelect(label) {
5910
+ setReceiptOpen(false);
5911
+ onFollowUpSelect?.(label);
5912
+ }
5913
+ (0, import_react14.useEffect)(() => {
5069
5914
  const node = transcriptRef.current;
5070
5915
  if (!node) return;
5071
- node.scrollTop = node.scrollHeight;
5916
+ const lastMessage2 = state.messages.at(-1);
5917
+ const visitorJustSent = lastMessage2?.role === "visitor";
5918
+ if (pinnedToBottomRef.current || visitorJustSent) {
5919
+ node.scrollTop = node.scrollHeight;
5920
+ }
5072
5921
  }, [
5073
5922
  state.messages,
5074
5923
  state.toolSteps,
@@ -5076,10 +5925,75 @@ function AgentRail({
5076
5925
  state.followUps,
5077
5926
  state.journey
5078
5927
  ]);
5079
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5928
+ (0, import_react14.useEffect)(() => {
5929
+ const node = transcriptRef.current;
5930
+ if (!node) return;
5931
+ const handleScroll = () => {
5932
+ if (node.clientHeight === 0) return;
5933
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5934
+ const pinned = distanceFromBottom < 48 || smoothScrollToLatestRef.current;
5935
+ pinnedToBottomRef.current = pinned;
5936
+ setShowJumpToLatest(!pinned);
5937
+ };
5938
+ node.addEventListener("scroll", handleScroll, { passive: true });
5939
+ handleScroll();
5940
+ return () => node.removeEventListener("scroll", handleScroll);
5941
+ }, []);
5942
+ (0, import_react14.useEffect)(() => {
5943
+ const node = transcriptRef.current;
5944
+ if (!node) return;
5945
+ const observer = new ResizeObserver(() => {
5946
+ if (node.clientHeight === 0) return;
5947
+ if (pinnedToBottomRef.current) {
5948
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5949
+ }
5950
+ });
5951
+ observer.observe(node);
5952
+ return () => observer.disconnect();
5953
+ }, []);
5954
+ (0, import_react14.useEffect)(() => {
5955
+ if (!receiptOpen) {
5956
+ lockedTranscriptScrollTopRef.current = null;
5957
+ return;
5958
+ }
5959
+ const node = transcriptRef.current;
5960
+ if (!node || lockedTranscriptScrollTopRef.current === null) return;
5961
+ node.scrollTop = lockedTranscriptScrollTopRef.current;
5962
+ }, [receiptOpen]);
5963
+ function openReceipt() {
5964
+ const node = transcriptRef.current;
5965
+ lockedTranscriptScrollTopRef.current = node?.scrollTop ?? null;
5966
+ setReceiptOpen(true);
5967
+ }
5968
+ function scrollToLatest() {
5969
+ const node = transcriptRef.current;
5970
+ if (!node) return;
5971
+ pinnedToBottomRef.current = true;
5972
+ setShowJumpToLatest(false);
5973
+ const reduceMotion = window.matchMedia(
5974
+ "(prefers-reduced-motion: reduce)"
5975
+ ).matches;
5976
+ if (reduceMotion) {
5977
+ node.scrollTo({ top: node.scrollHeight, behavior: "instant" });
5978
+ return;
5979
+ }
5980
+ smoothScrollToLatestRef.current = true;
5981
+ const settle = () => {
5982
+ smoothScrollToLatestRef.current = false;
5983
+ const distanceFromBottom = node.scrollHeight - node.scrollTop - node.clientHeight;
5984
+ const pinned = distanceFromBottom < 48;
5985
+ pinnedToBottomRef.current = pinned;
5986
+ setShowJumpToLatest(!pinned);
5987
+ };
5988
+ node.addEventListener("scrollend", settle, { once: true });
5989
+ window.setTimeout(settle, 900);
5990
+ node.scrollTo({ top: node.scrollHeight, behavior: "smooth" });
5991
+ }
5992
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5080
5993
  "aside",
5081
5994
  {
5082
- className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
5995
+ ref: railRef,
5996
+ className: `agent-rail not-typeset${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}${receiptOpen ? " agent-rail--receipt-open" : ""}`,
5083
5997
  "data-not-typeset": "",
5084
5998
  "data-color-scheme": resolvedColorScheme,
5085
5999
  spellCheck: false,
@@ -5089,193 +6003,234 @@ function AgentRail({
5089
6003
  autoFocus: mobileFullscreen || expanded,
5090
6004
  role: mobileFullscreen || expanded ? "dialog" : void 0,
5091
6005
  tabIndex: mobileFullscreen || expanded ? -1 : void 0,
5092
- children: [
5093
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__brand-row", children: [
5094
- onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5095
- "button",
5096
- {
5097
- type: "button",
5098
- className: "agent-rail__collapse",
5099
- "aria-label": "Collapse assist",
5100
- onClick: onCollapse,
5101
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(MinimizeIcon, {})
5102
- }
5103
- ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5104
- "button",
5105
- {
5106
- type: "button",
5107
- className: "agent-rail__close",
5108
- "aria-label": "Close agent",
5109
- onClick: onClose,
5110
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, {})
5111
- }
5112
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
5113
- resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__identity", children: [
5114
- showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5115
- "img",
5116
- {
5117
- className: "agent-rail__brand-logo",
5118
- src: resolvedBrandLogoUrl,
5119
- alt: "",
5120
- onError: () => {
5121
- setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
5122
- }
5123
- }
5124
- ) }) : null,
5125
- resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
5126
- ] }) : null,
5127
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "agent-rail__actions", children: [
5128
- onReset ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5129
- "button",
5130
- {
5131
- type: "button",
5132
- className: "agent-rail__new-chat",
5133
- "aria-label": "Start a new conversation",
5134
- disabled: !hasVisitorMessages2,
5135
- onClick: onReset,
5136
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(NewChatIcon, {})
5137
- }
5138
- ) : null,
5139
- onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5140
- "button",
5141
- {
5142
- type: "button",
5143
- className: "agent-rail__expand",
5144
- "aria-label": expanded ? "Exit full screen" : "Open full screen",
5145
- onClick: onExpandToggle,
5146
- children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ExpandIcon, {})
5147
- }
5148
- ) : null
5149
- ] })
5150
- ] }) }),
5151
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__thread", children: [
5152
- !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
5153
- greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5154
- MessageBubble,
5155
- {
5156
- message: greeting,
5157
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5158
- onBook
5159
- }
5160
- ) : null,
5161
- showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5162
- FollowUpChips,
5163
- {
5164
- suggestions: state.followUps,
5165
- disabled: isBusy,
5166
- label: "Start here",
5167
- onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
5168
- }
5169
- ) }) : null,
5170
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5171
- AgentActivityBubble,
6006
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6007
+ AgentRailOverlayContext.Provider,
6008
+ {
6009
+ value: { railRef, overlayRef },
6010
+ children: [
6011
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__surface", inert: receiptOpen || void 0, children: [
6012
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__brand-row", children: [
6013
+ onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6014
+ "button",
6015
+ {
6016
+ type: "button",
6017
+ className: "agent-rail__collapse",
6018
+ "aria-label": "Collapse assist",
6019
+ onClick: onCollapse,
6020
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MinimizeIcon, {})
6021
+ }
6022
+ ) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6023
+ "button",
6024
+ {
6025
+ type: "button",
6026
+ className: "agent-rail__close",
6027
+ "aria-label": "Close agent",
6028
+ onClick: onClose,
6029
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CloseIcon2, {})
6030
+ }
6031
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
6032
+ resolvedBrandLabel || showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__identity", children: [
6033
+ showBrandLogo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6034
+ "img",
6035
+ {
6036
+ className: "agent-rail__brand-logo",
6037
+ src: resolvedBrandLogoUrl,
6038
+ alt: "",
6039
+ onError: () => {
6040
+ setFailedLogoUrl(resolvedBrandLogoUrl ?? null);
6041
+ }
6042
+ }
6043
+ ) }) : null,
6044
+ resolvedBrandLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "agent-rail__brand-label", children: resolvedBrandLabel }) : null
6045
+ ] }) : null,
6046
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "agent-rail__actions", children: [
6047
+ onReset ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6048
+ "button",
6049
+ {
6050
+ type: "button",
6051
+ className: "agent-rail__new-chat",
6052
+ "aria-label": "Start a new conversation",
6053
+ disabled: !hasVisitorMessages2,
6054
+ onClick: handleReset,
6055
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(NewChatIcon, {})
6056
+ }
6057
+ ) : null,
6058
+ onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6059
+ "button",
6060
+ {
6061
+ type: "button",
6062
+ className: "agent-rail__expand",
6063
+ "aria-label": expanded ? "Exit full screen" : "Open full screen",
6064
+ onClick: onExpandToggle,
6065
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExpandIcon, {})
6066
+ }
6067
+ ) : null
6068
+ ] })
6069
+ ] }) }),
6070
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__thread", children: [
6071
+ !hasVisitorMessages2 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__welcome", "aria-label": "Welcome", children: [
6072
+ greeting?.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6073
+ MessageBubble,
6074
+ {
6075
+ message: greeting,
6076
+ bookingDisabled: isBusy,
6077
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6078
+ onBook
6079
+ }
6080
+ ) : null,
6081
+ showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6082
+ FollowUpChips,
6083
+ {
6084
+ suggestions: state.followUps,
6085
+ disabled: isBusy,
6086
+ label: "Start here",
6087
+ onSelect: (suggestion) => handleFollowUpSelect(suggestion.label)
6088
+ }
6089
+ ) }) : null,
6090
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6091
+ AgentActivityBubble,
6092
+ {
6093
+ brandLabel: resolvedBrandLabel,
6094
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6095
+ failed: state.phase === "error",
6096
+ steps: state.toolSteps
6097
+ }
6098
+ ) : null,
6099
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6100
+ VisitorToolResultView,
6101
+ {
6102
+ result,
6103
+ disabled: semanticSurfaceDisabled,
6104
+ onToolInput
6105
+ },
6106
+ result.id
6107
+ )),
6108
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6109
+ HumanInputCard,
6110
+ {
6111
+ request,
6112
+ onRespond: onInputResponse
6113
+ },
6114
+ request.requestId
6115
+ ))
6116
+ ] }) : null,
6117
+ visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__turn-block", children: [
6118
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6119
+ MessageBubble,
6120
+ {
6121
+ message,
6122
+ bookingDisabled: isBusy,
6123
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6124
+ offer: index === lastAgentIndex ? state.pendingOffer : void 0,
6125
+ onBook
6126
+ }
6127
+ ),
6128
+ index === lastAgentIndex && showMessageActions && message.role === "agent" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6129
+ MessageActions,
6130
+ {
6131
+ answeredAt: message.createdAt,
6132
+ copyText: hideToolCardFences(message.text).trim() || message.text,
6133
+ readAloud,
6134
+ receiptSteps,
6135
+ onOpenReceipt: receiptSteps ? openReceipt : void 0,
6136
+ onRegenerate: onRegenerate ? handleRegenerate : void 0,
6137
+ onFeedback: onFeedback ? (rating) => onFeedback(rating, message) : void 0
6138
+ }
6139
+ ) : null,
6140
+ index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
6141
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6142
+ AgentActivityBubble,
6143
+ {
6144
+ brandLabel: resolvedBrandLabel,
6145
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6146
+ failed: state.phase === "error",
6147
+ steps: state.toolSteps
6148
+ }
6149
+ ) : null,
6150
+ visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6151
+ VisitorToolResultView,
6152
+ {
6153
+ result,
6154
+ disabled: semanticSurfaceDisabled,
6155
+ onToolInput
6156
+ },
6157
+ result.id
6158
+ )),
6159
+ pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6160
+ HumanInputCard,
6161
+ {
6162
+ request,
6163
+ onRespond: onInputResponse
6164
+ },
6165
+ request.requestId
6166
+ ))
6167
+ ] }) : null
6168
+ ] }, message.id)),
6169
+ streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6170
+ MessageBubble,
6171
+ {
6172
+ message: streamingMessage,
6173
+ bookingDisabled: isBusy,
6174
+ brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
6175
+ offer: state.pendingOffer,
6176
+ onBook
6177
+ }
6178
+ ) : null,
6179
+ waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(BookingCardLoader, {}) : null,
6180
+ state.error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
6181
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
6182
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("strong", { children: "Something went wrong" }),
6183
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: state.error })
6184
+ ] }),
6185
+ onRetry ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
6186
+ ] }) : null
6187
+ ] }) }),
6188
+ showDisclaimerLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__disclaimer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: resolvedDisclaimerLabel }) }) : null,
6189
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
6190
+ showJumpToLatest ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6191
+ "button",
6192
+ {
6193
+ type: "button",
6194
+ className: "agent-rail__jump-to-latest",
6195
+ "aria-label": "Jump to the latest message",
6196
+ title: "Jump to the latest message",
6197
+ onClick: scrollToLatest,
6198
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, {})
6199
+ }
6200
+ ) : null,
6201
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6202
+ Composer,
6203
+ {
6204
+ variant: expanded || mobileFullscreen ? "dock" : "default",
6205
+ disabled: isBusy,
6206
+ form: composerForm,
6207
+ placeholder: composerPlaceholder,
6208
+ onSubmit: handleSubmit
6209
+ }
6210
+ ),
6211
+ poweredByLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: poweredByLabel }) }) }) : null
6212
+ ] })
6213
+ ] }),
6214
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: overlayRef, className: "agent-rail__overlay" }),
6215
+ receiptOpen && receiptSteps ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6216
+ AnswerReceiptDialog,
5172
6217
  {
5173
6218
  brandLabel: resolvedBrandLabel,
5174
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5175
- failed: state.phase === "error",
5176
- steps: state.toolSteps
6219
+ onClose: () => setReceiptOpen(false),
6220
+ steps: receiptSteps
5177
6221
  }
5178
- ) : null,
5179
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5180
- VisitorToolResultView,
5181
- {
5182
- result,
5183
- disabled: semanticSurfaceDisabled,
5184
- onToolInput
5185
- },
5186
- result.id
5187
- )),
5188
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5189
- HumanInputCard,
5190
- {
5191
- request,
5192
- onRespond: onInputResponse
5193
- },
5194
- request.requestId
5195
- ))
5196
- ] }) : null,
5197
- visibleMessages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__turn-block", children: [
5198
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5199
- MessageBubble,
5200
- {
5201
- message,
5202
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5203
- offer: index === lastAgentIndex ? state.pendingOffer : void 0,
5204
- onBook
5205
- }
5206
- ),
5207
- index === lastVisitorIndex ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
5208
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5209
- AgentActivityBubble,
5210
- {
5211
- brandLabel: resolvedBrandLabel,
5212
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5213
- failed: state.phase === "error",
5214
- steps: state.toolSteps
5215
- }
5216
- ) : null,
5217
- visibleVisitorToolResults.map((result) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5218
- VisitorToolResultView,
5219
- {
5220
- result,
5221
- disabled: semanticSurfaceDisabled,
5222
- onToolInput
5223
- },
5224
- result.id
5225
- )),
5226
- pendingInputRequests.slice(0, 1).map((request) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5227
- HumanInputCard,
5228
- {
5229
- request,
5230
- onRespond: onInputResponse
5231
- },
5232
- request.requestId
5233
- ))
5234
- ] }) : null
5235
- ] }, message.id)),
5236
- streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5237
- MessageBubble,
5238
- {
5239
- message: streamingMessage,
5240
- brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5241
- offer: state.pendingOffer,
5242
- onBook
5243
- }
5244
- ) : null,
5245
- waitingForBooking ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(BookingCardLoader, {}) : null,
5246
- state.error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("section", { className: "agent-rail__error", role: "alert", children: [
5247
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
5248
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("strong", { children: "Something went wrong" }),
5249
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { children: state.error })
5250
- ] }),
5251
- onRetry ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", onClick: onRetry, children: "Try again" }) : null
5252
- ] }) : null
5253
- ] }) }),
5254
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
5255
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5256
- Composer,
5257
- {
5258
- variant: expanded || mobileFullscreen ? "dock" : "default",
5259
- disabled: isBusy,
5260
- form: composerForm,
5261
- placeholder: composerPlaceholder,
5262
- onSubmit
5263
- }
5264
- ),
5265
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
5266
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "AI can make mistakes. Check important info." }),
5267
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: poweredByLabel })
5268
- ] }) })
5269
- ] })
5270
- ]
6222
+ ) : null
6223
+ ]
6224
+ }
6225
+ )
5271
6226
  }
5272
6227
  );
5273
6228
  }
5274
6229
 
5275
6230
  // src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
5276
- var import_jsx_runtime15 = require("react/jsx-runtime");
6231
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5277
6232
  function SparklesIcon() {
5278
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6233
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5279
6234
  "svg",
5280
6235
  {
5281
6236
  className: "assist-edge-tab__sparkles",
@@ -5283,21 +6238,21 @@ function SparklesIcon() {
5283
6238
  fill: "none",
5284
6239
  "aria-hidden": "true",
5285
6240
  children: [
5286
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6241
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5287
6242
  "path",
5288
6243
  {
5289
6244
  d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z",
5290
6245
  fill: "currentColor"
5291
6246
  }
5292
6247
  ),
5293
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6248
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5294
6249
  "path",
5295
6250
  {
5296
6251
  d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z",
5297
6252
  fill: "currentColor"
5298
6253
  }
5299
6254
  ),
5300
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6255
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5301
6256
  "path",
5302
6257
  {
5303
6258
  d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z",
@@ -5311,7 +6266,7 @@ function SparklesIcon() {
5311
6266
  function TabMarkIcon({ customIconUrl }) {
5312
6267
  const url = customIconUrl?.trim();
5313
6268
  if (url) {
5314
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6269
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5315
6270
  "img",
5316
6271
  {
5317
6272
  alt: "",
@@ -5321,10 +6276,10 @@ function TabMarkIcon({ customIconUrl }) {
5321
6276
  }
5322
6277
  );
5323
6278
  }
5324
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SparklesIcon, {});
6279
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(SparklesIcon, {});
5325
6280
  }
5326
6281
  function ChevronLeftIcon() {
5327
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6282
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5328
6283
  "path",
5329
6284
  {
5330
6285
  d: "M10 4L6 8l4 4",
@@ -5335,8 +6290,8 @@ function ChevronLeftIcon() {
5335
6290
  }
5336
6291
  ) });
5337
6292
  }
5338
- function ChevronDownIcon() {
5339
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6293
+ function ChevronDownIcon2() {
6294
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5340
6295
  "path",
5341
6296
  {
5342
6297
  d: "M4 6l4 4 4-4",
@@ -5348,7 +6303,7 @@ function ChevronDownIcon() {
5348
6303
  ) });
5349
6304
  }
5350
6305
  function DragDots() {
5351
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("i", {}, index)) });
6306
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("i", {}, index)) });
5352
6307
  }
5353
6308
  var VARIANT_COPY = {
5354
6309
  outline: { label: "Ask anything", aria: "Ask anything" },
@@ -5394,7 +6349,7 @@ function AssistEdgeTab({
5394
6349
  ...resolvedTextColor ? { "--as-text": resolvedTextColor } : {},
5395
6350
  colorScheme: resolvedColorScheme
5396
6351
  };
5397
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6352
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5398
6353
  "button",
5399
6354
  {
5400
6355
  type: "button",
@@ -5406,15 +6361,15 @@ function AssistEdgeTab({
5406
6361
  tabIndex: visible ? 0 : -1,
5407
6362
  onClick: onOpen,
5408
6363
  children: [
5409
- mobile ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5410
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
6364
+ mobile ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6365
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5411
6366
  "span",
5412
6367
  {
5413
6368
  className: "assist-edge-tab__mark assist-edge-tab__mark--mobile",
5414
6369
  "aria-hidden": "true",
5415
6370
  children: [
5416
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5417
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6371
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6372
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5418
6373
  "img",
5419
6374
  {
5420
6375
  className: "assist-edge-tab__logo",
@@ -5428,11 +6383,11 @@ function AssistEdgeTab({
5428
6383
  ]
5429
6384
  }
5430
6385
  ),
5431
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
5432
- ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5433
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5434
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5435
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6386
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel })
6387
+ ] }) : variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6388
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6390
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5436
6391
  "img",
5437
6392
  {
5438
6393
  className: "assist-edge-tab__logo",
@@ -5444,18 +6399,18 @@ function AssistEdgeTab({
5444
6399
  }
5445
6400
  ) : null
5446
6401
  ] }),
5447
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5448
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronDownIcon, {})
6402
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6403
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon2, {})
5449
6404
  ] }) : null,
5450
- variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5451
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {}),
5452
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5453
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(DragDots, {})
6405
+ variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6406
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {}),
6407
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6408
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DragDots, {})
5454
6409
  ] }) : null,
5455
- variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5456
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
5457
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabMarkIcon, { customIconUrl }),
5458
- showLogo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
6410
+ variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
6411
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "assist-edge-tab__mark", "aria-hidden": "true", children: [
6412
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabMarkIcon, { customIconUrl }),
6413
+ showLogo ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5459
6414
  "img",
5460
6415
  {
5461
6416
  className: "assist-edge-tab__logo",
@@ -5467,16 +6422,72 @@ function AssistEdgeTab({
5467
6422
  }
5468
6423
  ) : null
5469
6424
  ] }),
5470
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
5471
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ChevronLeftIcon, {})
6425
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "assist-edge-tab__label", children: visibleLabel }),
6426
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronLeftIcon, {})
5472
6427
  ] }) : null
5473
6428
  ]
5474
6429
  }
5475
6430
  );
5476
6431
  }
5477
6432
 
6433
+ // src/react/lib/agent-feedback.ts
6434
+ var AGENT_ANSWER_FEEDBACK_EVENT_TYPE = "agent_answer_feedback";
6435
+ function findPrecedingVisitorText(messages, agentMessageId) {
6436
+ const agentIndex = messages.findIndex(
6437
+ (message) => message.id === agentMessageId && message.role === "agent"
6438
+ );
6439
+ if (agentIndex < 0) return void 0;
6440
+ for (let index = agentIndex - 1; index >= 0; index -= 1) {
6441
+ const message = messages[index];
6442
+ if (message?.role === "visitor") {
6443
+ return message.text.trim() || void 0;
6444
+ }
6445
+ }
6446
+ return void 0;
6447
+ }
6448
+ function normalizeAgentFeedbackAnswerText(text) {
6449
+ const normalized = text.replace(/\s+/g, " ").trim();
6450
+ if (!normalized) return void 0;
6451
+ return normalized.length > 4e3 ? `${normalized.slice(0, 3997)}...` : normalized;
6452
+ }
6453
+ function buildAgentAnswerFeedbackEvent(input) {
6454
+ const positive = input.rating === "positive";
6455
+ const answer = input.answer ? normalizeAgentFeedbackAnswerText(input.answer) : void 0;
6456
+ return {
6457
+ event_type: AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
6458
+ company: input.analytics.companyIndex,
6459
+ session_id: input.visitorSessionId,
6460
+ page: input.page,
6461
+ timestamp: Date.now(),
6462
+ tracking_consent: input.analytics.trackingConsent,
6463
+ feedback_value: positive ? 1 : -1,
6464
+ // Aggregate-safe rating enum, kept even for anonymous (no-consent) events.
6465
+ feedback_rating: positive ? "helpful" : "not_helpful",
6466
+ surface: "agent_panel",
6467
+ index_id: input.indexId,
6468
+ index_version: input.version,
6469
+ message_id: input.messageId,
6470
+ ...input.agentSessionId ? { agent_session_id: input.agentSessionId } : {},
6471
+ ...input.analytics.trackingConsent && input.query ? { query: input.query } : {},
6472
+ ...input.analytics.trackingConsent && answer ? { answer } : {}
6473
+ };
6474
+ }
6475
+ function sendAgentAnswerFeedback(eventUrl, event) {
6476
+ try {
6477
+ void fetch(eventUrl, {
6478
+ body: JSON.stringify(event),
6479
+ credentials: "omit",
6480
+ headers: { "Content-Type": "application/json" },
6481
+ keepalive: true,
6482
+ method: "POST"
6483
+ }).catch(() => {
6484
+ });
6485
+ } catch {
6486
+ }
6487
+ }
6488
+
5478
6489
  // src/react/components/AgentWidget/AgentWidget.tsx
5479
- var import_jsx_runtime16 = require("react/jsx-runtime");
6490
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5480
6491
  function AgentWidget({
5481
6492
  indexId,
5482
6493
  customerId,
@@ -5490,13 +6501,14 @@ function AgentWidget({
5490
6501
  registerPanelController = false,
5491
6502
  colorScheme = "auto",
5492
6503
  branding,
6504
+ analytics,
5493
6505
  toolResultRegistry
5494
6506
  }) {
5495
6507
  const isMobile = useIsMobile();
5496
6508
  const placement = normalizeAgentPlacement(placementInput);
5497
- const railSlotRef = (0, import_react12.useRef)(null);
5498
- const [railCollapsed, setRailCollapsed] = (0, import_react12.useState)(defaultCollapsed);
5499
- const [railExpanded, setRailExpanded] = (0, import_react12.useState)(false);
6509
+ const railSlotRef = (0, import_react15.useRef)(null);
6510
+ const [railCollapsed, setRailCollapsed] = (0, import_react15.useState)(defaultCollapsed);
6511
+ const [railExpanded, setRailExpanded] = (0, import_react15.useState)(false);
5500
6512
  const pageShiftActive = shouldApplyPageShift({
5501
6513
  pageShift,
5502
6514
  isMobile,
@@ -5507,7 +6519,17 @@ function AgentWidget({
5507
6519
  active: pageShiftActive,
5508
6520
  railSlotRef
5509
6521
  });
5510
- const { state, reset, retry, respondToInput, respondToToolInput, submit } = useAgentChat({
6522
+ const {
6523
+ state,
6524
+ reset,
6525
+ retry,
6526
+ regenerate,
6527
+ respondToInput,
6528
+ respondToToolInput,
6529
+ submit,
6530
+ visitorSessionId,
6531
+ sessionId
6532
+ } = useAgentChat({
5511
6533
  customerId,
5512
6534
  getUnpublishedPreviewGrant,
5513
6535
  indexId,
@@ -5539,7 +6561,7 @@ function AgentWidget({
5539
6561
  } : {},
5540
6562
  ...branding?.colors?.border ? { border: branding.colors.border } : {}
5541
6563
  };
5542
- (0, import_react12.useEffect)(() => {
6564
+ (0, import_react15.useEffect)(() => {
5543
6565
  if (!registerPanelController) return;
5544
6566
  registerAgentPanelController(customerId, {
5545
6567
  open: () => setRailCollapsed(false),
@@ -5556,7 +6578,25 @@ function AgentWidget({
5556
6578
  if (isMobile) setRailCollapsed(false);
5557
6579
  await submit(message);
5558
6580
  }
5559
- (0, import_react12.useEffect)(() => {
6581
+ function handleFeedback(rating, message) {
6582
+ if (!analytics) return;
6583
+ sendAgentAnswerFeedback(
6584
+ analytics.eventUrl,
6585
+ buildAgentAnswerFeedbackEvent({
6586
+ agentSessionId: sessionId,
6587
+ analytics,
6588
+ indexId,
6589
+ messageId: message.id,
6590
+ page: window.location.href,
6591
+ query: findPrecedingVisitorText(state.messages, message.id),
6592
+ answer: message.text,
6593
+ rating,
6594
+ version: version ?? "published",
6595
+ visitorSessionId
6596
+ })
6597
+ );
6598
+ }
6599
+ (0, import_react15.useEffect)(() => {
5560
6600
  if (railCollapsed) return;
5561
6601
  const handleKeyDown = (event) => {
5562
6602
  if (event.key === "Tab" && (isMobile || railExpanded)) {
@@ -5590,19 +6630,19 @@ function AgentWidget({
5590
6630
  window.addEventListener("keydown", handleKeyDown);
5591
6631
  return () => window.removeEventListener("keydown", handleKeyDown);
5592
6632
  }, [isMobile, railCollapsed, railExpanded]);
5593
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "webless-agent-root", children: [
5594
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6633
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "webless-agent-root", children: [
6634
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5595
6635
  "div",
5596
6636
  {
5597
6637
  className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
5598
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6638
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5599
6639
  "div",
5600
6640
  {
5601
6641
  ref: railSlotRef,
5602
6642
  className: "webless-agent-root__rail-slot",
5603
6643
  inert: railCollapsed || void 0,
5604
6644
  "aria-hidden": railCollapsed,
5605
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6645
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5606
6646
  AgentRail,
5607
6647
  {
5608
6648
  theme,
@@ -5611,6 +6651,9 @@ function AgentWidget({
5611
6651
  brandLogoUrl: branding?.logoUrl,
5612
6652
  composerPlaceholder: branding?.composerPlaceholder ?? "Ask a question\u2026",
5613
6653
  poweredByLabel: branding?.poweredByLabel ?? "Powered by Webless",
6654
+ disclaimerLabel: branding?.disclaimer,
6655
+ answerReceipt: branding?.answerReceipt,
6656
+ readAloud: branding?.readAloud,
5614
6657
  state,
5615
6658
  mobileFullscreen: isMobile && !railCollapsed,
5616
6659
  expanded: railExpanded,
@@ -5620,17 +6663,22 @@ function AgentWidget({
5620
6663
  onSubmit: handleSubmit,
5621
6664
  onReset: reset,
5622
6665
  onRetry: () => void retry(),
6666
+ onRegenerate: () => void regenerate(),
6667
+ onFeedback: analytics ? handleFeedback : void 0,
5623
6668
  onInputResponse: (response) => void respondToInput(response),
5624
6669
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5625
6670
  onFollowUpSelect: (label) => void handleSubmit(label),
5626
- onBook: (input) => void submit(input.displayText, { runtimeText: input.runtimeText })
6671
+ onBook: (input) => void submit(input.displayText, {
6672
+ preservePendingOffer: true,
6673
+ runtimeText: input.runtimeText
6674
+ })
5627
6675
  }
5628
6676
  )
5629
6677
  }
5630
6678
  )
5631
6679
  }
5632
6680
  ),
5633
- railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6681
+ railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5634
6682
  AssistEdgeTab,
5635
6683
  {
5636
6684
  variant: placement.variant,
@@ -5656,21 +6704,26 @@ function AgentWidget({
5656
6704
  }
5657
6705
  // Annotate the CommonJS export names for ESM import in node:
5658
6706
  0 && (module.exports = {
6707
+ AGENT_ANSWER_FEEDBACK_EVENT_TYPE,
5659
6708
  AGENT_STRUCTURED_TOOL_INPUT_HEADER,
5660
6709
  AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION,
5661
6710
  AgentRail,
5662
6711
  AgentWidget,
5663
6712
  AssistEdgeTab,
5664
6713
  DEFAULT_AGENT_PLACEMENT,
6714
+ MessageActions,
6715
+ buildAgentAnswerFeedbackEvent,
5665
6716
  builtInVisitorToolResultRegistry,
5666
6717
  createIdleSuggestions,
5667
6718
  defaultAgentRailTheme,
5668
6719
  defaultDarkAgentRailTheme,
6720
+ findPrecedingVisitorText,
5669
6721
  formatAgentStructuredToolInput,
5670
6722
  hasVisitorMessages,
5671
6723
  isAgentBusy,
5672
6724
  normalizeAgentPlacement,
5673
6725
  presentVisitorToolResult,
6726
+ sendAgentAnswerFeedback,
5674
6727
  useAgentChat
5675
6728
  });
5676
6729
  //# sourceMappingURL=react.cjs.map