@cmnd-ai/chatbot-react 1.2.0 → 1.3.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 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 Node.js environments.
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, CmndChatBot } from "@cmnd-ai/chatbot-react";
23
- import { useEffect } from "react";
22
+ import { ChatProvider } from "@cmnd-ai/chatbot-react";
24
23
 
25
- const components = {
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
- <div>
99
- <ChatProvider apiKey="xxxxx" chatbotId={1} organizationId={1}>
100
- {(params) => <CmndChatBot {...params} components={components} />}
101
- </ChatProvider>
102
- </div>
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
- You can find an example implementation from Github [here](https://github.com/CyprusCodes/cmnd-react-chatbot-example.git)
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: React.ReactNode | ((props: CmndChatBotProps) => React.ReactNode);
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, } = dataObject;
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: string;
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(props: CmndChatBotProps): void;
12
+ declare function CmndChatBot(): CmndChatContext;
12
13
  export default CmndChatBot;
@@ -1,6 +1,6 @@
1
1
  import useChatContext from "../ChatProvider/useChatContext.js";
2
- function CmndChatBot(props) {
2
+ function CmndChatBot() {
3
3
  const chatContext = useChatContext();
4
- return;
4
+ return chatContext;
5
5
  }
6
6
  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;
@@ -8,7 +8,9 @@ import UIToolComponent from "../ui-tools/index.js";
8
8
  import remarkGfm from "remark-gfm";
9
9
  import ReactMarkdown from "react-markdown";
10
10
  import SyntaxHighlighter from "react-syntax-highlighter";
11
- import { oneDark } from "react-syntax-highlighter/dist/esm/styles/prism";
11
+ //@ts-ignore
12
+ import oneDark from "react-syntax-highlighter/dist/cjs/styles/prism/one-dark.js";
13
+ import { overrideStyle } from "../utils.js";
12
14
  const getChatAvatar = (role) => {
13
15
  switch (role) {
14
16
  case MessageRole.USER:
@@ -21,7 +23,7 @@ const getChatAvatar = (role) => {
21
23
  return _jsx(BsRobot, {});
22
24
  }
23
25
  };
24
- 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, }) => {
25
27
  const patchLastMessageToolInfo = useCallback((messages, toolInfo) => {
26
28
  const lastMessage = messages[messages.length - 1];
27
29
  if (lastMessage.role !== MessageRole.FUNCTION) {
@@ -102,15 +104,19 @@ const Chatbubble = ({ message, role, toolCallDetails, tools, postSessionMessage,
102
104
  width: "100%",
103
105
  background: "none",
104
106
  };
105
- return (_jsxs("div", { style: defaultStyle, className: `cmnd-chatbot-chat-bubble ${role}`, children: [_jsx("span", { style: {
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({
106
117
  fontSize: "30px",
107
118
  color: "black",
108
- }, children: getChatAvatar(role) }), _jsxs("p", { style: {
109
- backgroundColor: role === MessageRole.USER ? "#7A8194" : "#373E4E",
110
- color: "white",
111
- padding: "10px",
112
- borderRadius: "10px",
113
- }, 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: {
114
120
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
115
121
  // @ts-ignore
116
122
  code({ inline, className, children, ...props }) {
@@ -1,5 +1,6 @@
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
+ import "../styles/index.css";
3
4
  export interface ConversationProps {
4
5
  messages: any[];
5
6
  setMessages: Dispatch<SetStateAction<any[]>>;
@@ -22,6 +23,7 @@ export interface ConversationProps {
22
23
  error?: any;
23
24
  };
24
25
  UITools?: Record<string, React.FC<UIFunctionArguments<any>>>;
26
+ customStyles?: CustomStyles;
25
27
  }
26
- declare const Conversation: ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, }: ConversationProps) => JSX.Element;
28
+ 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
29
  export default Conversation;
@@ -1,19 +1,12 @@
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 { RiSendPlane2Line } from "react-icons/ri";
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("input", { id: "cmnd-input", className: "cmnd-input", onKeyDown: (e) => {
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
+ import "../styles/index.css";
6
+ const Conversation = ({ messages, handleSendClick, isChatLoading, error, messagesRef, enabledTools, postSessionMessage, setMessages, setChatbotConversationId, setIsChatLoading, setCanSendMessage, scrollToBottom, canSendMessage, setInput, input, Components, UITools, customStyles, }) => {
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, { 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
8
  canSendMessage,
12
- handleSendClick,
13
- } })) : (_jsx("span", { id: "cmnd-send-button", className: "cmnd-send-button", style: {
14
- opacity: canSendMessage ? "1" : "0.5",
15
- cursor: canSendMessage ? "pointer" : "not-allowed",
16
- fontSize: "1.5rem",
17
- }, onClick: handleSendClick, children: _jsx(RiSendPlane2Line, {}) }))] })] }));
9
+ handleSendClick
10
+ } })) : (_jsx("button", { className: "cmnd-send-button", onClick: handleSendClick, children: "Send" }))] })] }));
18
11
  };
19
12
  export default Conversation;
@@ -1,3 +1,7 @@
1
1
  /// <reference types="react" />
2
- declare const LoadingBubble: () => JSX.Element;
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,4 @@
1
1
  export { default as ChatProvider } from "./ChatProvider/index.js";
2
2
  export { default as useChatContext } from "./ChatProvider/useChatContext.js";
3
- export { CmndChatContext } from "./type.js";
3
+ export { CmndChatContext, InputFieldProps, SendButtonProps, CustomStyles, } from "./type.js";
4
4
  export { default as CmndChatBot } from "./CmndChatBot/index.js";
@@ -1,9 +1,8 @@
1
1
  import { ConversationDataObject } from "../type.js";
2
- declare const postUserConversation: ({ orgId, payload, apikey, chatbotId, baseUrl, onData, }: {
3
- orgId: number;
2
+ declare const postUserConversation: ({ payload, apikey, chatbotId, baseUrl, onData, }: {
4
3
  payload: object;
5
4
  chatbotId: number;
6
- apikey: string;
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 ({ orgId, payload, apikey, chatbotId, baseUrl, onData, }) => {
4
- const endpoint = `${baseUrl}/organizations/${orgId}/chatbots/${chatbotId}/conversations`;
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,205 @@
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
+ justify-content: center;
23
+ align-items: center;
24
+ padding: 10px;
25
+ }
26
+ .cmnd-input-wrapper {
27
+ display: flex;
28
+ width: 65%;
29
+ }
30
+ .cmnd-input-div {
31
+ width: 100%;
32
+ border: none;
33
+ border-radius: 20px;
34
+ display: flex;
35
+ padding: 0 10px;
36
+ margin-top: auto;
37
+ display: flex;
38
+ justify-content: center;
39
+ }
40
+ .cmnd-input {
41
+ flex: 3;
42
+ background-color: #3d4354;
43
+ border: none;
44
+ color: white;
45
+ font-size: 16px;
46
+ height: 100%;
47
+ padding: 10px;
48
+ border-radius: 20px 0 0 20px;
49
+ height: 45px;
50
+ outline: none;
51
+ }
52
+ .cmnd-send-button {
53
+ flex: 0;
54
+ background-color: #20232c;
55
+ border: none;
56
+ color: white;
57
+ font-size: 16px;
58
+ height: 100%;
59
+ padding: 0 20px;
60
+ border-radius: 0 20px 20px 0;
61
+ height: 45px;
62
+ }
63
+
64
+ .cmnd-chatbot-chat-bubble {
65
+ border-radius: 10px;
66
+ padding: 10px;
67
+ margin: 10px;
68
+ display: inline-block;
69
+ word-wrap: break-word;
70
+ }
71
+
72
+ .markdown {
73
+ max-width: none;
74
+ }
75
+
76
+ .markdown table {
77
+ border-collapse: separate;
78
+ border-spacing: 0px 0px;
79
+ margin-bottom: 0.25rem;
80
+ margin-top: 0.25rem;
81
+ width: 100%;
82
+ }
83
+ .prose :where(thead):not(:where([class~="not-prose"] *)) {
84
+ border-bottom-color: #4b5563;
85
+ border-bottom-width: 1px;
86
+ }
87
+
88
+ .markdown table thead {
89
+ border-bottom-color: #4b5563;
90
+ border-bottom-width: 1px;
91
+ }
92
+ .markdown th {
93
+ background-color: hsla(0, 0%, 100%, 0.1);
94
+ border: 1px solid hsla(0, 0%, 100%, 0.15);
95
+ padding: 0.25rem 0.75rem;
96
+ }
97
+
98
+ .markdown th {
99
+ border-left-width: 1px;
100
+ }
101
+
102
+ .markdown th {
103
+ border-right-width: 1px;
104
+ }
105
+ .markdown th:first-child {
106
+ border-top-left-radius: 0.375rem;
107
+ }
108
+
109
+ .markdown th:last-child {
110
+ border-right-width: 1px;
111
+ border-top-right-radius: 0.375rem;
112
+ }
113
+
114
+ .markdown td {
115
+ border: 1px solid hsla(0, 0%, 100%, 0.15);
116
+ padding: 0.25rem 0.75rem;
117
+ }
118
+
119
+ .markdown td:last-child,
120
+ .markdown td {
121
+ border-right-width: 1px;
122
+ }
123
+
124
+ .markdown td:last-child {
125
+ border-left-width: 1px;
126
+ }
127
+
128
+ .markdown tbody tr:last-child td:first-child {
129
+ border-bottom-left-radius: 0.375rem;
130
+ }
131
+ .markdown tbody tr:last-child td:last-child,
132
+ .markdown tbody tr:last-child td:first-child {
133
+ border-bottom-right-radius: 0.375rem;
134
+ }
135
+ .markdown blockquote {
136
+ border-left-width: 2px;
137
+ padding-left: 1rem;
138
+ }
139
+
140
+ .markdown blockquote > p {
141
+ margin: 0;
142
+ }
143
+ .markdown p {
144
+ margin-top: 0;
145
+ margin-bottom: 10px;
146
+ }
147
+
148
+ .markdown blockquote {
149
+ margin: 0;
150
+ padding: 0 1em;
151
+ color: #848d97;
152
+ border-left: 0.25em solid #30363d;
153
+ padding-top: 0.5rem;
154
+ margin-bottom: 1rem;
155
+ margin-top: 1rem;
156
+ }
157
+
158
+ .markdown ul,
159
+ .markdown ol {
160
+ padding-left: 1.625em;
161
+ }
162
+ .markdown pre {
163
+ background-color: #161b22;
164
+ border-radius: 0.375rem;
165
+ color: currentColor;
166
+ font-size: 0.875em;
167
+ font-weight: 400;
168
+ line-height: 1.7142857;
169
+ margin-bottom: 0.5rem;
170
+ margin-top: 0.5rem;
171
+ overflow-x: auto;
172
+ padding: 5px;
173
+ }
174
+ .markdown code:not(pre code) {
175
+ padding: 0.2em 0.4em;
176
+ margin: 0;
177
+ font-size: 85%;
178
+ white-space: break-spaces;
179
+ background-color: #6e768166;
180
+ border-radius: 6px;
181
+ }
182
+ .markdown a:hover {
183
+ color: #2964aa;
184
+ }
185
+ .markdown a {
186
+ color: #7ab7ff;
187
+ text-decoration: underline;
188
+ text-underline-offset: 0.2em;
189
+ font-weight: 400;
190
+ }
191
+
192
+ @media screen and (max-width: 1280px) {
193
+ .cmnd-conversations-messages {
194
+ width: 100%;
195
+ }
196
+ .cmnd-input-wrapper {
197
+ width: 100%;
198
+ }
199
+ .cmnd-input {
200
+ font-size: 14px;
201
+ }
202
+ .cmnd-send-button {
203
+ font-size: 14px;
204
+ }
205
+ }
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.2.0",
3
+ "version": "1.3.0",
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": "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",