@cmnd-ai/chatbot-react 1.9.2 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/Readme.md +113 -9
  2. package/dist/ChatProvider/index.d.ts +2 -2
  3. package/dist/ChatProvider/index.js +13 -13
  4. package/dist/ChatProvider/processStream/index.js +40 -15
  5. package/dist/CmndChatBot/index.d.ts +2 -1
  6. package/dist/CmndChatBot/index.js +2 -2
  7. package/dist/components/Chatbubble.d.ts +2 -2
  8. package/dist/components/Chatbubble.js +11 -11
  9. package/dist/components/Conversation.d.ts +3 -3
  10. package/dist/components/Conversation.js +2 -2
  11. package/dist/components/ConversationCard.js +1 -1
  12. package/dist/components/ConversationsPanel/index.d.ts +2 -2
  13. package/dist/components/ConversationsPanel/index.js +25 -23
  14. package/dist/components/LoadingBubble.js +1 -1
  15. package/dist/constants/endpoints.d.ts +3 -3
  16. package/dist/constants/endpoints.js +2 -2
  17. package/dist/hooks/use-cmnd-chat.d.ts +130 -0
  18. package/dist/hooks/use-cmnd-chat.js +396 -0
  19. package/dist/index.d.ts +4 -1
  20. package/dist/index.js +4 -0
  21. package/dist/services/deleteChatbotConversationMemory/index.d.ts +2 -2
  22. package/dist/services/deleteChatbotConversationMemory/index.js +2 -2
  23. package/dist/services/getChatBotConversationsList/index.d.ts +1 -1
  24. package/dist/services/getEmbedChatBotById.d.ts +1 -1
  25. package/dist/services/patchChatbotConversationMemory/index.d.ts +2 -2
  26. package/dist/services/patchChatbotConversationMemory/index.js +2 -2
  27. package/dist/type.d.ts +134 -41
  28. package/dist/type.js +12 -0
  29. package/dist/utils/cleanMarkdown.d.ts +8 -0
  30. package/dist/utils/cleanMarkdown.js +31 -0
  31. package/dist/utils/saveConversationIdToLocalStorage/index.d.ts +2 -2
  32. package/dist/utils/saveConversationIdToLocalStorage/index.js +8 -7
  33. package/package.json +4 -3
  34. package/readme.dev.md +49 -0
package/Readme.md CHANGED
@@ -117,6 +117,110 @@ const App = () => {
117
117
  };
118
118
  ```
119
119
 
120
+ ## Headless Usage with `useCMNDChat` Hook
121
+
122
+ If you want complete control over your UI while maintaining the powerful chatbot logic, you can use the `useCMNDChat` hook. It handles all state management, real-time streaming, conversation history, and tool orchestration.
123
+
124
+ ```tsx
125
+ import { useCMNDChat, MessageRole } from "@cmnd-ai/chatbot-react";
126
+
127
+ const MyCustomChat = () => {
128
+ const {
129
+ messages,
130
+ input,
131
+ setInput,
132
+ isChatLoading,
133
+ canSendMessage,
134
+ sendMessage,
135
+ submitToolResult,
136
+ conversations,
137
+ handleNewChat,
138
+ handleConversationSelect,
139
+ error,
140
+ } = useCMNDChat({
141
+ chatbotId: 123,
142
+ organizationId: 456,
143
+ baseUrl: "https://api.cmnd.ai",
144
+ apiKey: "your-api-key",
145
+ cleanResponse: true, // Optional: Returns assistant messages as plaintext
146
+ onData: (data) => console.log("Stream update:", data),
147
+ onToolCall: async (tool) => {
148
+ console.log("AI called tool:", tool.name);
149
+
150
+ // For UI tools, you must execute and call submitToolResult
151
+ if (tool.name === "my_custom_tool") {
152
+ const result = await runMyTool(tool.args);
153
+ submitToolResult(JSON.stringify(result));
154
+ }
155
+ },
156
+ });
157
+
158
+ return (
159
+ <div className="custom-chat">
160
+ <div className="message-list">
161
+ {messages.map((m) => (
162
+ <div key={m.id} className={`message ${m.role}`}>
163
+ {m.role === MessageRole.ASSISTANT ? "🤖" : "👤"}: {m.message}
164
+ {/* Handle tool calls */}
165
+ {m.role === MessageRole.FUNCTION && (
166
+ <div className="tool-ui">
167
+ Rendering Tool: {m.tool.name}
168
+ {/* Once done, call submitToolResult("result") */}
169
+ </div>
170
+ )}
171
+ </div>
172
+ ))}
173
+ </div>
174
+
175
+ <div className="controls">
176
+ <input
177
+ value={input}
178
+ onChange={(e) => setInput(e.target.value)}
179
+ placeholder="Type here..."
180
+ />
181
+ <button onClick={() => sendMessage()}>Send</button>
182
+ <button onClick={handleNewChat}>Clear Chat</button>
183
+ </div>
184
+ </div>
185
+ );
186
+ };
187
+ ```
188
+
189
+ ### Hook API Reference
190
+
191
+ #### `UseCMNDChatOptions`
192
+
193
+ | Option | Type | Description |
194
+ | ---------------- | --------------------- | -------------------------------------------------------------------------- |
195
+ | `chatbotId` | `number` | **Required**. Your unique chatbot ID. |
196
+ | `organizationId` | `number` | **Required**. Your unique organization ID. |
197
+ | `baseUrl` | `string` | **Required**. The CMND API base URL. |
198
+ | `apiKey` | `string` | Optional API key for authentication. |
199
+ | `initialMemory` | `object` | Context to send when starting a new conversation. |
200
+ | `UITools` | `CMNDChatbotUITool[]` | Array of custom UI tools. |
201
+ | `onData` | `function` | Triggered for every response chunk or message update. |
202
+ | `onToolCall` | `function` | Triggered when the AI requests a tool execution. |
203
+ | `cleanResponse` | `boolean` | If `true`, assistant messages are returned as plaintext. Default: `false`. |
204
+
205
+ #### `UseCMNDChatResult`
206
+
207
+ | Property | Type | Description |
208
+ | -------------------------- | ----------------------- | --------------------------------------------------------- |
209
+ | `messages` | `Message[]` | Array of all messages in the current conversation thread. |
210
+ | `input` | `string` | The current text in the chat input. |
211
+ | `setInput` | `function` | Update the chat input text. |
212
+ | `isChatLoading` | `boolean` | True if a message is being generated or tool is running. |
213
+ | `canSendMessage` | `boolean` | True if the system is ready to receive the next message. |
214
+ | `sendMessage` | `(text?) => Promise` | Send a message. Uses `input` if `text` is omitted. |
215
+ | `submitToolResult` | `(output) => Promise` | Submit results from a UI tool back to the AI. |
216
+ | `conversations` | `ChatbotConversation[]` | List of historical conversations. |
217
+ | `selectedConversation` | `ChatbotConversation` | The currently active conversation metadata. |
218
+ | `handleNewChat` | `function` | Starts a fresh conversation thread. |
219
+ | `handleConversationSelect` | `function` | Loads a specific conversation from history. |
220
+ | `handleDeleteConversation` | `function` | Deletes a conversation from history. |
221
+ | `tools` | `any[]` | All available tools (API + UI). |
222
+ | `error` | `string` | Contains description of any API or processing errors. |
223
+
120
224
  ## Props
121
225
 
122
226
  ### Required Props
@@ -130,15 +234,15 @@ const App = () => {
130
234
 
131
235
  ### Optional Props
132
236
 
133
- | Prop | Type | Default | Description |
134
- | ----------------------- | --------------------- | ----------- | ----------------------------------------------------- |
135
- | `theme` | `"light" \| "dark"` | `"light"` | Theme for the chatbot |
136
- | `UITools` | `CMNDChatbotUITool[]` | `[]` | Array of UI tools |
137
- | `enabledTools` | `any[]` | `[]` | Array of enabled tools |
138
- | `initialMemory` | `CMNDChatMemory` | `undefined` | Initial conversation memory |
139
- | `customStyles` | `CustomStyles` | `undefined` | Custom CSS styles |
140
- | `Components` | `Components` | `undefined` | Custom component overrides |
141
- | `chatHistoryStorageKey` | `string` | `undefined` | The chat history key defined by the client |
237
+ | Prop | Type | Default | Description |
238
+ | ----------------------- | --------------------- | ----------- | ------------------------------------------ |
239
+ | `theme` | `"light" \| "dark"` | `"light"` | Theme for the chatbot |
240
+ | `UITools` | `CMNDChatbotUITool[]` | `[]` | Array of UI tools |
241
+ | `enabledTools` | `any[]` | `[]` | Array of enabled tools |
242
+ | `initialMemory` | `CMNDChatMemory` | `undefined` | Initial conversation memory |
243
+ | `customStyles` | `CustomStyles` | `undefined` | Custom CSS styles |
244
+ | `Components` | `Components` | `undefined` | Custom component overrides |
245
+ | `chatHistoryStorageKey` | `string` | `undefined` | The chat history key defined by the client |
142
246
 
143
247
  ## Custom Components
144
248
 
@@ -5,7 +5,7 @@ export declare const ChatProviderContext: React.Context<CmndChatContext | undefi
5
5
  export interface ChatProviderProps extends Omit<CmndChatBotProps, "postSessionMessage"> {
6
6
  children?: React.ReactNode | ((props: CmndChatBotProps) => React.ReactNode);
7
7
  }
8
- export declare const setCurrentConversationMemory: (memory: CMNDChatMemory) => Promise<import("axios").AxiosResponse<any, any> | undefined>;
9
- export declare const deleteCurrentConversationMemory: (memoryKeyToDelete: string) => Promise<import("axios").AxiosResponse<any, any> | undefined>;
8
+ export declare const setCurrentConversationMemory: (memory: CMNDChatMemory) => Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
9
+ export declare const deleteCurrentConversationMemory: (memoryKeyToDelete: string) => Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
10
10
  declare function ChatProvider(props: ChatProviderProps): JSX.Element | null;
11
11
  export default ChatProvider;
@@ -7,16 +7,16 @@ import deleteChatbotConversationMemory from "../services/deleteChatbotConversati
7
7
  import parseUITools from "../utils/parseUITools.js";
8
8
  import getTools from "../utils/getTools/index.js";
9
9
  import { ConversationsPanel, } from "../components/ConversationsPanel/index.js";
10
- let globalChatbotConversationId;
10
+ let globalChatbotConversationRef;
11
11
  let globalChatbotProps;
12
12
  export const ChatProviderContext = React.createContext(undefined);
13
13
  export const setCurrentConversationMemory = async (memory) => {
14
14
  try {
15
- if (!globalChatbotConversationId || !globalChatbotProps) {
15
+ if (!globalChatbotConversationRef || !globalChatbotProps) {
16
16
  return Promise.reject("setCurrentConversationMemory method is only available when user is interacting with an active chat thread.");
17
17
  }
18
18
  return await patchChatbotConversationMemory({
19
- chatbotConversationId: globalChatbotConversationId,
19
+ chatbotConversationRef: globalChatbotConversationRef,
20
20
  memory,
21
21
  baseUrl: globalChatbotProps.baseUrl,
22
22
  chatbotId: globalChatbotProps.chatbotId,
@@ -29,11 +29,11 @@ export const setCurrentConversationMemory = async (memory) => {
29
29
  };
30
30
  export const deleteCurrentConversationMemory = async (memoryKeyToDelete) => {
31
31
  try {
32
- if (!globalChatbotConversationId || !globalChatbotProps) {
32
+ if (!globalChatbotConversationRef || !globalChatbotProps) {
33
33
  return Promise.reject("deleteCurrentConversationMemory method is only available when user is interacting with an active chat thread.");
34
34
  }
35
35
  return await deleteChatbotConversationMemory({
36
- chatbotConversationId: globalChatbotConversationId,
36
+ chatbotConversationRef: globalChatbotConversationRef,
37
37
  memoryKeyToDelete,
38
38
  baseUrl: globalChatbotProps.baseUrl,
39
39
  chatbotId: globalChatbotProps.chatbotId,
@@ -54,7 +54,7 @@ function ChatProvider(props) {
54
54
  const [canContinue] = useState(false);
55
55
  const [isChatLoading, setIsChatLoading] = useState(false);
56
56
  const [canSendMessage, setCanSendMessage] = useState(true);
57
- const [chatbotConversationId, setChatbotConversationId] = useState(undefined);
57
+ const [chatbotConversationRef, setChatbotConversationRef] = useState(undefined);
58
58
  const [enabledTools, setEnabledTools] = useState([]);
59
59
  const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);
60
60
  const [selectedConversation, setSelectedConversation] = useState(null);
@@ -63,8 +63,8 @@ function ChatProvider(props) {
63
63
  const [pendingSendText, setPendingSendText] = useState(null);
64
64
  const conversationsPanelRef = useRef(null);
65
65
  useEffect(() => {
66
- globalChatbotConversationId = chatbotConversationId;
67
- }, [chatbotConversationId]);
66
+ globalChatbotConversationRef = chatbotConversationRef;
67
+ }, [chatbotConversationRef]);
68
68
  useEffect(() => {
69
69
  setLoading(true);
70
70
  getEmbedChatBotById(baseUrl, organizationId, chatbotId)
@@ -86,8 +86,8 @@ function ChatProvider(props) {
86
86
  messages: newMessages,
87
87
  uiTools: parseUITools(UITools),
88
88
  };
89
- if (chatbotConversationId) {
90
- payload["chatbotConversationId"] = chatbotConversationId;
89
+ if (chatbotConversationRef) {
90
+ payload["chatbotConversationRef"] = chatbotConversationRef;
91
91
  }
92
92
  else {
93
93
  payload["initialMemory"] = initialMemory;
@@ -155,14 +155,14 @@ function ChatProvider(props) {
155
155
  canSendMessage,
156
156
  isChatLoading,
157
157
  postSessionMessage,
158
- setChatbotConversationId,
158
+ setChatbotConversationRef,
159
159
  setIsChatLoading,
160
160
  setCanSendMessage,
161
161
  enabledTools: getTools({
162
162
  apiTools: enabledTools,
163
163
  uiTools: parseUITools(UITools),
164
164
  }),
165
- chatbotConversationId,
165
+ chatbotConversationRef,
166
166
  UITools: parseUITools(UITools),
167
167
  },
168
168
  createNewConversation,
@@ -174,6 +174,6 @@ function ChatProvider(props) {
174
174
  }, children: error ? (_jsx("div", { children: "An error occured" })) : (_jsxs(_Fragment, { children: [props.children, _jsx(ConversationsPanel, { ref: conversationsPanelRef, organizationId: organizationId, chatbotId: chatbotId, baseUrl: baseUrl, chatHistoryStorageKey: props.chatHistoryStorageKey, theme: props.theme, enabledTools: getTools({
175
175
  apiTools: enabledTools,
176
176
  uiTools: parseUITools(UITools),
177
- }), postSessionMessage: postSessionMessage, setChatbotConversationId: setChatbotConversationId, chatbotConversationId: chatbotConversationId, Components: Components, UITools: parseUITools(UITools), customStyles: props.customStyles, isSidebarCollapsed: isSidebarCollapsed, setIsSidebarCollapsed: setIsSidebarCollapsed, selectedConversation: selectedConversation, setSelectedConversation: setSelectedConversation, messages: messages, setMessages: setMessages, input: input, setInput: setInput, inputRef: inputRef })] })) }));
177
+ }), postSessionMessage: postSessionMessage, setChatbotConversationRef: setChatbotConversationRef, chatbotConversationRef: chatbotConversationRef, Components: Components, UITools: parseUITools(UITools), customStyles: props.customStyles, isSidebarCollapsed: isSidebarCollapsed, setIsSidebarCollapsed: setIsSidebarCollapsed, selectedConversation: selectedConversation, setSelectedConversation: setSelectedConversation, messages: messages, setMessages: setMessages, input: input, setInput: setInput, inputRef: inputRef })] })) }));
178
178
  }
179
179
  export default ChatProvider;
@@ -3,6 +3,7 @@ const processStream = async (reader, onData) => {
3
3
  if (!onData)
4
4
  return;
5
5
  let fullAssistantMessage = "";
6
+ let functionName = "";
6
7
  let buffer = ""; // buffer to store incomplete JSON string fragments
7
8
  try {
8
9
  while (true) {
@@ -44,19 +45,32 @@ const processStream = async (reader, onData) => {
44
45
  });
45
46
  }
46
47
  else if (dataObject.function_call) {
47
- // console.log("no processing necessary");
48
+ const { name } = dataObject.function_call;
49
+ if (name)
50
+ functionName = name;
51
+ onData({
52
+ completionFinished: false,
53
+ finalResponseWithUsageData: false,
54
+ streamingFunctionCall: true,
55
+ functionName,
56
+ });
57
+ }
58
+ else if (dataObject.function_result) {
59
+ onData({
60
+ completionFinished: false,
61
+ finalResponseWithUsageData: false,
62
+ streamingFunctionCall: false,
63
+ functionResult: dataObject.function_result,
64
+ });
48
65
  }
49
66
  else {
50
- //at this point, the dataObject does not have a content propery
51
- //and it is completed
52
- //get the last message from the dataObject to check if it is a function call
53
- const { messages, completionFinished, finalResponseWithUsageData, conversationId, chatbotConversationId, totalTokens, totalCost, } = dataObject;
67
+ const { messages, completionFinished, finalResponseWithUsageData, conversationRef, chatbotConversationRef, totalTokens, totalCost, } = dataObject;
54
68
  onData({
55
69
  messages,
56
70
  completionFinished,
57
71
  finalResponseWithUsageData,
58
- conversationId,
59
- chatbotConversationId,
72
+ conversationRef,
73
+ chatbotConversationRef,
60
74
  totalTokens,
61
75
  totalCost,
62
76
  });
@@ -69,13 +83,23 @@ const processStream = async (reader, onData) => {
69
83
  continue;
70
84
  }
71
85
  console.error("StreamError caught", error);
72
- onData({
73
- completionFinished: true,
74
- message: error instanceof StreamError
75
- ? error.message
76
- : "Oops! I ran into a problem.",
77
- finalResponseWithUsageData: true,
78
- });
86
+ if (error instanceof StreamError) {
87
+ onData({
88
+ completionFinished: true,
89
+ message: error.message,
90
+ finalResponseWithUsageData: true,
91
+ hasError: true,
92
+ errorPath: error.path,
93
+ });
94
+ }
95
+ else {
96
+ onData({
97
+ completionFinished: true,
98
+ message: "Oops! I ran into a problem.",
99
+ finalResponseWithUsageData: true,
100
+ hasError: true,
101
+ });
102
+ }
79
103
  }
80
104
  }
81
105
  }
@@ -85,11 +109,12 @@ const processStream = async (reader, onData) => {
85
109
  }
86
110
  }
87
111
  catch (error) {
88
- console.error("Error processing stream", error);
112
+ console.error("Fatal error in processStream", error);
89
113
  onData({
90
114
  completionFinished: true,
91
115
  message: "Oops! I ran into a problem.",
92
116
  finalResponseWithUsageData: true,
117
+ hasError: true,
93
118
  });
94
119
  }
95
120
  };
@@ -20,6 +20,7 @@ export interface CmndChatBotProps {
20
20
  LoadingIndicator?: () => JSX.Element;
21
21
  error?: any;
22
22
  };
23
+ cleanResponse?: boolean;
23
24
  }
24
- declare function CmndChatBot({ chatbotId, organizationId, apiKey, baseUrl, theme, UITools, customStyles, chatHistoryStorageKey, enabledTools, Components, initialMemory, }: CmndChatBotProps): JSX.Element;
25
+ declare function CmndChatBot({ chatbotId, organizationId, apiKey, baseUrl, theme, UITools, customStyles, chatHistoryStorageKey, enabledTools, Components, initialMemory, cleanResponse, }: CmndChatBotProps): JSX.Element;
25
26
  export default CmndChatBot;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import ChatProvider from "../ChatProvider/index.js";
3
- function CmndChatBot({ chatbotId, organizationId, apiKey, baseUrl, theme, UITools, customStyles, chatHistoryStorageKey, enabledTools = [], Components, initialMemory, }) {
4
- return (_jsx(ChatProvider, { chatbotId: chatbotId, organizationId: organizationId, chatHistoryStorageKey: chatHistoryStorageKey, apiKey: apiKey, baseUrl: baseUrl, theme: theme, UITools: UITools, customStyles: customStyles, enabledTools: enabledTools, Components: Components, initialMemory: initialMemory }));
3
+ function CmndChatBot({ chatbotId, organizationId, apiKey, baseUrl, theme, UITools, customStyles, chatHistoryStorageKey, enabledTools = [], Components, initialMemory, cleanResponse, }) {
4
+ return (_jsx(ChatProvider, { chatbotId: chatbotId, organizationId: organizationId, chatHistoryStorageKey: chatHistoryStorageKey, apiKey: apiKey, baseUrl: baseUrl, theme: theme, UITools: UITools, customStyles: customStyles, enabledTools: enabledTools, Components: Components, initialMemory: initialMemory, cleanResponse: cleanResponse }));
5
5
  }
6
6
  export default CmndChatBot;
@@ -11,7 +11,7 @@ interface ChatBubbleProps {
11
11
  hide?: boolean;
12
12
  id: string;
13
13
  isLoadingBubble?: boolean;
14
- setChatbotConversationId: Dispatch<SetStateAction<number | undefined>>;
14
+ setChatbotConversationRef: Dispatch<SetStateAction<string | undefined>>;
15
15
  setCanSendMessage: Dispatch<SetStateAction<boolean>>;
16
16
  setIsChatLoading: Dispatch<SetStateAction<boolean>>;
17
17
  UITools?: CMNDChatbotUITool[];
@@ -29,5 +29,5 @@ interface ChatBubbleProps {
29
29
  error?: any;
30
30
  };
31
31
  }
32
- declare const Chatbubble: ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, isLoadingBubble, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, theme, Components, }: ChatBubbleProps) => JSX.Element | null;
32
+ declare const Chatbubble: ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationRef, setCanSendMessage, setIsChatLoading, isLoadingBubble, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, theme, Components, }: ChatBubbleProps) => JSX.Element | null;
33
33
  export default Chatbubble;
@@ -27,7 +27,7 @@ const patchLastMessageToolInfo = (messages, toolInfo) => {
27
27
  const newMessages = [...shallowCopyOfMessagesWithoutLast, copyOfLastMessage];
28
28
  return newMessages;
29
29
  };
30
- const confirmToolRun = async ({ messages, setMessages, postSessionMessage, setIsChatLoading, setCanSendMessage, setChatbotConversationId, chatbotId, organizationId, chatHistoryStorageKey }) => {
30
+ const confirmToolRun = async ({ messages, setMessages, postSessionMessage, setIsChatLoading, setCanSendMessage, setChatbotConversationRef, chatbotId, organizationId, chatHistoryStorageKey, }) => {
31
31
  const newMessages = patchLastMessageToolInfo(messages, {
32
32
  confirmed: true,
33
33
  });
@@ -38,14 +38,14 @@ const confirmToolRun = async ({ messages, setMessages, postSessionMessage, setIs
38
38
  if (data.finalResponseWithUsageData) {
39
39
  setCanSendMessage(true);
40
40
  setIsChatLoading(false);
41
- const { messages, chatbotConversationId } = data;
42
- if (chatbotConversationId) {
43
- setChatbotConversationId(chatbotConversationId);
41
+ const { messages, chatbotConversationRef } = data;
42
+ if (chatbotConversationRef) {
43
+ setChatbotConversationRef(chatbotConversationRef);
44
44
  await saveConversationIdToLocalStorage({
45
- chatbotConversationId,
45
+ chatbotConversationRef,
46
46
  chatbotId,
47
47
  organizationId,
48
- chatHistoryStorageKey
48
+ chatHistoryStorageKey,
49
49
  });
50
50
  }
51
51
  messages && setMessages(messages);
@@ -76,7 +76,7 @@ const getChatAvatar = (role, theme = "light", Components) => {
76
76
  return _jsx(BsRobot, { color: iconColor });
77
77
  }
78
78
  };
79
- const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, isLoadingBubble, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, theme, Components, }) => {
79
+ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationRef, setCanSendMessage, setIsChatLoading, isLoadingBubble, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, theme, Components, }) => {
80
80
  const toolData = tools?.find((t) => t.name === toolCallDetails?.name);
81
81
  const hasConfirmedToolRun = useRef(false);
82
82
  const isPostingMessage = useRef(false);
@@ -93,7 +93,7 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
93
93
  postSessionMessage,
94
94
  setIsChatLoading,
95
95
  setCanSendMessage,
96
- setChatbotConversationId,
96
+ setChatbotConversationRef,
97
97
  chatbotId,
98
98
  organizationId,
99
99
  chatHistoryStorageKey,
@@ -154,9 +154,9 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
154
154
  if (data.finalResponseWithUsageData) {
155
155
  setIsChatLoading(false);
156
156
  setCanSendMessage(true);
157
- const { chatbotConversationId, messages } = data;
158
- if (chatbotConversationId) {
159
- setChatbotConversationId(chatbotConversationId);
157
+ const { chatbotConversationRef, messages } = data;
158
+ if (chatbotConversationRef) {
159
+ setChatbotConversationRef(chatbotConversationRef);
160
160
  }
161
161
  messages && setMessages(messages);
162
162
  }
@@ -9,8 +9,8 @@ export interface ConversationProps {
9
9
  isChatLoading: boolean;
10
10
  error: string | null;
11
11
  messagesRef: React.RefObject<HTMLDivElement>;
12
- setChatbotConversationId: Dispatch<React.SetStateAction<number | undefined>>;
13
- chatbotConversationId: number | undefined;
12
+ setChatbotConversationRef: Dispatch<SetStateAction<string | undefined>>;
13
+ chatbotConversationRef: string | undefined;
14
14
  setIsChatLoading: Dispatch<SetStateAction<boolean>>;
15
15
  setCanSendMessage: Dispatch<SetStateAction<boolean>>;
16
16
  canSendMessage: boolean;
@@ -32,5 +32,5 @@ export interface ConversationProps {
32
32
  resetMessagesScroll?: () => void;
33
33
  inputRef?: React.RefObject<HTMLInputElement>;
34
34
  }
35
- declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, isMessagesScrolledToBottom, resetMessagesScroll, inputRef, }: ConversationProps) => JSX.Element;
35
+ declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationRef, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, isMessagesScrolledToBottom, resetMessagesScroll, inputRef, }: ConversationProps) => JSX.Element;
36
36
  export default Conversation;
@@ -3,8 +3,8 @@ import Chatbubble from "./Chatbubble.js";
3
3
  import LoadingBubble from "./LoadingBubble.js";
4
4
  import ScrollToBottomButton from "./ScrollToBottomButton.js";
5
5
  import ChatInputBox from "./ChatInputBox.js";
6
- const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, isMessagesScrolledToBottom = true, resetMessagesScroll, inputRef, }) => {
7
- return (_jsxs("div", { className: "cmnd-conversations", children: [_jsxs("div", { ref: messagesRef, id: "messages", className: "cmnd-conversations-messages", children: [error, messages.map((m, i) => (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, chatHistoryStorageKey: chatHistoryStorageKey, customStyles: customStyles, hide: m.hiddenFromUser, message: m.message, role: m.role, toolCallDetails: m.tool, tools: enabledTools, postSessionMessage: postSessionMessage, messages: messages, setMessages: setMessages, id: m.id, setChatbotConversationId: setChatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, UITools: UITools, theme: theme, Components: Components }, i))), isChatLoading ? (_jsx(LoadingBubble, { customStyles: customStyles, chatbotId: chatbotId, organizationId: organizationId, theme: theme, Components: Components })) : null] }), _jsx(ScrollToBottomButton, { onClick: resetMessagesScroll || (() => { }), isVisible: !isMessagesScrolledToBottom && messages.length > 0, theme: theme, customStyles: customStyles }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick, inputRef } })) : (_jsx(ChatInputBox, { input: input, setInput: setInput, handleSendClick: handleSendClick, inputRef: inputRef })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
6
+ const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationRef, setIsChatLoading, setCanSendMessage, canSendMessage, setInput, input, theme, Components, UITools, customStyles, chatbotId, organizationId, chatHistoryStorageKey, isMessagesScrolledToBottom = true, resetMessagesScroll, inputRef, }) => {
7
+ return (_jsxs("div", { className: "cmnd-conversations", children: [_jsxs("div", { ref: messagesRef, id: "messages", className: "cmnd-conversations-messages", children: [error, messages.map((m, i) => (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, chatHistoryStorageKey: chatHistoryStorageKey, customStyles: customStyles, hide: m.hiddenFromUser, message: m.message, role: m.role, toolCallDetails: m.tool, tools: enabledTools, postSessionMessage: postSessionMessage, messages: messages, setMessages: setMessages, id: m.id, setChatbotConversationRef: setChatbotConversationRef, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, UITools: UITools, theme: theme, Components: Components }, i))), isChatLoading ? (_jsx(LoadingBubble, { customStyles: customStyles, chatbotId: chatbotId, organizationId: organizationId, theme: theme, Components: Components })) : null] }), _jsx(ScrollToBottomButton, { onClick: resetMessagesScroll || (() => { }), isVisible: !isMessagesScrolledToBottom && messages.length > 0, theme: theme, customStyles: customStyles }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick, inputRef } })) : (_jsx(ChatInputBox, { input: input, setInput: setInput, handleSendClick: handleSendClick, inputRef: inputRef })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
8
8
  canSendMessage,
9
9
  handleSendClick,
10
10
  } })) : (_jsx("button", { className: "cmnd-send-button", onClick: handleSendClick, children: "Send" }))] })] }));
@@ -59,7 +59,7 @@ const ConversationCard = ({ conversation, isActive, onClick, onDelete, theme = "
59
59
  fontSize: "12px",
60
60
  color: colors.secondaryText,
61
61
  ...customStyles?.dateStyle,
62
- }, children: formatDate(conversation.updatedAt) })] }), onDelete && (_jsx("button", { className: "cmnd-conversation-delete", onClick: (e) => {
62
+ }, children: formatDate(conversation.updatedAt ?? conversation.createdAt) })] }), onDelete && (_jsx("button", { className: "cmnd-conversation-delete", onClick: (e) => {
63
63
  e.stopPropagation();
64
64
  onDelete();
65
65
  }, style: {
@@ -7,8 +7,8 @@ interface ConversationsPanelProps {
7
7
  chatHistoryStorageKey?: string;
8
8
  theme?: "light" | "dark";
9
9
  enabledTools?: any[];
10
- setChatbotConversationId: Dispatch<SetStateAction<number | undefined>>;
11
- chatbotConversationId: number | undefined;
10
+ setChatbotConversationRef: Dispatch<SetStateAction<string | undefined>>;
11
+ chatbotConversationRef: string | undefined;
12
12
  postSessionMessage: (newMessages: any, onData: any) => Promise<any>;
13
13
  Components?: {
14
14
  InputField?: (params: InputFieldProps) => JSX.Element;