reactbridge-sdk 0.2.13 → 0.2.15

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
@@ -132,7 +132,11 @@ class ReactBridgeAPI {
132
132
  // Pass the FULL ToolResult object to the orchestrator, not just the summary
133
133
  // The orchestrator needs: status, result_items, and detailed_data for sequential execution
134
134
  const toolResultJson = JSON.stringify(toolResult, null, 2);
135
- const request = Object.assign(Object.assign({}, originalRequest), { sessionId, query: `[Tool Result] ${toolResultJson}` });
135
+ const request = Object.assign(Object.assign({}, originalRequest), { sessionId, query: `[Tool Result] ${toolResultJson}`,
136
+ // CRITICAL: Remove document/image from subsequent requests
137
+ // If we keep them, the orchestrator will reprocess the PDF on every tool result
138
+ // This causes sequential execution to restart instead of continuing
139
+ document: undefined, image: undefined, modalityHint: undefined });
136
140
  return this.sendMessage(request);
137
141
  });
138
142
  }
@@ -729,6 +733,38 @@ const TypingIndicator = ({ theme }) => (React.createElement("div", { style: {
729
733
  }
730
734
  }
731
735
  `))));
736
+ // Expandable Message Component with Show More functionality
737
+ const ExpandableMessage = ({ content, isUser, theme, isExpanded, onToggleExpand, }) => {
738
+ const characterLimit = 300;
739
+ const isLongMessage = content.length > characterLimit;
740
+ const displayText = isExpanded ? content : content.substring(0, characterLimit);
741
+ return (React.createElement("div", { style: {
742
+ maxWidth: "70%",
743
+ padding: theme.spacing.md,
744
+ borderRadius: theme.borderRadius,
745
+ backgroundColor: isUser
746
+ ? theme.colors.primary
747
+ : theme.colors.surface,
748
+ color: isUser ? "#ffffff" : theme.colors.text,
749
+ fontSize: theme.fontSizes.md,
750
+ boxShadow: theme.boxShadow,
751
+ wordWrap: "break-word",
752
+ whiteSpace: "pre-wrap",
753
+ overflowWrap: "break-word",
754
+ } },
755
+ React.createElement("div", { style: { marginBottom: isLongMessage && !isExpanded ? "8px" : "0" } }, displayText),
756
+ isLongMessage && (React.createElement("button", { onClick: onToggleExpand, style: {
757
+ background: "none",
758
+ border: "none",
759
+ color: isUser ? "#ffffff" : theme.colors.primary,
760
+ cursor: "pointer",
761
+ textDecoration: "underline",
762
+ padding: "0",
763
+ marginTop: isExpanded ? "8px" : "0",
764
+ fontSize: theme.fontSizes.sm,
765
+ fontWeight: "bold",
766
+ } }, isExpanded ? "Show less" : "Show more..."))));
767
+ };
732
768
  // Default styling constants for the widget wrapper
733
769
  const defaultToggleButtonClass = "fixed bottom-6 right-6 z-40 w-14 h-14 rounded-full shadow-lg text-white bg-blue-600 hover:bg-blue-700 transition-all flex justify-center items-center cursor-pointer text-2xl";
734
770
  function ReactBridgeChatbox({ onIntentDetected, currentContext, placeholder = "Type your message...", height = "500px", width = "100%", theme: themeOverride, renderMessage, onError,
@@ -758,7 +794,12 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
758
794
  const [isUploadMenuOpen, setIsUploadMenuOpen] = React.useState(false);
759
795
  const [selectedFile, setSelectedFile] = React.useState(null);
760
796
  const [filePreview, setFilePreview] = React.useState(null);
797
+ // Track expanded messages by ID
798
+ const [expandedMessages, setExpandedMessages] = React.useState(new Set());
799
+ // Track textarea height
800
+ const [textareaHeight, setTextareaHeight] = React.useState(40);
761
801
  const messagesEndRef = React.useRef(null);
802
+ const textareaRef = React.useRef(null);
762
803
  const containerRef = React.useRef(null);
763
804
  // Fallback styles for header
764
805
  const finalHeaderBgColor = headerBgColor || theme.colors.primary;
@@ -768,26 +809,89 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
768
809
  var _a;
769
810
  (_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
770
811
  }, [messages]);
812
+ // Auto-scroll to bottom when widget opens
813
+ React.useEffect(() => {
814
+ if (isOpen && renderMode === "standard") {
815
+ setTimeout(() => {
816
+ var _a;
817
+ (_a = messagesEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
818
+ }, 100);
819
+ }
820
+ }, [isOpen, renderMode]);
821
+ // Handle textarea height adjustment
822
+ const handleTextareaChange = React.useCallback((e) => {
823
+ const textarea = e.target;
824
+ setInputValue(textarea.value);
825
+ // Reset height to calculate scroll height
826
+ textarea.style.height = "auto";
827
+ const scrollHeight = textarea.scrollHeight;
828
+ const lineHeight = parseInt(window.getComputedStyle(textarea).lineHeight);
829
+ const maxHeight = lineHeight * 3; // 3 lines max
830
+ if (scrollHeight <= maxHeight) {
831
+ textarea.style.height = scrollHeight + "px";
832
+ setTextareaHeight(scrollHeight);
833
+ }
834
+ else {
835
+ textarea.style.height = maxHeight + "px";
836
+ textarea.style.overflowY = "auto";
837
+ setTextareaHeight(maxHeight);
838
+ }
839
+ }, []);
840
+ // Handle key down for Shift+Enter and Enter submission
841
+ const handleKeyDown = React.useCallback((e) => {
842
+ if (e.key === "Enter") {
843
+ if (e.shiftKey) {
844
+ // Shift+Enter: Allow new line (default behavior)
845
+ return;
846
+ }
847
+ else {
848
+ // Enter alone: Submit
849
+ e.preventDefault();
850
+ const form = e.currentTarget.closest("form");
851
+ if (form) {
852
+ form.dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }));
853
+ }
854
+ }
855
+ }
856
+ }, []);
857
+ // Toggle message expansion
858
+ const toggleMessageExpansion = (messageId) => {
859
+ setExpandedMessages((prev) => {
860
+ const newSet = new Set(prev);
861
+ if (newSet.has(messageId)) {
862
+ newSet.delete(messageId);
863
+ }
864
+ else {
865
+ newSet.add(messageId);
866
+ }
867
+ return newSet;
868
+ });
869
+ };
771
870
  // Close upload menu and widget when clicking outside
772
871
  React.useEffect(() => {
773
872
  const handleClickOutside = (event) => {
774
873
  if (containerRef.current &&
775
874
  !containerRef.current.contains(event.target)) {
776
875
  setIsUploadMenuOpen(false);
777
- if (isOpen) {
876
+ if (isOpen && renderMode === "standard") {
778
877
  setIsOpen(false);
779
878
  }
780
879
  }
781
880
  };
782
881
  document.addEventListener("mousedown", handleClickOutside);
783
882
  return () => document.removeEventListener("mousedown", handleClickOutside);
784
- }, [isUploadMenuOpen, isOpen]);
883
+ }, [isUploadMenuOpen, isOpen, renderMode]);
785
884
  const handleSubmit = (e) => __awaiter(this, void 0, void 0, function* () {
786
885
  e.preventDefault();
787
886
  if ((!inputValue.trim() && !selectedFile) || isLoading)
788
887
  return;
789
888
  const query = inputValue.trim();
790
889
  setInputValue("");
890
+ setTextareaHeight(40);
891
+ if (textareaRef.current) {
892
+ textareaRef.current.style.height = "auto";
893
+ textareaRef.current.style.overflowY = "hidden";
894
+ }
791
895
  // Handle multimodal request
792
896
  if (selectedFile && filePreview) {
793
897
  if (filePreview.type === "image") {
@@ -860,22 +964,13 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
860
964
  // Don't render system messages in UI
861
965
  if (isSystem)
862
966
  return null;
967
+ const isExpanded = expandedMessages.has(message.id);
863
968
  return (React.createElement("div", { key: message.id, style: {
864
969
  display: "flex",
865
970
  justifyContent: isUser ? "flex-end" : "flex-start",
866
971
  marginBottom: theme.spacing.md,
867
972
  } },
868
- React.createElement("div", { style: {
869
- maxWidth: "70%",
870
- padding: theme.spacing.md,
871
- borderRadius: theme.borderRadius,
872
- backgroundColor: isUser
873
- ? theme.colors.primary
874
- : theme.colors.surface,
875
- color: isUser ? "#ffffff" : theme.colors.text,
876
- fontSize: theme.fontSizes.md,
877
- boxShadow: theme.boxShadow,
878
- } }, message.content)));
973
+ React.createElement(ExpandableMessage, { content: message.content, isUser: isUser, theme: theme, isExpanded: isExpanded, onToggleExpand: () => toggleMessageExpansion(message.id) })));
879
974
  };
880
975
  // --- RENDER LOGIC FOR 'BASIC' MODE (Original Behavior) ---
881
976
  if (renderMode === "basic") {
@@ -909,9 +1004,9 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
909
1004
  React.createElement("div", { style: {
910
1005
  display: "flex",
911
1006
  gap: theme.spacing.sm,
912
- alignItems: "center",
1007
+ alignItems: "flex-end",
913
1008
  } },
914
- React.createElement("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: placeholder, disabled: isLoading, style: {
1009
+ React.createElement("textarea", { ref: textareaRef, value: inputValue, onChange: handleTextareaChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: isLoading, style: {
915
1010
  flex: 1,
916
1011
  padding: theme.spacing.sm,
917
1012
  fontSize: theme.fontSizes.md,
@@ -920,6 +1015,11 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
920
1015
  backgroundColor: theme.colors.background,
921
1016
  color: theme.colors.text,
922
1017
  outline: "none",
1018
+ fontFamily: "inherit",
1019
+ resize: "none",
1020
+ minHeight: "40px",
1021
+ maxHeight: "120px",
1022
+ height: `${textareaHeight}px`,
923
1023
  } }),
924
1024
  React.createElement("button", { type: "button", onClick: () => setIsUploadMenuOpen(!isUploadMenuOpen), disabled: isLoading, title: "Attach file", style: {
925
1025
  padding: theme.spacing.sm,
@@ -1110,9 +1210,9 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
1110
1210
  React.createElement("div", { style: {
1111
1211
  display: "flex",
1112
1212
  gap: theme.spacing.sm,
1113
- alignItems: "center",
1213
+ alignItems: "flex-end",
1114
1214
  } },
1115
- React.createElement("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: placeholder, disabled: isLoading, style: {
1215
+ React.createElement("textarea", { ref: textareaRef, value: inputValue, onChange: handleTextareaChange, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: isLoading, style: {
1116
1216
  flex: 1,
1117
1217
  padding: theme.spacing.sm,
1118
1218
  fontSize: theme.fontSizes.md,
@@ -1121,6 +1221,11 @@ toggleButtonClass = defaultToggleButtonClass, toggleButtonTitle = "Open chat ass
1121
1221
  backgroundColor: theme.colors.background,
1122
1222
  color: theme.colors.text,
1123
1223
  outline: "none",
1224
+ fontFamily: "inherit",
1225
+ resize: "none",
1226
+ minHeight: "40px",
1227
+ maxHeight: "120px",
1228
+ height: `${textareaHeight}px`,
1124
1229
  } }),
1125
1230
  React.createElement("button", { type: "button", onClick: () => setIsUploadMenuOpen(!isUploadMenuOpen), disabled: isLoading, title: "Attach file", style: {
1126
1231
  padding: theme.spacing.sm,