@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.
- package/Readme.md +113 -9
- package/dist/ChatProvider/index.d.ts +2 -2
- package/dist/ChatProvider/index.js +13 -13
- package/dist/ChatProvider/processStream/index.js +40 -15
- package/dist/CmndChatBot/index.d.ts +2 -1
- package/dist/CmndChatBot/index.js +2 -2
- package/dist/components/Chatbubble.d.ts +2 -2
- package/dist/components/Chatbubble.js +11 -11
- package/dist/components/Conversation.d.ts +3 -3
- package/dist/components/Conversation.js +2 -2
- package/dist/components/ConversationCard.js +1 -1
- package/dist/components/ConversationsPanel/index.d.ts +2 -2
- package/dist/components/ConversationsPanel/index.js +25 -23
- package/dist/components/LoadingBubble.js +1 -1
- package/dist/constants/endpoints.d.ts +3 -3
- package/dist/constants/endpoints.js +2 -2
- package/dist/hooks/use-cmnd-chat.d.ts +130 -0
- package/dist/hooks/use-cmnd-chat.js +396 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -0
- package/dist/services/deleteChatbotConversationMemory/index.d.ts +2 -2
- package/dist/services/deleteChatbotConversationMemory/index.js +2 -2
- package/dist/services/getChatBotConversationsList/index.d.ts +1 -1
- package/dist/services/getEmbedChatBotById.d.ts +1 -1
- package/dist/services/patchChatbotConversationMemory/index.d.ts +2 -2
- package/dist/services/patchChatbotConversationMemory/index.js +2 -2
- package/dist/type.d.ts +134 -41
- package/dist/type.js +12 -0
- package/dist/utils/cleanMarkdown.d.ts +8 -0
- package/dist/utils/cleanMarkdown.js +31 -0
- package/dist/utils/saveConversationIdToLocalStorage/index.d.ts +2 -2
- package/dist/utils/saveConversationIdToLocalStorage/index.js +8 -7
- package/package.json +4 -3
- package/readme.dev.md +49 -0
|
@@ -10,11 +10,11 @@ import getConversationLocalStorageKey from "../../utils/getConversationLocalStor
|
|
|
10
10
|
import saveConversationIdToLocalStorage from "../../utils/saveConversationIdToLocalStorage/index.js";
|
|
11
11
|
import getUTCDateTime from "../../utils/getUTCDateTime/index.js";
|
|
12
12
|
import useMessagesScroll from "../../hooks/use-messages-scroll.js";
|
|
13
|
-
|
|
13
|
+
import { v4 as uuidv4 } from "uuid";
|
|
14
|
+
export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseUrl, chatHistoryStorageKey, theme = "light", enabledTools = [], setChatbotConversationRef, chatbotConversationRef, postSessionMessage, Components, UITools, customStyles, isSidebarCollapsed, setIsSidebarCollapsed, selectedConversation, setSelectedConversation, messages, setMessages, input, setInput, inputRef, }, ref) => {
|
|
14
15
|
const [isChatLoading, setIsChatLoading] = useState(false);
|
|
15
16
|
const [canSendMessage, setCanSendMessage] = useState(true);
|
|
16
17
|
const [conversationIds, setConversationIds] = useState([]);
|
|
17
|
-
const isSidebarCollapsedProp = typeof isSidebarCollapsed === "boolean" ? isSidebarCollapsed : false;
|
|
18
18
|
const setIsSidebarCollapsedProp = setIsSidebarCollapsed;
|
|
19
19
|
const [internalSidebarCollapsed, setInternalSidebarCollapsed] = useState(false);
|
|
20
20
|
const isSidebarCollapsedFinal = typeof isSidebarCollapsed === "boolean"
|
|
@@ -51,10 +51,11 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
51
51
|
},
|
|
52
52
|
};
|
|
53
53
|
const colors = themeColors[theme];
|
|
54
|
-
const localStorageKey = chatHistoryStorageKey ||
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
const localStorageKey = chatHistoryStorageKey ||
|
|
55
|
+
getConversationLocalStorageKey({
|
|
56
|
+
organizationId,
|
|
57
|
+
chatbotId,
|
|
58
|
+
});
|
|
58
59
|
useEffect(() => {
|
|
59
60
|
try {
|
|
60
61
|
const conversationsFromLocalStorage = JSON.parse(localStorage.getItem(localStorageKey) || "[]") ?? [];
|
|
@@ -75,7 +76,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
75
76
|
setConversationIds([]);
|
|
76
77
|
}
|
|
77
78
|
};
|
|
78
|
-
const { data, loading, error
|
|
79
|
+
const { data, loading, error } = useFetchData(async () => {
|
|
79
80
|
// Only fetch if we have conversation IDs
|
|
80
81
|
if (conversationIds.length === 0) {
|
|
81
82
|
return { chatbotConversations: [] };
|
|
@@ -116,11 +117,11 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
116
117
|
if (data.finalResponseWithUsageData) {
|
|
117
118
|
setIsChatLoading(false);
|
|
118
119
|
setCanSendMessage(true);
|
|
119
|
-
const {
|
|
120
|
+
const { chatbotConversationRef: newConversationId, messages: updatedMessages, } = data;
|
|
120
121
|
if (newConversationId) {
|
|
121
|
-
|
|
122
|
+
setChatbotConversationRef(newConversationId);
|
|
122
123
|
await saveConversationIdToLocalStorage({
|
|
123
|
-
|
|
124
|
+
chatbotConversationRef: newConversationId,
|
|
124
125
|
chatbotId,
|
|
125
126
|
organizationId,
|
|
126
127
|
chatHistoryStorageKey,
|
|
@@ -131,7 +132,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
131
132
|
"New Conversation") {
|
|
132
133
|
setSelectedConversation({
|
|
133
134
|
...selectedConversation,
|
|
134
|
-
|
|
135
|
+
chatbotConversationRef: newConversationId,
|
|
135
136
|
chatbotConversationTitle: input.substring(0, 50) + (input.length > 50 ? "..." : ""),
|
|
136
137
|
messages: updatedMessages || newMessages,
|
|
137
138
|
});
|
|
@@ -162,7 +163,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
162
163
|
};
|
|
163
164
|
const handleConversationSelect = (conversation) => {
|
|
164
165
|
setSelectedConversation(conversation);
|
|
165
|
-
|
|
166
|
+
setChatbotConversationRef(conversation.chatbotConversationRef);
|
|
166
167
|
const formattedMessages = conversation.messages.map((msg) => ({
|
|
167
168
|
...msg,
|
|
168
169
|
id: msg.id || Date.now().toString(),
|
|
@@ -171,12 +172,12 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
171
172
|
};
|
|
172
173
|
const handleNewChat = () => {
|
|
173
174
|
setSelectedConversation(null);
|
|
174
|
-
|
|
175
|
+
setChatbotConversationRef(undefined);
|
|
175
176
|
setMessages([]);
|
|
176
177
|
setInput("");
|
|
177
178
|
const dateString = getUTCDateTime();
|
|
178
179
|
const newConversation = {
|
|
179
|
-
|
|
180
|
+
chatbotConversationRef: uuidv4(),
|
|
180
181
|
messages: [],
|
|
181
182
|
chatbotId: chatbotId,
|
|
182
183
|
chatbotConversationTitle: "New Conversation",
|
|
@@ -192,10 +193,10 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
192
193
|
const currentConversations = JSON.parse(localStorage.getItem(localStorageKey) || "[]") ?? [];
|
|
193
194
|
const updatedConversations = currentConversations.filter((id) => id !== conversationId);
|
|
194
195
|
localStorage.setItem(localStorageKey, JSON.stringify(updatedConversations));
|
|
195
|
-
if (selectedConversation?.
|
|
196
|
+
if (selectedConversation?.chatbotConversationRef === conversationId) {
|
|
196
197
|
setSelectedConversation(null);
|
|
197
198
|
setMessages([]);
|
|
198
|
-
|
|
199
|
+
setChatbotConversationRef(undefined);
|
|
199
200
|
}
|
|
200
201
|
refetchConversationIds();
|
|
201
202
|
}
|
|
@@ -207,6 +208,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
207
208
|
console.log("Set conversation memory:", memory);
|
|
208
209
|
};
|
|
209
210
|
const allConversations = React.useMemo(() => {
|
|
211
|
+
console.log("data", data?.chatbotConversations);
|
|
210
212
|
const existingConversations = data?.chatbotConversations || [];
|
|
211
213
|
const newConversation = selectedConversation &&
|
|
212
214
|
selectedConversation.chatbotConversationTitle === "New Conversation"
|
|
@@ -217,8 +219,8 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
217
219
|
conversations.push(newConversation);
|
|
218
220
|
}
|
|
219
221
|
return conversations.sort((a, b) => {
|
|
220
|
-
const dateA = new Date(a.updatedAt);
|
|
221
|
-
const dateB = new Date(b.updatedAt);
|
|
222
|
+
const dateA = new Date(a.updatedAt ?? a.createdAt);
|
|
223
|
+
const dateB = new Date(b.updatedAt ?? b.createdAt);
|
|
222
224
|
return dateB.getTime() - dateA.getTime();
|
|
223
225
|
});
|
|
224
226
|
}, [data?.chatbotConversations, selectedConversation]);
|
|
@@ -316,8 +318,8 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
316
318
|
textAlign: "center",
|
|
317
319
|
padding: "20px",
|
|
318
320
|
color: colors.secondaryText,
|
|
319
|
-
}, children: "No conversations yet" })) : (allConversations.map((conversation) => (_jsx(ConversationCard, { conversation: conversation, isActive: selectedConversation?.
|
|
320
|
-
conversation.
|
|
321
|
+
}, children: "No conversations yet" })) : (allConversations.map((conversation) => (_jsx(ConversationCard, { conversation: conversation, isActive: selectedConversation?.chatbotConversationRef ===
|
|
322
|
+
conversation.chatbotConversationRef, onClick: () => {
|
|
321
323
|
if (conversation.chatbotConversationTitle ===
|
|
322
324
|
"New Conversation") {
|
|
323
325
|
}
|
|
@@ -331,7 +333,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
331
333
|
setMessages([]);
|
|
332
334
|
}
|
|
333
335
|
else {
|
|
334
|
-
handleDeleteConversation(conversation.
|
|
336
|
+
handleDeleteConversation(conversation.chatbotConversationRef);
|
|
335
337
|
}
|
|
336
338
|
}, theme: theme, customStyles: {
|
|
337
339
|
conversationCardStyle: customStyles?.conversationCardStyle,
|
|
@@ -339,7 +341,7 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
339
341
|
titleStyle: customStyles?.titleStyle,
|
|
340
342
|
dateStyle: customStyles?.dateStyle,
|
|
341
343
|
deleteButtonStyle: customStyles?.deleteButtonStyle,
|
|
342
|
-
} }, conversation.
|
|
344
|
+
} }, conversation.chatbotConversationRef)))) })] }), _jsx("div", { className: "cmnd-chat-area", style: {
|
|
343
345
|
flex: 1,
|
|
344
346
|
display: "flex",
|
|
345
347
|
flexDirection: "column",
|
|
@@ -352,5 +354,5 @@ export const ConversationsPanel = forwardRef(({ organizationId, chatbotId, baseU
|
|
|
352
354
|
fontSize: "16px",
|
|
353
355
|
textAlign: "center",
|
|
354
356
|
padding: "20px",
|
|
355
|
-
}, children: _jsx("div", { children: _jsx("div", { children: "Select a conversation or start a new one" }) }) })) : (_jsx(Conversation, { messages: messages, setMessages: setMessages, handleSendClick: handleSendClick, input: input, setInput: setInput, isChatLoading: isChatLoading, error: error ? "Error loading conversations" : null, messagesRef: messagesRef,
|
|
357
|
+
}, children: _jsx("div", { children: _jsx("div", { children: "Select a conversation or start a new one" }) }) })) : (_jsx(Conversation, { messages: messages, setMessages: setMessages, handleSendClick: handleSendClick, input: input, setInput: setInput, isChatLoading: isChatLoading, error: error ? "Error loading conversations" : null, messagesRef: messagesRef, setChatbotConversationRef: setChatbotConversationRef, chatbotConversationRef: chatbotConversationRef, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, canSendMessage: canSendMessage, enabledTools: enabledTools, postSessionMessage: postSessionMessage, theme: theme, Components: Components, UITools: UITools, customStyles: customStyles, setCurrentConversationMemory: setCurrentConversationMemory, chatbotId: chatbotId, organizationId: organizationId, chatHistoryStorageKey: chatHistoryStorageKey, isMessagesScrolledToBottom: isMessagesScrolledToBottom, resetMessagesScroll: resetMessagesScroll, inputRef: inputRef })) })] }));
|
|
356
358
|
});
|
|
@@ -8,6 +8,6 @@ const LoadingBubble = ({ customStyles, chatbotId, organizationId, theme, Compone
|
|
|
8
8
|
display: "block",
|
|
9
9
|
shapeRendering: "auto",
|
|
10
10
|
}, width: "60px", height: "30px", viewBox: "0 0 100 100", preserveAspectRatio: "xMidYMid", children: [_jsxs("circle", { cx: "84", cy: "50", r: "10", fill: "#000", children: [_jsx("animate", { attributeName: "r", repeatCount: "indefinite", dur: "0.25s", calcMode: "spline", keyTimes: "0;1", values: "10;0", keySplines: "0 0.5 0.5 1", begin: "0s" }), _jsx("animate", { attributeName: "fill", repeatCount: "indefinite", dur: "1s", calcMode: "discrete", keyTimes: "0;0.25;0.5;0.75;1", values: color, begin: "0s" })] }), _jsxs("circle", { cx: "16", cy: "50", r: "10", fill: color, children: [_jsx("animate", { attributeName: "r", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "0;0;10;10;10", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "0s" }), _jsx("animate", { attributeName: "cx", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "16;16;16;50;84", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "0s" })] }), _jsxs("circle", { cx: "50", cy: "50", r: "10", fill: color, children: [_jsx("animate", { attributeName: "r", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "0;0;10;10;10", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.25s" }), _jsx("animate", { attributeName: "cx", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "16;16;16;50;84", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.25s" })] }), _jsxs("circle", { cx: "84", cy: "50", r: "10", fill: color, children: [_jsx("animate", { attributeName: "r", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "0;0;10;10;10", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.5s" }), _jsx("animate", { attributeName: "cx", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "16;16;16;50;84", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.5s" })] }), _jsxs("circle", { cx: "16", cy: "50", r: "10", fill: color, children: [_jsx("animate", { attributeName: "r", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "0;0;10;10;10", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.75s" }), _jsx("animate", { attributeName: "cx", repeatCount: "indefinite", dur: "1s", calcMode: "spline", keyTimes: "0;0.25;0.5;0.75;1", values: "16;16;16;50;84", keySplines: "0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1", begin: "-0.75s" })] })] }) }));
|
|
11
|
-
return (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, isLoadingBubble: true, customStyles: customStyles, theme: theme, Components: Components, message: Components?.LoadingIndicator ? (_jsx(Components.LoadingIndicator, {})) : (defaultLoadingIndicator), role: MessageRole.ASSISTANT, messages: [], postSessionMessage: () => { }, id: "__loading__", setMessages: () => { },
|
|
11
|
+
return (_jsx(Chatbubble, { chatbotId: chatbotId, organizationId: organizationId, isLoadingBubble: true, customStyles: customStyles, theme: theme, Components: Components, message: Components?.LoadingIndicator ? (_jsx(Components.LoadingIndicator, {})) : (defaultLoadingIndicator), role: MessageRole.ASSISTANT, messages: [], postSessionMessage: () => { }, id: "__loading__", setMessages: () => { }, setChatbotConversationRef: () => { }, setCanSendMessage: () => { }, setIsChatLoading: () => { } }));
|
|
12
12
|
};
|
|
13
13
|
export default LoadingBubble;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
declare const chatbot: {
|
|
2
|
-
patchChatbotConversationMemory: (organizationId: number, chatbotId: number,
|
|
3
|
-
deleteChatbotConversationMemory: (organizationId: number, chatbotId: number,
|
|
2
|
+
patchChatbotConversationMemory: (organizationId: number, chatbotId: number, chatbotConversationRef: string) => string;
|
|
3
|
+
deleteChatbotConversationMemory: (organizationId: number, chatbotId: number, chatbotConversationRef: string, memoryKeyToDelete: string) => string;
|
|
4
4
|
getChatBotConversationsList: ({ organizationId, chatbotId, conversationIds, }: {
|
|
5
5
|
organizationId: number;
|
|
6
6
|
chatbotId: number;
|
|
7
|
-
conversationIds:
|
|
7
|
+
conversationIds: string[];
|
|
8
8
|
}) => string;
|
|
9
9
|
};
|
|
10
10
|
export { chatbot };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const chatbot = {
|
|
2
|
-
patchChatbotConversationMemory: (organizationId, chatbotId,
|
|
3
|
-
deleteChatbotConversationMemory: (organizationId, chatbotId,
|
|
2
|
+
patchChatbotConversationMemory: (organizationId, chatbotId, chatbotConversationRef) => `/organizations/${organizationId}/chatbots/${chatbotId}/conversations/${chatbotConversationRef}/memory`,
|
|
3
|
+
deleteChatbotConversationMemory: (organizationId, chatbotId, chatbotConversationRef, memoryKeyToDelete) => `/organizations/${organizationId}/chatbots/${chatbotId}/conversations/${chatbotConversationRef}/memory/${memoryKeyToDelete}`,
|
|
4
4
|
getChatBotConversationsList: ({ organizationId, chatbotId, conversationIds, }) => {
|
|
5
5
|
const ids = Array.isArray(conversationIds)
|
|
6
6
|
? conversationIds.join(",")
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ChatbotConversation, Message, CMNDChatMemory, CMNDChatbotUITool, ConversationDataObject, ToolDetails } from "../type.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring the useCMNDChat hook.
|
|
5
|
+
*/
|
|
6
|
+
export interface UseCMNDChatOptions {
|
|
7
|
+
/** The unique identifier for the chatbot. */
|
|
8
|
+
chatbotId: number;
|
|
9
|
+
/** The unique identifier for the organization. */
|
|
10
|
+
organizationId: number;
|
|
11
|
+
/** The base URL for the CMND API. */
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
/** Optional API key for authentication. If provided, it will be sent in the 'x-api-key' header. */
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
/** Optional key used for local message persistence. Defaults to a combined string of orgId and chatbotId. */
|
|
16
|
+
chatHistoryStorageKey?: string;
|
|
17
|
+
/** Initial memory/context to send when starting a new conversation. */
|
|
18
|
+
initialMemory?: CMNDChatMemory;
|
|
19
|
+
/** Array of custom UI tools that the AI can call. */
|
|
20
|
+
UITools?: CMNDChatbotUITool[];
|
|
21
|
+
/** Callback triggered whenever new data (chunks or finalized messages) is received from the stream. */
|
|
22
|
+
onData?: (data: ConversationDataObject) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Callback triggered whenever the AI initiates a tool call.
|
|
25
|
+
*
|
|
26
|
+
* For **backend tools**: The hook automatically confirms them, which triggers your backend server
|
|
27
|
+
* to execute the tool and return the output. Use this callback for logging or UI updates.
|
|
28
|
+
*
|
|
29
|
+
* For **UI tools**: You must execute the tool in your frontend, then call submitToolResult with the output.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* onToolCall: async (toolDetails) => {
|
|
34
|
+
* if (toolDetails.name === 'show_ui_component') {
|
|
35
|
+
* // UI tool - execute in frontend
|
|
36
|
+
* displayComponent(toolDetails.args);
|
|
37
|
+
* submitToolResult('Component displayed');
|
|
38
|
+
* }
|
|
39
|
+
* // Backend tools are handled automatically by the server
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
onToolCall?: (toolCall: ToolDetails) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Whether to clean the AI response by removing markdown characters.
|
|
46
|
+
* If true, assistant messages will be returned as plaintext.
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
cleanResponse?: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The object returned by the useCMNDChat hook.
|
|
53
|
+
*/
|
|
54
|
+
export interface UseCMNDChatResult {
|
|
55
|
+
/** The list of messages in the current active conversation thread. */
|
|
56
|
+
messages: Message[];
|
|
57
|
+
/** A setter function for the messages list. */
|
|
58
|
+
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
|
|
59
|
+
/** The current text value of the chat input field. */
|
|
60
|
+
input: string;
|
|
61
|
+
/** A setter function for the chat input field. */
|
|
62
|
+
setInput: React.Dispatch<React.SetStateAction<string>>;
|
|
63
|
+
/** Indicates if a message is currently being processed or streamed. */
|
|
64
|
+
isChatLoading: boolean;
|
|
65
|
+
/** Indicates if the user is allowed to send a message (e.g., not loading, not empty). */
|
|
66
|
+
canSendMessage: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Sends a message to the chatbot.
|
|
69
|
+
* @param text Optional text to send. If not provided, it uses the current 'input' state.
|
|
70
|
+
* @param onData Optional callback for this specific message stream.
|
|
71
|
+
*/
|
|
72
|
+
sendMessage: (text?: string, onData?: (data: ConversationDataObject) => void) => Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Submits the result of a tool call back to the AI.
|
|
75
|
+
* @param toolOutput The string result of the tool execution.
|
|
76
|
+
* @param onData Optional callback for the resulting message stream.
|
|
77
|
+
*/
|
|
78
|
+
submitToolResult: (toolOutput: string, onData?: (data: ConversationDataObject) => void) => Promise<void>;
|
|
79
|
+
/** The reference ID for the current active conversation. */
|
|
80
|
+
chatbotConversationRef: string | undefined;
|
|
81
|
+
/** A list of all historical conversations for the current chatbot/org. */
|
|
82
|
+
conversations: ChatbotConversation[];
|
|
83
|
+
/** The currently selected conversation object from history. */
|
|
84
|
+
selectedConversation: ChatbotConversation | null;
|
|
85
|
+
/** Resets the chat state and prepares for a new conversation thread. */
|
|
86
|
+
handleNewChat: () => void;
|
|
87
|
+
/**
|
|
88
|
+
* Switches to an existing conversation from history.
|
|
89
|
+
* @param conversation The conversation object to load.
|
|
90
|
+
*/
|
|
91
|
+
handleConversationSelect: (conversation: ChatbotConversation) => void;
|
|
92
|
+
/**
|
|
93
|
+
* Deletes a conversation from history and local storage.
|
|
94
|
+
* @param conversationId The ID of the conversation to delete.
|
|
95
|
+
*/
|
|
96
|
+
handleDeleteConversation: (conversationId: string) => Promise<void>;
|
|
97
|
+
/** Re-fetches the list of historical conversations. */
|
|
98
|
+
refreshConversations: () => Promise<void>;
|
|
99
|
+
/** Combined list of backend tools (from API) and UI tools (provided in options). */
|
|
100
|
+
tools: any[];
|
|
101
|
+
/** Holds any error message encountered during API calls. */
|
|
102
|
+
error: string | null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A comprehensive hook to manage CMND.AI chatbot logic without being forced to use the default UI.
|
|
106
|
+
* This hook handles conversation state, message sending (including streaming), history management, and tool call orchestration.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```tsx
|
|
110
|
+
* const { messages, sendMessage, input, setInput, submitToolResult } = useCMNDChat({
|
|
111
|
+
* chatbotId: 1,
|
|
112
|
+
* organizationId: 1,
|
|
113
|
+
* baseUrl: 'https://api.cmnd.ai',
|
|
114
|
+
* cleanResponse: true, // Optional: Returns assistant messages as plaintext
|
|
115
|
+
* onToolCall: async (toolDetails) => {
|
|
116
|
+
* // Backend tools are auto-confirmed by the hook
|
|
117
|
+
* if (toolDetails.name === 'get_playlists') {
|
|
118
|
+
* console.log('Fetching playlists from backend...');
|
|
119
|
+
* }
|
|
120
|
+
*
|
|
121
|
+
* // UI tools need manual execution and confirmation
|
|
122
|
+
* if (toolDetails.name === 'show_notification') {
|
|
123
|
+
* showNotification(toolDetails.args.message);
|
|
124
|
+
* submitToolResult('Notification displayed');
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
export declare const useCMNDChat: (options: UseCMNDChatOptions) => UseCMNDChatResult;
|