@vamlabs/vam-chatbot 0.1.67 → 0.1.68
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/dist/web-component.js +1 -1
- package/package.json +1 -2
package/dist/web-component.js
CHANGED
|
@@ -26,7 +26,7 @@ return /******/ (() => { // webpackBootstrap
|
|
|
26
26
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
27
27
|
|
|
28
28
|
"use strict";
|
|
29
|
-
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs\");\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/render/dom/features-animation.mjs\");\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/render/components/m/proxy.mjs\");\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var react_use_websocket__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-use-websocket */ \"./node_modules/react-use-websocket/dist/index.js\");\n/* harmony import */ var _components_ChatbotHeader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/ChatbotHeader */ \"./components/ChatbotHeader.jsx\");\n/* harmony import */ var _components_ChatbotBody__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/ChatbotBody */ \"./components/ChatbotBody.jsx\");\n/* harmony import */ var _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Chatbot.module.css */ \"./Chatbot.module.css\");\n/* harmony import */ var _utils_variants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/variants */ \"./utils/variants.js\");\n/* harmony import */ var _utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/websocketHandlers */ \"./utils/websocketHandlers.js\");\n/* harmony import */ var _utils_useClickHandler__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils/useClickHandler */ \"./utils/useClickHandler.js\");\n/* harmony import */ var _utils_defaults__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils/defaults */ \"./utils/defaults.js\");\n/* harmony import */ var _utils_config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/config */ \"./utils/config.js\");\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react/jsx-runtime */ \"./node_modules/react/jsx-runtime.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* \n- valid chatbot states:\n 0: \"at rest\",\n 1: \"waiting for response from api\"\n 2: \"receiving response from api\"\n*/\n\nconst fixSpecialLLMChars = text => {\n // forward slash is replaced by <|slash|> in the response from the api\n return text.replace(/\\u003c\\|slash\\|\\u003e/g, \"/\");\n};\nfunction Chatbot(_ref) {\n let {\n clientId,\n onTrackEvent\n } = _ref;\n const [messageList, setMessageList] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);\n const [inputText, setInputText] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\");\n const [chatbotState, setChatbotState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);\n const [chatbotMinimized, setChatbotMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n const [chatbotPopupMinimized, setChatbotPopupMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);\n const [promptsData, setPromptsData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({\n show: true,\n prompts: []\n });\n const [promptsMinimized, setPromptsMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n const [shouldConnectWebsocket, setShouldConnectWebsocket] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);\n const [chatbotConfig, setChatbotConfig] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({\n fetchedData: false,\n data: {}\n });\n const [chatbotIcon, setChatbotIcon] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n const defaultMessageList = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);\n const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n const scrollAnchorRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n const chatbotRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n\n // Use the custom hook to track clicks\n (0,_utils_useClickHandler__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(onTrackEvent, chatbotRef);\n\n // use effect to upate the css variables once available through the chatbot config API\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n try {\n if (chatbotConfig?.data?.styles?.css_variables) {\n // escape special characters with backslash\n // since query selctor does not allow special characters\n let chatbotParent = document?.querySelector(\"vam-chatbot\")?.shadowRoot.querySelector(`.${_Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent.replace(/([^\\w-])/g, \"\\\\$1\")}`) || document?.querySelector(`.${_Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent.replace(/([^\\w-])/g, \"\\\\$1\")}`);\n for (let variable in chatbotConfig.data.styles.css_variables) {\n chatbotParent.style.setProperty(`--${variable}`, chatbotConfig.data.styles.css_variables[variable]);\n }\n }\n } catch (error) {\n console.log(error);\n }\n }, [chatbotConfig?.data?.styles?.css_variables]);\n\n // useeffect to store the chatbot icon when its url is fetched from the chatbot config API\n // this is to prevent the api call being made on render of every message\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n try {\n if (chatbotConfig?.data?.icon_url) {\n const fetchChatbotIcon = async () => {\n let url = chatbotConfig?.data?.icon_url;\n let apiResponse = await (0,axios__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n url,\n method: \"GET\",\n responseType: \"blob\"\n });\n let imageBlob = apiResponse.data;\n if (imageBlob) {\n let imageObjectURL = URL.createObjectURL(imageBlob);\n setChatbotIcon(imageObjectURL);\n }\n };\n fetchChatbotIcon();\n }\n } catch (error) {\n console.log(error);\n }\n }, [chatbotConfig?.data?.icon_url]);\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n const fetchConfigData = async () => {\n // Check if configUrl is null and handle appropriately\n if (!_utils_config__WEBPACK_IMPORTED_MODULE_9__.configUrl) {\n console.error(\"Chatbot config URL is not set. Please provide CHATBOT_DEV_URL or CHATBOT_PROD_URL environment variables.\");\n return;\n }\n const url = _utils_config__WEBPACK_IMPORTED_MODULE_9__.configUrl;\n const method = \"POST\";\n const requestBody = {\n clientId\n };\n try {\n let apiResponse = await (0,axios__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n url,\n method,\n data: requestBody\n });\n if (apiResponse?.data) {\n let data = apiResponse.data;\n setChatbotConfig({\n fetchedData: true,\n data\n });\n setPromptsData(data?.default_prompts || {\n show: false,\n prompts: []\n });\n setMessageList(data?.default_message_list || []);\n defaultMessageList.current = data?.default_message_list || [];\n } else {\n // handle no data here\n console.log(\"no data found for the provided client id: \", clientId);\n }\n } catch (e) {\n console.error(e);\n // handle api failure here\n }\n };\n fetchConfigData();\n }, [clientId]);\n let websocket = (0,react_use_websocket__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(chatbotConfig?.data?.websocket_url, {\n onOpen: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnOpen)(event),\n onClose: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnClose)(event, chatbotMinimized, setShouldConnectWebsocket),\n // onReconnectStop:\n onMessage: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnMessage)(event, handleWebsocketResponse),\n onError: _utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnError,\n shouldReconnect: closeEvent => !chatbotMinimized,\n // only attempt reconnection when the chatbot is maximized\n heartbeat: {\n message: JSON.stringify({\n action: \"heartbeat\",\n data: \"ping\"\n }),\n returnMessage: \"pong\",\n // to prevent re-rendering the component\n timeout: 9000,\n interval: 6000\n }\n }, shouldConnectWebsocket // handle the connection of the websocket using this variable\n );\n\n // scroll to the latest message whenever the message list updates\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n scrollAnchorRef.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"end\",\n inline: \"nearest\"\n });\n }, [messageList]);\n\n // set the chatbot connection to \"true\" when the chatbot is maximized\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n if (!chatbotMinimized) {\n setShouldConnectWebsocket(true);\n }\n }, [chatbotMinimized]);\n const handleWebsocketResponse = event => {\n try {\n try {\n event = JSON.parse(event.data);\n } catch (error) {}\n let {\n status,\n data\n } = event || {};\n let {\n response,\n sources,\n image_links,\n promoted_topics\n } = data || {};\n if (status === \"streaming\") {\n // set the chatbot state to \"receiving response\" and initialize the response\n setChatbotState(2);\n if (response) {\n setMessageList(prevList => {\n let responseList = [...prevList];\n try {\n let latestMessage = prevList.slice(-1)[0];\n if (latestMessage?.status === \"streaming\") {\n latestMessage.data.text = fixSpecialLLMChars(response);\n } else {\n let responseMessage = {\n source: \"bot\",\n data: {\n text: response\n },\n origin: \"server\",\n status: \"streaming\"\n };\n responseList = [...responseList, responseMessage];\n }\n } catch (error) {}\n return responseList;\n });\n }\n } else if (status === \"done\") {\n setChatbotState(0);\n\n // update the status as done for the last message\n setMessageList(prevList => {\n let responseList = [...prevList];\n try {\n let latestMessage = responseList.slice(-1)[0];\n if (latestMessage?.source !== \"user\") {\n latestMessage.status = \"done\";\n latestMessage.data.text = fixSpecialLLMChars(response);\n latestMessage.data.sources = sources?.map(fixSpecialLLMChars);\n if (promoted_topics) {\n const promotedImageLinks = promoted_topics.map(pt => pt?.image_link)?.filter(Boolean)?.map(fixSpecialLLMChars);\n latestMessage.data.image_links = promotedImageLinks?.length > 0 ? promotedImageLinks : image_links?.map(fixSpecialLLMChars);\n latestMessage.data.promoted_topics = promoted_topics?.filter(item => item?.title);\n }\n } else {\n let responseMessage = {\n source: \"bot\",\n data: {\n text: _utils_defaults__WEBPACK_IMPORTED_MODULE_8__.errorResponse\n },\n origin: \"server\",\n status: \"done\"\n };\n responseList = [...responseList, responseMessage];\n }\n } catch (error) {}\n return responseList;\n });\n }\n } catch (error) {}\n };\n\n // to keep the input field in focus and scroll to the latest message\n // when the enter button is clicked.\n // const focusInput = () => {\n // inputRef.current.focus();\n // };\n\n // to handle the minimize/maximize animation of the chatbot.\n const handleChatbotAnimation = () => {\n setChatbotMinimized(!chatbotMinimized);\n };\n\n // to reset the chatbot content.\n const resetChatbot = () => {\n try {\n forceConnectWebsocket();\n setMessageList(defaultMessageList.current);\n setPromptsData(prevData => {\n return {\n ...prevData,\n show: true\n };\n });\n setChatbotState(0);\n } catch (error) {}\n };\n const handleInput = event => {\n try {\n setInputText(event.target.value);\n } catch (error) {}\n };\n const getChatHistory = () => {\n let response = [];\n try {\n let historyItem = {\n user: \"\",\n assistant: \"\"\n };\n for (let message of messageList) {\n if (message.source === \"user\") {\n historyItem.user = message?.data?.text;\n } else if (message.source === \"bot\" && message.origin === \"server\") {\n historyItem.assistant = message?.data?.text;\n response.push(historyItem);\n historyItem = {\n user: \"\",\n assistant: \"\"\n };\n }\n }\n } catch (error) {\n console.log(error);\n } finally {\n return response;\n }\n };\n\n // try to connect the websocket connection by force by setting its flag to false and true\n const forceConnectWebsocket = () => {\n setShouldConnectWebsocket(false); // set state to false\n setTimeout(() => {\n setShouldConnectWebsocket(true); // set state back to true after a short delay\n }, 500);\n };\n const handleSubmit = async function () {\n let prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : \"\";\n let typewriterEffect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n if (!prompt) {\n prompt = inputText;\n } else {\n typewriterEffect = true;\n }\n try {\n prompt = prompt.trim();\n if (prompt) {\n // force reconnect the websocket if it belongs to either of the following states: [-1, 2, 3]\n if ([-1, 2, 3].includes(websocket?.readyState)) {\n forceConnectWebsocket();\n }\n setChatbotState(1);\n\n // put the user's prompt in the chat\n let userMessage = {\n source: \"user\",\n data: {\n text: prompt\n },\n status: \"done\",\n typewriterEffect\n };\n setMessageList(prevList => [...prevList, userMessage]);\n\n // hide the default prompts\n setPromptsData({\n ...promptsData,\n show: false\n });\n\n // clear the input field\n setInputText(\"\");\n\n // prepare the chat history\n let chatHistory = getChatHistory();\n\n // send the user's query to the webhook\n websocket.sendJsonMessage({\n action: \"message\",\n data: {\n message: prompt,\n chatHistory,\n clientId\n }\n });\n }\n } catch (error) {\n // responseMessage = {\n // source: \"error\",\n // text: \"An error occured.\",\n // };\n console.log(error);\n }\n };\n return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.Fragment, {\n children: chatbotConfig?.fetchedData && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent,\n ref: chatbotRef,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_12__.LazyMotion, {\n features: framer_motion__WEBPACK_IMPORTED_MODULE_13__.domAnimation,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n initial: false,\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotContainer,\n animate: chatbotMinimized ? \"hide\" : \"show\",\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.maximizedChatbotVariants,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_components_ChatbotHeader__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n headerText: chatbotConfig?.data?.header_text,\n setPromptsMinimized: setPromptsMinimized,\n handleChatbotAnimation: handleChatbotAnimation,\n resetChatbot: resetChatbot\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_components_ChatbotBody__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n messageList: messageList,\n promptsData: promptsData,\n handleSubmit: handleSubmit,\n chatbotState: chatbotState,\n scrollAnchorRef: scrollAnchorRef,\n promptsMinimized: promptsMinimized,\n setPromptsMinimized: setPromptsMinimized,\n inputRef: inputRef,\n inputText: inputText,\n handleInput: handleInput,\n placeholderInputText: chatbotConfig?.data?.placeholder_input_text,\n chatbotIcon: chatbotIcon\n })]\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotVariants,\n animate: chatbotMinimized ? \"show\" : \"hide\",\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotCircleContainer,\n children: [!chatbotPopupMinimized && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popupContainer,\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotContentVariants,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"button\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].closePopup,\n onClick: () => setChatbotPopupMinimized(true),\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"i\", {\n className: \"bi bi-x-circle-fill\"\n })\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popup,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popupContent,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"span\", {\n children: chatbotConfig?.data?.popup_body_text\n })\n })\n })]\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotContentVariants,\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotCircle,\n onClick: handleChatbotAnimation,\n children: chatbotIcon && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"img\", {\n src: chatbotIcon,\n loading: \"lazy\",\n alt: \"chatbot icon\",\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotIcon\n })\n })\n })]\n })]\n })\n })\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Chatbot);\n\n//# sourceURL=webpack://VamChatbot/./Chatbot.jsx?");
|
|
29
|
+
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/components/LazyMotion/index.mjs\");\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/render/dom/features-animation.mjs\");\n/* harmony import */ var framer_motion__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! framer-motion */ \"./node_modules/framer-motion/dist/es/render/components/m/proxy.mjs\");\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var react_use_websocket__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-use-websocket */ \"./node_modules/react-use-websocket/dist/index.js\");\n/* harmony import */ var _components_ChatbotHeader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/ChatbotHeader */ \"./components/ChatbotHeader.jsx\");\n/* harmony import */ var _components_ChatbotBody__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/ChatbotBody */ \"./components/ChatbotBody.jsx\");\n/* harmony import */ var _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Chatbot.module.css */ \"./Chatbot.module.css\");\n/* harmony import */ var _utils_variants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/variants */ \"./utils/variants.js\");\n/* harmony import */ var _utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/websocketHandlers */ \"./utils/websocketHandlers.js\");\n/* harmony import */ var _utils_useClickHandler__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils/useClickHandler */ \"./utils/useClickHandler.js\");\n/* harmony import */ var _utils_defaults__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils/defaults */ \"./utils/defaults.js\");\n/* harmony import */ var _utils_config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/config */ \"./utils/config.js\");\n/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react/jsx-runtime */ \"./node_modules/react/jsx-runtime.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n/* \n- valid chatbot states:\n 0: \"at rest\",\n 1: \"waiting for response from api\"\n 2: \"receiving response from api\"\n*/\n\nconst fixSpecialLLMChars = text => {\n // forward slash is replaced by <|slash|> in the response from the api\n return text.replace(/\\u003c\\|slash\\|\\u003e/g, \"/\");\n};\nfunction Chatbot(_ref) {\n let {\n clientId,\n onTrackEvent\n } = _ref;\n const [messageList, setMessageList] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);\n const [inputText, setInputText] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(\"\");\n const [chatbotState, setChatbotState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);\n const [chatbotMinimized, setChatbotMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n const [chatbotPopupMinimized, setChatbotPopupMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);\n const [promptsData, setPromptsData] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({\n show: true,\n prompts: []\n });\n const [promptsMinimized, setPromptsMinimized] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);\n const [shouldConnectWebsocket, setShouldConnectWebsocket] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);\n const [chatbotConfig, setChatbotConfig] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({\n fetchedData: false,\n data: {}\n });\n const [chatbotIcon, setChatbotIcon] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);\n const defaultMessageList = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);\n const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n const scrollAnchorRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n const chatbotRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);\n\n // Use the custom hook to track clicks\n (0,_utils_useClickHandler__WEBPACK_IMPORTED_MODULE_7__[\"default\"])(onTrackEvent, chatbotRef);\n\n // use effect to upate the css variables once available through the chatbot config API\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n try {\n if (chatbotConfig?.data?.styles?.css_variables) {\n // escape special characters with backslash\n // since query selctor does not allow special characters\n let chatbotParent = document?.querySelector(\"vam-chatbot\")?.shadowRoot.querySelector(`.${_Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent.replace(/([^\\w-])/g, \"\\\\$1\")}`) || document?.querySelector(`.${_Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent.replace(/([^\\w-])/g, \"\\\\$1\")}`);\n for (let variable in chatbotConfig.data.styles.css_variables) {\n chatbotParent.style.setProperty(`--${variable}`, chatbotConfig.data.styles.css_variables[variable]);\n }\n }\n } catch (error) {\n console.log(error);\n }\n }, [chatbotConfig?.data?.styles?.css_variables]);\n\n // useeffect to store the chatbot icon when its url is fetched from the chatbot config API\n // this is to prevent the api call being made on render of every message\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n try {\n if (chatbotConfig?.data?.icon_url) {\n const fetchChatbotIcon = async () => {\n let url = chatbotConfig?.data?.icon_url;\n let apiResponse = await (0,axios__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n url,\n method: \"GET\",\n responseType: \"blob\"\n });\n let imageBlob = apiResponse.data;\n if (imageBlob) {\n let imageObjectURL = URL.createObjectURL(imageBlob);\n setChatbotIcon(imageObjectURL);\n }\n };\n fetchChatbotIcon();\n }\n } catch (error) {\n console.log(error);\n }\n }, [chatbotConfig?.data?.icon_url]);\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n const fetchConfigData = async () => {\n // Check if configUrl is null and handle appropriately\n if (!_utils_config__WEBPACK_IMPORTED_MODULE_9__.configUrl) {\n console.error(\"Chatbot config URL is not set. Please provide CHATBOT_DEV_URL or CHATBOT_PROD_URL environment variables.\");\n return;\n }\n const url = `${_utils_config__WEBPACK_IMPORTED_MODULE_9__.configUrl}/api/getBotConfig`;\n const method = \"POST\";\n const requestBody = {\n clientId\n };\n try {\n let apiResponse = await (0,axios__WEBPACK_IMPORTED_MODULE_11__[\"default\"])({\n url,\n method,\n data: requestBody\n });\n if (apiResponse?.data) {\n let data = apiResponse.data;\n setChatbotConfig({\n fetchedData: true,\n data\n });\n setPromptsData(data?.default_prompts || {\n show: false,\n prompts: []\n });\n setMessageList(data?.default_message_list || []);\n defaultMessageList.current = data?.default_message_list || [];\n } else {\n // handle no data here\n console.log(\"no data found for the provided client id: \", clientId);\n }\n } catch (e) {\n console.error(e);\n // handle api failure here\n }\n };\n fetchConfigData();\n }, [clientId]);\n let websocket = (0,react_use_websocket__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(chatbotConfig?.data?.websocket_url, {\n onOpen: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnOpen)(event),\n onClose: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnClose)(event, chatbotMinimized, setShouldConnectWebsocket),\n // onReconnectStop:\n onMessage: event => (0,_utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnMessage)(event, handleWebsocketResponse),\n onError: _utils_websocketHandlers__WEBPACK_IMPORTED_MODULE_6__.handleWebsocketOnError,\n shouldReconnect: closeEvent => !chatbotMinimized,\n // only attempt reconnection when the chatbot is maximized\n heartbeat: {\n message: JSON.stringify({\n action: \"heartbeat\",\n data: \"ping\"\n }),\n returnMessage: \"pong\",\n // to prevent re-rendering the component\n timeout: 9000,\n interval: 6000\n }\n }, shouldConnectWebsocket // handle the connection of the websocket using this variable\n );\n\n // scroll to the latest message whenever the message list updates\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n scrollAnchorRef.current?.scrollIntoView({\n behavior: \"smooth\",\n block: \"end\",\n inline: \"nearest\"\n });\n }, [messageList]);\n\n // set the chatbot connection to \"true\" when the chatbot is maximized\n (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {\n if (!chatbotMinimized) {\n setShouldConnectWebsocket(true);\n }\n }, [chatbotMinimized]);\n const handleWebsocketResponse = event => {\n try {\n try {\n event = JSON.parse(event.data);\n } catch (error) {}\n let {\n status,\n data\n } = event || {};\n let {\n response,\n sources,\n image_links,\n promoted_topics\n } = data || {};\n if (status === \"streaming\") {\n // set the chatbot state to \"receiving response\" and initialize the response\n setChatbotState(2);\n if (response) {\n setMessageList(prevList => {\n let responseList = [...prevList];\n try {\n let latestMessage = prevList.slice(-1)[0];\n if (latestMessage?.status === \"streaming\") {\n latestMessage.data.text = fixSpecialLLMChars(response);\n } else {\n let responseMessage = {\n source: \"bot\",\n data: {\n text: response\n },\n origin: \"server\",\n status: \"streaming\"\n };\n responseList = [...responseList, responseMessage];\n }\n } catch (error) {}\n return responseList;\n });\n }\n } else if (status === \"done\") {\n setChatbotState(0);\n\n // update the status as done for the last message\n setMessageList(prevList => {\n let responseList = [...prevList];\n try {\n let latestMessage = responseList.slice(-1)[0];\n if (latestMessage?.source !== \"user\") {\n latestMessage.status = \"done\";\n latestMessage.data.text = fixSpecialLLMChars(response);\n latestMessage.data.sources = sources?.map(fixSpecialLLMChars);\n if (promoted_topics) {\n const promotedImageLinks = promoted_topics.map(pt => pt?.image_link)?.filter(Boolean)?.map(fixSpecialLLMChars);\n latestMessage.data.image_links = promotedImageLinks?.length > 0 ? promotedImageLinks : image_links?.map(fixSpecialLLMChars);\n latestMessage.data.promoted_topics = promoted_topics?.filter(item => item?.title);\n }\n } else {\n let responseMessage = {\n source: \"bot\",\n data: {\n text: _utils_defaults__WEBPACK_IMPORTED_MODULE_8__.errorResponse\n },\n origin: \"server\",\n status: \"done\"\n };\n responseList = [...responseList, responseMessage];\n }\n } catch (error) {}\n return responseList;\n });\n }\n } catch (error) {}\n };\n\n // to keep the input field in focus and scroll to the latest message\n // when the enter button is clicked.\n // const focusInput = () => {\n // inputRef.current.focus();\n // };\n\n // to handle the minimize/maximize animation of the chatbot.\n const handleChatbotAnimation = () => {\n setChatbotMinimized(!chatbotMinimized);\n };\n\n // to reset the chatbot content.\n const resetChatbot = () => {\n try {\n forceConnectWebsocket();\n setMessageList(defaultMessageList.current);\n setPromptsData(prevData => {\n return {\n ...prevData,\n show: true\n };\n });\n setChatbotState(0);\n } catch (error) {}\n };\n const handleInput = event => {\n try {\n setInputText(event.target.value);\n } catch (error) {}\n };\n const getChatHistory = () => {\n let response = [];\n try {\n let historyItem = {\n user: \"\",\n assistant: \"\"\n };\n for (let message of messageList) {\n if (message.source === \"user\") {\n historyItem.user = message?.data?.text;\n } else if (message.source === \"bot\" && message.origin === \"server\") {\n historyItem.assistant = message?.data?.text;\n response.push(historyItem);\n historyItem = {\n user: \"\",\n assistant: \"\"\n };\n }\n }\n } catch (error) {\n console.log(error);\n } finally {\n return response;\n }\n };\n\n // try to connect the websocket connection by force by setting its flag to false and true\n const forceConnectWebsocket = () => {\n setShouldConnectWebsocket(false); // set state to false\n setTimeout(() => {\n setShouldConnectWebsocket(true); // set state back to true after a short delay\n }, 500);\n };\n const handleSubmit = async function () {\n let prompt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : \"\";\n let typewriterEffect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n if (!prompt) {\n prompt = inputText;\n } else {\n typewriterEffect = true;\n }\n try {\n prompt = prompt.trim();\n if (prompt) {\n // force reconnect the websocket if it belongs to either of the following states: [-1, 2, 3]\n if ([-1, 2, 3].includes(websocket?.readyState)) {\n forceConnectWebsocket();\n }\n setChatbotState(1);\n\n // put the user's prompt in the chat\n let userMessage = {\n source: \"user\",\n data: {\n text: prompt\n },\n status: \"done\",\n typewriterEffect\n };\n setMessageList(prevList => [...prevList, userMessage]);\n\n // hide the default prompts\n setPromptsData({\n ...promptsData,\n show: false\n });\n\n // clear the input field\n setInputText(\"\");\n\n // prepare the chat history\n let chatHistory = getChatHistory();\n\n // send the user's query to the webhook\n websocket.sendJsonMessage({\n action: \"message\",\n data: {\n message: prompt,\n chatHistory,\n clientId\n }\n });\n }\n } catch (error) {\n // responseMessage = {\n // source: \"error\",\n // text: \"An error occured.\",\n // };\n console.log(error);\n }\n };\n return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.Fragment, {\n children: chatbotConfig?.fetchedData && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotParent,\n ref: chatbotRef,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_12__.LazyMotion, {\n features: framer_motion__WEBPACK_IMPORTED_MODULE_13__.domAnimation,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n initial: false,\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotContainer,\n animate: chatbotMinimized ? \"hide\" : \"show\",\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.maximizedChatbotVariants,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_components_ChatbotHeader__WEBPACK_IMPORTED_MODULE_2__[\"default\"], {\n headerText: chatbotConfig?.data?.header_text,\n setPromptsMinimized: setPromptsMinimized,\n handleChatbotAnimation: handleChatbotAnimation,\n resetChatbot: resetChatbot\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(_components_ChatbotBody__WEBPACK_IMPORTED_MODULE_3__[\"default\"], {\n messageList: messageList,\n promptsData: promptsData,\n handleSubmit: handleSubmit,\n chatbotState: chatbotState,\n scrollAnchorRef: scrollAnchorRef,\n promptsMinimized: promptsMinimized,\n setPromptsMinimized: setPromptsMinimized,\n inputRef: inputRef,\n inputText: inputText,\n handleInput: handleInput,\n placeholderInputText: chatbotConfig?.data?.placeholder_input_text,\n chatbotIcon: chatbotIcon\n })]\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotVariants,\n animate: chatbotMinimized ? \"show\" : \"hide\",\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotCircleContainer,\n children: [!chatbotPopupMinimized && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxs)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popupContainer,\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotContentVariants,\n children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"button\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].closePopup,\n onClick: () => setChatbotPopupMinimized(true),\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"i\", {\n className: \"bi bi-x-circle-fill\"\n })\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popup,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].popupContent,\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"span\", {\n children: chatbotConfig?.data?.popup_body_text\n })\n })\n })]\n }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(framer_motion__WEBPACK_IMPORTED_MODULE_14__.m.div, {\n variants: _utils_variants__WEBPACK_IMPORTED_MODULE_5__.minimizedChatbotContentVariants,\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotCircle,\n onClick: handleChatbotAnimation,\n children: chatbotIcon && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"div\", {\n children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_10__.jsx)(\"img\", {\n src: chatbotIcon,\n loading: \"lazy\",\n alt: \"chatbot icon\",\n className: _Chatbot_module_css__WEBPACK_IMPORTED_MODULE_4__[\"default\"].chatbotIcon\n })\n })\n })]\n })]\n })\n })\n });\n}\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Chatbot);\n\n//# sourceURL=webpack://VamChatbot/./Chatbot.jsx?");
|
|
30
30
|
|
|
31
31
|
/***/ }),
|
|
32
32
|
|
package/package.json
CHANGED