@cmnd-ai/chatbot-react 1.2.1 → 1.3.1
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 +10 -82
- package/dist/ChatProvider/index.d.ts +1 -1
- package/dist/ChatProvider/index.js +2 -3
- package/dist/ChatProvider/processStream/index.js +9 -5
- package/dist/CmndChatBot/index.d.ts +4 -3
- package/dist/CmndChatBot/index.js +2 -2
- package/dist/components/ChatInputBox.d.ts +8 -0
- package/dist/components/ChatInputBox.js +9 -0
- package/dist/components/Chatbubble.d.ts +3 -2
- package/dist/components/Chatbubble.js +13 -8
- package/dist/components/Conversation.d.ts +3 -2
- package/dist/components/Conversation.js +5 -13
- package/dist/components/LoadingBubble.d.ts +5 -1
- package/dist/components/LoadingBubble.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/services/postUserConversation.d.ts +2 -3
- package/dist/services/postUserConversation.js +3 -5
- package/dist/styles/index.css +204 -0
- package/dist/type.d.ts +9 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +12 -0
- package/package.json +6 -2
package/Readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## @cmnd-ai/chatbot-react
|
|
2
2
|
|
|
3
|
-
This npm package provides a customizable chatbot component for use in web applications, designed specifically for
|
|
3
|
+
This npm package provides a customizable chatbot component for use in web applications, designed specifically for React environments.
|
|
4
4
|
|
|
5
5
|
### Installation
|
|
6
6
|
|
|
@@ -19,91 +19,19 @@ yarn add @cmnd-ai/chatbot-react
|
|
|
19
19
|
### Example implementation
|
|
20
20
|
|
|
21
21
|
```javascript
|
|
22
|
-
import { ChatProvider
|
|
23
|
-
import { useEffect } from "react";
|
|
22
|
+
import { ChatProvider } from "@cmnd-ai/chatbot-react";
|
|
24
23
|
|
|
25
|
-
const
|
|
26
|
-
messages({ props }) {
|
|
27
|
-
const messages = props.chats.data?.messages || [];
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
const comp = document.querySelector(`#lastItemId`);
|
|
31
|
-
if (!comp) return;
|
|
32
|
-
|
|
33
|
-
setTimeout(() => {
|
|
34
|
-
comp.scrollIntoView({
|
|
35
|
-
behavior: "smooth",
|
|
36
|
-
block: "end", // Scroll to the bottom of the container
|
|
37
|
-
});
|
|
38
|
-
}, 500);
|
|
39
|
-
}, [messages.length]);
|
|
40
|
-
|
|
41
|
-
const getchild = () => {
|
|
42
|
-
if (props.chats.error) {
|
|
43
|
-
return <h1>Error</h1>;
|
|
44
|
-
}
|
|
45
|
-
if (!props.chats.data?.messages?.length)
|
|
46
|
-
return <h1>Ask me a question</h1>;
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<div>
|
|
50
|
-
{messages.map((eachMessage, msgIndex) => (
|
|
51
|
-
<div
|
|
52
|
-
key={eachMessage.id}
|
|
53
|
-
id={msgIndex === messages.length - 1 ? "lastItemId" : undefined}
|
|
54
|
-
>
|
|
55
|
-
{eachMessage.message + ""}
|
|
56
|
-
</div>
|
|
57
|
-
))}
|
|
58
|
-
</div>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return <div style={{ flexGrow: 1 }}>{getchild()}</div>;
|
|
63
|
-
},
|
|
64
|
-
userInputBox({ props }) {
|
|
65
|
-
return (
|
|
66
|
-
<div
|
|
67
|
-
style={{
|
|
68
|
-
display: "flex",
|
|
69
|
-
gap: "1rem",
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
<input
|
|
73
|
-
style={{
|
|
74
|
-
flexGrow: 1,
|
|
75
|
-
}}
|
|
76
|
-
type="text"
|
|
77
|
-
value={props.userInputData.textValue}
|
|
78
|
-
onChange={(e) => props.userInputData.setTextValue(e.target.value)}
|
|
79
|
-
placeholder="Type here"
|
|
80
|
-
disabled={props.userInputData.isSending}
|
|
81
|
-
/>
|
|
82
|
-
<button
|
|
83
|
-
onClick={props.userInputData.submitMessage}
|
|
84
|
-
disabled={props.userInputData.isSending}
|
|
85
|
-
>
|
|
86
|
-
{props.userInputData.isSending ? "Sending..." : "Send"}
|
|
87
|
-
</button>
|
|
88
|
-
</div>
|
|
89
|
-
);
|
|
90
|
-
},
|
|
91
|
-
error({ props }) {
|
|
92
|
-
return <div>Error: {props.chats.error + ""}</div>;
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
function App() {
|
|
24
|
+
const App = () => {
|
|
97
25
|
return (
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
26
|
+
<ChatProvider
|
|
27
|
+
baseUrl="<your-cmnd-api-base-url>"
|
|
28
|
+
chatbotId={"<your-chatbot-id>"}
|
|
29
|
+
organizationId={"<your-organization-id>"}
|
|
30
|
+
/>
|
|
103
31
|
);
|
|
104
|
-
}
|
|
32
|
+
};
|
|
105
33
|
|
|
106
34
|
export default App;
|
|
107
35
|
```
|
|
108
36
|
|
|
109
|
-
|
|
37
|
+
For more information on customizing the chatbot components, please refer [here](https://github.com/CyprusCodes/cmnd-react-chatbot-example.git)
|
|
@@ -3,7 +3,7 @@ import { CmndChatBotProps } from "../CmndChatBot/index.js";
|
|
|
3
3
|
import { CmndChatContext } from "../type.js";
|
|
4
4
|
export declare const ChatProviderContext: React.Context<CmndChatContext | undefined>;
|
|
5
5
|
export interface ChatProviderProps extends CmndChatBotProps {
|
|
6
|
-
children
|
|
6
|
+
children?: React.ReactNode | ((props: CmndChatBotProps) => React.ReactNode);
|
|
7
7
|
}
|
|
8
8
|
declare function ChatProvider(props: ChatProviderProps): JSX.Element | null;
|
|
9
9
|
export default ChatProvider;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { MessageRole, } from "../type.js";
|
|
4
4
|
import postUserConversation from "../services/postUserConversation.js";
|
|
@@ -43,7 +43,6 @@ function ChatProvider(props) {
|
|
|
43
43
|
if (!organizationId || !chatbotId)
|
|
44
44
|
return;
|
|
45
45
|
return postUserConversation({
|
|
46
|
-
orgId: organizationId,
|
|
47
46
|
payload: newMessages,
|
|
48
47
|
apikey: props.apiKey,
|
|
49
48
|
chatbotId,
|
|
@@ -114,6 +113,6 @@ function ChatProvider(props) {
|
|
|
114
113
|
scrollToBottom,
|
|
115
114
|
enabledTools,
|
|
116
115
|
},
|
|
117
|
-
}, children: error ? (_jsx("div", { children: "An error occured" })) : (_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 })) }));
|
|
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 })] })) }));
|
|
118
117
|
}
|
|
119
118
|
export default ChatProvider;
|
|
@@ -15,13 +15,17 @@ const processStream = async (reader, onData) => {
|
|
|
15
15
|
const lines = chunk.split("\n");
|
|
16
16
|
for (const line of lines) {
|
|
17
17
|
let dataString = line;
|
|
18
|
+
if (line === "") {
|
|
19
|
+
// skip empty line of content
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
18
22
|
if (line.startsWith("data: ")) {
|
|
19
23
|
dataString = line.slice(6);
|
|
20
24
|
}
|
|
21
25
|
if (dataString === "[DONE]") {
|
|
22
26
|
onData({
|
|
23
27
|
completionFinished: true,
|
|
24
|
-
finalResponseWithUsageData: false
|
|
28
|
+
finalResponseWithUsageData: false
|
|
25
29
|
});
|
|
26
30
|
}
|
|
27
31
|
else {
|
|
@@ -35,14 +39,14 @@ const processStream = async (reader, onData) => {
|
|
|
35
39
|
onData({
|
|
36
40
|
completionFinished: false,
|
|
37
41
|
finalResponseWithUsageData: false,
|
|
38
|
-
message: fullAssistantMessage
|
|
42
|
+
message: fullAssistantMessage
|
|
39
43
|
});
|
|
40
44
|
}
|
|
41
45
|
else {
|
|
42
46
|
//at this point, the dataObject does not have a content propery
|
|
43
47
|
//and it is completed
|
|
44
48
|
//get the last message from the dataObject to check if it is a function call
|
|
45
|
-
const { messages, completionFinished, finalResponseWithUsageData, chatbotConversationId, conversationId, totalTokens, totalCost
|
|
49
|
+
const { messages, completionFinished, finalResponseWithUsageData, chatbotConversationId, conversationId, totalTokens, totalCost } = dataObject;
|
|
46
50
|
onData({
|
|
47
51
|
messages,
|
|
48
52
|
completionFinished,
|
|
@@ -50,7 +54,7 @@ const processStream = async (reader, onData) => {
|
|
|
50
54
|
conversationId,
|
|
51
55
|
chatbotConversationId,
|
|
52
56
|
totalTokens,
|
|
53
|
-
totalCost
|
|
57
|
+
totalCost
|
|
54
58
|
});
|
|
55
59
|
}
|
|
56
60
|
}
|
|
@@ -65,7 +69,7 @@ const processStream = async (reader, onData) => {
|
|
|
65
69
|
onData({
|
|
66
70
|
completionFinished: true,
|
|
67
71
|
message: fullAssistantMessage,
|
|
68
|
-
finalResponseWithUsageData: true
|
|
72
|
+
finalResponseWithUsageData: true
|
|
69
73
|
});
|
|
70
74
|
console.error(error);
|
|
71
75
|
throw new Error(error);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { UIFunctionArguments } from "../type.js";
|
|
2
|
+
import { CmndChatContext, CustomStyles, UIFunctionArguments } from "../type.js";
|
|
3
3
|
import { ConversationProps } from "../components/Conversation.js";
|
|
4
4
|
export interface CmndChatBotProps extends Pick<ConversationProps, 'Components'> {
|
|
5
5
|
chatbotId: number;
|
|
6
6
|
organizationId: number;
|
|
7
|
-
apiKey
|
|
7
|
+
apiKey?: string;
|
|
8
8
|
baseUrl: string;
|
|
9
9
|
UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
|
|
10
|
+
customStyles?: CustomStyles;
|
|
10
11
|
}
|
|
11
|
-
declare function CmndChatBot(
|
|
12
|
+
declare function CmndChatBot(): CmndChatContext;
|
|
12
13
|
export default CmndChatBot;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface ChatInputBoxProps {
|
|
3
|
+
input: string;
|
|
4
|
+
setInput: (input: string) => void;
|
|
5
|
+
handleSendClick: () => void;
|
|
6
|
+
}
|
|
7
|
+
declare const ChatInputBox: ({ input, setInput, handleSendClick }: ChatInputBoxProps) => JSX.Element;
|
|
8
|
+
export default ChatInputBox;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const ChatInputBox = ({ input, setInput, handleSendClick }) => {
|
|
3
|
+
return (_jsx("div", { className: "cmnd-input-wrapper", children: _jsx("input", { autoFocus: true, id: "cmnd-input", className: "cmnd-input", onKeyDown: e => {
|
|
4
|
+
if (e.key === "Enter") {
|
|
5
|
+
handleSendClick();
|
|
6
|
+
}
|
|
7
|
+
}, autoComplete: "off", value: input, onChange: e => setInput(e.target.value), type: "text", placeholder: "Type something..." }) }));
|
|
8
|
+
};
|
|
9
|
+
export default ChatInputBox;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { Dispatch, ReactNode, SetStateAction } from "react";
|
|
2
|
-
import { MessageRole, ToolDetails, ToolData, UIFunctionArguments } from "../type.js";
|
|
2
|
+
import { MessageRole, ToolDetails, ToolData, UIFunctionArguments, CustomStyles } from "../type.js";
|
|
3
3
|
interface ChatBubbleProps {
|
|
4
4
|
message: string | ReactNode | null;
|
|
5
5
|
role: MessageRole;
|
|
@@ -16,6 +16,7 @@ interface ChatBubbleProps {
|
|
|
16
16
|
setIsChatLoading: Dispatch<SetStateAction<boolean>>;
|
|
17
17
|
scrollToBottom: () => void;
|
|
18
18
|
UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
|
|
19
|
+
customStyles?: CustomStyles;
|
|
19
20
|
}
|
|
20
|
-
declare const Chatbubble: ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, }: ChatBubbleProps) => JSX.Element | null;
|
|
21
|
+
declare const Chatbubble: ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, customStyles, }: ChatBubbleProps) => JSX.Element | null;
|
|
21
22
|
export default Chatbubble;
|
|
@@ -10,6 +10,7 @@ import ReactMarkdown from "react-markdown";
|
|
|
10
10
|
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
|
+
import { overrideStyle } from "../utils.js";
|
|
13
14
|
const getChatAvatar = (role) => {
|
|
14
15
|
switch (role) {
|
|
15
16
|
case MessageRole.USER:
|
|
@@ -22,7 +23,7 @@ const getChatAvatar = (role) => {
|
|
|
22
23
|
return _jsx(BsRobot, {});
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
|
-
const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, }) => {
|
|
26
|
+
const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage, setMessages, messages, hide, setChatbotConversationId, setCanSendMessage, setIsChatLoading, scrollToBottom, isLoadingBubble, UITools, customStyles, }) => {
|
|
26
27
|
const patchLastMessageToolInfo = useCallback((messages, toolInfo) => {
|
|
27
28
|
const lastMessage = messages[messages.length - 1];
|
|
28
29
|
if (lastMessage.role !== MessageRole.FUNCTION) {
|
|
@@ -103,15 +104,19 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
|
|
|
103
104
|
width: "100%",
|
|
104
105
|
background: "none",
|
|
105
106
|
};
|
|
106
|
-
|
|
107
|
+
const defaultChatBubbleStyle = {
|
|
108
|
+
backgroundColor: role === MessageRole.USER ? "#7A8194" : "#373E4E",
|
|
109
|
+
color: "white",
|
|
110
|
+
padding: "10px",
|
|
111
|
+
borderRadius: "10px",
|
|
112
|
+
};
|
|
113
|
+
const chatBubbleCustomStyle = overrideStyle(role === MessageRole.USER
|
|
114
|
+
? customStyles?.userChatbubbleStyle ?? defaultChatBubbleStyle
|
|
115
|
+
: customStyles?.botChatbubbleStyle ?? defaultChatBubbleStyle, customStyles?.chatbubbleStyle);
|
|
116
|
+
return (_jsxs("div", { style: defaultStyle, className: `cmnd-chatbot-chat-bubble ${role}`, children: [_jsx("span", { style: overrideStyle({
|
|
107
117
|
fontSize: "30px",
|
|
108
118
|
color: "black",
|
|
109
|
-
}, children: getChatAvatar(role) }), _jsxs("p", { style: {
|
|
110
|
-
backgroundColor: role === MessageRole.USER ? "#7A8194" : "#373E4E",
|
|
111
|
-
color: "white",
|
|
112
|
-
padding: "10px",
|
|
113
|
-
borderRadius: "10px",
|
|
114
|
-
}, children: [role === MessageRole.USER || isLoadingBubble ? (_jsx("span", { children: message })) : (_jsx(ReactMarkdown, { className: "markdown", remarkPlugins: [remarkGfm], children: message?.toString() ?? "", remarkRehypeOptions: { passThrough: ["link"] }, components: {
|
|
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: {
|
|
115
120
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
116
121
|
// @ts-ignore
|
|
117
122
|
code({ inline, className, children, ...props }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { Dispatch, SetStateAction } from "react";
|
|
2
|
-
import { InputFieldProps, SendButtonProps, UIFunctionArguments } from "../type.js";
|
|
2
|
+
import { CustomStyles, InputFieldProps, SendButtonProps, UIFunctionArguments } from "../type.js";
|
|
3
3
|
export interface ConversationProps {
|
|
4
4
|
messages: any[];
|
|
5
5
|
setMessages: Dispatch<SetStateAction<any[]>>;
|
|
@@ -22,6 +22,7 @@ export interface ConversationProps {
|
|
|
22
22
|
error?: any;
|
|
23
23
|
};
|
|
24
24
|
UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
|
|
25
|
+
customStyles?: CustomStyles;
|
|
25
26
|
}
|
|
26
|
-
declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, }: ConversationProps) => JSX.Element;
|
|
27
|
+
declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, customStyles, }: ConversationProps) => JSX.Element;
|
|
27
28
|
export default Conversation;
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import Chatbubble from "./Chatbubble.js";
|
|
3
3
|
import LoadingBubble from "./LoadingBubble.js";
|
|
4
|
-
import
|
|
5
|
-
const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, }) => {
|
|
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, { 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, {}) : null] }), _jsxs("div", { id: "cmnd-input-div", className: "cmnd-input-div", children: [Components?.InputField ? (_jsx(Components.InputField, { ...{ input, setInput, canSendMessage, handleSendClick } })) : (_jsx(
|
|
7
|
-
if (e.key === "Enter") {
|
|
8
|
-
handleSendClick();
|
|
9
|
-
}
|
|
10
|
-
}, autoComplete: "off", value: input, onChange: (e) => setInput(e.target.value), type: "text", placeholder: "type something..." })), Components?.SendButton ? (_jsx(Components.SendButton, { ...{
|
|
4
|
+
import ChatInputBox from "./ChatInputBox.js";
|
|
5
|
+
const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, customStyles, }) => {
|
|
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, { ...{
|
|
11
7
|
canSendMessage,
|
|
12
|
-
handleSendClick
|
|
13
|
-
} })) : (_jsx("
|
|
14
|
-
opacity: canSendMessage ? "1" : "0.5",
|
|
15
|
-
cursor: canSendMessage ? "pointer" : "not-allowed",
|
|
16
|
-
fontSize: "1.5rem",
|
|
17
|
-
}, onClick: handleSendClick, children: _jsx(RiSendPlane2Line, {}) }))] })] }));
|
|
8
|
+
handleSendClick
|
|
9
|
+
} })) : (_jsx("button", { className: "cmnd-send-button", onClick: handleSendClick, children: "Send" }))] })] }));
|
|
18
10
|
};
|
|
19
11
|
export default Conversation;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
import { CustomStyles } from "../type.js";
|
|
3
|
+
interface LoadingBubbleProps {
|
|
4
|
+
customStyles?: CustomStyles;
|
|
5
|
+
}
|
|
6
|
+
declare const LoadingBubble: ({ customStyles }: LoadingBubbleProps) => JSX.Element;
|
|
3
7
|
export default LoadingBubble;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { MessageRole } from "../type.js";
|
|
3
3
|
import Chatbubble from "./Chatbubble.js";
|
|
4
|
-
const LoadingBubble = () => {
|
|
4
|
+
const LoadingBubble = ({ customStyles }) => {
|
|
5
5
|
const color = "white";
|
|
6
|
-
return (_jsx(Chatbubble, { isLoadingBubble: true, message: _jsx("div", { className: "loading-container", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", style: {
|
|
6
|
+
return (_jsx(Chatbubble, { isLoadingBubble: true, customStyles: customStyles, message: _jsx("div", { className: "loading-container", children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", xmlnsXlink: "http://www.w3.org/1999/xlink", style: {
|
|
7
7
|
margin: "auto",
|
|
8
8
|
display: "block",
|
|
9
9
|
shapeRendering: "auto",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import "./styles/index.css";
|
|
1
2
|
export { default as ChatProvider } from "./ChatProvider/index.js";
|
|
2
3
|
export { default as useChatContext } from "./ChatProvider/useChatContext.js";
|
|
3
|
-
export { CmndChatContext } from "./type.js";
|
|
4
|
+
export { CmndChatContext, InputFieldProps, SendButtonProps, CustomStyles } from "./type.js";
|
|
4
5
|
export { default as CmndChatBot } from "./CmndChatBot/index.js";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ConversationDataObject } from "../type.js";
|
|
2
|
-
declare const postUserConversation: ({
|
|
3
|
-
orgId: number;
|
|
2
|
+
declare const postUserConversation: ({ payload, apikey, chatbotId, baseUrl, onData, }: {
|
|
4
3
|
payload: object;
|
|
5
4
|
chatbotId: number;
|
|
6
|
-
apikey
|
|
5
|
+
apikey?: string | undefined;
|
|
7
6
|
baseUrl: string;
|
|
8
7
|
onData?: ((data: ConversationDataObject) => void) | undefined;
|
|
9
8
|
}) => Promise<void>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import processStream from "../ChatProvider/processStream/index.js";
|
|
3
|
-
const postUserConversation = async ({
|
|
4
|
-
const endpoint = `${baseUrl}/
|
|
3
|
+
const postUserConversation = async ({ payload, apikey, chatbotId, baseUrl, onData, }) => {
|
|
4
|
+
const endpoint = `${baseUrl}/chatbots/${chatbotId}/conversations`;
|
|
5
5
|
const response = await axios.post(endpoint, {
|
|
6
6
|
messages: payload,
|
|
7
7
|
}, {
|
|
@@ -14,9 +14,7 @@ const postUserConversation = async ({ orgId, payload, apikey, chatbotId, baseUrl
|
|
|
14
14
|
responseType: "stream",
|
|
15
15
|
adapter: "fetch",
|
|
16
16
|
});
|
|
17
|
-
const reader = response.data
|
|
18
|
-
.pipeThrough(new TextDecoderStream())
|
|
19
|
-
.getReader();
|
|
17
|
+
const reader = response.data.pipeThrough(new TextDecoderStream()).getReader();
|
|
20
18
|
await processStream(reader, onData);
|
|
21
19
|
};
|
|
22
20
|
export default postUserConversation;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
* {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
.cmnd-conversations {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
height: 100%;
|
|
10
|
+
overflow: none;
|
|
11
|
+
padding: 10px;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
align-items: center;
|
|
14
|
+
}
|
|
15
|
+
.cmnd-conversations-messages {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
max-height: 100%;
|
|
19
|
+
overflow-y: scroll;
|
|
20
|
+
overflow-x: hidden;
|
|
21
|
+
width: 60%;
|
|
22
|
+
align-items: center;
|
|
23
|
+
padding: 10px;
|
|
24
|
+
}
|
|
25
|
+
.cmnd-input-wrapper {
|
|
26
|
+
display: flex;
|
|
27
|
+
width: 65%;
|
|
28
|
+
}
|
|
29
|
+
.cmnd-input-div {
|
|
30
|
+
width: 100%;
|
|
31
|
+
border: none;
|
|
32
|
+
border-radius: 20px;
|
|
33
|
+
display: flex;
|
|
34
|
+
padding: 0 10px;
|
|
35
|
+
margin-top: auto;
|
|
36
|
+
display: flex;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
}
|
|
39
|
+
.cmnd-input {
|
|
40
|
+
flex: 3;
|
|
41
|
+
background-color: #3d4354;
|
|
42
|
+
border: none;
|
|
43
|
+
color: white;
|
|
44
|
+
font-size: 16px;
|
|
45
|
+
height: 100%;
|
|
46
|
+
padding: 10px;
|
|
47
|
+
border-radius: 20px 0 0 20px;
|
|
48
|
+
height: 45px;
|
|
49
|
+
outline: none;
|
|
50
|
+
}
|
|
51
|
+
.cmnd-send-button {
|
|
52
|
+
flex: 0;
|
|
53
|
+
background-color: #20232c;
|
|
54
|
+
border: none;
|
|
55
|
+
color: white;
|
|
56
|
+
font-size: 16px;
|
|
57
|
+
height: 100%;
|
|
58
|
+
padding: 0 20px;
|
|
59
|
+
border-radius: 0 20px 20px 0;
|
|
60
|
+
height: 45px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.cmnd-chatbot-chat-bubble {
|
|
64
|
+
border-radius: 10px;
|
|
65
|
+
padding: 10px;
|
|
66
|
+
margin: 10px;
|
|
67
|
+
display: inline-block;
|
|
68
|
+
word-wrap: break-word;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.markdown {
|
|
72
|
+
max-width: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.markdown table {
|
|
76
|
+
border-collapse: separate;
|
|
77
|
+
border-spacing: 0px 0px;
|
|
78
|
+
margin-bottom: 0.25rem;
|
|
79
|
+
margin-top: 0.25rem;
|
|
80
|
+
width: 100%;
|
|
81
|
+
}
|
|
82
|
+
.prose :where(thead):not(:where([class~="not-prose"] *)) {
|
|
83
|
+
border-bottom-color: #4b5563;
|
|
84
|
+
border-bottom-width: 1px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.markdown table thead {
|
|
88
|
+
border-bottom-color: #4b5563;
|
|
89
|
+
border-bottom-width: 1px;
|
|
90
|
+
}
|
|
91
|
+
.markdown th {
|
|
92
|
+
background-color: hsla(0, 0%, 100%, 0.1);
|
|
93
|
+
border: 1px solid hsla(0, 0%, 100%, 0.15);
|
|
94
|
+
padding: 0.25rem 0.75rem;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.markdown th {
|
|
98
|
+
border-left-width: 1px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.markdown th {
|
|
102
|
+
border-right-width: 1px;
|
|
103
|
+
}
|
|
104
|
+
.markdown th:first-child {
|
|
105
|
+
border-top-left-radius: 0.375rem;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.markdown th:last-child {
|
|
109
|
+
border-right-width: 1px;
|
|
110
|
+
border-top-right-radius: 0.375rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.markdown td {
|
|
114
|
+
border: 1px solid hsla(0, 0%, 100%, 0.15);
|
|
115
|
+
padding: 0.25rem 0.75rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.markdown td:last-child,
|
|
119
|
+
.markdown td {
|
|
120
|
+
border-right-width: 1px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.markdown td:last-child {
|
|
124
|
+
border-left-width: 1px;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.markdown tbody tr:last-child td:first-child {
|
|
128
|
+
border-bottom-left-radius: 0.375rem;
|
|
129
|
+
}
|
|
130
|
+
.markdown tbody tr:last-child td:last-child,
|
|
131
|
+
.markdown tbody tr:last-child td:first-child {
|
|
132
|
+
border-bottom-right-radius: 0.375rem;
|
|
133
|
+
}
|
|
134
|
+
.markdown blockquote {
|
|
135
|
+
border-left-width: 2px;
|
|
136
|
+
padding-left: 1rem;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.markdown blockquote > p {
|
|
140
|
+
margin: 0;
|
|
141
|
+
}
|
|
142
|
+
.markdown p {
|
|
143
|
+
margin-top: 0;
|
|
144
|
+
margin-bottom: 10px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.markdown blockquote {
|
|
148
|
+
margin: 0;
|
|
149
|
+
padding: 0 1em;
|
|
150
|
+
color: #848d97;
|
|
151
|
+
border-left: 0.25em solid #30363d;
|
|
152
|
+
padding-top: 0.5rem;
|
|
153
|
+
margin-bottom: 1rem;
|
|
154
|
+
margin-top: 1rem;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.markdown ul,
|
|
158
|
+
.markdown ol {
|
|
159
|
+
padding-left: 1.625em;
|
|
160
|
+
}
|
|
161
|
+
.markdown pre {
|
|
162
|
+
background-color: #161b22;
|
|
163
|
+
border-radius: 0.375rem;
|
|
164
|
+
color: currentColor;
|
|
165
|
+
font-size: 0.875em;
|
|
166
|
+
font-weight: 400;
|
|
167
|
+
line-height: 1.7142857;
|
|
168
|
+
margin-bottom: 0.5rem;
|
|
169
|
+
margin-top: 0.5rem;
|
|
170
|
+
overflow-x: auto;
|
|
171
|
+
padding: 5px;
|
|
172
|
+
}
|
|
173
|
+
.markdown code:not(pre code) {
|
|
174
|
+
padding: 0.2em 0.4em;
|
|
175
|
+
margin: 0;
|
|
176
|
+
font-size: 85%;
|
|
177
|
+
white-space: break-spaces;
|
|
178
|
+
background-color: #6e768166;
|
|
179
|
+
border-radius: 6px;
|
|
180
|
+
}
|
|
181
|
+
.markdown a:hover {
|
|
182
|
+
color: #2964aa;
|
|
183
|
+
}
|
|
184
|
+
.markdown a {
|
|
185
|
+
color: #7ab7ff;
|
|
186
|
+
text-decoration: underline;
|
|
187
|
+
text-underline-offset: 0.2em;
|
|
188
|
+
font-weight: 400;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@media screen and (max-width: 1280px) {
|
|
192
|
+
.cmnd-conversations-messages {
|
|
193
|
+
width: 100%;
|
|
194
|
+
}
|
|
195
|
+
.cmnd-input-wrapper {
|
|
196
|
+
width: 100%;
|
|
197
|
+
}
|
|
198
|
+
.cmnd-input {
|
|
199
|
+
font-size: 14px;
|
|
200
|
+
}
|
|
201
|
+
.cmnd-send-button {
|
|
202
|
+
font-size: 14px;
|
|
203
|
+
}
|
|
204
|
+
}
|
package/dist/type.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
1
2
|
import { ConversationProps } from "./components/Conversation.js";
|
|
2
3
|
export interface CmndChatContext {
|
|
3
4
|
props: Partial<ConversationProps>;
|
|
@@ -100,4 +101,12 @@ interface ToolMessage {
|
|
|
100
101
|
tool: ToolDetails;
|
|
101
102
|
}
|
|
102
103
|
export type Message = GenericMessage | ToolMessage;
|
|
104
|
+
export interface CustomStyles {
|
|
105
|
+
chatAvatarStyle?: CSSProperties;
|
|
106
|
+
inputStyle?: CSSProperties;
|
|
107
|
+
sendButtonStyle?: CSSProperties;
|
|
108
|
+
chatbubbleStyle?: CSSProperties;
|
|
109
|
+
botChatbubbleStyle?: CSSProperties;
|
|
110
|
+
userChatbubbleStyle?: CSSProperties;
|
|
111
|
+
}
|
|
103
112
|
export {};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
1
|
import { CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Overrides properties of a base CSS style with provided overrides.
|
|
4
|
+
*
|
|
5
|
+
* @param style - The base CSS style to be overridden.
|
|
6
|
+
* @param overrides - An optional object containing properties to override in the base style.
|
|
7
|
+
* @returns A new CSSProperties object with overridden properties.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // Override backgroundColor and width properties
|
|
11
|
+
* const baseStyle = { backgroundColor: "#f0f0f0", width: "400px" };
|
|
12
|
+
* const customStyle = overrideStyle(baseStyle, { backgroundColor: "blue", width: "300px" });
|
|
13
|
+
*/
|
|
2
14
|
export declare const overrideStyle: (style: CSSProperties, overrides?: Partial<CSSProperties>) => CSSProperties;
|
package/dist/utils.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overrides properties of a base CSS style with provided overrides.
|
|
3
|
+
*
|
|
4
|
+
* @param style - The base CSS style to be overridden.
|
|
5
|
+
* @param overrides - An optional object containing properties to override in the base style.
|
|
6
|
+
* @returns A new CSSProperties object with overridden properties.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Override backgroundColor and width properties
|
|
10
|
+
* const baseStyle = { backgroundColor: "#f0f0f0", width: "400px" };
|
|
11
|
+
* const customStyle = overrideStyle(baseStyle, { backgroundColor: "blue", width: "300px" });
|
|
12
|
+
*/
|
|
1
13
|
export const overrideStyle = (style, overrides) => {
|
|
2
14
|
return { ...style, ...overrides };
|
|
3
15
|
};
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmnd-ai/chatbot-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"description": "",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"files": [
|
|
8
8
|
"dist/",
|
|
9
9
|
"package.json",
|
|
10
|
+
"dist/styles/index.css",
|
|
10
11
|
"ReadMe.md"
|
|
11
12
|
],
|
|
12
13
|
"scripts": {
|
|
13
|
-
"build": "tsc",
|
|
14
|
+
"build": "tsc && npm run copy-css",
|
|
15
|
+
"copy-css": "mkdir -p dist/styles && cp src/styles/index.css dist/styles/index.css",
|
|
16
|
+
"dev": "npm run copy-css && tsc -w",
|
|
14
17
|
"prepublishOnly": "npm run build",
|
|
15
18
|
"semantic-release": "semantic-release"
|
|
16
19
|
},
|
|
@@ -18,6 +21,7 @@
|
|
|
18
21
|
"author": "",
|
|
19
22
|
"license": "ISC",
|
|
20
23
|
"devDependencies": {
|
|
24
|
+
"@types/express-unless": "^2.0.3",
|
|
21
25
|
"@types/react": "18.0.28",
|
|
22
26
|
"@types/react-syntax-highlighter": "^15.5.13",
|
|
23
27
|
"semantic-release": "^22.0.12",
|