@cmnd-ai/chatbot-react 1.3.2 → 1.5.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.
@@ -1,9 +1,11 @@
1
1
  import React from "react";
2
2
  import { CmndChatBotProps } from "../CmndChatBot/index.js";
3
- import { CmndChatContext } from "../type.js";
3
+ import { CmndChatContext, CMNDChatMemory } from "../type.js";
4
4
  export declare const ChatProviderContext: React.Context<CmndChatContext | undefined>;
5
5
  export interface ChatProviderProps extends CmndChatBotProps {
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
10
  declare function ChatProvider(props: ChatProviderProps): JSX.Element | null;
9
11
  export default ChatProvider;
@@ -4,9 +4,50 @@ import { MessageRole, } from "../type.js";
4
4
  import postUserConversation from "../services/postUserConversation.js";
5
5
  import Conversation from "../components/Conversation.js";
6
6
  import getChatBotById from "../services/getchatBotById.js";
7
+ import patchChatbotConversationMemory from "../services/patchChatbotConversationMemory/index.js";
8
+ import deleteChatbotConversationMemory from "../services/deleteChatbotConversationMemory/index.js";
9
+ import parseUITools from "../utils/parseUITools.js";
10
+ import getTools from "../utils/getTools/index.js";
11
+ let globalChatbotConversationId;
12
+ let globalChatbotProps;
7
13
  export const ChatProviderContext = React.createContext(undefined);
14
+ export const setCurrentConversationMemory = async (memory) => {
15
+ try {
16
+ if (!globalChatbotConversationId || !globalChatbotProps) {
17
+ return Promise.reject("setCurrentConversationMemory method is only available when user is interacting with an active chat thread.");
18
+ }
19
+ return await patchChatbotConversationMemory({
20
+ chatbotConversationId: globalChatbotConversationId,
21
+ memory,
22
+ baseUrl: globalChatbotProps.baseUrl,
23
+ chatbotId: globalChatbotProps.chatbotId,
24
+ organizationId: globalChatbotProps.organizationId,
25
+ });
26
+ }
27
+ catch (error) {
28
+ Promise.reject(error);
29
+ }
30
+ };
31
+ export const deleteCurrentConversationMemory = async (memoryKeyToDelete) => {
32
+ try {
33
+ if (!globalChatbotConversationId || !globalChatbotProps) {
34
+ return Promise.reject("deleteCurrentConversationMemory method is only available when user is interacting with an active chat thread.");
35
+ }
36
+ return await deleteChatbotConversationMemory({
37
+ chatbotConversationId: globalChatbotConversationId,
38
+ memoryKeyToDelete,
39
+ baseUrl: globalChatbotProps.baseUrl,
40
+ chatbotId: globalChatbotProps.chatbotId,
41
+ organizationId: globalChatbotProps.organizationId,
42
+ });
43
+ }
44
+ catch (error) {
45
+ Promise.reject(error);
46
+ }
47
+ };
8
48
  function ChatProvider(props) {
9
- const { chatbotId, organizationId, baseUrl, Components, UITools } = props;
49
+ globalChatbotProps = props;
50
+ const { chatbotId, organizationId, baseUrl, Components, UITools, initialMemory, } = props;
10
51
  const [loading, setLoading] = useState(true);
11
52
  const [messages, setMessages] = useState([]);
12
53
  const [error, setError] = useState(null);
@@ -17,6 +58,9 @@ function ChatProvider(props) {
17
58
  const messagesRef = useRef(null);
18
59
  const [chatbotConversationId, setChatbotConversationId] = useState(undefined);
19
60
  const [enabledTools, setEnabledTools] = useState([]);
61
+ useEffect(() => {
62
+ globalChatbotConversationId = chatbotConversationId;
63
+ }, [chatbotConversationId]);
20
64
  useEffect(() => {
21
65
  setLoading(true);
22
66
  getChatBotById(baseUrl, organizationId, chatbotId)
@@ -42,8 +86,18 @@ function ChatProvider(props) {
42
86
  const postSessionMessage = async (newMessages, onData) => {
43
87
  if (!organizationId || !chatbotId)
44
88
  return;
89
+ const payload = {
90
+ messages: newMessages,
91
+ uiTools: parseUITools(UITools),
92
+ };
93
+ if (chatbotConversationId) {
94
+ payload["chatbotConversationId"] = chatbotConversationId;
95
+ }
96
+ else {
97
+ payload["initialMemory"] = initialMemory;
98
+ }
45
99
  return postUserConversation({
46
- payload: newMessages,
100
+ payload,
47
101
  apikey: props.apiKey,
48
102
  chatbotId,
49
103
  baseUrl,
@@ -111,8 +165,16 @@ function ChatProvider(props) {
111
165
  setIsChatLoading,
112
166
  setCanSendMessage,
113
167
  scrollToBottom,
114
- enabledTools,
168
+ enabledTools: getTools({
169
+ apiTools: enabledTools,
170
+ uiTools: parseUITools(UITools),
171
+ }),
172
+ chatbotConversationId,
173
+ UITools: parseUITools(UITools),
115
174
  },
116
- }, children: error ? (_jsx("div", { children: "An error occured" })) : (_jsxs(_Fragment, { children: [props.children, _jsx(Conversation, { messages: messages, setMessages: setMessages, postSessionMessage: postSessionMessage, isChatLoading: isChatLoading, messagesRef: messagesRef, input: input, setInput: setInput, handleSendClick: handleSendClick, setChatbotConversationId: setChatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, canSendMessage: canSendMessage, scrollToBottom: scrollToBottom, error: error, enabledTools: enabledTools, Components: Components, UITools: UITools, customStyles: props.customStyles })] })) }));
175
+ }, children: error ? (_jsx("div", { children: "An error occured" })) : (_jsxs(_Fragment, { children: [props.children, _jsx(Conversation, { messages: messages, setMessages: setMessages, postSessionMessage: postSessionMessage, isChatLoading: isChatLoading, messagesRef: messagesRef, input: input, setInput: setInput, handleSendClick: handleSendClick, setChatbotConversationId: setChatbotConversationId, setIsChatLoading: setIsChatLoading, setCanSendMessage: setCanSendMessage, canSendMessage: canSendMessage, scrollToBottom: scrollToBottom, error: error, enabledTools: getTools({
176
+ apiTools: enabledTools,
177
+ uiTools: parseUITools(UITools),
178
+ }), Components: Components, UITools: parseUITools(UITools), customStyles: props.customStyles, chatbotConversationId: chatbotConversationId, setCurrentConversationMemory: setCurrentConversationMemory })] })) }));
117
179
  }
118
180
  export default ChatProvider;
@@ -1,13 +1,13 @@
1
- import React from "react";
2
- import { CmndChatContext, CustomStyles, UIFunctionArguments } from "../type.js";
1
+ import { CMNDChatbotUITool, CMNDChatMemory, CustomStyles } from "../type.js";
3
2
  import { ConversationProps } from "../components/Conversation.js";
4
- export interface CmndChatBotProps extends Pick<ConversationProps, 'Components'> {
3
+ export interface CmndChatBotProps extends Pick<ConversationProps, "Components"> {
5
4
  chatbotId: number;
6
5
  organizationId: number;
7
6
  apiKey?: string;
8
7
  baseUrl: string;
9
- UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
8
+ UITools?: CMNDChatbotUITool[];
10
9
  customStyles?: CustomStyles;
10
+ initialMemory?: CMNDChatMemory;
11
11
  }
12
- declare function CmndChatBot(): CmndChatContext;
12
+ declare function CmndChatBot(): import("../type.js").CmndChatContext;
13
13
  export default CmndChatBot;
@@ -1,5 +1,5 @@
1
- import React, { Dispatch, ReactNode, SetStateAction } from "react";
2
- import { MessageRole, ToolDetails, ToolData, UIFunctionArguments, CustomStyles } from "../type.js";
1
+ import { Dispatch, ReactNode, SetStateAction } from "react";
2
+ import { MessageRole, ToolDetails, ToolData, CustomStyles, CMNDChatbotUITool } from "../type.js";
3
3
  interface ChatBubbleProps {
4
4
  message: string | ReactNode | null;
5
5
  role: MessageRole;
@@ -15,7 +15,7 @@ interface ChatBubbleProps {
15
15
  setCanSendMessage: Dispatch<SetStateAction<boolean>>;
16
16
  setIsChatLoading: Dispatch<SetStateAction<boolean>>;
17
17
  scrollToBottom: () => void;
18
- UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
18
+ UITools?: CMNDChatbotUITool[];
19
19
  customStyles?: CustomStyles;
20
20
  }
21
21
  declare const Chatbubble: ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, customStyles, }: ChatBubbleProps) => JSX.Element | null;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useEffect, } from "react";
2
+ import { useEffect, useRef, } from "react";
3
3
  import { MessageRole, FunctionType, } from "../type.js";
4
4
  import { BsTools, BsRobot } from "react-icons/bs";
5
5
  import { FaUserCircle } from "react-icons/fa";
@@ -11,6 +11,57 @@ import SyntaxHighlighter from "react-syntax-highlighter";
11
11
  //@ts-ignore
12
12
  import oneDark from "react-syntax-highlighter/dist/cjs/styles/prism/one-dark.js";
13
13
  import { overrideStyle } from "../utils.js";
14
+ const patchLastMessageToolInfo = (messages, toolInfo) => {
15
+ console.log("patchLastMessageToolInfo", messages, toolInfo);
16
+ const lastMessage = messages[messages.length - 1];
17
+ if (lastMessage.role !== MessageRole.FUNCTION) {
18
+ return messages;
19
+ }
20
+ const shallowCopyOfMessagesWithoutLast = messages.slice(0, -1);
21
+ const copyOfLastMessage = { ...lastMessage };
22
+ copyOfLastMessage.tool = {
23
+ ...copyOfLastMessage.tool,
24
+ ...toolInfo,
25
+ };
26
+ const newMessages = [...shallowCopyOfMessagesWithoutLast, copyOfLastMessage];
27
+ return newMessages;
28
+ };
29
+ const confirmToolRun = async ({ messages, setMessages, postSessionMessage, setIsChatLoading, setCanSendMessage, setChatbotConversationId, scrollToBottom, }) => {
30
+ const newMessages = patchLastMessageToolInfo(messages, {
31
+ confirmed: true,
32
+ });
33
+ setIsChatLoading(true);
34
+ setCanSendMessage(false);
35
+ setMessages(newMessages);
36
+ await postSessionMessage(newMessages, (data) => {
37
+ if (data.finalResponseWithUsageData) {
38
+ setCanSendMessage(true);
39
+ setIsChatLoading(false);
40
+ const { messages, chatbotConversationId } = data;
41
+ if (chatbotConversationId) {
42
+ setChatbotConversationId(chatbotConversationId);
43
+ // saveConversationIdToLocalStorage(
44
+ // chatbotConversationId.toString(),
45
+ // config.chatbot_id!,
46
+ // config.organization_id!
47
+ // );
48
+ }
49
+ messages && setMessages(messages);
50
+ }
51
+ if (data.message) {
52
+ setIsChatLoading(false);
53
+ const newAssistantMessage = {
54
+ unuseful: false,
55
+ hiddenFromUser: false,
56
+ role: MessageRole.ASSISTANT,
57
+ message: "",
58
+ };
59
+ newAssistantMessage.message = data.message;
60
+ setMessages([...newMessages, newAssistantMessage]);
61
+ scrollToBottom();
62
+ }
63
+ });
64
+ };
14
65
  const getChatAvatar = (role) => {
15
66
  switch (role) {
16
67
  case MessageRole.USER:
@@ -24,78 +75,31 @@ const getChatAvatar = (role) => {
24
75
  }
25
76
  };
26
77
  const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, customStyles, }) => {
27
- const patchLastMessageToolInfo = useCallback((messages, toolInfo) => {
28
- const lastMessage = messages[messages.length - 1];
29
- if (lastMessage.role !== MessageRole.FUNCTION) {
30
- return messages;
31
- }
32
- const shallowCopyOfMessagesWithoutLast = messages.slice(0, -1);
33
- const copyOfLastMessage = { ...lastMessage };
34
- copyOfLastMessage.tool = {
35
- ...copyOfLastMessage.tool,
36
- ...toolInfo,
37
- };
38
- const newMessages = [
39
- ...shallowCopyOfMessagesWithoutLast,
40
- copyOfLastMessage,
41
- ];
42
- return newMessages;
43
- }, []);
44
- const confirmToolRun = useCallback(async ({ messages, setMessages, postSessionMessage, }) => {
45
- const newMessages = patchLastMessageToolInfo(messages, {
46
- confirmed: true,
47
- });
48
- setIsChatLoading(true);
49
- setCanSendMessage(false);
50
- setMessages(newMessages);
51
- await postSessionMessage(newMessages, (data) => {
52
- if (data.finalResponseWithUsageData) {
53
- setCanSendMessage(true);
54
- setIsChatLoading(false);
55
- const { messages, chatbotConversationId } = data;
56
- if (chatbotConversationId) {
57
- setChatbotConversationId(chatbotConversationId);
58
- // saveConversationIdToLocalStorage(
59
- // chatbotConversationId.toString(),
60
- // config.chatbot_id!,
61
- // config.organization_id!
62
- // );
63
- }
64
- messages && setMessages(messages);
65
- }
66
- if (data.message) {
67
- setIsChatLoading(false);
68
- const newAssistantMessage = {
69
- unuseful: false,
70
- hiddenFromUser: false,
71
- role: MessageRole.ASSISTANT,
72
- message: "",
73
- };
74
- newAssistantMessage.message = data.message;
75
- setMessages([...newMessages, newAssistantMessage]);
76
- scrollToBottom();
77
- }
78
- });
79
- }, [patchLastMessageToolInfo]);
80
- const toolData = tools?.find((t) => t.title === toolCallDetails?.name);
78
+ const toolData = tools?.find((t) => t.name === toolCallDetails?.name);
79
+ const hasConfirmedToolRun = useRef(false);
80
+ const isPostingMessage = useRef(false);
81
81
  useEffect(() => {
82
- if (role === MessageRole.FUNCTION &&
82
+ if (!hasConfirmedToolRun.current &&
83
+ role === MessageRole.FUNCTION &&
83
84
  tools &&
84
- toolData?.metadata.functionType === FunctionType.BACKEND &&
85
+ toolData?.functionType === FunctionType.BACKEND &&
85
86
  Boolean(toolCallDetails?.runAt) === false) {
87
+ hasConfirmedToolRun.current = true;
86
88
  confirmToolRun({
87
89
  messages,
88
90
  setMessages,
89
91
  postSessionMessage,
92
+ setIsChatLoading,
93
+ setCanSendMessage,
94
+ setChatbotConversationId,
95
+ scrollToBottom,
90
96
  });
91
97
  }
92
98
  }, []);
93
99
  if (hide)
94
100
  return null;
95
101
  const defaultStyle = {
96
- display: toolData?.metadata.functionType === FunctionType.BACKEND
97
- ? "none"
98
- : "flex",
102
+ display: toolData?.functionType === FunctionType.BACKEND ? "none" : "flex",
99
103
  flexDirection: role === MessageRole.USER ? "row-reverse" : "row",
100
104
  gap: "10px",
101
105
  textAlign: role === MessageRole.USER ? "right" : "left",
@@ -116,7 +120,7 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
116
120
  return (_jsxs("div", { style: defaultStyle, className: `cmnd-chatbot-chat-bubble ${role}`, children: [_jsx("span", { style: overrideStyle({
117
121
  fontSize: "30px",
118
122
  color: "black",
119
- }, customStyles?.chatAvatarStyle), children: getChatAvatar(role) }), _jsxs("p", { style: chatBubbleCustomStyle, children: [role === MessageRole.USER || isLoadingBubble ? (_jsx("span", { children: message })) : (_jsx(ReactMarkdown, { className: "markdown", remarkPlugins: [remarkGfm], children: message?.toString() ?? "", remarkRehypeOptions: { passThrough: ["link"] }, components: {
123
+ }, customStyles?.chatAvatarStyle), children: getChatAvatar(role) }), _jsxs("span", { style: chatBubbleCustomStyle, children: [role === MessageRole.USER || isLoadingBubble ? (_jsx("span", { children: message })) : (_jsx(ReactMarkdown, { className: "markdown", remarkPlugins: [remarkGfm], children: message?.toString() ?? "", remarkRehypeOptions: { passThrough: ["link"] }, components: {
120
124
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
121
125
  // @ts-ignore
122
126
  code({ inline, className, children, ...props }) {
@@ -125,11 +129,14 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
125
129
  const language = match ? match[1] : undefined;
126
130
  return !inline && match ? (_jsx(SyntaxHighlighter, { children: code, language: language, wrapLongLines: true, style: oneDark, ...props })) : (_jsx("code", { className: className, ...props, children: children }));
127
131
  },
128
- } })), role === MessageRole.FUNCTION && (_jsx("div", { children: toolData?.metadata?.functionType === FunctionType.UI ? (_jsx(ErrorBoundary, { fallback: _jsxs("div", { children: ["Failed to render ", toolCallDetails?.name, ". Please report this error."] }), onError: (error) => {
132
+ } })), role === MessageRole.FUNCTION && (_jsx("div", { children: toolData?.functionType === FunctionType.UI ? (_jsx(ErrorBoundary, { fallback: _jsxs("div", { children: ["Failed to render ", toolCallDetails?.name, ". Please report this error."] }), onError: (error) => {
129
133
  // todo: report this error to some central place
130
134
  // with toolCallDetails name, args, and conversation id
131
135
  console.log("captured error", error);
132
136
  }, children: _jsx(UIToolComponent, { functionName: toolCallDetails?.name ?? "", functionArgs: toolCallDetails?.args, previousRunResults: toolCallDetails?.output, UITools: UITools, captureResults: async (msg) => {
137
+ if (isPostingMessage.current)
138
+ return; // Prevent multiple calls
139
+ isPostingMessage.current = true;
133
140
  setIsChatLoading(true);
134
141
  setCanSendMessage(false);
135
142
  const newMessages = patchLastMessageToolInfo(messages, {
@@ -139,10 +146,11 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
139
146
  });
140
147
  setMessages(newMessages);
141
148
  const onData = (data) => {
149
+ isPostingMessage.current = false;
142
150
  if (data.finalResponseWithUsageData) {
143
151
  setIsChatLoading(false);
144
152
  setCanSendMessage(true);
145
- const { messages, chatbotConversationId } = data;
153
+ const { chatbotConversationId, messages } = data;
146
154
  if (chatbotConversationId) {
147
155
  setChatbotConversationId(chatbotConversationId);
148
156
  }
@@ -154,14 +162,18 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
154
162
  unuseful: false,
155
163
  hiddenFromUser: false,
156
164
  role: MessageRole.ASSISTANT,
157
- message: "",
165
+ message: data.message,
158
166
  };
159
- newAssistantMessage.message = data.message;
160
167
  setMessages([...newMessages, newAssistantMessage]);
161
168
  scrollToBottom();
162
169
  }
163
170
  };
164
- await postSessionMessage(newMessages, onData);
171
+ try {
172
+ await postSessionMessage(newMessages, onData);
173
+ }
174
+ finally {
175
+ isPostingMessage.current = false;
176
+ }
165
177
  } }) })) : (_jsx(_Fragment, {})) }, "2"))] })] }));
166
178
  };
167
179
  export default Chatbubble;
@@ -1,5 +1,5 @@
1
1
  import React, { Dispatch, SetStateAction } from "react";
2
- import { CustomStyles, InputFieldProps, SendButtonProps, UIFunctionArguments } from "../type.js";
2
+ import { CMNDChatbotUITool, CMNDChatMemory, CustomStyles, InputFieldProps, SendButtonProps } from "../type.js";
3
3
  export interface ConversationProps {
4
4
  messages: any[];
5
5
  setMessages: Dispatch<SetStateAction<any[]>>;
@@ -10,6 +10,7 @@ export interface ConversationProps {
10
10
  error: string | null;
11
11
  messagesRef: React.RefObject<HTMLDivElement>;
12
12
  setChatbotConversationId: Dispatch<React.SetStateAction<number | undefined>>;
13
+ chatbotConversationId: number | undefined;
13
14
  setIsChatLoading: Dispatch<SetStateAction<boolean>>;
14
15
  setCanSendMessage: Dispatch<SetStateAction<boolean>>;
15
16
  canSendMessage: boolean;
@@ -21,8 +22,9 @@ export interface ConversationProps {
21
22
  SendButton?: (params: SendButtonProps) => JSX.Element;
22
23
  error?: any;
23
24
  };
24
- UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
25
+ UITools?: CMNDChatbotUITool[];
25
26
  customStyles?: CustomStyles;
27
+ setCurrentConversationMemory: (memory: CMNDChatMemory) => Promise<any>;
26
28
  }
27
29
  declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, customStyles, }: ConversationProps) => JSX.Element;
28
30
  export default Conversation;
@@ -5,7 +5,7 @@ import ChatInputBox from "./ChatInputBox.js";
5
5
  const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, customStyles, }) => {
6
6
  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, { 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, scrollToBottom: scrollToBottom, UITools: UITools }, i))), isChatLoading ? _jsx(LoadingBubble, { customStyles: customStyles }) : null] }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick } })) : (_jsx(ChatInputBox, { input: input, setInput: setInput, handleSendClick: handleSendClick })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
7
7
  canSendMessage,
8
- handleSendClick
8
+ handleSendClick,
9
9
  } })) : (_jsx("button", { className: "cmnd-send-button", onClick: handleSendClick, children: "Send" }))] })] }));
10
10
  };
11
11
  export default Conversation;
@@ -0,0 +1,5 @@
1
+ declare const chatbot: {
2
+ patchChatbotConversationMemory: (organizationId: number, chatbotId: number, chatbotConversationId: number) => string;
3
+ deleteChatbotConversationMemory: (organizationId: number, chatbotId: number, chatbotConversationId: number, memoryKeyToDelete: string) => string;
4
+ };
5
+ export { chatbot };
@@ -0,0 +1,5 @@
1
+ const chatbot = {
2
+ patchChatbotConversationMemory: (organizationId, chatbotId, chatbotConversationId) => `/organizations/${organizationId}/chatbots/${chatbotId}/conversations/${chatbotConversationId}/memory`,
3
+ deleteChatbotConversationMemory: (organizationId, chatbotId, chatbotConversationId, memoryKeyToDelete) => `/organizations/${organizationId}/chatbots/${chatbotId}/conversations/${chatbotConversationId}/memory/${memoryKeyToDelete}`,
4
+ };
5
+ export { chatbot };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export { default as ChatProvider } from "./ChatProvider/index.js";
2
- export { default as useChatContext } from "./ChatProvider/useChatContext.js";
3
- export { CmndChatContext, InputFieldProps, SendButtonProps, CustomStyles, } from "./type.js";
4
- export { default as CmndChatBot } from "./CmndChatBot/index.js";
2
+ export { CmndChatContext, InputFieldProps, SendButtonProps, CustomStyles, CMNDChatMemory, } from "./type.js";
3
+ export { setCurrentConversationMemory, deleteCurrentConversationMemory, } from "./ChatProvider/index.js";
package/dist/index.js CHANGED
@@ -1,3 +1,2 @@
1
1
  export { default as ChatProvider } from "./ChatProvider/index.js";
2
- export { default as useChatContext } from "./ChatProvider/useChatContext.js";
3
- export { default as CmndChatBot } from "./CmndChatBot/index.js";
2
+ export { setCurrentConversationMemory, deleteCurrentConversationMemory, } from "./ChatProvider/index.js";
@@ -0,0 +1,9 @@
1
+ interface IDeleteChatbotConversationMemory {
2
+ organizationId: number;
3
+ chatbotId: number;
4
+ chatbotConversationId: number;
5
+ memoryKeyToDelete: string;
6
+ baseUrl: string;
7
+ }
8
+ declare const deleteChatbotConversationMemory: ({ organizationId, chatbotId, chatbotConversationId, memoryKeyToDelete, baseUrl, }: IDeleteChatbotConversationMemory) => Promise<import("axios").AxiosResponse<any, any>>;
9
+ export default deleteChatbotConversationMemory;
@@ -0,0 +1,7 @@
1
+ import { chatbot } from "../../constants/endpoints.js";
2
+ import axios from "axios";
3
+ const deleteChatbotConversationMemory = ({ organizationId, chatbotId, chatbotConversationId, memoryKeyToDelete, baseUrl, }) => {
4
+ const endpoint = chatbot.deleteChatbotConversationMemory(organizationId, chatbotId, chatbotConversationId, memoryKeyToDelete);
5
+ return axios.delete(`${baseUrl}${endpoint}`);
6
+ };
7
+ export default deleteChatbotConversationMemory;
@@ -0,0 +1,11 @@
1
+ interface IPatchChatbotConversationMemory {
2
+ organizationId: number;
3
+ chatbotId: number;
4
+ chatbotConversationId: number;
5
+ memory: {
6
+ [key: string]: any;
7
+ };
8
+ baseUrl: string;
9
+ }
10
+ declare const patchChatbotConversationMemory: ({ organizationId, chatbotId, chatbotConversationId, memory, baseUrl, }: IPatchChatbotConversationMemory) => Promise<import("axios").AxiosResponse<any, any>>;
11
+ export default patchChatbotConversationMemory;
@@ -0,0 +1,9 @@
1
+ import axios from "axios";
2
+ import { chatbot } from "../../constants/endpoints.js";
3
+ const patchChatbotConversationMemory = ({ organizationId, chatbotId, chatbotConversationId, memory, baseUrl, }) => {
4
+ const endpoint = chatbot.patchChatbotConversationMemory(organizationId, chatbotId, chatbotConversationId);
5
+ return axios.patch(`${baseUrl}${endpoint}`, {
6
+ memory,
7
+ });
8
+ };
9
+ export default patchChatbotConversationMemory;
@@ -2,9 +2,7 @@ import axios from "axios";
2
2
  import processStream from "../ChatProvider/processStream/index.js";
3
3
  const postUserConversation = async ({ payload, apikey, chatbotId, baseUrl, onData, }) => {
4
4
  const endpoint = `${baseUrl}/chatbots/${chatbotId}/conversations`;
5
- const response = await axios.post(endpoint, {
6
- messages: payload,
7
- }, {
5
+ const response = await axios.post(endpoint, payload, {
8
6
  headers: {
9
7
  Accept: "text/event-stream",
10
8
  "accept-language": "en-US,en;q=0.9",
package/dist/type.d.ts CHANGED
@@ -56,7 +56,6 @@ export declare enum FunctionType {
56
56
  BACKEND = "backend"
57
57
  }
58
58
  export type ToolData = {
59
- [x: string]: any;
60
59
  name: string;
61
60
  description: string;
62
61
  category: string;
@@ -71,6 +70,25 @@ export type UIFunctionArguments<AIProvidedParams> = {
71
70
  previousRunResults?: string;
72
71
  captureResults: (result: string) => void;
73
72
  };
73
+ export interface CMNDChatbotUITool {
74
+ name: string;
75
+ description: string;
76
+ category: string;
77
+ subcategory?: string;
78
+ dangerous?: boolean;
79
+ associatedCommands?: string[];
80
+ prerequisites?: string[];
81
+ argumentSchema: any;
82
+ rerun?: boolean;
83
+ rerunWithDifferentParameters?: boolean;
84
+ capturesUserInput?: boolean;
85
+ functionType?: "ui";
86
+ runCmd: (args: {
87
+ functionArgs?: Record<string, any>;
88
+ captureResults?: (result: any) => Promise<any>;
89
+ previousRunResults?: any;
90
+ }, ref?: React.RefObject<HTMLElement>) => void;
91
+ }
74
92
  export declare enum MessageRole {
75
93
  FUNCTION = "function",
76
94
  USER = "user",
@@ -109,4 +127,7 @@ export interface CustomStyles {
109
127
  botChatbubbleStyle?: CSSProperties;
110
128
  userChatbubbleStyle?: CSSProperties;
111
129
  }
130
+ export interface CMNDChatMemory {
131
+ [key: string]: any;
132
+ }
112
133
  export {};
@@ -1,10 +1,11 @@
1
1
  import React from "react";
2
- import { UIFunctionArguments } from "../type.js";
3
- declare const UIToolComponent: ({ functionName, functionArgs, previousRunResults, captureResults, UITools, }: {
2
+ import { CMNDChatbotUITool } from "../type.js";
3
+ interface UIToolComponentProps {
4
4
  functionName: string;
5
5
  functionArgs: any;
6
- previousRunResults?: string | undefined;
7
- captureResults: (result: string) => void;
8
- UITools?: Record<string, React.FC<UIFunctionArguments<any>>> | undefined;
9
- }) => JSX.Element;
6
+ previousRunResults?: string;
7
+ captureResults?: ((result: any) => Promise<any>) | undefined;
8
+ UITools?: CMNDChatbotUITool[];
9
+ }
10
+ declare const UIToolComponent: React.FC<UIToolComponentProps>;
10
11
  export default UIToolComponent;
@@ -1,9 +1,30 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- const UIToolComponent = ({ functionName, functionArgs, previousRunResults, captureResults, UITools = {}, }) => {
3
- const Component = UITools[functionName];
4
- if (!Component) {
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useEffect, useRef, useState } from "react";
3
+ const UIToolComponent = ({ functionName, functionArgs, previousRunResults, captureResults, UITools = [], }) => {
4
+ const itemRef = useRef(null);
5
+ const hasRun = useRef(false); // Prevent multiple calls
6
+ const [component, setComponent] = useState(null);
7
+ const tool = UITools.find((tool) => tool.name === functionName);
8
+ useEffect(() => {
9
+ if (tool && !hasRun.current) {
10
+ hasRun.current = true; // Mark as executed
11
+ const result = tool.runCmd({
12
+ functionArgs,
13
+ captureResults,
14
+ previousRunResults,
15
+ }, itemRef);
16
+ // If runCmd returns a React element, store it in state
17
+ if (React.isValidElement(result)) {
18
+ setComponent(result);
19
+ }
20
+ }
21
+ }, [tool, functionArgs, previousRunResults, captureResults]);
22
+ if (!tool) {
5
23
  throw new Error(`Tried to render non-existing UI-Tool component for ${functionName}.`);
6
24
  }
7
- return (_jsx(Component, { functionArgs: functionArgs, previousRunResults: previousRunResults, captureResults: captureResults }));
25
+ if (component) {
26
+ return _jsx(_Fragment, { children: component });
27
+ }
28
+ return (_jsx(_Fragment, { children: _jsx("div", { ref: itemRef }) }));
8
29
  };
9
30
  export default UIToolComponent;
@@ -0,0 +1,5 @@
1
+ declare const getTools: ({ uiTools, apiTools, }: {
2
+ uiTools?: any[] | undefined;
3
+ apiTools?: any[] | undefined;
4
+ }) => any[];
5
+ export default getTools;
@@ -0,0 +1,5 @@
1
+ const getTools = ({ uiTools = [], apiTools = [], }) => {
2
+ apiTools = apiTools.map((tool) => ({ ...tool.metadata }));
3
+ return [...apiTools, ...uiTools];
4
+ };
5
+ export default getTools;
@@ -0,0 +1,3 @@
1
+ import { CMNDChatbotUITool } from "../type.js";
2
+ declare const parseUITools: (uiTools?: CMNDChatbotUITool[]) => CMNDChatbotUITool[];
3
+ export default parseUITools;
@@ -0,0 +1,18 @@
1
+ const parseUITools = (uiTools) => {
2
+ if (!uiTools)
3
+ return [];
4
+ return uiTools.map((tool) => {
5
+ return {
6
+ ...tool,
7
+ rerun: tool.rerun ?? false,
8
+ capturesUserInput: tool.capturesUserInput ?? false,
9
+ rerunWithDifferentParameters: tool.rerunWithDifferentParameters ?? false,
10
+ prerequisites: tool.prerequisites ?? [],
11
+ associatedCommands: tool.associatedCommands ?? [],
12
+ dangerous: tool.dangerous ?? false,
13
+ subcategory: tool.subcategory ?? "",
14
+ functionType: "ui",
15
+ };
16
+ });
17
+ };
18
+ export default parseUITools;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmnd-ai/chatbot-react",
3
- "version": "1.3.2",
3
+ "version": "1.5.0",
4
4
  "main": "dist/index.js",
5
5
  "description": "",
6
6
  "type": "module",