@webless/agent 0.6.10 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -780,6 +780,30 @@ function bookingPresenter(kind) {
780
780
  }
781
781
  };
782
782
  }
783
+ function providerErrorPresenter() {
784
+ return {
785
+ kind: "provider_error",
786
+ present: ({ envelope }) => {
787
+ const output = asRecord3(envelope.output);
788
+ const providerError = asRecord3(output?.providerError);
789
+ const message = safeText(providerError?.message);
790
+ const action = safeText(providerError?.action);
791
+ if (!message || !action) return null;
792
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
793
+ return {
794
+ kind: "summary",
795
+ status: "failed",
796
+ title: message,
797
+ description: action,
798
+ ...resourceLabels.length ? {
799
+ details: [
800
+ { label: "Affected", value: resourceLabels.join(", ") }
801
+ ]
802
+ } : {}
803
+ };
804
+ }
805
+ };
806
+ }
783
807
  function asRecord3(value) {
784
808
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
785
809
  }
@@ -897,6 +921,7 @@ function fallbackTitleFromKind(kind) {
897
921
  return "Saved";
898
922
  }
899
923
  var builtInVisitorToolResultRegistry = [
924
+ providerErrorPresenter(),
900
925
  bookingPresenter("booking_offer"),
901
926
  bookingPresenter("booking_confirmed"),
902
927
  bookingPresenter("booking_canceled"),
@@ -946,7 +971,7 @@ function finalizeSummaryPresentation(result, proposed) {
946
971
  return {
947
972
  id: result.callId,
948
973
  toolName: result.toolName,
949
- status: result.status,
974
+ status: proposed.status ?? result.status,
950
975
  kind: "summary",
951
976
  title,
952
977
  ...description && description !== title ? { description } : {},
@@ -955,7 +980,7 @@ function finalizeSummaryPresentation(result, proposed) {
955
980
  };
956
981
  }
957
982
  function presentVisitorToolResult(result, registry = []) {
958
- const envelope = parseAgentToolResultEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
983
+ const envelope = parseAgentToolResultEnvelope(result.output) ?? providerErrorEnvelope(result.output) ?? legacyBookingEnvelope(result.output);
959
984
  const proposed = envelope ? resolvePresenterOutput(result, envelope, registry) : null;
960
985
  if (proposed?.kind === "booking") {
961
986
  return {
@@ -1018,6 +1043,25 @@ function presentVisitorToolResult(result, registry = []) {
1018
1043
  }
1019
1044
  return finalizeSummaryPresentation(result, proposed);
1020
1045
  }
1046
+ function providerErrorEnvelope(output) {
1047
+ const record = asRecord3(output);
1048
+ const providerError = asRecord3(record?.providerError);
1049
+ const message = safeText(providerError?.message);
1050
+ const action = safeText(providerError?.action);
1051
+ if (!message || !action) return null;
1052
+ const resourceLabels = Array.isArray(providerError?.resourceLabels) ? providerError.resourceLabels.map(safeText).filter(Boolean).slice(0, MAX_DETAILS) : [];
1053
+ return {
1054
+ schemaVersion: "webless.tool-result.v1",
1055
+ output: {
1056
+ providerError: {
1057
+ action,
1058
+ message,
1059
+ ...resourceLabels.length ? { resourceLabels } : {}
1060
+ }
1061
+ },
1062
+ presentationKinds: ["provider_error"]
1063
+ };
1064
+ }
1021
1065
  function legacyBookingEnvelope(output) {
1022
1066
  const card = bookingCardFromActionOutput(output);
1023
1067
  return card ? {
@@ -2702,6 +2746,7 @@ function useAgentChat({
2702
2746
  let streamStarted = Boolean(initialText);
2703
2747
  let streamed = initialText;
2704
2748
  const capturedOffers = [];
2749
+ let bookingConfirmed = false;
2705
2750
  let capturedInputCount = 0;
2706
2751
  const handlers = {
2707
2752
  onWork: (item) => {
@@ -2726,6 +2771,7 @@ function useAgentChat({
2726
2771
  }
2727
2772
  if (!isActiveRun()) return;
2728
2773
  if (card.type === "booking_confirmed") {
2774
+ bookingConfirmed = true;
2729
2775
  pendingBookingRef.current = card;
2730
2776
  savePendingWidgetBooking(
2731
2777
  resolvedStorageKeyPrefix,
@@ -2801,7 +2847,10 @@ function useAgentChat({
2801
2847
  initialText,
2802
2848
  message: visitorText,
2803
2849
  signal
2804
- }) : await clientRef.current.sendTurn(visitorText, { handlers, signal });
2850
+ }) : await clientRef.current.sendTurn(visitorText, {
2851
+ handlers,
2852
+ signal
2853
+ });
2805
2854
  if (resume && finalText === null) {
2806
2855
  finalText = await clientRef.current.sendTurn(visitorText, {
2807
2856
  handlers,
@@ -2820,6 +2869,7 @@ function useAgentChat({
2820
2869
  const parsedCards = extractToolCards(displayText);
2821
2870
  for (const card of parsedCards) {
2822
2871
  if (card.type === "booking_confirmed") {
2872
+ bookingConfirmed = true;
2823
2873
  pendingBookingRef.current = card;
2824
2874
  savePendingWidgetBooking(resolvedStorageKeyPrefix, visitorId, card);
2825
2875
  }
@@ -2834,7 +2884,7 @@ function useAgentChat({
2834
2884
  messages: appendAgentTurnMessage(prev.messages, displayText),
2835
2885
  toolSteps: completeActivePlanning(prev.toolSteps),
2836
2886
  streamingText: "",
2837
- pendingOffer: capturedOffers.at(-1) ?? prev.pendingOffer,
2887
+ pendingOffer: bookingConfirmed ? null : capturedOffers.at(-1) ?? prev.pendingOffer,
2838
2888
  pendingInputs: (prev.pendingInputs ?? []).filter(
2839
2889
  isChatCollectibleInputRequest
2840
2890
  ),
@@ -2860,7 +2910,6 @@ function useAgentChat({
2860
2910
  } : step
2861
2911
  ),
2862
2912
  streamingText: "",
2863
- pendingOffer: null,
2864
2913
  error: message
2865
2914
  }));
2866
2915
  runRef.current = null;
@@ -2968,7 +3017,7 @@ ${outgoing}` : outgoing;
2968
3017
  journey: null,
2969
3018
  followUps: [],
2970
3019
  streamingText: "",
2971
- pendingOffer: null,
3020
+ pendingOffer: options?.preservePendingOffer ? prev.pendingOffer : null,
2972
3021
  pendingInputs: [],
2973
3022
  toolResults: [],
2974
3023
  error: null
@@ -3004,7 +3053,6 @@ ${outgoing}` : outgoing;
3004
3053
  journey: null,
3005
3054
  followUps: [],
3006
3055
  streamingText: "",
3007
- pendingOffer: null,
3008
3056
  pendingInputs: [],
3009
3057
  toolResults: [],
3010
3058
  error: null
@@ -3651,6 +3699,7 @@ function BookingCardLoader() {
3651
3699
  return /* @__PURE__ */ jsx4("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsx4("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) });
3652
3700
  }
3653
3701
  function BookingCard({
3702
+ disabled = false,
3654
3703
  offer,
3655
3704
  onBook
3656
3705
  }) {
@@ -3746,216 +3795,230 @@ function BookingCard({
3746
3795
  })
3747
3796
  });
3748
3797
  }
3749
- return /* @__PURE__ */ jsx4("section", { className: "booking-card", "aria-label": "Book a meeting", children: /* @__PURE__ */ jsxs4("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3750
- /* @__PURE__ */ jsx4("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ jsxs4(
3751
- "li",
3752
- {
3753
- className: [
3754
- "booking-card__step-indicator",
3755
- index === stepIndex ? "booking-card__step-indicator--active" : "",
3756
- index < stepIndex ? "booking-card__step-indicator--complete" : ""
3757
- ].filter(Boolean).join(" "),
3758
- "aria-current": index === stepIndex ? "step" : void 0,
3759
- children: [
3760
- /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: index + 1 }),
3761
- /* @__PURE__ */ jsx4("span", { children: item.label })
3762
- ]
3763
- },
3764
- item.id
3765
- )) }),
3766
- step === "date" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3767
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3768
- timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3769
- "Times in ",
3770
- timeZone
3771
- ] }) : null,
3772
- offer.eventTypes.length > 1 ? /* @__PURE__ */ jsxs4(
3773
- "label",
3774
- {
3775
- className: "booking-card__field",
3776
- htmlFor: `${fieldId}-type`,
3777
- children: [
3778
- /* @__PURE__ */ jsx4("span", { children: "Meeting" }),
3798
+ return /* @__PURE__ */ jsx4(
3799
+ "section",
3800
+ {
3801
+ className: "booking-card",
3802
+ "aria-busy": disabled || void 0,
3803
+ "aria-label": "Book a meeting",
3804
+ children: /* @__PURE__ */ jsxs4("form", { className: "booking-card__form", onSubmit: handleSubmit, children: [
3805
+ /* @__PURE__ */ jsx4("ol", { className: "booking-card__steps", "aria-label": "Booking steps", children: BOOKING_STEPS.map((item, index) => /* @__PURE__ */ jsxs4(
3806
+ "li",
3807
+ {
3808
+ className: [
3809
+ "booking-card__step-indicator",
3810
+ index === stepIndex ? "booking-card__step-indicator--active" : "",
3811
+ index < stepIndex ? "booking-card__step-indicator--complete" : ""
3812
+ ].filter(Boolean).join(" "),
3813
+ "aria-current": index === stepIndex ? "step" : void 0,
3814
+ children: [
3815
+ /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: index + 1 }),
3816
+ /* @__PURE__ */ jsx4("span", { children: item.label })
3817
+ ]
3818
+ },
3819
+ item.id
3820
+ )) }),
3821
+ step === "date" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3822
+ /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
3823
+ timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3824
+ "Times in ",
3825
+ timeZone
3826
+ ] }) : null,
3827
+ offer.eventTypes.length > 1 ? /* @__PURE__ */ jsxs4(
3828
+ "label",
3829
+ {
3830
+ className: "booking-card__field",
3831
+ htmlFor: `${fieldId}-type`,
3832
+ children: [
3833
+ /* @__PURE__ */ jsx4("span", { children: "Meeting" }),
3834
+ /* @__PURE__ */ jsx4(
3835
+ "select",
3836
+ {
3837
+ id: `${fieldId}-type`,
3838
+ value: eventTypeUri,
3839
+ disabled,
3840
+ onChange: (event) => selectEventType(event.target.value),
3841
+ children: offer.eventTypes.map((item) => /* @__PURE__ */ jsx4("option", { value: item.uri, children: item.name }, item.uri))
3842
+ }
3843
+ )
3844
+ ]
3845
+ }
3846
+ ) : null,
3847
+ /* @__PURE__ */ jsxs4("div", { className: "booking-card__month", children: [
3779
3848
  /* @__PURE__ */ jsx4(
3780
- "select",
3849
+ "button",
3781
3850
  {
3782
- id: `${fieldId}-type`,
3783
- value: eventTypeUri,
3784
- onChange: (event) => selectEventType(event.target.value),
3785
- children: offer.eventTypes.map((item) => /* @__PURE__ */ jsx4("option", { value: item.uri, children: item.name }, item.uri))
3851
+ type: "button",
3852
+ className: "booking-card__nav",
3853
+ "aria-label": "Previous month",
3854
+ disabled: disabled || !canPrevMonth,
3855
+ onClick: () => goToMonth(-1),
3856
+ children: "\u2039"
3857
+ }
3858
+ ),
3859
+ /* @__PURE__ */ jsx4("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3860
+ /* @__PURE__ */ jsx4(
3861
+ "button",
3862
+ {
3863
+ type: "button",
3864
+ className: "booking-card__nav",
3865
+ "aria-label": "Next month",
3866
+ disabled: disabled || !canNextMonth,
3867
+ onClick: () => goToMonth(1),
3868
+ children: "\u203A"
3786
3869
  }
3787
3870
  )
3788
- ]
3789
- }
3790
- ) : null,
3791
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__month", children: [
3792
- /* @__PURE__ */ jsx4(
3793
- "button",
3794
- {
3795
- type: "button",
3796
- className: "booking-card__nav",
3797
- "aria-label": "Previous month",
3798
- disabled: !canPrevMonth,
3799
- onClick: () => goToMonth(-1),
3800
- children: "\u2039"
3801
- }
3802
- ),
3803
- /* @__PURE__ */ jsx4("p", { className: "booking-card__month-title", children: formatMonthTitle(visibleMonth.year, visibleMonth.month) }),
3804
- /* @__PURE__ */ jsx4(
3805
- "button",
3806
- {
3807
- type: "button",
3808
- className: "booking-card__nav",
3809
- "aria-label": "Next month",
3810
- disabled: !canNextMonth,
3811
- onClick: () => goToMonth(1),
3812
- children: "\u203A"
3813
- }
3814
- )
3815
- ] }),
3816
- /* @__PURE__ */ jsx4("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ jsx4("span", { children: label }, label)) }),
3817
- offer.slots.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3818
- /* @__PURE__ */ jsx4(
3819
- "div",
3820
- {
3821
- className: "booking-card__calendar",
3822
- role: "grid",
3823
- "aria-label": "Available dates",
3824
- children: cells.map((cell, index) => {
3825
- if (!cell) {
3826
- return /* @__PURE__ */ jsx4(
3827
- "span",
3828
- {
3829
- className: "booking-card__day"
3830
- },
3831
- `empty-${index}`
3832
- );
3871
+ ] }),
3872
+ /* @__PURE__ */ jsx4("div", { className: "booking-card__weekdays", children: weekdays.map((label) => /* @__PURE__ */ jsx4("span", { children: label }, label)) }),
3873
+ offer.slots.length === 0 ? /* @__PURE__ */ jsx4("p", { className: "booking-card__loading", role: "status", children: "Finding available times\u2026" }) : null,
3874
+ /* @__PURE__ */ jsx4(
3875
+ "div",
3876
+ {
3877
+ className: "booking-card__calendar",
3878
+ role: "grid",
3879
+ "aria-label": "Available dates",
3880
+ children: cells.map((cell, index) => {
3881
+ if (!cell) {
3882
+ return /* @__PURE__ */ jsx4(
3883
+ "span",
3884
+ {
3885
+ className: "booking-card__day"
3886
+ },
3887
+ `empty-${index}`
3888
+ );
3889
+ }
3890
+ const available = availableByDate.has(cell.key);
3891
+ const selected = cell.key === selectedDate;
3892
+ return /* @__PURE__ */ jsx4(
3893
+ "button",
3894
+ {
3895
+ type: "button",
3896
+ className: [
3897
+ "booking-card__day",
3898
+ available ? "booking-card__day--available" : "",
3899
+ selected ? "booking-card__day--selected" : ""
3900
+ ].filter(Boolean).join(" "),
3901
+ disabled: disabled || !available,
3902
+ "aria-pressed": selected,
3903
+ onClick: () => selectDate(cell.key),
3904
+ children: cell.day
3905
+ },
3906
+ cell.key
3907
+ );
3908
+ })
3833
3909
  }
3834
- const available = availableByDate.has(cell.key);
3835
- const selected = cell.key === selectedDate;
3836
- return /* @__PURE__ */ jsx4(
3910
+ )
3911
+ ] }, "date") : null,
3912
+ step === "time" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3913
+ /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3914
+ /* @__PURE__ */ jsx4(
3837
3915
  "button",
3838
3916
  {
3839
3917
  type: "button",
3840
- className: [
3841
- "booking-card__day",
3842
- available ? "booking-card__day--available" : "",
3843
- selected ? "booking-card__day--selected" : ""
3844
- ].filter(Boolean).join(" "),
3845
- disabled: !available,
3846
- "aria-pressed": selected,
3847
- onClick: () => selectDate(cell.key),
3848
- children: cell.day
3849
- },
3850
- cell.key
3851
- );
3852
- })
3853
- }
3854
- )
3855
- ] }, "date") : null,
3856
- step === "time" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3857
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3858
- /* @__PURE__ */ jsx4(
3859
- "button",
3860
- {
3861
- type: "button",
3862
- className: "booking-card__nav",
3863
- "aria-label": "Back to dates",
3864
- onClick: () => setStep("date"),
3865
- children: "\u2039"
3866
- }
3867
- ),
3868
- /* @__PURE__ */ jsxs4("div", { children: [
3869
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
3870
- timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3871
- "Times in ",
3872
- timeZone
3873
- ] }) : null
3874
- ] })
3875
- ] }),
3876
- /* @__PURE__ */ jsx4("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ jsx4(
3877
- "button",
3878
- {
3879
- type: "button",
3880
- className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
3881
- onClick: () => selectTime(slot.startTime),
3882
- children: formatTimeChip(slot.startTime)
3883
- },
3884
- slot.startTime
3885
- )) })
3886
- ] }, "time") : null,
3887
- step === "details" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3888
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3889
- /* @__PURE__ */ jsx4(
3890
- "button",
3891
- {
3892
- type: "button",
3893
- className: "booking-card__nav",
3894
- "aria-label": "Back to times",
3895
- onClick: () => setStep("time"),
3896
- children: "\u2039"
3897
- }
3898
- ),
3899
- /* @__PURE__ */ jsxs4("div", { children: [
3900
- /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: "Enter details" }),
3901
- /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
3902
- selectedType?.location ? /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: selectedType.location }) : null
3903
- ] })
3904
- ] }),
3905
- /* @__PURE__ */ jsxs4("div", { className: "booking-card__identity", children: [
3906
- /* @__PURE__ */ jsxs4(
3907
- "label",
3908
- {
3909
- className: "booking-card__field",
3910
- htmlFor: `${fieldId}-name`,
3911
- children: [
3912
- /* @__PURE__ */ jsx4("span", { children: "Name" }),
3913
- /* @__PURE__ */ jsx4(
3914
- "input",
3915
- {
3916
- id: `${fieldId}-name`,
3917
- autoComplete: "name",
3918
- value: name,
3919
- onChange: (event) => setName(event.target.value),
3920
- required: true
3921
- }
3922
- )
3923
- ]
3924
- }
3925
- ),
3926
- /* @__PURE__ */ jsxs4(
3927
- "label",
3928
- {
3929
- className: "booking-card__field",
3930
- htmlFor: `${fieldId}-email`,
3931
- children: [
3932
- /* @__PURE__ */ jsx4("span", { children: "Email" }),
3933
- /* @__PURE__ */ jsx4(
3934
- "input",
3935
- {
3936
- id: `${fieldId}-email`,
3937
- type: "email",
3938
- autoComplete: "email",
3939
- value: email,
3940
- onChange: (event) => setEmail(event.target.value),
3941
- required: true
3942
- }
3943
- )
3944
- ]
3945
- }
3946
- )
3947
- ] }),
3948
- /* @__PURE__ */ jsx4(
3949
- "button",
3950
- {
3951
- type: "submit",
3952
- className: "booking-card__submit",
3953
- disabled: !name.trim() || !email.trim(),
3954
- children: "Book this time"
3955
- }
3956
- )
3957
- ] }, "details") : null
3958
- ] }) });
3918
+ className: "booking-card__nav",
3919
+ "aria-label": "Back to dates",
3920
+ disabled,
3921
+ onClick: () => setStep("date"),
3922
+ children: "\u2039"
3923
+ }
3924
+ ),
3925
+ /* @__PURE__ */ jsxs4("div", { children: [
3926
+ /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedSample ? formatLongDate(selectedSample) : "Pick a time" }),
3927
+ timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
3928
+ "Times in ",
3929
+ timeZone
3930
+ ] }) : null
3931
+ ] })
3932
+ ] }),
3933
+ /* @__PURE__ */ jsx4("div", { className: "booking-card__times", children: daySlots.map((slot) => /* @__PURE__ */ jsx4(
3934
+ "button",
3935
+ {
3936
+ type: "button",
3937
+ className: startTime === slot.startTime ? "booking-card__time booking-card__time--selected" : "booking-card__time",
3938
+ disabled,
3939
+ onClick: () => selectTime(slot.startTime),
3940
+ children: formatTimeChip(slot.startTime)
3941
+ },
3942
+ slot.startTime
3943
+ )) })
3944
+ ] }, "time") : null,
3945
+ step === "details" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
3946
+ /* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
3947
+ /* @__PURE__ */ jsx4(
3948
+ "button",
3949
+ {
3950
+ type: "button",
3951
+ className: "booking-card__nav",
3952
+ "aria-label": "Back to times",
3953
+ disabled,
3954
+ onClick: () => setStep("time"),
3955
+ children: "\u2039"
3956
+ }
3957
+ ),
3958
+ /* @__PURE__ */ jsxs4("div", { children: [
3959
+ /* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: "Enter details" }),
3960
+ /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: formatSlotLabel(startTime) }),
3961
+ selectedType?.location ? /* @__PURE__ */ jsx4("p", { className: "booking-card__tz", children: selectedType.location }) : null
3962
+ ] })
3963
+ ] }),
3964
+ /* @__PURE__ */ jsxs4("div", { className: "booking-card__identity", children: [
3965
+ /* @__PURE__ */ jsxs4(
3966
+ "label",
3967
+ {
3968
+ className: "booking-card__field",
3969
+ htmlFor: `${fieldId}-name`,
3970
+ children: [
3971
+ /* @__PURE__ */ jsx4("span", { children: "Name" }),
3972
+ /* @__PURE__ */ jsx4(
3973
+ "input",
3974
+ {
3975
+ id: `${fieldId}-name`,
3976
+ autoComplete: "name",
3977
+ disabled,
3978
+ value: name,
3979
+ onChange: (event) => setName(event.target.value),
3980
+ required: true
3981
+ }
3982
+ )
3983
+ ]
3984
+ }
3985
+ ),
3986
+ /* @__PURE__ */ jsxs4(
3987
+ "label",
3988
+ {
3989
+ className: "booking-card__field",
3990
+ htmlFor: `${fieldId}-email`,
3991
+ children: [
3992
+ /* @__PURE__ */ jsx4("span", { children: "Email" }),
3993
+ /* @__PURE__ */ jsx4(
3994
+ "input",
3995
+ {
3996
+ id: `${fieldId}-email`,
3997
+ type: "email",
3998
+ autoComplete: "email",
3999
+ disabled,
4000
+ value: email,
4001
+ onChange: (event) => setEmail(event.target.value),
4002
+ required: true
4003
+ }
4004
+ )
4005
+ ]
4006
+ }
4007
+ )
4008
+ ] }),
4009
+ /* @__PURE__ */ jsx4(
4010
+ "button",
4011
+ {
4012
+ type: "submit",
4013
+ className: "booking-card__submit",
4014
+ disabled: disabled || !name.trim() || !email.trim(),
4015
+ children: disabled ? "Booking\u2026" : "Book this time"
4016
+ }
4017
+ )
4018
+ ] }, "details") : null
4019
+ ] })
4020
+ }
4021
+ );
3959
4022
  }
3960
4023
 
3961
4024
  // src/react/components/MessageBubble/MessageBubble.tsx
@@ -3972,9 +4035,7 @@ function paragraphsAreNearDuplicates(first, second) {
3972
4035
  if (left === right) return true;
3973
4036
  const shorter = left.length <= right.length ? left : right;
3974
4037
  const longer = left.length <= right.length ? right : left;
3975
- return longer.startsWith(
3976
- shorter.slice(0, Math.floor(shorter.length * 0.85))
3977
- );
4038
+ return longer.startsWith(shorter.slice(0, Math.floor(shorter.length * 0.85)));
3978
4039
  }
3979
4040
  function paragraphsShareOpening(first, second) {
3980
4041
  const opening = first.split("\n")[0]?.trim();
@@ -4002,6 +4063,7 @@ function collapseRepeatedText(text) {
4002
4063
  function MessageBubble({
4003
4064
  message,
4004
4065
  brandLogoUrl,
4066
+ bookingDisabled = false,
4005
4067
  offer,
4006
4068
  onBook
4007
4069
  }) {
@@ -4037,18 +4099,17 @@ function MessageBubble({
4037
4099
  children: displayText
4038
4100
  }
4039
4101
  ),
4040
- citations.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsxs5(
4041
- "a",
4042
- {
4043
- href: citation.url,
4044
- target: "_blank",
4045
- rel: "noreferrer",
4046
- children: [
4047
- /* @__PURE__ */ jsx5("span", { className: "message-bubble__source-icon", "aria-hidden": "true", children: "\u25A6" }),
4048
- /* @__PURE__ */ jsx5("span", { children: citation.label })
4049
- ]
4050
- }
4051
- ) }, citation.id)) }) : null
4102
+ citations.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "message-bubble__sources", "aria-label": "Sources", children: citations.map((citation) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsxs5("a", { href: citation.url, target: "_blank", rel: "noreferrer", children: [
4103
+ /* @__PURE__ */ jsx5(
4104
+ "span",
4105
+ {
4106
+ className: "message-bubble__source-icon",
4107
+ "aria-hidden": "true",
4108
+ children: "\u25A6"
4109
+ }
4110
+ ),
4111
+ /* @__PURE__ */ jsx5("span", { children: citation.label })
4112
+ ] }) }, citation.id)) }) : null
4052
4113
  ] });
4053
4114
  return /* @__PURE__ */ jsxs5("article", { className: "message-bubble message-bubble--agent", children: [
4054
4115
  displayText ? showBrandLogo ? /* @__PURE__ */ jsxs5("div", { className: "message-bubble__agent-row", children: [
@@ -4067,6 +4128,7 @@ function MessageBubble({
4067
4128
  offers.map((nextOffer, index) => /* @__PURE__ */ jsx5(
4068
4129
  BookingCard,
4069
4130
  {
4131
+ disabled: bookingDisabled,
4070
4132
  offer: nextOffer,
4071
4133
  onBook
4072
4134
  },
@@ -5046,6 +5108,7 @@ function AgentRail({
5046
5108
  MessageBubble,
5047
5109
  {
5048
5110
  message: greeting,
5111
+ bookingDisabled: isBusy,
5049
5112
  brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5050
5113
  onBook
5051
5114
  }
@@ -5091,6 +5154,7 @@ function AgentRail({
5091
5154
  MessageBubble,
5092
5155
  {
5093
5156
  message,
5157
+ bookingDisabled: isBusy,
5094
5158
  brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5095
5159
  offer: index === lastAgentIndex ? state.pendingOffer : void 0,
5096
5160
  onBook
@@ -5129,6 +5193,7 @@ function AgentRail({
5129
5193
  MessageBubble,
5130
5194
  {
5131
5195
  message: streamingMessage,
5196
+ bookingDisabled: isBusy,
5132
5197
  brandLogoUrl: showBrandLogo ? resolvedBrandLogoUrl : void 0,
5133
5198
  offer: state.pendingOffer,
5134
5199
  onBook
@@ -5614,7 +5679,10 @@ function AgentWidget({
5614
5679
  onInputResponse: (response) => void respondToInput(response),
5615
5680
  onToolInput: (surface, values) => void respondToToolInput(surface, values),
5616
5681
  onFollowUpSelect: (label) => void handleSubmit(label),
5617
- onBook: (input) => void submit(input.displayText, { runtimeText: input.runtimeText })
5682
+ onBook: (input) => void submit(input.displayText, {
5683
+ preservePendingOffer: true,
5684
+ runtimeText: input.runtimeText
5685
+ })
5618
5686
  }
5619
5687
  )
5620
5688
  }
@@ -5670,4 +5738,4 @@ export {
5670
5738
  AssistEdgeTab,
5671
5739
  AgentWidget
5672
5740
  };
5673
- //# sourceMappingURL=chunk-NEI5GKGH.js.map
5741
+ //# sourceMappingURL=chunk-YNF2UPGJ.js.map