@ensembleapp/client-sdk 0.0.36 → 0.0.38

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/index.js CHANGED
@@ -31,7 +31,7 @@ styleInject(':root[data-chat-widget],\n[data-chat-widget] {\n --chat-primary: #
31
31
 
32
32
  // lib/chat/ChatWidget.tsx
33
33
  import { Send, StopCircle } from "lucide-react";
34
- import { forwardRef, useCallback as useCallback6, useEffect as useEffect6, useImperativeHandle, useMemo as useMemo4, useRef as useRef5, useState as useState7 } from "react";
34
+ import { forwardRef, useCallback as useCallback6, useEffect as useEffect6, useImperativeHandle, useMemo as useMemo5, useRef as useRef5, useState as useState7 } from "react";
35
35
 
36
36
  // ../../node_modules/.pnpm/@ai-sdk+provider@3.0.8/node_modules/@ai-sdk/provider/dist/index.mjs
37
37
  var marker = "vercel.ai.error";
@@ -21531,7 +21531,7 @@ function useChat({
21531
21531
  []
21532
21532
  );
21533
21533
  const transport = useMemo(() => new DefaultChatTransport({
21534
- api: `${baseUrl}/api/chat`,
21534
+ api: `${baseUrl}/chat`,
21535
21535
  fetch: authFetch,
21536
21536
  headers: {
21537
21537
  "Content-Type": "application/json",
@@ -21576,7 +21576,7 @@ function useChat({
21576
21576
  useEffect(() => {
21577
21577
  const fetchInitialMessages = async () => {
21578
21578
  try {
21579
- const response = await authFetch(`${baseUrl}/api/chat/messages`, {
21579
+ const response = await authFetch(`${baseUrl}/chat/messages`, {
21580
21580
  method: "GET",
21581
21581
  headers: {
21582
21582
  "thread-id": threadId
@@ -21625,52 +21625,55 @@ function useFeedback({
21625
21625
  api,
21626
21626
  threadId,
21627
21627
  agentId,
21628
- agentVersion,
21629
- agentExecutionId
21628
+ agentVersion
21630
21629
  }) {
21631
21630
  const { baseUrl, token } = api;
21632
21631
  const [submittedFeedback, setSubmittedFeedback] = useState2({});
21633
21632
  const [isSubmitting, setIsSubmitting] = useState2(null);
21634
21633
  const [error48, setError] = useState2(null);
21635
21634
  const submitFeedback = useCallback(
21636
- async ({ messageId, rating, improvementText }) => {
21635
+ async (messageId, { rating, improvementText, notes }) => {
21637
21636
  setIsSubmitting(messageId);
21638
21637
  setError(null);
21639
21638
  try {
21639
+ const body = {
21640
+ agentId,
21641
+ agentVersion,
21642
+ threadId,
21643
+ messageId,
21644
+ rating,
21645
+ improvementText,
21646
+ notes
21647
+ };
21640
21648
  const response = await fetch(`${baseUrl}/api/feedback`, {
21641
21649
  method: "POST",
21642
21650
  headers: {
21643
21651
  "Content-Type": "application/json",
21644
21652
  Authorization: `Bearer ${token}`
21645
21653
  },
21646
- body: JSON.stringify({
21647
- threadId,
21648
- messageId,
21649
- rating,
21650
- improvementText: improvementText || void 0,
21651
- agentId: agentId || void 0,
21652
- agentVersion: agentVersion !== void 0 ? String(agentVersion) : void 0,
21653
- orchestrationId: agentExecutionId || void 0
21654
- })
21654
+ body: JSON.stringify(body)
21655
21655
  });
21656
21656
  if (!response.ok) {
21657
21657
  const errorData = await response.json().catch(() => ({}));
21658
21658
  throw new Error(errorData.error || `Failed to submit feedback: ${response.statusText}`);
21659
21659
  }
21660
21660
  const { data } = await response.json();
21661
+ if (data.deleted || !rating) {
21662
+ setSubmittedFeedback((prev) => {
21663
+ const next = { ...prev };
21664
+ delete next[messageId];
21665
+ return next;
21666
+ });
21667
+ return null;
21668
+ }
21661
21669
  const feedback = {
21662
- id: data.id,
21663
- messageId: data.messageId,
21664
21670
  rating: data.rating,
21665
21671
  improvementText: data.improvementText,
21666
- createdAt: new Date(data.createdAt)
21672
+ notes: data.notes
21667
21673
  };
21668
21674
  setSubmittedFeedback((prev) => ({
21669
21675
  ...prev,
21670
- [messageId]: {
21671
- rating: feedback.rating,
21672
- comment: feedback.improvementText
21673
- }
21676
+ [messageId]: feedback
21674
21677
  }));
21675
21678
  return feedback;
21676
21679
  } catch (err) {
@@ -21682,7 +21685,7 @@ function useFeedback({
21682
21685
  setIsSubmitting(null);
21683
21686
  }
21684
21687
  },
21685
- [baseUrl, token, threadId, agentId, agentVersion, agentExecutionId]
21688
+ [baseUrl, token, threadId, agentId, agentVersion]
21686
21689
  );
21687
21690
  const getFeedbackForMessage = useCallback(
21688
21691
  (messageId) => {
@@ -22171,7 +22174,7 @@ function FullDisplayMode({
22171
22174
  }
22172
22175
 
22173
22176
  // lib/chat/renderers/MessageRenderer.tsx
22174
- import React4, { useCallback as useCallback4 } from "react";
22177
+ import React5, { useCallback as useCallback5, useMemo as useMemo4 } from "react";
22175
22178
  import ReactMarkdown from "react-markdown";
22176
22179
 
22177
22180
  // ../../node_modules/.pnpm/ccount@2.0.1/node_modules/ccount/index.js
@@ -25633,20 +25636,221 @@ function remarkGfm(options) {
25633
25636
  toMarkdownExtensions.push(gfmToMarkdown(settings));
25634
25637
  }
25635
25638
 
25639
+ // lib/chat/components/MessageFeedback.css
25640
+ styleInject(".chat-widget__feedback {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-top: 0.35rem;\n}\n.chat-widget__feedback-button {\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n color: #9ca3af;\n cursor: pointer;\n border-radius: 0.35rem;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-button:hover:not(:disabled) {\n background: rgba(0, 0, 0, 0.05);\n color: #6b7280;\n}\n.chat-widget__feedback-button:disabled {\n cursor: default;\n opacity: 0.5;\n}\n.chat-widget__feedback-button--positive.chat-widget__feedback-button--selected {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.1);\n}\n.chat-widget__feedback-button--negative.chat-widget__feedback-button--selected {\n color: #ef4444;\n background: rgba(239, 68, 68, 0.1);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--selected {\n background: rgba(0, 0, 0, 0.05);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--has-content {\n color: #3b82f6;\n}\n.chat-widget__feedback-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__feedback-comment-section {\n margin-top: 0.75rem;\n background: var(--chat-background, #ffffff);\n border: 1px solid var(--chat-border, #e5e7eb);\n border-radius: 0.5rem;\n padding: 0.75rem;\n width: 100%;\n max-width: 400px;\n}\n.chat-widget__feedback-comment-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.5rem;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--chat-assistant-text, #111827);\n}\n.chat-widget__feedback-comment-required {\n font-size: 0.6875rem;\n font-weight: 500;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.1);\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n}\n.chat-widget__feedback-comment-body {\n display: flex;\n gap: 0.5rem;\n align-items: flex-start;\n}\n.chat-widget__feedback-textarea {\n flex: 1;\n min-height: 60px;\n padding: 0.625rem;\n border: 1px solid var(--chat-border, #e5e7eb);\n border-radius: 0.35rem;\n font-size: 0.875rem;\n font-family: inherit;\n resize: vertical;\n color: var(--chat-input-text, #111827);\n background: var(--chat-input-bg, #ffffff);\n line-height: 1.5;\n}\n.chat-widget__feedback-textarea:focus {\n outline: none;\n border-color: var(--chat-primary, #3b82f6);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n.chat-widget__feedback-textarea::-moz-placeholder {\n color: var(--chat-input-placeholder, #6b7280);\n}\n.chat-widget__feedback-textarea::placeholder {\n color: var(--chat-input-placeholder, #6b7280);\n}\n.chat-widget__feedback-actions {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n}\n.chat-widget__feedback-cancel,\n.chat-widget__feedback-submit {\n padding: 0.35rem 0.75rem;\n font-size: 0.75rem;\n font-weight: 500;\n border-radius: 0.3rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-cancel {\n background: transparent;\n border: none;\n color: #9ca3af;\n padding: 0.25rem 0.5rem;\n}\n.chat-widget__feedback-cancel:hover {\n color: #6b7280;\n}\n.chat-widget__feedback-submit {\n background: var(--chat-primary, #3b82f6);\n border: none;\n color: var(--chat-primary-text, #ffffff);\n}\n.chat-widget__feedback-submit:hover:not(:disabled) {\n background: var(--chat-primary-hover, #2563eb);\n}\n.chat-widget__feedback-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__feedback-wrapper {\n position: relative;\n}\n");
25641
+
25642
+ // lib/chat/components/MessageFeedback.tsx
25643
+ import { MessageSquare, MessageSquareText, ThumbsDown, ThumbsUp } from "lucide-react";
25644
+ import { useCallback as useCallback4, useEffect as useEffect4, useState as useState5 } from "react";
25645
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
25646
+ var classNames = {
25647
+ wrapper: "chat-widget__feedback-wrapper",
25648
+ container: "chat-widget__feedback",
25649
+ button: "chat-widget__feedback-button",
25650
+ buttonPositive: "chat-widget__feedback-button--positive",
25651
+ buttonNegative: "chat-widget__feedback-button--negative",
25652
+ commentBody: "chat-widget__feedback-comment-body",
25653
+ buttonComment: "chat-widget__feedback-button--comment",
25654
+ buttonSelected: "chat-widget__feedback-button--selected",
25655
+ buttonHasContent: "chat-widget__feedback-button--has-content",
25656
+ icon: "chat-widget__feedback-icon",
25657
+ commentSection: "chat-widget__feedback-comment-section",
25658
+ commentHeader: "chat-widget__feedback-comment-header",
25659
+ commentRequired: "chat-widget__feedback-comment-required",
25660
+ textarea: "chat-widget__feedback-textarea",
25661
+ actions: "chat-widget__feedback-actions",
25662
+ cancelButton: "chat-widget__feedback-cancel",
25663
+ submitButton: "chat-widget__feedback-submit"
25664
+ };
25665
+ var MessageFeedback = ({
25666
+ messageId,
25667
+ existingRating,
25668
+ existingComment,
25669
+ isSubmitting,
25670
+ requireCommentForNegative = false,
25671
+ onSubmit
25672
+ }) => {
25673
+ const [savedRating, setSavedRating] = useState5(existingRating ?? null);
25674
+ const [savedComment, setSavedComment] = useState5(existingComment ?? "");
25675
+ const [pendingRating, setPendingRating] = useState5(null);
25676
+ const [showCommentBox, setShowCommentBox] = useState5(false);
25677
+ const [commentText, setCommentText] = useState5(existingComment ?? "");
25678
+ useEffect4(() => {
25679
+ if (existingRating) {
25680
+ setSavedRating(existingRating);
25681
+ }
25682
+ if (existingComment !== void 0) {
25683
+ setSavedComment(existingComment);
25684
+ setCommentText(existingComment);
25685
+ }
25686
+ }, [existingRating, existingComment]);
25687
+ const handlePositiveClick = useCallback4(() => {
25688
+ if (savedRating === "positive") {
25689
+ setSavedRating(null);
25690
+ setSavedComment("");
25691
+ setCommentText("");
25692
+ setPendingRating(null);
25693
+ onSubmit(messageId, { rating: null, improvementText: null });
25694
+ } else {
25695
+ setSavedRating("positive");
25696
+ setPendingRating(null);
25697
+ onSubmit(messageId, { rating: "positive" });
25698
+ }
25699
+ }, [messageId, savedRating, onSubmit]);
25700
+ const handleNegativeClick = useCallback4(() => {
25701
+ if (savedRating === "negative") {
25702
+ setSavedRating(null);
25703
+ setSavedComment("");
25704
+ setCommentText("");
25705
+ setPendingRating(null);
25706
+ onSubmit(messageId, { rating: null, improvementText: null });
25707
+ } else if (requireCommentForNegative) {
25708
+ setPendingRating("negative");
25709
+ setShowCommentBox(true);
25710
+ } else {
25711
+ setSavedRating("negative");
25712
+ setPendingRating(null);
25713
+ onSubmit(messageId, { rating: "negative" });
25714
+ }
25715
+ }, [messageId, savedRating, requireCommentForNegative, onSubmit]);
25716
+ const handleCommentToggle = useCallback4(() => {
25717
+ if (showCommentBox) {
25718
+ setShowCommentBox(false);
25719
+ if (pendingRating === "negative" && requireCommentForNegative) {
25720
+ setPendingRating(null);
25721
+ }
25722
+ setCommentText(savedComment);
25723
+ } else {
25724
+ setShowCommentBox(true);
25725
+ }
25726
+ }, [showCommentBox, pendingRating, requireCommentForNegative, savedComment]);
25727
+ const handleCommentCancel = useCallback4(() => {
25728
+ setShowCommentBox(false);
25729
+ setCommentText(savedComment);
25730
+ if (pendingRating === "negative" && requireCommentForNegative) {
25731
+ setPendingRating(null);
25732
+ }
25733
+ }, [pendingRating, requireCommentForNegative, savedComment]);
25734
+ const handleCommentSubmit = useCallback4(() => {
25735
+ const ratingToSubmit = pendingRating ?? savedRating;
25736
+ if (ratingToSubmit === "negative" && requireCommentForNegative && !commentText.trim()) {
25737
+ return;
25738
+ }
25739
+ const hasExistingComment = savedComment.length > 0;
25740
+ if (!ratingToSubmit && !commentText.trim() && !hasExistingComment) {
25741
+ return;
25742
+ }
25743
+ const commentToSubmit = commentText.trim() || (hasExistingComment ? null : void 0);
25744
+ onSubmit(messageId, {
25745
+ rating: ratingToSubmit,
25746
+ improvementText: commentToSubmit
25747
+ });
25748
+ if (ratingToSubmit) {
25749
+ setSavedRating(ratingToSubmit);
25750
+ }
25751
+ setSavedComment(commentText.trim());
25752
+ setPendingRating(null);
25753
+ setShowCommentBox(false);
25754
+ }, [messageId, pendingRating, savedRating, savedComment, commentText, requireCommentForNegative, onSubmit]);
25755
+ const displayRating = pendingRating ?? savedRating;
25756
+ const isPositiveSelected = displayRating === "positive";
25757
+ const isNegativeSelected = displayRating === "negative";
25758
+ const isCommentRequired = isNegativeSelected && requireCommentForNegative;
25759
+ const hasComment = savedComment.length > 0;
25760
+ const canSubmitComment = (!isCommentRequired || commentText.trim().length > 0) && (displayRating || commentText.trim().length > 0 || hasComment);
25761
+ const CommentIcon = hasComment ? MessageSquareText : MessageSquare;
25762
+ return /* @__PURE__ */ jsxs3("div", { className: classNames.wrapper, children: [
25763
+ /* @__PURE__ */ jsxs3("div", { className: classNames.container, children: [
25764
+ /* @__PURE__ */ jsx4(
25765
+ "button",
25766
+ {
25767
+ type: "button",
25768
+ className: `${classNames.button} ${classNames.buttonPositive} ${isPositiveSelected ? classNames.buttonSelected : ""}`,
25769
+ onClick: handlePositiveClick,
25770
+ disabled: isSubmitting,
25771
+ title: "Good response",
25772
+ "aria-label": "Mark as good response",
25773
+ children: /* @__PURE__ */ jsx4(ThumbsUp, { className: classNames.icon })
25774
+ }
25775
+ ),
25776
+ /* @__PURE__ */ jsx4(
25777
+ "button",
25778
+ {
25779
+ type: "button",
25780
+ className: `${classNames.button} ${classNames.buttonNegative} ${isNegativeSelected ? classNames.buttonSelected : ""}`,
25781
+ onClick: handleNegativeClick,
25782
+ disabled: isSubmitting,
25783
+ title: "Could be improved",
25784
+ "aria-label": "Mark as could be improved",
25785
+ children: /* @__PURE__ */ jsx4(ThumbsDown, { className: classNames.icon })
25786
+ }
25787
+ ),
25788
+ /* @__PURE__ */ jsx4(
25789
+ "button",
25790
+ {
25791
+ type: "button",
25792
+ className: `${classNames.button} ${classNames.buttonComment} ${showCommentBox ? classNames.buttonSelected : ""} ${hasComment ? classNames.buttonHasContent : ""}`,
25793
+ onClick: handleCommentToggle,
25794
+ disabled: isSubmitting,
25795
+ title: "Add comment",
25796
+ "aria-label": "Add comment",
25797
+ children: /* @__PURE__ */ jsx4(CommentIcon, { className: classNames.icon })
25798
+ }
25799
+ )
25800
+ ] }),
25801
+ showCommentBox && /* @__PURE__ */ jsxs3("div", { className: classNames.commentSection, children: [
25802
+ /* @__PURE__ */ jsx4("div", { className: classNames.commentHeader, children: isCommentRequired && /* @__PURE__ */ jsx4("span", { className: classNames.commentRequired, children: "Required" }) }),
25803
+ /* @__PURE__ */ jsxs3("div", { className: classNames.commentBody, children: [
25804
+ /* @__PURE__ */ jsx4(
25805
+ "textarea",
25806
+ {
25807
+ className: classNames.textarea,
25808
+ placeholder: isNegativeSelected ? "What could be improved?" : "Share your thoughts...",
25809
+ value: commentText,
25810
+ onChange: (e) => setCommentText(e.target.value),
25811
+ rows: 3
25812
+ }
25813
+ ),
25814
+ /* @__PURE__ */ jsxs3("div", { className: classNames.actions, children: [
25815
+ /* @__PURE__ */ jsx4(
25816
+ "button",
25817
+ {
25818
+ type: "button",
25819
+ className: classNames.submitButton,
25820
+ onClick: handleCommentSubmit,
25821
+ disabled: isSubmitting || !canSubmitComment,
25822
+ children: "Save"
25823
+ }
25824
+ ),
25825
+ /* @__PURE__ */ jsx4(
25826
+ "button",
25827
+ {
25828
+ type: "button",
25829
+ className: classNames.cancelButton,
25830
+ onClick: handleCommentCancel,
25831
+ children: "Cancel"
25832
+ }
25833
+ )
25834
+ ] })
25835
+ ] })
25836
+ ] })
25837
+ ] });
25838
+ };
25839
+
25636
25840
  // lib/chat/components/TagGroupDisplay.css
25637
25841
  styleInject('.tag-group {\n margin: 6px 0;\n}\n.tag-group-header {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n background: none;\n border: none;\n padding: 2px 6px 2px 2px;\n cursor: pointer;\n font-size: 13px;\n color: #666;\n border-radius: 4px;\n transition: background-color 0.15s ease;\n}\n.tag-group-header:hover {\n background: #f5f5f5;\n}\n.tag-group-chevron {\n width: 14px;\n height: 14px;\n flex-shrink: 0;\n transition: transform 0.15s ease;\n color: #999;\n}\n.tag-group-chevron--expanded {\n transform: rotate(90deg);\n}\n.tag-group-label {\n font-weight: 500;\n color: #555;\n}\n.tag-group-content {\n margin-left: 7px;\n padding-left: 12px;\n border-left: 2px solid #e0e0e0;\n margin-top: 4px;\n}\n.tag-group-item {\n margin: 4px 0;\n font-size: 13px;\n color: #444;\n}\n.tag-group-item--text {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n}\n.tag-group-item--text::before {\n content: "\\2022";\n color: #999;\n font-size: 14px;\n line-height: 1.4;\n flex-shrink: 0;\n}\n.tag-group-item .tool-call-item {\n margin: 0;\n}\n.tag-group-item--widget {\n display: block;\n margin: 8px 0;\n}\n.tag-group-item .chat-widget__markdown {\n margin: 0;\n}\n.tag-group-item .chat-widget__markdown p {\n margin: 0;\n}\n');
25638
25842
 
25639
25843
  // lib/chat/components/TagGroupDisplay.tsx
25640
25844
  import { ChevronRight } from "lucide-react";
25641
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
25845
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
25642
25846
  function TagGroupDisplay({
25643
25847
  tagId,
25644
25848
  isExpanded,
25645
25849
  onToggle,
25646
25850
  children
25647
25851
  }) {
25648
- return /* @__PURE__ */ jsxs3("div", { className: "tag-group", children: [
25649
- /* @__PURE__ */ jsxs3(
25852
+ return /* @__PURE__ */ jsxs4("div", { className: "tag-group", children: [
25853
+ /* @__PURE__ */ jsxs4(
25650
25854
  "button",
25651
25855
  {
25652
25856
  className: "tag-group-header",
@@ -25654,18 +25858,18 @@ function TagGroupDisplay({
25654
25858
  "aria-expanded": isExpanded,
25655
25859
  type: "button",
25656
25860
  children: [
25657
- /* @__PURE__ */ jsx4(
25861
+ /* @__PURE__ */ jsx5(
25658
25862
  ChevronRight,
25659
25863
  {
25660
25864
  className: `tag-group-chevron ${isExpanded ? "tag-group-chevron--expanded" : ""}`,
25661
25865
  "aria-hidden": "true"
25662
25866
  }
25663
25867
  ),
25664
- /* @__PURE__ */ jsx4("span", { className: "tag-group-label", children: tagId })
25868
+ /* @__PURE__ */ jsx5("span", { className: "tag-group-label", children: tagId })
25665
25869
  ]
25666
25870
  }
25667
25871
  ),
25668
- isExpanded && /* @__PURE__ */ jsx4("div", { className: "tag-group-content", role: "region", children })
25872
+ isExpanded && /* @__PURE__ */ jsx5("div", { className: "tag-group-content", role: "region", children })
25669
25873
  ] });
25670
25874
  }
25671
25875
 
@@ -25673,14 +25877,14 @@ function TagGroupDisplay({
25673
25877
  styleInject(".tool-call-item {\n font-size: 13px;\n color: #666;\n margin: 4px 0;\n}\n.tool-call-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 4px;\n margin-bottom: 4px;\n}\n.tool-call-spinner {\n width: 12px;\n height: 12px;\n border: 2px solid #e0e0e0;\n border-top-color: #666;\n border-radius: 50%;\n animation: tool-call-spin 0.8s linear infinite;\n flex-shrink: 0;\n}\n@keyframes tool-call-spin {\n to {\n transform: rotate(360deg);\n }\n}\n.tool-call-status-icon {\n width: 12px;\n height: 12px;\n border: 2px solid #e0e0e0;\n border-radius: 50%;\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n}\n.tool-call-status-icon--error {\n border-color: #dc2626;\n}\n.tool-call-status-icon__inner {\n width: 8px;\n height: 8px;\n}\n.tool-call-status-icon__inner--success {\n color: #9ca3af;\n}\n.tool-call-status-icon__inner--error {\n color: #dc2626;\n}\n.tool-call-label {\n color: #888;\n}\n.tool-call-label code {\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n font-size: 12px;\n background: #f5f5f5;\n padding: 2px 6px;\n border-radius: 4px;\n color: #555;\n}\n.tool-call-toggle {\n font-size: 9px;\n font-weight: 600;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: #6b7280;\n background: transparent;\n border: 1px solid #d1d5db;\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 6px;\n margin-left: 4px;\n transition: all 0.15s ease;\n}\n.tool-call-toggle:hover {\n color: #374151;\n border-color: #9ca3af;\n background: #f9fafb;\n}\n.tool-call-details {\n margin-top: 8px;\n margin-left: 16px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.tool-call-section {\n display: flex;\n gap: 4px;\n}\n.tool-call-section-label {\n flex-shrink: 0;\n font-size: 10px;\n font-weight: 600;\n color: #6b7280;\n width: 28px;\n padding-top: 8px;\n text-align: right;\n}\n.tool-call-section-content-wrapper {\n flex: 1;\n position: relative;\n min-width: 0;\n}\n.tool-call-section-toggle {\n position: absolute;\n top: 4px;\n right: 4px;\n font-size: 9px;\n font-weight: 600;\n letter-spacing: 0.5px;\n text-transform: uppercase;\n color: #6b7280;\n background: rgba(255, 255, 255, 0.9);\n border: 1px solid #d1d5db;\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 6px;\n transition: all 0.15s ease;\n opacity: 0;\n z-index: 1;\n}\n.tool-call-section-content-wrapper:hover .tool-call-section-toggle {\n opacity: 1;\n}\n.tool-call-section-toggle:hover {\n color: #374151;\n border-color: #9ca3af;\n background: #f9fafb;\n}\n.tool-call-section-content {\n padding: 8px 12px;\n background: #f8f9fa;\n border-radius: 6px;\n border: 1px solid #e9ecef;\n overflow-x: auto;\n}\n.tool-call-section-content.collapsed {\n max-height: 2.4em;\n overflow: hidden;\n padding-top: 4px;\n padding-bottom: 4px;\n}\n.tool-call-section-content.collapsed pre {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n display: block;\n max-width: 100%;\n}\n.tool-call-section-content pre {\n margin: 0;\n font-family:\n ui-monospace,\n SFMono-Regular,\n Menlo,\n Monaco,\n Consolas,\n monospace;\n font-size: 11px;\n color: #333;\n white-space: pre-wrap;\n word-break: break-word;\n}\n.tool-call-error {\n color: #dc2626;\n font-weight: 600;\n font-size: 9px;\n letter-spacing: 0.5px;\n margin-left: auto;\n}\n");
25674
25878
 
25675
25879
  // lib/chat/components/ToolCallDisplay.tsx
25676
- import { useState as useState5 } from "react";
25677
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
25880
+ import { useState as useState6 } from "react";
25881
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
25678
25882
  function CollapsibleSection({ label, content }) {
25679
- const [isCollapsed, setIsCollapsed] = useState5(false);
25680
- return /* @__PURE__ */ jsxs4("div", { className: "tool-call-section", children: [
25681
- /* @__PURE__ */ jsx5("div", { className: "tool-call-section-label", children: label }),
25682
- /* @__PURE__ */ jsxs4("div", { className: "tool-call-section-content-wrapper", children: [
25683
- /* @__PURE__ */ jsx5(
25883
+ const [isCollapsed, setIsCollapsed] = useState6(false);
25884
+ return /* @__PURE__ */ jsxs5("div", { className: "tool-call-section", children: [
25885
+ /* @__PURE__ */ jsx6("div", { className: "tool-call-section-label", children: label }),
25886
+ /* @__PURE__ */ jsxs5("div", { className: "tool-call-section-content-wrapper", children: [
25887
+ /* @__PURE__ */ jsx6(
25684
25888
  "button",
25685
25889
  {
25686
25890
  className: "tool-call-section-toggle",
@@ -25689,12 +25893,12 @@ function CollapsibleSection({ label, content }) {
25689
25893
  children: isCollapsed ? "SHOW" : "HIDE"
25690
25894
  }
25691
25895
  ),
25692
- /* @__PURE__ */ jsx5("div", { className: `tool-call-section-content ${isCollapsed ? "collapsed" : ""}`, children: /* @__PURE__ */ jsx5("pre", { children: formatOutput(content) }) })
25896
+ /* @__PURE__ */ jsx6("div", { className: `tool-call-section-content ${isCollapsed ? "collapsed" : ""}`, children: /* @__PURE__ */ jsx6("pre", { children: formatOutput(content) }) })
25693
25897
  ] })
25694
25898
  ] });
25695
25899
  }
25696
25900
  function ToolCallDisplay({ toolPart, className = "" }) {
25697
- const [isExpanded, setIsExpanded] = useState5(false);
25901
+ const [isExpanded, setIsExpanded] = useState6(false);
25698
25902
  const toolName = "toolName" in toolPart ? toolPart.toolName : toolPart.type.replace("tool-", "");
25699
25903
  const state = "state" in toolPart ? toolPart.state : "pending";
25700
25904
  const hasOutput = state === "output-available" && "output" in toolPart && toolPart.output !== void 0;
@@ -25706,23 +25910,23 @@ function ToolCallDisplay({ toolPart, className = "" }) {
25706
25910
  const canExpand = hasInput || hasOutput;
25707
25911
  const renderStatusIcon = () => {
25708
25912
  if (isLoading) {
25709
- return /* @__PURE__ */ jsx5("span", { className: "tool-call-spinner" });
25913
+ return /* @__PURE__ */ jsx6("span", { className: "tool-call-spinner" });
25710
25914
  }
25711
25915
  const borderClass = hasError ? "tool-call-status-icon--error" : "";
25712
- return /* @__PURE__ */ jsx5("span", { className: `tool-call-status-icon ${borderClass}`, children: hasError ? /* @__PURE__ */ jsxs4("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--error", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [
25713
- /* @__PURE__ */ jsx5("line", { x1: "5", y1: "5", x2: "11", y2: "11" }),
25714
- /* @__PURE__ */ jsx5("line", { x1: "11", y1: "5", x2: "5", y2: "11" })
25715
- ] }) : /* @__PURE__ */ jsx5("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--success", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx5("polyline", { points: "4,8 7,11 12,5" }) }) });
25916
+ return /* @__PURE__ */ jsx6("span", { className: `tool-call-status-icon ${borderClass}`, children: hasError ? /* @__PURE__ */ jsxs5("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--error", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [
25917
+ /* @__PURE__ */ jsx6("line", { x1: "5", y1: "5", x2: "11", y2: "11" }),
25918
+ /* @__PURE__ */ jsx6("line", { x1: "11", y1: "5", x2: "5", y2: "11" })
25919
+ ] }) : /* @__PURE__ */ jsx6("svg", { className: "tool-call-status-icon__inner tool-call-status-icon__inner--success", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx6("polyline", { points: "4,8 7,11 12,5" }) }) });
25716
25920
  };
25717
- return /* @__PURE__ */ jsxs4("div", { className: `tool-call-item ${className}`, children: [
25718
- /* @__PURE__ */ jsxs4("div", { className: "tool-call-header", children: [
25921
+ return /* @__PURE__ */ jsxs5("div", { className: `tool-call-item ${className}`, children: [
25922
+ /* @__PURE__ */ jsxs5("div", { className: "tool-call-header", children: [
25719
25923
  renderStatusIcon(),
25720
- /* @__PURE__ */ jsxs4("span", { className: "tool-call-label", children: [
25924
+ /* @__PURE__ */ jsxs5("span", { className: "tool-call-label", children: [
25721
25925
  isLoading ? "Calling" : "Called",
25722
25926
  " ",
25723
- /* @__PURE__ */ jsx5("code", { children: toolName })
25927
+ /* @__PURE__ */ jsx6("code", { children: toolName })
25724
25928
  ] }),
25725
- canExpand && /* @__PURE__ */ jsx5(
25929
+ canExpand && /* @__PURE__ */ jsx6(
25726
25930
  "button",
25727
25931
  {
25728
25932
  className: "tool-call-toggle",
@@ -25731,11 +25935,11 @@ function ToolCallDisplay({ toolPart, className = "" }) {
25731
25935
  children: isExpanded ? "HIDE" : "SHOW"
25732
25936
  }
25733
25937
  ),
25734
- hasError && /* @__PURE__ */ jsx5("span", { className: "tool-call-error", children: "ERROR" })
25938
+ hasError && /* @__PURE__ */ jsx6("span", { className: "tool-call-error", children: "ERROR" })
25735
25939
  ] }),
25736
- isExpanded && canExpand && /* @__PURE__ */ jsxs4("div", { className: "tool-call-details", children: [
25737
- hasInput && /* @__PURE__ */ jsx5(CollapsibleSection, { label: "IN", content: input }),
25738
- hasOutput && /* @__PURE__ */ jsx5(CollapsibleSection, { label: "OUT", content: output })
25940
+ isExpanded && canExpand && /* @__PURE__ */ jsxs5("div", { className: "tool-call-details", children: [
25941
+ hasInput && /* @__PURE__ */ jsx6(CollapsibleSection, { label: "IN", content: input }),
25942
+ hasOutput && /* @__PURE__ */ jsx6(CollapsibleSection, { label: "OUT", content: output })
25739
25943
  ] })
25740
25944
  ] });
25741
25945
  }
@@ -25754,7 +25958,7 @@ function formatOutput(output) {
25754
25958
 
25755
25959
  // lib/chat/components/WidgetRenderer.tsx
25756
25960
  import hash2 from "object-hash";
25757
- import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef4 } from "react";
25961
+ import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4 } from "react";
25758
25962
 
25759
25963
  // lib/ui-widgets.ts
25760
25964
  var SDK_WIDGET_MARKER = /* @__PURE__ */ Symbol("__isSDKWidget");
@@ -25770,7 +25974,7 @@ function createSDKWidget(widget) {
25770
25974
  var createWidget = (widget) => widget;
25771
25975
 
25772
25976
  // lib/chat/components/WidgetRenderer.tsx
25773
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
25977
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
25774
25978
  function renderError(container, message) {
25775
25979
  container.innerHTML = "";
25776
25980
  const errorDiv = document.createElement("div");
@@ -25778,7 +25982,7 @@ function renderError(container, message) {
25778
25982
  errorDiv.textContent = message;
25779
25983
  container.appendChild(errorDiv);
25780
25984
  }
25781
- function WidgetRenderer({ widget, payload, enriched }) {
25985
+ function WidgetRenderer({ widget, payload, enriched, messageContext }) {
25782
25986
  const containerRef = useRef4(null);
25783
25987
  const rootRef = useRef4(null);
25784
25988
  const customerReactDOMRef = useRef4(void 0);
@@ -25789,7 +25993,7 @@ function WidgetRenderer({ widget, payload, enriched }) {
25789
25993
  }
25790
25994
  const payloadHash = useMemo3(() => hash2(payload ?? {}), [payload]);
25791
25995
  const enrichedHash = useMemo3(() => hash2(enriched ?? {}), [enriched]);
25792
- useEffect4(() => {
25996
+ useEffect5(() => {
25793
25997
  return () => {
25794
25998
  if (rootRef.current) {
25795
25999
  rootRef.current.unmount();
@@ -25806,7 +26010,7 @@ function WidgetRenderer({ widget, payload, enriched }) {
25806
26010
  isRenderedRef.current = false;
25807
26011
  };
25808
26012
  }, []);
25809
- useEffect4(() => {
26013
+ useEffect5(() => {
25810
26014
  if (isSdk) return;
25811
26015
  try {
25812
26016
  if (!containerRef.current) {
@@ -25815,7 +26019,7 @@ function WidgetRenderer({ widget, payload, enriched }) {
25815
26019
  }
25816
26020
  let element;
25817
26021
  try {
25818
- element = widget.render(payload, enriched);
26022
+ element = widget.render(payload, enriched, { messageContext });
25819
26023
  } catch (error48) {
25820
26024
  console.error(`Widget "${widget.widgetType}" render function threw:`, error48);
25821
26025
  renderError(containerRef.current, `Widget render error: ${widget.widgetType}`);
@@ -25876,39 +26080,52 @@ To fix, add your ReactDOM to the widget config:
25876
26080
  renderError(containerRef.current, `Widget system error: ${widget.widgetType}`);
25877
26081
  }
25878
26082
  }
25879
- }, [isSdk, widget, payload, enriched, payloadHash, enrichedHash]);
26083
+ }, [isSdk, widget, payload, enriched, payloadHash, enrichedHash, messageContext]);
25880
26084
  if (isSdk) {
25881
26085
  try {
25882
- const element = widget.render(payload, enriched);
25883
- return /* @__PURE__ */ jsx6(Fragment3, { children: element });
26086
+ const element = widget.render(payload, enriched, { messageContext });
26087
+ return /* @__PURE__ */ jsx7(Fragment3, { children: element });
25884
26088
  } catch (error48) {
25885
26089
  console.error(`SDK widget "${widget.widgetType}" render threw:`, error48);
25886
26090
  const errorMessage = error48 instanceof Error ? error48.message : String(error48);
25887
- return /* @__PURE__ */ jsxs5("div", { className: "widget-error", title: errorMessage, children: [
26091
+ return /* @__PURE__ */ jsxs6("div", { className: "widget-error", title: errorMessage, children: [
25888
26092
  "Widget error: ",
25889
26093
  widget.widgetType
25890
26094
  ] });
25891
26095
  }
25892
26096
  }
25893
- return /* @__PURE__ */ jsx6("div", { ref: containerRef, className: "widget-customer-root" });
26097
+ return /* @__PURE__ */ jsx7("div", { ref: containerRef, className: "widget-customer-root" });
25894
26098
  }
25895
26099
 
25896
26100
  // lib/chat/renderers/MessageRenderer.tsx
25897
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
26101
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
25898
26102
  function FormattedMarkdownComponent({ children }) {
25899
26103
  const MarkdownComponent = ReactMarkdown;
25900
- return /* @__PURE__ */ jsx7(MarkdownComponent, { remarkPlugins: [remarkGfm], children: children.replace(/\n\n/gi, "\n\n \n\n") });
26104
+ return /* @__PURE__ */ jsx8(MarkdownComponent, { remarkPlugins: [remarkGfm], children: children.replace(/\n\n/gi, "\n\n \n\n") });
25901
26105
  }
25902
- var FormattedMarkdown = React4.memo(FormattedMarkdownComponent);
26106
+ var FormattedMarkdown = React5.memo(FormattedMarkdownComponent);
25903
26107
  function MessageRenderer({
25904
26108
  message,
25905
26109
  widgets,
25906
26110
  readonly: readonly2 = false,
25907
26111
  displayMode = "brief",
25908
26112
  tagExpansion,
25909
- className
26113
+ className,
26114
+ feedback
25910
26115
  }) {
25911
- const renderPart = useCallback4(
26116
+ const messageContext = useMemo4(() => {
26117
+ if (!feedback) return void 0;
26118
+ return {
26119
+ messageId: message.id,
26120
+ getFeedback: feedback.getFeedback,
26121
+ submitFeedback: feedback.submitFeedback
26122
+ };
26123
+ }, [message.id, feedback]);
26124
+ const existingFeedback = useMemo4(
26125
+ () => feedback?.getFeedback() ?? null,
26126
+ [feedback]
26127
+ );
26128
+ const renderPart = useCallback5(
25912
26129
  (part, key) => {
25913
26130
  if (part == null) {
25914
26131
  return null;
@@ -25916,42 +26133,43 @@ function MessageRenderer({
25916
26133
  if (part.type === "text") {
25917
26134
  const trimmed = part.text?.trim();
25918
26135
  if (!trimmed) return null;
25919
- return /* @__PURE__ */ jsx7("div", { className: "chat-widget__markdown", children: /* @__PURE__ */ jsx7(FormattedMarkdown, { children: trimmed }) }, key);
26136
+ return /* @__PURE__ */ jsx8("div", { className: "chat-widget__markdown", children: /* @__PURE__ */ jsx8(FormattedMarkdown, { children: trimmed }) }, key);
25920
26137
  }
25921
26138
  if (part.type.startsWith("tool-") || part.type === "dynamic-tool") {
25922
- return /* @__PURE__ */ jsx7(ToolCallDisplay, { toolPart: part }, key);
26139
+ return /* @__PURE__ */ jsx8(ToolCallDisplay, { toolPart: part }, key);
25923
26140
  }
25924
26141
  if (part.type === "data-ui") {
25925
26142
  const dataPart = part;
25926
26143
  const uiWidgets = dataPart.data;
25927
26144
  if (!Array.isArray(uiWidgets)) return null;
25928
26145
  if (!widgets || widgets.length === 0) {
25929
- return /* @__PURE__ */ jsxs6("div", { className: "text-muted-foreground text-sm italic", children: [
26146
+ return /* @__PURE__ */ jsxs7("div", { className: "text-muted-foreground text-sm italic", children: [
25930
26147
  "[UI Widget: ",
25931
26148
  uiWidgets.map((w) => w.widgetType || "unknown").join(", "),
25932
26149
  "]"
25933
26150
  ] }, key);
25934
26151
  }
25935
- return /* @__PURE__ */ jsx7(React4.Fragment, { children: uiWidgets.map((widget, idx) => {
26152
+ return /* @__PURE__ */ jsx8(React5.Fragment, { children: uiWidgets.map((widget, idx) => {
25936
26153
  const widgetDef = widgets.find((w) => w.widgetType === widget.widgetType);
25937
26154
  if (!widgetDef) {
25938
- return /* @__PURE__ */ jsxs6("span", { children: [
26155
+ return /* @__PURE__ */ jsxs7("span", { children: [
25939
26156
  "[Unknown widget: ",
25940
26157
  widget.widgetType,
25941
26158
  "]"
25942
26159
  ] }, `${key}-widget-${idx}`);
25943
26160
  }
25944
- return /* @__PURE__ */ jsx7(
26161
+ return /* @__PURE__ */ jsx8(
25945
26162
  "div",
25946
26163
  {
25947
26164
  className: "chat-widget__widget",
25948
26165
  inert: readonly2 ? true : void 0,
25949
- children: /* @__PURE__ */ jsx7(
26166
+ children: /* @__PURE__ */ jsx8(
25950
26167
  WidgetRenderer,
25951
26168
  {
25952
26169
  widget: widgetDef,
25953
26170
  payload: widget.payload,
25954
- enriched: widget.enriched ?? {}
26171
+ enriched: widget.enriched ?? {},
26172
+ messageContext: messageContext ?? void 0
25955
26173
  }
25956
26174
  )
25957
26175
  },
@@ -25961,12 +26179,12 @@ function MessageRenderer({
25961
26179
  }
25962
26180
  return null;
25963
26181
  },
25964
- [widgets, readonly2]
26182
+ [widgets, readonly2, messageContext]
25965
26183
  );
25966
- const renderGroup = useCallback4(
26184
+ const renderGroup = useCallback5(
25967
26185
  (groupName, key, children) => {
25968
26186
  const isExpanded = tagExpansion?.state.get(key) ?? true;
25969
- return /* @__PURE__ */ jsx7(
26187
+ return /* @__PURE__ */ jsx8(
25970
26188
  TagGroupDisplay,
25971
26189
  {
25972
26190
  tagId: groupName,
@@ -25980,236 +26198,32 @@ function MessageRenderer({
25980
26198
  [tagExpansion]
25981
26199
  );
25982
26200
  const DisplayMode = displayMode === "brief" ? BriefDisplayMode : FullDisplayMode;
25983
- return /* @__PURE__ */ jsx7("div", { className, children: /* @__PURE__ */ jsx7(
25984
- DisplayMode,
25985
- {
25986
- sections: message.sections,
25987
- messageId: message.id,
25988
- renderPart,
25989
- renderGroup
25990
- }
25991
- ) });
25992
- }
25993
-
25994
- // lib/chat/components/MessageFeedback.css
25995
- styleInject(".chat-widget__feedback {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n margin-top: 0.35rem;\n}\n.chat-widget__feedback-button {\n border: none;\n background: transparent;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.75rem;\n height: 1.75rem;\n padding: 0;\n color: #9ca3af;\n cursor: pointer;\n border-radius: 0.35rem;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-button:hover:not(:disabled) {\n background: rgba(0, 0, 0, 0.05);\n color: #6b7280;\n}\n.chat-widget__feedback-button:disabled {\n cursor: default;\n opacity: 0.5;\n}\n.chat-widget__feedback-button--positive.chat-widget__feedback-button--selected {\n color: #22c55e;\n background: rgba(34, 197, 94, 0.1);\n}\n.chat-widget__feedback-button--negative.chat-widget__feedback-button--selected {\n color: #ef4444;\n background: rgba(239, 68, 68, 0.1);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--selected {\n color: var(--chat-primary, #3b82f6);\n background: rgba(59, 130, 246, 0.1);\n}\n.chat-widget__feedback-button--comment.chat-widget__feedback-button--has-content {\n color: var(--chat-primary, #3b82f6);\n}\n.chat-widget__feedback-icon {\n width: 1rem;\n height: 1rem;\n}\n.chat-widget__feedback-comment-section {\n margin-top: 0.75rem;\n background: var(--chat-background, #ffffff);\n border: 1px solid var(--chat-border, #e5e7eb);\n border-radius: 0.5rem;\n padding: 0.75rem;\n width: 100%;\n max-width: 400px;\n}\n.chat-widget__feedback-comment-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.5rem;\n font-size: 0.8125rem;\n font-weight: 600;\n color: var(--chat-assistant-text, #111827);\n}\n.chat-widget__feedback-comment-required {\n font-size: 0.6875rem;\n font-weight: 500;\n color: #ef4444;\n background: rgba(239, 68, 68, 0.1);\n padding: 0.125rem 0.375rem;\n border-radius: 0.25rem;\n}\n.chat-widget__feedback-textarea {\n width: 100%;\n min-height: 120px;\n padding: 0.625rem;\n border: 1px solid var(--chat-border, #e5e7eb);\n border-radius: 0.35rem;\n font-size: 0.875rem;\n font-family: inherit;\n resize: vertical;\n color: var(--chat-input-text, #111827);\n background: var(--chat-input-bg, #ffffff);\n line-height: 1.5;\n}\n.chat-widget__feedback-textarea:focus {\n outline: none;\n border-color: var(--chat-primary, #3b82f6);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n.chat-widget__feedback-textarea::-moz-placeholder {\n color: var(--chat-input-placeholder, #6b7280);\n}\n.chat-widget__feedback-textarea::placeholder {\n color: var(--chat-input-placeholder, #6b7280);\n}\n.chat-widget__feedback-actions {\n display: flex;\n justify-content: flex-end;\n gap: 0.5rem;\n margin-top: 0.75rem;\n}\n.chat-widget__feedback-cancel,\n.chat-widget__feedback-submit {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n font-weight: 500;\n border-radius: 0.35rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.chat-widget__feedback-cancel {\n background: transparent;\n border: 1px solid var(--chat-border, #e5e7eb);\n color: #6b7280;\n}\n.chat-widget__feedback-cancel:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n.chat-widget__feedback-submit {\n background: var(--chat-primary, #3b82f6);\n border: none;\n color: var(--chat-primary-text, #ffffff);\n}\n.chat-widget__feedback-submit:hover:not(:disabled) {\n background: var(--chat-primary-hover, #2563eb);\n}\n.chat-widget__feedback-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.chat-widget__feedback-wrapper {\n position: relative;\n}\n");
25996
-
25997
- // lib/chat/components/MessageFeedback.tsx
25998
- import { MessageSquare, ThumbsDown, ThumbsUp } from "lucide-react";
25999
- import { useCallback as useCallback5, useEffect as useEffect5, useState as useState6 } from "react";
26000
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
26001
- var classNames = {
26002
- wrapper: "chat-widget__feedback-wrapper",
26003
- container: "chat-widget__feedback",
26004
- button: "chat-widget__feedback-button",
26005
- buttonPositive: "chat-widget__feedback-button--positive",
26006
- buttonNegative: "chat-widget__feedback-button--negative",
26007
- buttonComment: "chat-widget__feedback-button--comment",
26008
- buttonSelected: "chat-widget__feedback-button--selected",
26009
- buttonHasContent: "chat-widget__feedback-button--has-content",
26010
- icon: "chat-widget__feedback-icon",
26011
- commentSection: "chat-widget__feedback-comment-section",
26012
- commentHeader: "chat-widget__feedback-comment-header",
26013
- commentRequired: "chat-widget__feedback-comment-required",
26014
- textarea: "chat-widget__feedback-textarea",
26015
- actions: "chat-widget__feedback-actions",
26016
- cancelButton: "chat-widget__feedback-cancel",
26017
- submitButton: "chat-widget__feedback-submit"
26018
- };
26019
- var MessageFeedback = ({
26020
- messageId,
26021
- existingRating,
26022
- existingComment,
26023
- isSubmitting,
26024
- requireCommentForNegative = false,
26025
- onSubmit
26026
- }) => {
26027
- const [savedRating, setSavedRating] = useState6(existingRating ?? null);
26028
- const [savedComment, setSavedComment] = useState6(existingComment ?? "");
26029
- const [pendingRating, setPendingRating] = useState6(null);
26030
- const [showCommentBox, setShowCommentBox] = useState6(false);
26031
- const [commentText, setCommentText] = useState6(existingComment ?? "");
26032
- useEffect5(() => {
26033
- if (existingRating) {
26034
- setSavedRating(existingRating);
26035
- }
26036
- if (existingComment !== void 0) {
26037
- setSavedComment(existingComment);
26038
- setCommentText(existingComment);
26039
- }
26040
- }, [existingRating, existingComment]);
26041
- const handlePositiveClick = useCallback5(() => {
26042
- setSavedRating("positive");
26043
- setPendingRating(null);
26044
- onSubmit(messageId, "positive", commentText.trim() || void 0);
26045
- }, [messageId, commentText, onSubmit]);
26046
- const handleNegativeClick = useCallback5(() => {
26047
- if (requireCommentForNegative) {
26048
- setPendingRating("negative");
26049
- setShowCommentBox(true);
26050
- } else {
26051
- setSavedRating("negative");
26052
- setPendingRating(null);
26053
- onSubmit(messageId, "negative", commentText.trim() || void 0);
26054
- }
26055
- }, [messageId, commentText, requireCommentForNegative, onSubmit]);
26056
- const handleCommentToggle = useCallback5(() => {
26057
- if (showCommentBox) {
26058
- setShowCommentBox(false);
26059
- if (pendingRating === "negative" && requireCommentForNegative) {
26060
- setPendingRating(null);
26061
- }
26062
- setCommentText(savedComment);
26063
- } else {
26064
- setShowCommentBox(true);
26065
- }
26066
- }, [showCommentBox, pendingRating, requireCommentForNegative, savedComment]);
26067
- const handleCommentCancel = useCallback5(() => {
26068
- setShowCommentBox(false);
26069
- setCommentText(savedComment);
26070
- if (pendingRating === "negative" && requireCommentForNegative) {
26071
- setPendingRating(null);
26072
- }
26073
- }, [pendingRating, requireCommentForNegative, savedComment]);
26074
- const handleCommentSubmit = useCallback5(() => {
26075
- const ratingToSubmit = pendingRating ?? savedRating;
26076
- if (!ratingToSubmit) {
26077
- return;
26078
- }
26079
- if (ratingToSubmit === "negative" && requireCommentForNegative && !commentText.trim()) {
26080
- return;
26081
- }
26082
- onSubmit(messageId, ratingToSubmit, commentText.trim() || void 0);
26083
- setSavedRating(ratingToSubmit);
26084
- setSavedComment(commentText.trim());
26085
- setPendingRating(null);
26086
- setShowCommentBox(false);
26087
- }, [messageId, pendingRating, savedRating, commentText, requireCommentForNegative, onSubmit]);
26088
- const displayRating = pendingRating ?? savedRating;
26089
- const isPositiveSelected = displayRating === "positive";
26090
- const isNegativeSelected = displayRating === "negative";
26091
- const isCommentRequired = isNegativeSelected && requireCommentForNegative;
26092
- const canSubmitComment = !isCommentRequired || commentText.trim().length > 0;
26093
- const hasComment = savedComment.length > 0;
26094
- return /* @__PURE__ */ jsxs7("div", { className: classNames.wrapper, children: [
26095
- /* @__PURE__ */ jsxs7("div", { className: classNames.container, children: [
26096
- /* @__PURE__ */ jsx8(
26097
- "button",
26098
- {
26099
- type: "button",
26100
- className: `${classNames.button} ${classNames.buttonPositive} ${isPositiveSelected ? classNames.buttonSelected : ""}`,
26101
- onClick: handlePositiveClick,
26102
- disabled: isSubmitting,
26103
- title: "Good response",
26104
- "aria-label": "Mark as good response",
26105
- children: /* @__PURE__ */ jsx8(ThumbsUp, { className: classNames.icon })
26106
- }
26107
- ),
26108
- /* @__PURE__ */ jsx8(
26109
- "button",
26110
- {
26111
- type: "button",
26112
- className: `${classNames.button} ${classNames.buttonNegative} ${isNegativeSelected ? classNames.buttonSelected : ""}`,
26113
- onClick: handleNegativeClick,
26114
- disabled: isSubmitting,
26115
- title: "Could be improved",
26116
- "aria-label": "Mark as could be improved",
26117
- children: /* @__PURE__ */ jsx8(ThumbsDown, { className: classNames.icon })
26118
- }
26119
- ),
26120
- /* @__PURE__ */ jsx8(
26121
- "button",
26122
- {
26123
- type: "button",
26124
- className: `${classNames.button} ${classNames.buttonComment} ${showCommentBox ? classNames.buttonSelected : ""} ${hasComment ? classNames.buttonHasContent : ""}`,
26125
- onClick: handleCommentToggle,
26126
- disabled: isSubmitting,
26127
- title: "Add comment",
26128
- "aria-label": "Add comment",
26129
- children: /* @__PURE__ */ jsx8(MessageSquare, { className: classNames.icon })
26130
- }
26131
- )
26132
- ] }),
26133
- showCommentBox && /* @__PURE__ */ jsxs7("div", { className: classNames.commentSection, children: [
26134
- /* @__PURE__ */ jsxs7("div", { className: classNames.commentHeader, children: [
26135
- /* @__PURE__ */ jsx8("span", { children: "Add a comment" }),
26136
- isCommentRequired && /* @__PURE__ */ jsx8("span", { className: classNames.commentRequired, children: "Required" })
26137
- ] }),
26138
- /* @__PURE__ */ jsx8(
26139
- "textarea",
26140
- {
26141
- className: classNames.textarea,
26142
- placeholder: isNegativeSelected ? "What could be improved?" : "Share your thoughts...",
26143
- value: commentText,
26144
- onChange: (e) => setCommentText(e.target.value),
26145
- rows: 5
26146
- }
26147
- ),
26148
- /* @__PURE__ */ jsxs7("div", { className: classNames.actions, children: [
26149
- /* @__PURE__ */ jsx8(
26150
- "button",
26151
- {
26152
- type: "button",
26153
- className: classNames.cancelButton,
26154
- onClick: handleCommentCancel,
26155
- children: "Cancel"
26156
- }
26157
- ),
26158
- /* @__PURE__ */ jsx8(
26159
- "button",
26160
- {
26161
- type: "button",
26162
- className: classNames.submitButton,
26163
- onClick: handleCommentSubmit,
26164
- disabled: isSubmitting || !canSubmitComment || !displayRating,
26165
- children: displayRating ? "Save" : "Select Rating First"
26166
- }
26167
- )
26168
- ] })
26169
- ] })
26170
- ] });
26171
- };
26172
-
26173
- // lib/chat/renderers/MessageWithFeedbackRenderer.tsx
26174
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
26175
- function MessageWithFeedbackRenderer({
26176
- message,
26177
- widgets,
26178
- readonly: readonly2,
26179
- displayMode,
26180
- tagExpansion,
26181
- className,
26182
- feedback
26183
- }) {
26184
- const showFeedbackButtons = !readonly2 && feedback?.enabled && feedback?.showButtons && message.role === "assistant" && message.id !== "welcome-message";
26185
- return /* @__PURE__ */ jsxs8(Fragment4, { children: [
26186
- /* @__PURE__ */ jsx9(
26187
- MessageRenderer,
26201
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
26202
+ /* @__PURE__ */ jsx8("div", { className, children: /* @__PURE__ */ jsx8(
26203
+ DisplayMode,
26188
26204
  {
26189
- message,
26190
- widgets,
26191
- readonly: readonly2,
26192
- displayMode,
26193
- tagExpansion,
26194
- className
26205
+ sections: message.sections,
26206
+ messageId: message.id,
26207
+ renderPart,
26208
+ renderGroup
26195
26209
  }
26196
- ),
26197
- showFeedbackButtons && feedback?.onSubmit && /* @__PURE__ */ jsx9(
26210
+ ) }),
26211
+ !readonly2 && feedback && /* @__PURE__ */ jsx8(
26198
26212
  MessageFeedback,
26199
26213
  {
26200
26214
  messageId: message.id,
26201
- existingRating: feedback.existingRating,
26202
- existingComment: feedback.existingComment,
26203
- isSubmitting: feedback.submitting,
26215
+ existingRating: existingFeedback?.rating,
26216
+ existingComment: existingFeedback?.improvementText,
26217
+ isSubmitting: feedback.loading,
26204
26218
  requireCommentForNegative: feedback.requireCommentForNegative,
26205
- onSubmit: (messageId, rating, comment) => feedback.onSubmit(rating, comment)
26219
+ onSubmit: (_, params) => feedback.submitFeedback(params)
26206
26220
  }
26207
26221
  )
26208
26222
  ] });
26209
26223
  }
26210
26224
 
26211
26225
  // lib/chat/ChatWidget.tsx
26212
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
26226
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
26213
26227
  var classNames2 = {
26214
26228
  container: "chat-widget",
26215
26229
  header: "chat-widget__header",
@@ -26289,11 +26303,11 @@ var ChatWidget = forwardRef(function ChatWidget2({
26289
26303
  widgets,
26290
26304
  feedback
26291
26305
  }, ref) {
26292
- const theme = useMemo4(
26306
+ const theme = useMemo5(
26293
26307
  () => ({ ...defaultTheme, ...styleProps || {} }),
26294
26308
  [styleProps]
26295
26309
  );
26296
- const themeVariables = useMemo4(
26310
+ const themeVariables = useMemo5(
26297
26311
  () => ({
26298
26312
  "--chat-primary": theme.primaryColor,
26299
26313
  "--chat-primary-text": theme.primaryTextColor,
@@ -26331,7 +26345,7 @@ var ChatWidget = forwardRef(function ChatWidget2({
26331
26345
  } = useChat({
26332
26346
  api,
26333
26347
  threadId,
26334
- agentId: agentId ?? void 0,
26348
+ agentId,
26335
26349
  agentVersion,
26336
26350
  agentExecutionId: agentExecutionId ?? void 0,
26337
26351
  dataContext,
@@ -26350,21 +26364,14 @@ var ChatWidget = forwardRef(function ChatWidget2({
26350
26364
  const feedbackEnabled = feedback?.enabled !== false;
26351
26365
  const {
26352
26366
  submitFeedback,
26353
- getFeedbackForMessage,
26367
+ getFeedbackForMessage: getFeedback,
26354
26368
  isSubmitting: feedbackSubmitting
26355
26369
  } = useFeedback({
26356
26370
  api,
26357
26371
  threadId,
26358
- agentId: agentId ?? void 0,
26359
- agentVersion,
26360
- agentExecutionId: agentExecutionId ?? void 0
26372
+ agentId,
26373
+ agentVersion
26361
26374
  });
26362
- const handleFeedbackSubmit = useCallback6(
26363
- (messageId, rating, improvementText) => {
26364
- submitFeedback({ messageId, rating, improvementText });
26365
- },
26366
- [submitFeedback]
26367
- );
26368
26375
  const [tagExpansionState, setTagExpansionState] = useState7(/* @__PURE__ */ new Map());
26369
26376
  const handleTagToggle = useCallback6((messageId, tagId, currentlyExpanded) => {
26370
26377
  suppressScrollRef.current = true;
@@ -26375,7 +26382,7 @@ var ChatWidget = forwardRef(function ChatWidget2({
26375
26382
  return next;
26376
26383
  });
26377
26384
  }, []);
26378
- const voiceConfig = useMemo4(() => {
26385
+ const voiceConfig = useMemo5(() => {
26379
26386
  if (!voice || voice.enabled === false || !voice.url) {
26380
26387
  return null;
26381
26388
  }
@@ -26498,15 +26505,15 @@ var ChatWidget = forwardRef(function ChatWidget2({
26498
26505
  console.error("Failed to register chat widgets", err);
26499
26506
  });
26500
26507
  }, [api, threadId, widgets, onAuthError]);
26501
- return /* @__PURE__ */ jsxs9(
26508
+ return /* @__PURE__ */ jsxs8(
26502
26509
  "div",
26503
26510
  {
26504
26511
  className: cn(classNames2.container, className),
26505
26512
  style: themeVariables,
26506
26513
  "data-chat-widget": "",
26507
26514
  children: [
26508
- title && /* @__PURE__ */ jsx10("div", { className: classNames2.header, children: /* @__PURE__ */ jsx10("h3", { className: classNames2.headerTitle, children: title }) }),
26509
- /* @__PURE__ */ jsxs9(
26515
+ title && /* @__PURE__ */ jsx9("div", { className: classNames2.header, children: /* @__PURE__ */ jsx9("h3", { className: classNames2.headerTitle, children: title }) }),
26516
+ /* @__PURE__ */ jsxs8(
26510
26517
  "div",
26511
26518
  {
26512
26519
  className: classNames2.messagesContainer,
@@ -26514,26 +26521,25 @@ var ChatWidget = forwardRef(function ChatWidget2({
26514
26521
  onScroll: handleScroll,
26515
26522
  children: [
26516
26523
  messages.map((message, index) => {
26517
- const isLastMessage = index === messages.length - 1;
26518
- const showFeedback = !(status === "streaming" && isLastMessage);
26519
- const feedbackData = getFeedbackForMessage(message.id);
26520
26524
  const isUser = message.role === "user";
26521
- return /* @__PURE__ */ jsx10("div", { className: classNames2.messageWrapper, children: /* @__PURE__ */ jsx10(
26525
+ const isLastMessage = index === messages.length - 1;
26526
+ const showFeedback = feedbackEnabled && !isUser && !(status === "streaming" && isLastMessage);
26527
+ return /* @__PURE__ */ jsx9("div", { className: classNames2.messageWrapper, children: /* @__PURE__ */ jsx9(
26522
26528
  "div",
26523
26529
  {
26524
26530
  className: cn(
26525
26531
  classNames2.messageRow,
26526
26532
  isUser ? classNames2.userMessageRow : classNames2.assistantMessageRow
26527
26533
  ),
26528
- children: /* @__PURE__ */ jsx10(
26534
+ children: /* @__PURE__ */ jsx9(
26529
26535
  "div",
26530
26536
  {
26531
26537
  className: cn(
26532
26538
  classNames2.messageBubble,
26533
26539
  isUser ? classNames2.userMessage : classNames2.assistantMessage
26534
26540
  ),
26535
- children: /* @__PURE__ */ jsx10(
26536
- MessageWithFeedbackRenderer,
26541
+ children: /* @__PURE__ */ jsx9(
26542
+ MessageRenderer,
26537
26543
  {
26538
26544
  message,
26539
26545
  widgets,
@@ -26542,15 +26548,12 @@ var ChatWidget = forwardRef(function ChatWidget2({
26542
26548
  state: tagExpansionState,
26543
26549
  onToggle: (tagId) => handleTagToggle(message.id, tagId, tagExpansionState.get(`${message.id}-group-${tagId}`) ?? true)
26544
26550
  },
26545
- feedback: {
26546
- enabled: feedbackEnabled,
26547
- showButtons: showFeedback,
26548
- existingRating: feedbackData?.rating,
26549
- existingComment: feedbackData?.comment,
26550
- submitting: feedbackSubmitting === message.id,
26551
+ feedback: showFeedback ? {
26552
+ loading: feedbackSubmitting === message.id,
26551
26553
  requireCommentForNegative: feedback?.requireCommentForNegative,
26552
- onSubmit: (rating, comment) => handleFeedbackSubmit(message.id, rating, comment)
26553
- }
26554
+ getFeedback: () => getFeedback(message.id),
26555
+ submitFeedback: (params) => submitFeedback(message.id, params)
26556
+ } : void 0
26554
26557
  }
26555
26558
  )
26556
26559
  }
@@ -26558,17 +26561,17 @@ var ChatWidget = forwardRef(function ChatWidget2({
26558
26561
  }
26559
26562
  ) }, message.id);
26560
26563
  }),
26561
- status === "streaming" && /* @__PURE__ */ jsx10("div", { className: classNames2.loadingContainer, children: /* @__PURE__ */ jsx10("div", { className: classNames2.loadingBubble, children: /* @__PURE__ */ jsxs9("div", { className: classNames2.loadingDots, children: [
26562
- /* @__PURE__ */ jsx10("div", { className: classNames2.loadingDot }),
26563
- /* @__PURE__ */ jsx10("div", { className: classNames2.loadingDot, "data-delay": "1" }),
26564
- /* @__PURE__ */ jsx10("div", { className: classNames2.loadingDot, "data-delay": "2" })
26564
+ status === "streaming" && /* @__PURE__ */ jsx9("div", { className: classNames2.loadingContainer, children: /* @__PURE__ */ jsx9("div", { className: classNames2.loadingBubble, children: /* @__PURE__ */ jsxs8("div", { className: classNames2.loadingDots, children: [
26565
+ /* @__PURE__ */ jsx9("div", { className: classNames2.loadingDot }),
26566
+ /* @__PURE__ */ jsx9("div", { className: classNames2.loadingDot, "data-delay": "1" }),
26567
+ /* @__PURE__ */ jsx9("div", { className: classNames2.loadingDot, "data-delay": "2" })
26565
26568
  ] }) }) }),
26566
- /* @__PURE__ */ jsx10("div", { ref: messagesEndRef })
26569
+ /* @__PURE__ */ jsx9("div", { ref: messagesEndRef })
26567
26570
  ]
26568
26571
  }
26569
26572
  ),
26570
- /* @__PURE__ */ jsx10("div", { className: classNames2.inputContainer, children: /* @__PURE__ */ jsxs9("form", { onSubmit: handleSubmit, className: classNames2.inputForm, children: [
26571
- /* @__PURE__ */ jsx10(
26573
+ /* @__PURE__ */ jsx9("div", { className: classNames2.inputContainer, children: /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, className: classNames2.inputForm, children: [
26574
+ /* @__PURE__ */ jsx9(
26572
26575
  "textarea",
26573
26576
  {
26574
26577
  ref: textareaRef,
@@ -26581,7 +26584,7 @@ var ChatWidget = forwardRef(function ChatWidget2({
26581
26584
  className: classNames2.textarea
26582
26585
  }
26583
26586
  ),
26584
- /* @__PURE__ */ jsx10("div", { className: classNames2.toolbar, children: speechEnabled && /* @__PURE__ */ jsx10(
26587
+ /* @__PURE__ */ jsx9("div", { className: classNames2.toolbar, children: speechEnabled && /* @__PURE__ */ jsx9(
26585
26588
  SpeechToTextButton,
26586
26589
  {
26587
26590
  className: classNames2.micButton,
@@ -26595,14 +26598,14 @@ var ChatWidget = forwardRef(function ChatWidget2({
26595
26598
  onListeningChange: setIsMicActive
26596
26599
  }
26597
26600
  ) }),
26598
- /* @__PURE__ */ jsx10(
26601
+ /* @__PURE__ */ jsx9(
26599
26602
  "button",
26600
26603
  {
26601
26604
  type: "button",
26602
26605
  onClick: status === "streaming" ? stop : handleSendMessage,
26603
26606
  disabled: status === "streaming" ? false : !input.trim() || status !== "ready",
26604
26607
  className: classNames2.submitButton,
26605
- children: status === "streaming" ? /* @__PURE__ */ jsx10(StopCircle, { className: classNames2.sendIcon }) : /* @__PURE__ */ jsx10(Send, { className: classNames2.sendIcon })
26608
+ children: status === "streaming" ? /* @__PURE__ */ jsx9(StopCircle, { className: classNames2.sendIcon }) : /* @__PURE__ */ jsx9(Send, { className: classNames2.sendIcon })
26606
26609
  }
26607
26610
  )
26608
26611
  ] }) })
@@ -26616,8 +26619,8 @@ styleInject(".chat-popup__anchor {\n position: fixed;\n inset-block-end: 20px;
26616
26619
 
26617
26620
  // lib/chat/PopupChatWidget.tsx
26618
26621
  import { MessageSquare as MessageSquare2, X } from "lucide-react";
26619
- import { useEffect as useEffect7, useMemo as useMemo5, useState as useState8 } from "react";
26620
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
26622
+ import { useEffect as useEffect7, useMemo as useMemo6, useState as useState8 } from "react";
26623
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
26621
26624
  function PopupChatWidget({ anchor, ...props }) {
26622
26625
  const [isOpen, setIsOpen] = useState8(anchor?.initiallyOpen ?? false);
26623
26626
  const [hasOpened, setHasOpened] = useState8(anchor?.initiallyOpen ?? false);
@@ -26641,7 +26644,7 @@ function PopupChatWidget({ anchor, ...props }) {
26641
26644
  const anchorPositionClass = anchor?.position === "bottom-start" ? "chat-popup--start" : "chat-popup--end";
26642
26645
  const closeConfig = anchor?.closeButton ?? props.closeButton;
26643
26646
  const showClose = closeConfig?.show !== false;
26644
- const themeStyle = useMemo5(() => {
26647
+ const themeStyle = useMemo6(() => {
26645
26648
  const primary = props.styles?.primaryColor ?? "#3b82f6";
26646
26649
  const primaryText = props.styles?.primaryTextColor ?? "#ffffff";
26647
26650
  const background = props.styles?.backgroundColor ?? "#ffffff";
@@ -26665,7 +26668,7 @@ function PopupChatWidget({ anchor, ...props }) {
26665
26668
  "--chat-header-text": headerText
26666
26669
  };
26667
26670
  }, [props.styles]);
26668
- const popupStyle = useMemo5(() => {
26671
+ const popupStyle = useMemo6(() => {
26669
26672
  const size = props.popupSize ?? {};
26670
26673
  return {
26671
26674
  width: size.width ?? "600px",
@@ -26674,8 +26677,8 @@ function PopupChatWidget({ anchor, ...props }) {
26674
26677
  maxHeight: size.maxHeight ?? "calc(100vh - 140px)"
26675
26678
  };
26676
26679
  }, [props.popupSize]);
26677
- return /* @__PURE__ */ jsxs10("div", { style: themeStyle, children: [
26678
- /* @__PURE__ */ jsx11("div", { className: cn("chat-popup__anchor", anchorPositionClass), children: anchor?.render ? anchor.render({ isOpen: openResolved, toggle: handleToggle }) : !openResolved && /* @__PURE__ */ jsxs10(
26680
+ return /* @__PURE__ */ jsxs9("div", { style: themeStyle, children: [
26681
+ /* @__PURE__ */ jsx10("div", { className: cn("chat-popup__anchor", anchorPositionClass), children: anchor?.render ? anchor.render({ isOpen: openResolved, toggle: handleToggle }) : !openResolved && /* @__PURE__ */ jsxs9(
26679
26682
  "button",
26680
26683
  {
26681
26684
  type: "button",
@@ -26684,12 +26687,12 @@ function PopupChatWidget({ anchor, ...props }) {
26684
26687
  "aria-expanded": isOpen,
26685
26688
  "aria-label": anchor?.label ?? "Open chat",
26686
26689
  children: [
26687
- /* @__PURE__ */ jsx11(MessageSquare2, { className: "chat-popup__anchor-icon" }),
26688
- /* @__PURE__ */ jsx11("span", { children: anchor?.label ?? "Chat" })
26690
+ /* @__PURE__ */ jsx10(MessageSquare2, { className: "chat-popup__anchor-icon" }),
26691
+ /* @__PURE__ */ jsx10("span", { children: anchor?.label ?? "Chat" })
26689
26692
  ]
26690
26693
  }
26691
26694
  ) }),
26692
- /* @__PURE__ */ jsx11(
26695
+ /* @__PURE__ */ jsx10(
26693
26696
  "div",
26694
26697
  {
26695
26698
  className: cn(
@@ -26697,27 +26700,27 @@ function PopupChatWidget({ anchor, ...props }) {
26697
26700
  anchorPositionClass,
26698
26701
  openResolved ? "chat-popup__panel--open" : "chat-popup__panel--closed"
26699
26702
  ),
26700
- children: /* @__PURE__ */ jsxs10("div", { className: "chat-popup__panel-inner", style: popupStyle, children: [
26701
- showClose && /* @__PURE__ */ jsx11(
26703
+ children: /* @__PURE__ */ jsxs9("div", { className: "chat-popup__panel-inner", style: popupStyle, children: [
26704
+ showClose && /* @__PURE__ */ jsx10(
26702
26705
  "div",
26703
26706
  {
26704
26707
  className: cn(
26705
26708
  "chat-popup__close",
26706
26709
  closeConfig?.position === "top-start" ? "chat-popup__close--start" : "chat-popup__close--end"
26707
26710
  ),
26708
- children: closeConfig?.render ? closeConfig.render({ toggle: handleToggle }) : /* @__PURE__ */ jsx11(
26711
+ children: closeConfig?.render ? closeConfig.render({ toggle: handleToggle }) : /* @__PURE__ */ jsx10(
26709
26712
  "button",
26710
26713
  {
26711
26714
  type: "button",
26712
26715
  className: "chat-popup__close-button",
26713
26716
  onClick: handleToggle,
26714
26717
  "aria-label": "Close chat",
26715
- children: /* @__PURE__ */ jsx11(X, { className: "chat-popup__close-icon" })
26718
+ children: /* @__PURE__ */ jsx10(X, { className: "chat-popup__close-icon" })
26716
26719
  }
26717
26720
  )
26718
26721
  }
26719
26722
  ),
26720
- hasOpened && /* @__PURE__ */ jsx11(ChatWidget, { ...props })
26723
+ hasOpened && /* @__PURE__ */ jsx10(ChatWidget, { ...props })
26721
26724
  ] })
26722
26725
  }
26723
26726
  )
@@ -26725,62 +26728,97 @@ function PopupChatWidget({ anchor, ...props }) {
26725
26728
  }
26726
26729
 
26727
26730
  // lib/chat/widgets/VendorCards.tsx
26728
- import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
26731
+ import { MessageSquare as MessageSquare3, MessageSquareText as MessageSquareText2, ThumbsDown as ThumbsDown2, ThumbsUp as ThumbsUp2 } from "lucide-react";
26732
+ import React8 from "react";
26733
+ import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
26729
26734
  var vendorCardsSchema = jsonSchema({
26730
26735
  type: "object",
26731
26736
  description: "displaying a list of vendor cards. Use this widget to represent data from CareNetwork vendor search tool.",
26732
26737
  properties: {
26733
- fromLocation: {
26734
- type: "string",
26735
- description: "The location the user is searching for"
26736
- },
26737
- fromCoordinates: {
26738
- type: "object",
26739
- description: "The location's lat/lng coordinates. This must come from the previous geocoding tool as-is - do NOT guess",
26740
- properties: {
26741
- latitude: { type: "number" },
26742
- longitude: { type: "number" }
26743
- },
26744
- required: ["latitude", "longitude"]
26745
- },
26738
+ // fromLocation: {
26739
+ // type: 'string',
26740
+ // description: 'The location the user is searching for',
26741
+ // },
26742
+ // fromCoordinates: {
26743
+ // type: 'object',
26744
+ // description: "The location's lat/lng coordinates. This must come from the previous geocoding tool as-is - do NOT guess",
26745
+ // properties: {
26746
+ // latitude: { type: 'number' },
26747
+ // longitude: { type: 'number' },
26748
+ // },
26749
+ // required: ['latitude', 'longitude'],
26750
+ // },
26746
26751
  vendors: {
26747
26752
  type: "array",
26748
26753
  items: {
26749
26754
  type: "object",
26750
26755
  properties: {
26751
- vendor_id: { type: "string" },
26752
- notes: {
26753
- type: "string",
26754
- description: "Why this vendor was recommended"
26755
- },
26756
- vendorCoordinates: {
26757
- type: "object",
26758
- description: "The lat/lng coordinates of this vendor. This must come from the vendor's location.coordinates from the previous vendor search tool - do NOT guess",
26759
- properties: {
26760
- latitude: { type: "number" },
26761
- longitude: { type: "number" }
26762
- },
26763
- required: ["latitude", "longitude"]
26764
- }
26756
+ vendor_id: { type: "string" }
26757
+ // notes: {
26758
+ // type: 'string',
26759
+ // description: 'Give 7-10 words on why this vendor was recommended. Only include the notes for the top 3 vendors',
26760
+ // },
26761
+ // vendorCoordinates: {
26762
+ // type: 'object',
26763
+ // description: "The lat/lng coordinates of this vendor. This must come from the vendor's location.coordinates from the previous vendor search tool - do NOT guess",
26764
+ // properties: {
26765
+ // latitude: { type: 'number' },
26766
+ // longitude: { type: 'number' },
26767
+ // },
26768
+ // required: ['latitude', 'longitude'],
26769
+ // },
26765
26770
  },
26766
- required: ["vendor_id", "vendorCoordinates"]
26771
+ required: ["vendor_id"]
26772
+ // required: ['vendor_id', 'vendorCoordinates'],
26767
26773
  }
26774
+ // description: '5-7 vendors to display. With notes for the top 3 only',
26768
26775
  }
26769
26776
  },
26770
- required: ["fromLocation", "fromCoordinates", "vendors"]
26777
+ required: ["vendors"]
26778
+ // required: ['fromLocation', 'fromCoordinates', 'vendors'],
26771
26779
  });
26772
- function VendorCards({ payload, enriched, onAddToList }) {
26773
- if (!enriched || !enriched.vendorDetails || !enriched.distanceMatrix) {
26774
- return /* @__PURE__ */ jsx12("div", { children: "Outdated vendor-cards widget" });
26775
- }
26776
- const { vendorDetails, distanceMatrix } = enriched;
26780
+ function VendorCards({ payload, enriched, onAddToList, onFeedback, existingFeedback }) {
26781
+ const [feedbackState, setFeedbackState] = React8.useState({});
26782
+ const initializedRef = React8.useRef(false);
26783
+ React8.useEffect(() => {
26784
+ if (!initializedRef.current && existingFeedback && existingFeedback.length > 0) {
26785
+ initializedRef.current = true;
26786
+ const initialState = {};
26787
+ for (const note of existingFeedback) {
26788
+ if (note.noteId) {
26789
+ initialState[note.noteId] = {
26790
+ rating: note.rating ?? null,
26791
+ commentText: note.comment ?? null,
26792
+ showComment: false
26793
+ };
26794
+ }
26795
+ }
26796
+ setFeedbackState(initialState);
26797
+ }
26798
+ }, [existingFeedback]);
26799
+ const getFeedbackState = (vendorId) => {
26800
+ return feedbackState[vendorId] || { rating: null, commentText: null, showComment: false };
26801
+ };
26802
+ const updateFeedbackState = (vendorId, updates) => {
26803
+ setFeedbackState((prev) => ({
26804
+ ...prev,
26805
+ [vendorId]: { ...getFeedbackState(vendorId), ...updates }
26806
+ }));
26807
+ };
26808
+ const removeFeedbackState = (vendorId) => {
26809
+ setFeedbackState((prev) => {
26810
+ const { [vendorId]: _, ...rest } = prev;
26811
+ return rest;
26812
+ });
26813
+ };
26814
+ const { vendorDetails, distanceMatrix } = enriched || {};
26777
26815
  const vendorData = vendorDetails?.data ?? {};
26778
26816
  const distances = distanceMatrix?.data ?? [];
26779
26817
  const formatDistance = (meters) => {
26780
26818
  const miles = meters / 1609.34;
26781
26819
  return miles < 0.1 ? "< 0.1 mi" : `${miles.toFixed(1)} mi`;
26782
26820
  };
26783
- return /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: payload.vendors.map((v, index) => {
26821
+ return /* @__PURE__ */ jsx11("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: payload.vendors.map((v, index) => {
26784
26822
  const data = vendorData[v.vendor_id];
26785
26823
  const name21 = data?.names?.[0]?.value ?? "Unknown";
26786
26824
  const address = data?.location?.address;
@@ -26796,7 +26834,7 @@ function VendorCards({ payload, enriched, onAddToList }) {
26796
26834
  const careLocationType = subtypes.includes("In-Home") ? "In-Home" : subtypes.includes("In-Center") ? "In-Center" : null;
26797
26835
  const backgroundCheckStatus = data?.references_and_background_check?.background_check_status?.toLowerCase();
26798
26836
  const hasBackgroundCheck = backgroundCheckStatus === "clear" || backgroundCheckStatus === "completed";
26799
- return /* @__PURE__ */ jsxs11(
26837
+ return /* @__PURE__ */ jsxs10(
26800
26838
  "div",
26801
26839
  {
26802
26840
  style: {
@@ -26808,12 +26846,13 @@ function VendorCards({ payload, enriched, onAddToList }) {
26808
26846
  border: "1px solid #e5e7eb",
26809
26847
  borderRadius: "0.5rem",
26810
26848
  boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)",
26811
- fontSize: "0.875rem"
26849
+ fontSize: "0.875rem",
26850
+ position: "relative"
26812
26851
  },
26813
26852
  children: [
26814
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [
26815
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
26816
- /* @__PURE__ */ jsx12("div", { style: {
26853
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start" }, children: [
26854
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
26855
+ /* @__PURE__ */ jsx11("div", { style: {
26817
26856
  width: "2rem",
26818
26857
  height: "2rem",
26819
26858
  borderRadius: "9999px",
@@ -26825,9 +26864,9 @@ function VendorCards({ payload, enriched, onAddToList }) {
26825
26864
  fontSize: "0.875rem",
26826
26865
  color: "#374151"
26827
26866
  }, children: name21.charAt(0).toUpperCase() }),
26828
- /* @__PURE__ */ jsx12("span", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827" }, children: name21 })
26867
+ /* @__PURE__ */ jsx11("span", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827" }, children: name21 })
26829
26868
  ] }),
26830
- onAddToList && /* @__PURE__ */ jsx12(
26869
+ onAddToList && /* @__PURE__ */ jsx11(
26831
26870
  "button",
26832
26871
  {
26833
26872
  onClick: () => onAddToList(v.vendor_id),
@@ -26843,62 +26882,233 @@ function VendorCards({ payload, enriched, onAddToList }) {
26843
26882
  }
26844
26883
  )
26845
26884
  ] }),
26846
- (reviewCount || cnScore) && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", color: "#6b7280" }, children: [
26847
- avgRating && /* @__PURE__ */ jsxs11(Fragment5, { children: [
26848
- /* @__PURE__ */ jsx12("span", { style: { color: "#facc15" }, children: "\u2605" }),
26849
- /* @__PURE__ */ jsx12("span", { children: avgRating.toFixed(1) }),
26850
- reviewCount && /* @__PURE__ */ jsxs11("span", { style: { color: "#9ca3af" }, children: [
26885
+ (reviewCount != null || cnScore != null) && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", color: "#6b7280" }, children: [
26886
+ avgRating != null && /* @__PURE__ */ jsxs10(Fragment5, { children: [
26887
+ /* @__PURE__ */ jsx11("span", { style: { color: "#facc15" }, children: "\u2605" }),
26888
+ /* @__PURE__ */ jsx11("span", { children: avgRating.toFixed(1) }),
26889
+ reviewCount != null && /* @__PURE__ */ jsxs10("span", { style: { color: "#9ca3af" }, children: [
26851
26890
  "(",
26852
26891
  reviewCount,
26853
26892
  " reviews)"
26854
26893
  ] })
26855
26894
  ] }),
26856
- avgRating && cnScore ? /* @__PURE__ */ jsx12("span", { style: { color: "#9ca3af" }, children: "\u2022" }) : null,
26857
- cnScore ? /* @__PURE__ */ jsxs11("span", { children: [
26895
+ avgRating != null && cnScore != null ? /* @__PURE__ */ jsx11("span", { style: { color: "#9ca3af" }, children: "\u2022" }) : null,
26896
+ cnScore != null ? /* @__PURE__ */ jsxs10("span", { children: [
26858
26897
  "CN Score: ",
26859
26898
  cnScore
26860
26899
  ] }) : null
26861
26900
  ] }),
26862
- careLocationType && /* @__PURE__ */ jsx12("div", { style: { color: "#6b7280" }, children: careLocationType }),
26863
- address && /* @__PURE__ */ jsx12("div", { style: { color: "#6b7280" }, children: address }),
26864
- distance && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26865
- /* @__PURE__ */ jsx12("span", { children: "\u{1F4CD}" }),
26866
- /* @__PURE__ */ jsxs11("span", { children: [
26901
+ careLocationType && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: careLocationType }),
26902
+ address && /* @__PURE__ */ jsx11("div", { style: { color: "#6b7280" }, children: address }),
26903
+ distance && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26904
+ /* @__PURE__ */ jsx11("span", { children: "\u{1F4CD}" }),
26905
+ /* @__PURE__ */ jsxs10("span", { children: [
26867
26906
  distance,
26868
26907
  " from ",
26869
26908
  payload.fromLocation
26870
26909
  ] })
26871
26910
  ] }),
26872
- hourlyRate && /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26873
- /* @__PURE__ */ jsx12("span", { children: "\u{1F4B0}" }),
26874
- /* @__PURE__ */ jsxs11("span", { children: [
26911
+ hourlyRate && /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#6b7280" }, children: [
26912
+ /* @__PURE__ */ jsx11("span", { children: "\u{1F4B0}" }),
26913
+ /* @__PURE__ */ jsxs10("span", { children: [
26875
26914
  "Rate: $",
26876
26915
  hourlyRate,
26877
26916
  "/hr"
26878
26917
  ] })
26879
26918
  ] }),
26880
- v.notes && /* @__PURE__ */ jsxs11("div", { style: { color: "#374151", marginTop: "0.4rem" }, children: [
26881
- /* @__PURE__ */ jsx12("span", { style: { marginRight: "0.25rem" }, children: "\u2728" }),
26882
- /* @__PURE__ */ jsx12("strong", { children: "Recommendation notes" }),
26883
- /* @__PURE__ */ jsx12("div", { style: { marginLeft: "1.25rem", marginTop: "0.25rem", color: "#6b7280" }, children: v.notes })
26919
+ v.notes && /* @__PURE__ */ jsxs10("div", { style: { color: "#374151", marginTop: "0.4rem" }, children: [
26920
+ /* @__PURE__ */ jsx11("span", { style: { marginRight: "0.25rem" }, children: "\u2728" }),
26921
+ /* @__PURE__ */ jsx11("strong", { children: "Recommendation notes" }),
26922
+ /* @__PURE__ */ jsx11("div", { style: { marginLeft: "1.25rem", marginTop: "0.25rem", color: "#6b7280" }, children: v.notes })
26884
26923
  ] }),
26885
- /* @__PURE__ */ jsxs11("div", { style: {
26886
- display: "flex",
26887
- flexWrap: "wrap",
26888
- gap: "0.5rem",
26889
- marginTop: "0.25rem",
26890
- paddingTop: "0.5rem",
26891
- borderTop: "1px solid #f3f4f6"
26892
- }, children: [
26893
- verification?.verified && /* @__PURE__ */ jsxs11("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26894
- /* @__PURE__ */ jsx12("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26895
- " Wellthy Verified"
26896
- ] }),
26897
- hasBackgroundCheck && /* @__PURE__ */ jsxs11("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26898
- /* @__PURE__ */ jsx12("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26899
- " Background check"
26900
- ] })
26901
- ] })
26924
+ (() => {
26925
+ const state = getFeedbackState(v.vendor_id);
26926
+ const isPositiveSelected = state.rating === "positive";
26927
+ const isNegativeSelected = state.rating === "negative";
26928
+ const handleRatingClick = (rating) => {
26929
+ const currentState = getFeedbackState(v.vendor_id);
26930
+ if (currentState.rating === rating) {
26931
+ removeFeedbackState(v.vendor_id);
26932
+ onFeedback?.(v.vendor_id, {});
26933
+ } else {
26934
+ updateFeedbackState(v.vendor_id, { rating });
26935
+ onFeedback?.(v.vendor_id, { rating, vendorId: v.vendor_id, vendorName: name21 });
26936
+ }
26937
+ };
26938
+ const handleCommentToggle = () => {
26939
+ const currentState = getFeedbackState(v.vendor_id);
26940
+ updateFeedbackState(v.vendor_id, { showComment: !currentState.showComment });
26941
+ };
26942
+ const handleCommentSubmit = () => {
26943
+ const currentState = getFeedbackState(v.vendor_id);
26944
+ const trimmedComment = currentState.commentText?.trim();
26945
+ if (trimmedComment) {
26946
+ updateFeedbackState(v.vendor_id, { showComment: false, commentText: trimmedComment });
26947
+ onFeedback?.(v.vendor_id, { comment: trimmedComment, vendorId: v.vendor_id, vendorName: name21 });
26948
+ }
26949
+ };
26950
+ return /* @__PURE__ */ jsxs10(Fragment5, { children: [
26951
+ /* @__PURE__ */ jsxs10("div", { style: {
26952
+ display: "flex",
26953
+ flexWrap: "wrap",
26954
+ gap: "0.5rem",
26955
+ // marginTop: '0.25rem',
26956
+ alignItems: "center",
26957
+ minHeight: "1.75rem"
26958
+ }, children: [
26959
+ verification?.verified && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26960
+ /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26961
+ " Wellthy Verified"
26962
+ ] }),
26963
+ hasBackgroundCheck && /* @__PURE__ */ jsxs10("span", { style: { display: "flex", alignItems: "center", gap: "0.25rem", color: "#22c55e", fontSize: "0.75rem" }, children: [
26964
+ /* @__PURE__ */ jsx11("span", { style: { fontSize: "0.875rem" }, children: "\u2713" }),
26965
+ " Background check"
26966
+ ] }),
26967
+ onFeedback && /* @__PURE__ */ jsxs10("div", { style: {
26968
+ marginLeft: "auto",
26969
+ display: "flex",
26970
+ gap: "0.25rem",
26971
+ alignItems: "center"
26972
+ }, children: [
26973
+ /* @__PURE__ */ jsx11(
26974
+ "button",
26975
+ {
26976
+ onClick: () => handleRatingClick("positive"),
26977
+ style: {
26978
+ background: isPositiveSelected ? "rgba(34, 197, 94, 0.1)" : "transparent",
26979
+ border: "none",
26980
+ borderRadius: "0.35rem",
26981
+ padding: "0.25rem",
26982
+ cursor: "pointer",
26983
+ display: "flex",
26984
+ alignItems: "center",
26985
+ justifyContent: "center",
26986
+ color: isPositiveSelected ? "#22c55e" : "#9ca3af",
26987
+ width: "1.75rem",
26988
+ height: "1.75rem"
26989
+ },
26990
+ title: "This vendor was helpful",
26991
+ children: /* @__PURE__ */ jsx11(ThumbsUp2, { style: { width: "1rem", height: "1rem" } })
26992
+ }
26993
+ ),
26994
+ /* @__PURE__ */ jsx11(
26995
+ "button",
26996
+ {
26997
+ onClick: () => handleRatingClick("negative"),
26998
+ style: {
26999
+ background: isNegativeSelected ? "rgba(239, 68, 68, 0.1)" : "transparent",
27000
+ border: "none",
27001
+ borderRadius: "0.35rem",
27002
+ padding: "0.25rem",
27003
+ cursor: "pointer",
27004
+ display: "flex",
27005
+ alignItems: "center",
27006
+ justifyContent: "center",
27007
+ color: isNegativeSelected ? "#ef4444" : "#9ca3af",
27008
+ width: "1.75rem",
27009
+ height: "1.75rem"
27010
+ },
27011
+ title: "This vendor was not helpful",
27012
+ children: /* @__PURE__ */ jsx11(ThumbsDown2, { style: { width: "1rem", height: "1rem" } })
27013
+ }
27014
+ ),
27015
+ (() => {
27016
+ const hasComment = !!state.commentText?.trim();
27017
+ const CommentIcon = hasComment ? MessageSquareText2 : MessageSquare3;
27018
+ return /* @__PURE__ */ jsx11(
27019
+ "button",
27020
+ {
27021
+ onClick: handleCommentToggle,
27022
+ style: {
27023
+ background: state.showComment ? "rgba(0, 0, 0, 0.05)" : "transparent",
27024
+ border: "none",
27025
+ borderRadius: "0.35rem",
27026
+ padding: "0.25rem",
27027
+ cursor: "pointer",
27028
+ display: "flex",
27029
+ alignItems: "center",
27030
+ justifyContent: "center",
27031
+ color: hasComment ? "#3b82f6" : state.showComment ? "#6b7280" : "#9ca3af",
27032
+ width: "1.75rem",
27033
+ height: "1.75rem"
27034
+ },
27035
+ title: hasComment ? "Edit comment" : "Add comment",
27036
+ children: /* @__PURE__ */ jsx11(CommentIcon, { style: { width: "1rem", height: "1rem" } })
27037
+ }
27038
+ );
27039
+ })()
27040
+ ] })
27041
+ ] }),
27042
+ state.showComment && /* @__PURE__ */ jsx11("div", { style: {
27043
+ position: "absolute",
27044
+ bottom: 0,
27045
+ left: 0,
27046
+ right: 0,
27047
+ background: "#ffffff",
27048
+ borderTop: "1px solid #e5e7eb",
27049
+ borderRadius: "0 0 0.5rem 0.5rem",
27050
+ padding: "0.75rem 1rem",
27051
+ boxShadow: "0 -2px 8px rgba(0, 0, 0, 0.1)"
27052
+ }, children: /* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: "0.5rem", alignItems: "flex-start" }, children: [
27053
+ /* @__PURE__ */ jsx11(
27054
+ "textarea",
27055
+ {
27056
+ placeholder: "Share your thoughts about this vendor...",
27057
+ value: state.commentText ?? "",
27058
+ onChange: (e) => updateFeedbackState(v.vendor_id, { commentText: e.target.value }),
27059
+ rows: 2,
27060
+ style: {
27061
+ flex: 1,
27062
+ padding: "0.5rem",
27063
+ border: "1px solid #e5e7eb",
27064
+ borderRadius: "0.35rem",
27065
+ fontSize: "0.875rem",
27066
+ fontFamily: "inherit",
27067
+ resize: "none",
27068
+ minHeight: "50px"
27069
+ }
27070
+ }
27071
+ ),
27072
+ /* @__PURE__ */ jsxs10("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: [
27073
+ /* @__PURE__ */ jsx11(
27074
+ "button",
27075
+ {
27076
+ onClick: handleCommentSubmit,
27077
+ disabled: !state.commentText?.trim(),
27078
+ style: {
27079
+ padding: "0.35rem 0.75rem",
27080
+ fontSize: "0.75rem",
27081
+ fontWeight: 500,
27082
+ borderRadius: "0.3rem",
27083
+ cursor: state.commentText?.trim() ? "pointer" : "not-allowed",
27084
+ background: "#3b82f6",
27085
+ border: "none",
27086
+ color: "#ffffff",
27087
+ opacity: state.commentText?.trim() ? 1 : 0.5
27088
+ },
27089
+ children: "Save"
27090
+ }
27091
+ ),
27092
+ /* @__PURE__ */ jsx11(
27093
+ "button",
27094
+ {
27095
+ onClick: handleCommentToggle,
27096
+ style: {
27097
+ padding: "0.25rem 0.5rem",
27098
+ fontSize: "0.75rem",
27099
+ fontWeight: 500,
27100
+ background: "transparent",
27101
+ border: "none",
27102
+ color: "#9ca3af",
27103
+ cursor: "pointer"
27104
+ },
27105
+ children: "Cancel"
27106
+ }
27107
+ )
27108
+ ] })
27109
+ ] }) })
27110
+ ] });
27111
+ })()
26902
27112
  ]
26903
27113
  },
26904
27114
  v.vendor_id
@@ -26907,7 +27117,7 @@ function VendorCards({ payload, enriched, onAddToList }) {
26907
27117
  }
26908
27118
 
26909
27119
  // lib/chat/widgets/default-widgets.tsx
26910
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
27120
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
26911
27121
  var defaultChatWidgets = [
26912
27122
  createSDKWidget({
26913
27123
  widgetType: "person-card",
@@ -26916,7 +27126,7 @@ var defaultChatWidgets = [
26916
27126
  photoUri: zod_default.string().optional().describe("URL to a photo of the person"),
26917
27127
  details: zod_default.record(zod_default.string(), zod_default.any()).optional()
26918
27128
  }).describe("showing a person card with name, photo and additional details"),
26919
- render: (payload) => /* @__PURE__ */ jsx13(
27129
+ render: (payload) => /* @__PURE__ */ jsx12(
26920
27130
  "div",
26921
27131
  {
26922
27132
  style: {
@@ -26929,8 +27139,8 @@ var defaultChatWidgets = [
26929
27139
  borderRadius: "0.5rem",
26930
27140
  boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"
26931
27141
  },
26932
- children: /* @__PURE__ */ jsxs12("div", { style: { display: "flex", alignItems: "flex-start", gap: "0.75rem" }, children: [
26933
- payload.photoUri && /* @__PURE__ */ jsx13(
27142
+ children: /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "flex-start", gap: "0.75rem" }, children: [
27143
+ payload.photoUri && /* @__PURE__ */ jsx12(
26934
27144
  "img",
26935
27145
  {
26936
27146
  src: payload.photoUri,
@@ -26945,14 +27155,14 @@ var defaultChatWidgets = [
26945
27155
  loading: "lazy"
26946
27156
  }
26947
27157
  ),
26948
- /* @__PURE__ */ jsxs12("div", { style: { flex: 1, minWidth: 0 }, children: [
26949
- /* @__PURE__ */ jsx13("div", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827", marginBottom: "0.25rem" }, children: payload.name }),
26950
- payload.details ? /* @__PURE__ */ jsx13("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: Object.entries(payload.details).map(([key, value]) => /* @__PURE__ */ jsxs12("div", { style: { display: "flex", gap: "0.5rem", fontSize: "0.875rem" }, children: [
26951
- /* @__PURE__ */ jsxs12("span", { style: { color: "#6b7280", fontWeight: 500, minWidth: "fit-content" }, children: [
27158
+ /* @__PURE__ */ jsxs11("div", { style: { flex: 1, minWidth: 0 }, children: [
27159
+ /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600, fontSize: "1rem", color: "#111827", marginBottom: "0.25rem" }, children: payload.name }),
27160
+ payload.details ? /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: Object.entries(payload.details).map(([key, value]) => /* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: "0.5rem", fontSize: "0.875rem" }, children: [
27161
+ /* @__PURE__ */ jsxs11("span", { style: { color: "#6b7280", fontWeight: 500, minWidth: "fit-content" }, children: [
26952
27162
  key,
26953
27163
  ":"
26954
27164
  ] }),
26955
- /* @__PURE__ */ jsx13("span", { style: { color: "#374151" }, children: String(value) })
27165
+ /* @__PURE__ */ jsx12("span", { style: { color: "#374151" }, children: String(value) })
26956
27166
  ] }, key)) }) : null
26957
27167
  ] })
26958
27168
  ] })
@@ -26965,7 +27175,7 @@ var defaultChatWidgets = [
26965
27175
  uri: zod_default.string().url(),
26966
27176
  text: zod_default.string().optional()
26967
27177
  }).describe("rendering a clickable link"),
26968
- render: (payload) => /* @__PURE__ */ jsx13(
27178
+ render: (payload) => /* @__PURE__ */ jsx12(
26969
27179
  "a",
26970
27180
  {
26971
27181
  href: payload.uri,
@@ -27013,25 +27223,34 @@ var getVendorCardsWidget = (isProd) => {
27013
27223
  inputs: {
27014
27224
  vendorIds: "${vendors|map('vendor_id')|join(',')}"
27015
27225
  }
27016
- },
27017
- /* calculate distance from user to each vendor */
27018
- distanceMatrix: {
27019
- toolId: distanceMatrixToolId,
27020
- inputs: {
27021
- origin: "${fromCoordinates}",
27022
- destinations: "${vendors|map('vendorCoordinates')}"
27023
- }
27024
27226
  }
27227
+ /* calculate distance from user to each vendor */
27228
+ // distanceMatrix: {
27229
+ // toolId: distanceMatrixToolId,
27230
+ // inputs: {
27231
+ // origin: "${fromCoordinates}",
27232
+ // destinations: "${vendors|map('vendorCoordinates')}",
27233
+ // },
27234
+ // }
27025
27235
  },
27026
- render: (payload, enriched) => /* @__PURE__ */ jsx13(
27236
+ render: (payload, enriched, { messageContext }) => /* @__PURE__ */ jsx12(
27027
27237
  VendorCards,
27028
27238
  {
27029
27239
  payload,
27030
27240
  enriched,
27241
+ existingFeedback: messageContext?.getFeedback?.()?.notes,
27031
27242
  onAddToList: (vendorId) => {
27032
27243
  window.dispatchEvent(new CustomEvent("vendor-selected", {
27033
27244
  detail: { vendorId }
27034
27245
  }));
27246
+ },
27247
+ onFeedback: (noteId, payload2) => {
27248
+ messageContext?.submitFeedback?.({
27249
+ notes: [{
27250
+ noteId,
27251
+ ...payload2
27252
+ }]
27253
+ });
27035
27254
  }
27036
27255
  }
27037
27256
  )
@@ -27044,9 +27263,7 @@ export {
27044
27263
  ChatWidget,
27045
27264
  FullDisplayMode,
27046
27265
  FullDisplayMode as FullRenderer,
27047
- MessageWithFeedbackRenderer as MessageBubbleRenderer,
27048
27266
  MessageRenderer,
27049
- MessageWithFeedbackRenderer,
27050
27267
  PopupChatWidget,
27051
27268
  SDK_WIDGET_MARKER,
27052
27269
  TagGroupDisplay,