@brainfish-ai/components 0.18.7 → 0.19.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.
@@ -58,7 +58,12 @@ declare enum ActionType {
58
58
  CallPhone = "call_phone",
59
59
  OpenUrl = "open_url",
60
60
  SendEmail = "send_email",
61
- RunCallback = "run_callback"
61
+ RunCallback = "run_callback",
62
+ LaunchIntercomChat = "launch_intercom_chat",
63
+ LaunchZendeskChat = "launch_zendesk_chat",
64
+ LaunchZendeskMessenger = "launch_zendesk_messenger",
65
+ LaunchFreshdesk = "launch_freshdesk",
66
+ LaunchSupportTicketForm = "launch_support_ticket_form"
62
67
  }
63
68
 
64
69
  declare type AddActionButtons = {
@@ -94,6 +99,7 @@ export declare interface Answer {
94
99
  uncertaintyFallbackText?: string;
95
100
  searchIntentId?: string;
96
101
  actions?: Action[];
102
+ hasError?: boolean;
97
103
  }
98
104
 
99
105
  declare type AnswerBlock = MarkdownTextBlock | ActionButtonsBlock | ActionInputFormBlock;
@@ -327,7 +333,11 @@ declare enum NextBestActionType {
327
333
  Email = "email",
328
334
  Phone = "phone",
329
335
  Callback = "callback",
330
- Function = "function"
336
+ Function = "function",
337
+ ZendeskChat = "zendesk_chat",
338
+ ZendeskMessenger = "zendesk_messenger",
339
+ IntercomChat = "intercom_chat",
340
+ Freshdesk = "freshdesk"
331
341
  }
332
342
 
333
343
  declare type NoArticlesFound = {
@@ -1,4 +1,4 @@
1
- import React__default, { useState, useCallback, useMemo, createContext, useContext, Fragment, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
1
+ import React__default, { useState, useCallback, useMemo, createContext, useContext, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';
2
2
  import { motion, AnimatePresence } from 'framer-motion';
3
3
  import rehypeRaw from 'rehype-raw';
4
4
  import remarkGfm from 'remark-gfm';
@@ -3677,7 +3677,9 @@ const reducer = (draft, action) => {
3677
3677
  const answer = getTargetAnswer(draft, action.payload.index ?? -1);
3678
3678
  const block = answer && getLastTextBlock(answer);
3679
3679
  if (block && isMarkdownTextBlock(block)) {
3680
- block.text += action.payload.error;
3680
+ block.text = action.payload.error;
3681
+ answer.state = "completed";
3682
+ answer.hasError = true;
3681
3683
  }
3682
3684
  return;
3683
3685
  }
@@ -3691,7 +3693,8 @@ const reducer = (draft, action) => {
3691
3693
  case AnswersActions.COMPLETE_ANSWER: {
3692
3694
  const answer = getTargetAnswer(draft, action.payload.index);
3693
3695
  if (answer) {
3694
- if (answer.state === "streaming") {
3696
+ const shouldComplete = answer.state === "streaming" || answer.state === "fetching-search-results" || answer.state === "fetching-stream";
3697
+ if (shouldComplete) {
3695
3698
  answer.state = "completed";
3696
3699
  }
3697
3700
  }
@@ -3917,7 +3920,51 @@ function AnswerBlock({ block, redirectRules, state }) {
3917
3920
  }
3918
3921
  }
3919
3922
 
3923
+ var ActionType = /* @__PURE__ */ ((ActionType2) => {
3924
+ ActionType2["CallPhone"] = "call_phone";
3925
+ ActionType2["OpenUrl"] = "open_url";
3926
+ ActionType2["SendEmail"] = "send_email";
3927
+ ActionType2["RunCallback"] = "run_callback";
3928
+ ActionType2["LaunchIntercomChat"] = "launch_intercom_chat";
3929
+ ActionType2["LaunchZendeskChat"] = "launch_zendesk_chat";
3930
+ ActionType2["LaunchZendeskMessenger"] = "launch_zendesk_messenger";
3931
+ ActionType2["LaunchFreshdesk"] = "launch_freshdesk";
3932
+ ActionType2["LaunchSupportTicketForm"] = "launch_support_ticket_form";
3933
+ return ActionType2;
3934
+ })(ActionType || {});
3935
+ var NextBestActionType = /* @__PURE__ */ ((NextBestActionType2) => {
3936
+ NextBestActionType2["Link"] = "link";
3937
+ NextBestActionType2["Email"] = "email";
3938
+ NextBestActionType2["Phone"] = "phone";
3939
+ NextBestActionType2["Callback"] = "callback";
3940
+ NextBestActionType2["Function"] = "function";
3941
+ NextBestActionType2["ZendeskChat"] = "zendesk_chat";
3942
+ NextBestActionType2["ZendeskMessenger"] = "zendesk_messenger";
3943
+ NextBestActionType2["IntercomChat"] = "intercom_chat";
3944
+ NextBestActionType2["Freshdesk"] = "freshdesk";
3945
+ return NextBestActionType2;
3946
+ })(NextBestActionType || {});
3947
+
3920
3948
  const MotionButton$1 = motion(Button);
3949
+ const closeBrainfishWidget = () => {
3950
+ if (window.Brainfish?.HelpWidget?.close) {
3951
+ window.Brainfish.HelpWidget.close();
3952
+ }
3953
+ };
3954
+ const ActionButton = ({ icon, label, index, onClick, showArrowOut = false, asChild = false, children }) => /* @__PURE__ */ React__default.createElement(
3955
+ MotionButton$1,
3956
+ {
3957
+ initial: { opacity: 0, x: -20 },
3958
+ animate: { opacity: 1, x: 0 },
3959
+ transition: { delay: index * 0.1 },
3960
+ className: "w-full text-left h-12 text-base [&_svg]:size-6",
3961
+ variant: "ghost",
3962
+ onClick,
3963
+ asChild
3964
+ },
3965
+ asChild ? children : /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: icon }), /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, label), showArrowOut && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" }))
3966
+ );
3967
+ const ActionLink = ({ href, icon, label, index, onClick }) => /* @__PURE__ */ React__default.createElement(ActionButton, { icon, label, index, onClick, asChild: true }, /* @__PURE__ */ React__default.createElement("a", { href, target: "_blank", rel: "noopener noreferrer" }, icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: icon }), /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, label), /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })));
3921
3968
  const NextBestActions = ({ nextBestActions, onActionClick }) => {
3922
3969
  if (!nextBestActions.length) return null;
3923
3970
  return /* @__PURE__ */ React__default.createElement(
@@ -3929,102 +3976,155 @@ const NextBestActions = ({ nextBestActions, onActionClick }) => {
3929
3976
  className: "w-full"
3930
3977
  },
3931
3978
  /* @__PURE__ */ React__default.createElement("div", { className: "rounded-lg overflow-hidden bg-card border divide-y divide-dark-300" }, nextBestActions.map((action, index) => {
3932
- const handleClick = () => {
3933
- onActionClick(action);
3979
+ const handleClick = (success) => {
3980
+ onActionClick(action, success);
3934
3981
  };
3935
- const className = "w-full h-12 py-2 px-4 inline-flex items-center justify-center gap-2 whitespace-nowrap text-base font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground";
3936
3982
  const key = `${action.label}-${index}`.replace(/\s+/g, "-");
3937
3983
  switch (action.type) {
3938
- case "email":
3984
+ case NextBestActionType.Email:
3939
3985
  return /* @__PURE__ */ React__default.createElement(
3940
- motion.a,
3986
+ ActionLink,
3941
3987
  {
3942
3988
  key,
3943
- initial: { opacity: 0, x: -20 },
3944
- animate: { opacity: 1, x: 0 },
3945
- transition: { delay: index * 0.1 },
3946
3989
  href: `mailto:${action.value}`,
3947
- target: "_blank",
3948
- rel: "noopener noreferrer",
3949
- className,
3990
+ icon: action.icon,
3991
+ label: action.label,
3992
+ index,
3950
3993
  onClick: () => handleClick()
3951
- },
3952
- action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
3953
- /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
3954
- /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
3994
+ }
3955
3995
  );
3956
- case "link":
3996
+ case NextBestActionType.Link:
3957
3997
  return /* @__PURE__ */ React__default.createElement(
3958
- motion.a,
3998
+ ActionLink,
3959
3999
  {
3960
4000
  key,
3961
- initial: { opacity: 0, x: -20 },
3962
- animate: { opacity: 1, x: 0 },
3963
- transition: { delay: index * 0.1 },
3964
4001
  href: addPopupWidgetUtm(action.value),
3965
- target: "_blank",
3966
- rel: "noopener noreferrer",
3967
- className,
4002
+ icon: action.icon,
4003
+ label: action.label,
4004
+ index,
3968
4005
  onClick: () => handleClick()
3969
- },
3970
- action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
3971
- /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
3972
- /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
4006
+ }
3973
4007
  );
3974
- case "phone":
4008
+ case NextBestActionType.Phone:
3975
4009
  return /* @__PURE__ */ React__default.createElement(
3976
- motion.a,
4010
+ ActionLink,
3977
4011
  {
3978
4012
  key,
3979
- initial: { opacity: 0, x: -20 },
3980
- animate: { opacity: 1, x: 0 },
3981
- transition: { delay: index * 0.1 },
3982
4013
  href: `tel:${action.value}`,
3983
- target: "_blank",
3984
- rel: "noopener noreferrer",
3985
- className,
4014
+ icon: action.icon,
4015
+ label: action.label,
4016
+ index,
3986
4017
  onClick: () => handleClick()
3987
- },
3988
- action.icon && /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: action.icon }),
3989
- /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
3990
- /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
4018
+ }
4019
+ );
4020
+ case NextBestActionType.ZendeskChat:
4021
+ return /* @__PURE__ */ React__default.createElement(
4022
+ ActionButton,
4023
+ {
4024
+ key,
4025
+ icon: action.icon,
4026
+ label: action.label,
4027
+ index,
4028
+ onClick: () => {
4029
+ if (window.zE) {
4030
+ closeBrainfishWidget();
4031
+ window.zE("webWidget", "open");
4032
+ handleClick(true);
4033
+ } else {
4034
+ console.error(
4035
+ "Zendesk Chat is not loaded. Make sure you've included the Zendesk Chat script in your website."
4036
+ );
4037
+ handleClick(false);
4038
+ }
4039
+ }
4040
+ }
4041
+ );
4042
+ case NextBestActionType.ZendeskMessenger:
4043
+ return /* @__PURE__ */ React__default.createElement(
4044
+ ActionButton,
4045
+ {
4046
+ key,
4047
+ icon: action.icon,
4048
+ label: action.label,
4049
+ index,
4050
+ onClick: () => {
4051
+ if (window.zE) {
4052
+ closeBrainfishWidget();
4053
+ window.zE("messenger", "open");
4054
+ handleClick(true);
4055
+ } else {
4056
+ console.error(
4057
+ "Zendesk Messenger is not loaded. Make sure you've included the Zendesk Messenger script in your website."
4058
+ );
4059
+ handleClick(false);
4060
+ }
4061
+ }
4062
+ }
4063
+ );
4064
+ case NextBestActionType.IntercomChat:
4065
+ return /* @__PURE__ */ React__default.createElement(
4066
+ ActionButton,
4067
+ {
4068
+ key,
4069
+ icon: action.icon,
4070
+ label: action.label,
4071
+ index,
4072
+ onClick: () => {
4073
+ if (window.Intercom) {
4074
+ closeBrainfishWidget();
4075
+ window.Intercom("show");
4076
+ handleClick(true);
4077
+ } else {
4078
+ console.error(
4079
+ "Intercom is not loaded. Make sure you've included the Intercom script in your website."
4080
+ );
4081
+ handleClick(false);
4082
+ }
4083
+ }
4084
+ }
4085
+ );
4086
+ case NextBestActionType.Freshdesk:
4087
+ return /* @__PURE__ */ React__default.createElement(
4088
+ ActionButton,
4089
+ {
4090
+ key,
4091
+ icon: action.icon,
4092
+ label: action.label,
4093
+ index,
4094
+ onClick: () => {
4095
+ if (window.fcWidget) {
4096
+ closeBrainfishWidget();
4097
+ setTimeout(() => {
4098
+ window.fcWidget.open();
4099
+ window.fcWidget.show();
4100
+ }, 300);
4101
+ handleClick(true);
4102
+ } else {
4103
+ console.error(
4104
+ "Freshdesk is not loaded. Make sure you've included the Freshdesk script in your website."
4105
+ );
4106
+ handleClick(false);
4107
+ }
4108
+ }
4109
+ }
3991
4110
  );
3992
4111
  default:
3993
- return /* @__PURE__ */ React__default.createElement(Fragment, { key }, /* @__PURE__ */ React__default.createElement(
3994
- MotionButton$1,
4112
+ return /* @__PURE__ */ React__default.createElement(
4113
+ ActionButton,
3995
4114
  {
3996
- initial: { opacity: 0, x: -20 },
3997
- animate: { opacity: 1, x: 0 },
3998
- transition: { delay: index * 0.1 },
3999
- className: "w-full text-left h-12 rounded-none [&_svg]:pointer-events-none [&_svg]:size-6 [&_svg]:shrink-0 hover:bg-accent hover:text-accent-foreground text-base font-medium",
4000
- variant: "ghost",
4001
- onClick: () => handleClick()
4002
- },
4003
- /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowCircleRight" }),
4004
- /* @__PURE__ */ React__default.createElement("span", { className: "flex-grow" }, action.label),
4005
- /* @__PURE__ */ React__default.createElement(MemoizedIcon, { iconName: "ArrowSquareOut" })
4006
- ));
4115
+ key,
4116
+ icon: "ArrowCircleRight",
4117
+ label: action.label,
4118
+ index,
4119
+ onClick: () => handleClick(),
4120
+ showArrowOut: true
4121
+ }
4122
+ );
4007
4123
  }
4008
4124
  }))
4009
4125
  );
4010
4126
  };
4011
4127
 
4012
- var ActionType = /* @__PURE__ */ ((ActionType2) => {
4013
- ActionType2["CallPhone"] = "call_phone";
4014
- ActionType2["OpenUrl"] = "open_url";
4015
- ActionType2["SendEmail"] = "send_email";
4016
- ActionType2["RunCallback"] = "run_callback";
4017
- return ActionType2;
4018
- })(ActionType || {});
4019
- var NextBestActionType = /* @__PURE__ */ ((NextBestActionType2) => {
4020
- NextBestActionType2["Link"] = "link";
4021
- NextBestActionType2["Email"] = "email";
4022
- NextBestActionType2["Phone"] = "phone";
4023
- NextBestActionType2["Callback"] = "callback";
4024
- NextBestActionType2["Function"] = "function";
4025
- return NextBestActionType2;
4026
- })(NextBestActionType || {});
4027
-
4028
4128
  const getActionMapping = (action) => {
4029
4129
  const actionMapping = {
4030
4130
  [ActionType.CallPhone]: {
@@ -4055,6 +4155,36 @@ const getActionMapping = (action) => {
4055
4155
  });
4056
4156
  },
4057
4157
  getLabel: (a) => a.action?.options?.title || "Run Action"
4158
+ },
4159
+ [ActionType.LaunchZendeskChat]: {
4160
+ type: NextBestActionType.ZendeskChat,
4161
+ icon: "ChatCircleDots",
4162
+ getValue: (a) => a.action?.options?.embedKey || a.id,
4163
+ getLabel: (a) => a.action?.options?.title || "Chat with us"
4164
+ },
4165
+ [ActionType.LaunchZendeskMessenger]: {
4166
+ type: NextBestActionType.ZendeskMessenger,
4167
+ icon: "ChatCircleDots",
4168
+ getValue: (a) => a.action?.options?.embedKey || a.id,
4169
+ getLabel: (a) => a.action?.options?.title || "Chat with us"
4170
+ },
4171
+ [ActionType.LaunchIntercomChat]: {
4172
+ type: NextBestActionType.IntercomChat,
4173
+ icon: "ChatCircleDots",
4174
+ getValue: (a) => a.action?.options?.appId || a.id,
4175
+ getLabel: (a) => a.action?.options?.title || "Chat with us"
4176
+ },
4177
+ [ActionType.LaunchFreshdesk]: {
4178
+ type: NextBestActionType.Freshdesk,
4179
+ icon: "ChatCircleDots",
4180
+ getValue: (a) => a.action?.options?.token || a.id,
4181
+ getLabel: (a) => a.action?.options?.title || "Chat with us"
4182
+ },
4183
+ [ActionType.LaunchSupportTicketForm]: {
4184
+ type: NextBestActionType.Link,
4185
+ icon: "Notepad",
4186
+ getValue: (a) => a.action?.options?.formUrl || a.id,
4187
+ getLabel: (a) => a.action?.options?.title || "Submit a ticket"
4058
4188
  }
4059
4189
  };
4060
4190
  const mapping = actionMapping[action.type] || {
@@ -4109,13 +4239,14 @@ const AnswerActions = ({
4109
4239
  NextBestActions,
4110
4240
  {
4111
4241
  nextBestActions: mappedActions,
4112
- onActionClick: (action) => {
4242
+ onActionClick: (action, success) => {
4113
4243
  if (action) {
4114
4244
  handleActionClick?.({
4115
4245
  action,
4116
4246
  searchQueryId: searchQueryId || "",
4117
4247
  query: question,
4118
- answer
4248
+ answer,
4249
+ success
4119
4250
  });
4120
4251
  }
4121
4252
  }
@@ -4447,7 +4578,9 @@ const useConversationLoader = ({ loadConversationEndpoint, headers, mergedTextCo
4447
4578
  answerListDispatch(clearAll());
4448
4579
  clearConversationId();
4449
4580
  setShowResults(false);
4450
- setLoadError(mergedTextConfig.errorText || "An error occurred");
4581
+ setLoadError(
4582
+ mergedTextConfig.errorText || "Sorry, we were unable to process the request right now. Please try again in a moment."
4583
+ );
4451
4584
  }).finally(() => {
4452
4585
  setIsLoadingConversation(false);
4453
4586
  });
@@ -4648,7 +4781,8 @@ function Answer({
4648
4781
  handleActionClick,
4649
4782
  nextBestActions,
4650
4783
  isLastAnswer,
4651
- onFeedbackReasonSubmit
4784
+ onFeedbackReasonSubmit,
4785
+ hasError = false
4652
4786
  }) {
4653
4787
  const [isCopied, setIsCopied] = useState(false);
4654
4788
  const [isExpanded, setIsExpanded] = useState(false);
@@ -4658,6 +4792,7 @@ function Answer({
4658
4792
  const isFetchingSearchResults = state === "fetching-search-results";
4659
4793
  const isIdle = state === "getting-action-inputs" || state === "completed";
4660
4794
  const isCompleted = state === "completed";
4795
+ const showError = hasError && isCompleted;
4661
4796
  const handleCopy = async () => {
4662
4797
  try {
4663
4798
  await navigator.clipboard.writeText(answer);
@@ -4692,10 +4827,20 @@ function Answer({
4692
4827
  "data-name": "SearchResults",
4693
4828
  "data-index": index
4694
4829
  },
4695
- /* @__PURE__ */ React__default.createElement("div", { className: "px-4 pt-4 pb-2" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex items-start justify-between gap-2 min-h-9" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.createElement(GeneratingStar, { loading: !isIdle }), /* @__PURE__ */ React__default.createElement("h2", { className: "leading-normal font-semibold m-0 text-foreground self-center text-lg" }, question)), isCompleted && /* @__PURE__ */ React__default.createElement(TooltipProvider, null, /* @__PURE__ */ React__default.createElement(Tooltip, null, /* @__PURE__ */ React__default.createElement(TooltipTrigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => void handleCopy(), className: "-mt-1 flex-shrink-0" }, isCopied ? /* @__PURE__ */ React__default.createElement(Check, { className: "text-feedback-positive", weight: "bold" }) : /* @__PURE__ */ React__default.createElement(Copy, { className: "text-secondary-foreground", weight: "bold" }))), /* @__PURE__ */ React__default.createElement(TooltipContent, null, /* @__PURE__ */ React__default.createElement("p", null, isCopied ? "Copied!" : "Copy")))))),
4696
- isFetchingInitialAnswer && /* @__PURE__ */ React__default.createElement("div", { className: "space-y-4 mt-2 px-4" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React__default.createElement("div", { className: "size-5 rounded-full bg-primary/30" }), /* @__PURE__ */ React__default.createElement("div", { className: "flex items-center gap-2 text-sm text-foreground" }, isFetchingSearchResults ? textConfig.loadingSearchText : textConfig.loadingAnswerText))),
4697
- /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col" }, blocks?.map((block, i) => /* @__PURE__ */ React__default.createElement("div", { key: i, className: "p-4 border-b last:border-b-0 border-dashed" }, /* @__PURE__ */ React__default.createElement(AnswerBlock, { block, redirectRules, state })))),
4698
- isCompleted && /* @__PURE__ */ React__default.createElement(
4830
+ /* @__PURE__ */ React__default.createElement("div", { className: "px-4 pt-4 pb-2" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex items-start justify-between gap-2 min-h-9" }, /* @__PURE__ */ React__default.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React__default.createElement(GeneratingStar, { loading: !isIdle }), /* @__PURE__ */ React__default.createElement("h2", { className: "leading-normal font-semibold m-0 text-foreground self-center text-lg" }, question)), isCompleted && !showError && /* @__PURE__ */ React__default.createElement(TooltipProvider, null, /* @__PURE__ */ React__default.createElement(Tooltip, null, /* @__PURE__ */ React__default.createElement(TooltipTrigger, { asChild: true }, /* @__PURE__ */ React__default.createElement(Button, { variant: "ghost", size: "icon", onClick: () => void handleCopy(), className: "-mt-1 flex-shrink-0" }, isCopied ? /* @__PURE__ */ React__default.createElement(Check, { className: "text-feedback-positive", weight: "bold" }) : /* @__PURE__ */ React__default.createElement(Copy, { className: "text-secondary-foreground", weight: "bold" }))), /* @__PURE__ */ React__default.createElement(TooltipContent, null, /* @__PURE__ */ React__default.createElement("p", null, isCopied ? "Copied!" : "Copy")))))),
4831
+ isFetchingInitialAnswer && /* @__PURE__ */ React__default.createElement("div", { className: "px-4 pt-0 pb-2" }, /* @__PURE__ */ React__default.createElement("p", { className: "text-sm text-muted-foreground" }, isFetchingSearchResults ? textConfig.loadingSearchText : textConfig.loadingAnswerText)),
4832
+ /* @__PURE__ */ React__default.createElement("div", { className: "flex flex-col" }, blocks?.map((block, i) => /* @__PURE__ */ React__default.createElement(
4833
+ "div",
4834
+ {
4835
+ key: i,
4836
+ className: cn(
4837
+ "px-4 pt-0 pb-2 border-b last:border-b-0 border-dashed",
4838
+ showError && "text-muted-foreground"
4839
+ )
4840
+ },
4841
+ /* @__PURE__ */ React__default.createElement(AnswerBlock, { block, redirectRules, state })
4842
+ ))),
4843
+ isCompleted && !showError && /* @__PURE__ */ React__default.createElement(
4699
4844
  AnswerActions,
4700
4845
  {
4701
4846
  actions,
@@ -4708,7 +4853,7 @@ function Answer({
4708
4853
  answer
4709
4854
  }
4710
4855
  ),
4711
- isCompleted && !disableFeedback && /* @__PURE__ */ React__default.createElement("div", { className: "p-4 pt-0" }, /* @__PURE__ */ React__default.createElement(
4856
+ isCompleted && !disableFeedback && !showError && /* @__PURE__ */ React__default.createElement("div", { className: "p-4 pt-0" }, /* @__PURE__ */ React__default.createElement(
4712
4857
  Feedback,
4713
4858
  {
4714
4859
  feedback,
@@ -5449,7 +5594,7 @@ const defaultTextConfig = {
5449
5594
  allDocumentsText: "All documents",
5450
5595
  loadingSearchText: "Searching for relevant content...",
5451
5596
  loadingAnswerText: "Crafting a response...",
5452
- errorText: "Sorry, there was an error generating the answer.",
5597
+ errorText: "Sorry, we were unable to process the request right now. Please try again in a moment.",
5453
5598
  followUpPlaceholder: "Type your response or follow-up",
5454
5599
  positiveAnswerText: "Helpful",
5455
5600
  negativeAnswerText: "Not helpful",
@@ -5863,7 +6008,11 @@ const ChatSearchComponent = forwardRef(
5863
6008
  }
5864
6009
  } catch (e) {
5865
6010
  console.error("Error generating answer for query:", e);
5866
- answerListDispatch(setAnswerError({ error: mergedTextConfig.errorText || "An error occurred." }));
6011
+ answerListDispatch(
6012
+ setAnswerError({
6013
+ error: mergedTextConfig.errorText || "Sorry, we were unable to process the request right now. Please try again in a moment."
6014
+ })
6015
+ );
5867
6016
  } finally {
5868
6017
  answerListDispatch(completeAnswer());
5869
6018
  }
@@ -5898,7 +6047,11 @@ const ChatSearchComponent = forwardRef(
5898
6047
  });
5899
6048
  } catch (e) {
5900
6049
  console.error("Error generating answer for action:", e);
5901
- answerListDispatch(setAnswerError({ error: mergedTextConfig.errorText || "An error occurred." }));
6050
+ answerListDispatch(
6051
+ setAnswerError({
6052
+ error: mergedTextConfig.errorText || "Sorry, we were unable to process the request right now. Please try again in a moment."
6053
+ })
6054
+ );
5902
6055
  } finally {
5903
6056
  answerListDispatch(completeAnswer());
5904
6057
  setIsSearching(false);
@@ -5934,7 +6087,11 @@ const ChatSearchComponent = forwardRef(
5934
6087
  });
5935
6088
  } catch (e) {
5936
6089
  console.error("Error generating answer for action:", e);
5937
- answerListDispatch(setAnswerError({ error: mergedTextConfig.errorText || "An error occurred." }));
6090
+ answerListDispatch(
6091
+ setAnswerError({
6092
+ error: mergedTextConfig.errorText || "Sorry, we were unable to process the request right now. Please try again in a moment."
6093
+ })
6094
+ );
5938
6095
  } finally {
5939
6096
  answerListDispatch(completeAnswer());
5940
6097
  setIsSearching(false);
@@ -6017,7 +6174,11 @@ const ChatSearchComponent = forwardRef(
6017
6174
  searchQuery,
6018
6175
  ...event.metaData
6019
6176
  });
6020
- answerListDispatch(setAnswerError({ error: mergedTextConfig.errorText || "An error occurred." }));
6177
+ answerListDispatch(
6178
+ setAnswerError({
6179
+ error: mergedTextConfig.errorText || "Sorry, we were unable to process the request right now. Please try again in a moment."
6180
+ })
6181
+ );
6021
6182
  } finally {
6022
6183
  setIsSearching(false);
6023
6184
  }
@@ -6412,10 +6573,11 @@ const ChatSearchComponent = forwardRef(
6412
6573
  actions: answer.actions,
6413
6574
  handleActionClick: handleNextBestActionClick,
6414
6575
  isLastAnswer: i === answers.length - 1,
6415
- onFeedbackReasonSubmit: (reason) => void handleFeedbackReasonSubmit(reason, answer.searchQueryId)
6576
+ onFeedbackReasonSubmit: (reason) => void handleFeedbackReasonSubmit(reason, answer.searchQueryId),
6577
+ hasError: answer.hasError
6416
6578
  }
6417
6579
  ),
6418
- i === answers.length - 1 && !disableFollowUpQuestions && answer.followUpQuestions && answer.state === "completed" && /* @__PURE__ */ React__default.createElement(
6580
+ i === answers.length - 1 && !disableFollowUpQuestions && answer.followUpQuestions && answer.state === "completed" && !answer.hasError && /* @__PURE__ */ React__default.createElement(
6419
6581
  FollowUpQuestions,
6420
6582
  {
6421
6583
  questions: answer.followUpQuestions,
@@ -6479,4 +6641,4 @@ const ChatSearch = forwardRef(({ featureFlags, ...props }, ref) => /* @__PURE__
6479
6641
  ChatSearch.displayName = "ChatSearch";
6480
6642
 
6481
6643
  export { ChatSearch as C, ChatSearchProvider as a, useIsChatSearchDirty as b, useChatSearch as u };
6482
- //# sourceMappingURL=ChatSearch.DSB-T76c.js.map
6644
+ //# sourceMappingURL=ChatSearch.g9-_lvsz.js.map