{"version":3,"file":"ChatContainer.mjs","names":["React","useState","useEffect","useRef","useCallback","AmbientTextField","FluentButton","useUser","ChatMessage","Link","Typography","makeStyles","apiMutate","useChatBot","useTranslation","useSnackbar","ConfigService","useStyles","theme","loadingContainer","display","fontSize","pulseEllipsis","animation","animationDelay","transform","opacity","ChatContainer","props","classes","console","warn","messageHistory","addMessage","removeMessageHistory","removeLoadingMessage","user","newMessageContent","setNewMessageContent","messageEndRef","productId","config","UNITY_PRODUCT_ID","aiSearchUrl","AI_SEARCH_URL","aiSearchIndexName","AI_SEARCH_INDEX_NAME","aiSearchKey","AI_SEARCH_KEY","udpAiApiBase","UDPAI_API_BASE","enqueueSnackbar","t","youName","defaultValue","aiAssistantName","handleSendMessage","name","addLoadingMessage","sendMessage","error","handleNewSession","variant","anchorOrigin","vertical","horizontal","messageContent","loading","current","scrollIntoView","behavior","formatCitations","citations","map","citation","url","whiteSpace","title","parseAiResponse","response","gptResponseMessage","data","LLMResponse","choices","message","messageText","content","context","showCitations","toString","includes","textContent","replaceAll","responseMessage","wordWrap","length","e","errorMessage","executeQuery","aiModelId","method","headers","currentProductId","messageHistoryTextArray","item","role","createdBy","body","modelName","useCache","payload","max_tokens","temperature","n","presence_penalty","messages","data_sources","type","parameters","endpoint","semantic_configuration","query_type","in_scope","strictness","top_n_documents","authentication","key","index_name","filter","aiResponse","flexDirection","height","gap","padding","overflowY","flexGrow","index","marginTop","position","bottom","zIndex","background","target","value","shiftKey","preventDefault"],"sources":["../../src/chatBot/ChatContainer.jsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { AmbientTextField } from '../UI/inputs/textField/AmbientTextField';\nimport { FluentButton } from '../UI/inputs/buttons/FluentButton';\nimport { useUser } from '../utilities/auth/useUser';\nimport { ChatMessage } from './ChatMessage';\nimport { Link, Typography } from '@material-ui/core';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { apiMutate } from '../utilities/useAxiosMutate';\nimport { useChatBot } from '../utilities/chatBot/useChatBot';\nimport { useTranslation } from 'react-i18next';\nimport { useSnackbar } from 'notistack';\nimport { ConfigService } from '../configService';\n\nconst useStyles = makeStyles((theme) => ({\n  loadingContainer: {\n    display: 'inline-block',\n    fontSize: '2em', // Adjust the font size to make the whole section bigger\n  },\n  pulseEllipsis: {\n    display: 'inline-block',\n    animation: '$pulse 1.5s infinite',\n    '&:nth-of-type(2)': {\n      animationDelay: '0.5s',\n    },\n    '&:nth-of-type(3)': {\n      animationDelay: '1s',\n    },\n  },\n  '@keyframes pulse': {\n    '0%': {\n      transform: 'scale(1)',\n      opacity: 0.6,\n    },\n    '50%': {\n      transform: 'scale(1.2)',\n      opacity: 1,\n    },\n    '100%': {\n      transform: 'scale(1)',\n      opacity: 0.6,\n    },\n  },\n}));\n\n\n/**\n * @deprecated This component is deprecated and will be removed in a future version.\n * Use `UdpAiAssistant` instead.\n */\nexport const ChatContainer = (props) => {\n  const classes = useStyles();\n\n  useEffect(() => {\n    console.warn(\n      'The \"ChatContainer\" component is deprecated and will be removed in a future version. ' +\n      'Use \"UdpAiAssistant\" instead.'\n    );\n  }, []);\n\n  const { messageHistory, addMessage, removeMessageHistory, removeLoadingMessage } = useChatBot()\n  const user = useUser();\n  const [newMessageContent, setNewMessageContent] = useState('');\n  const messageEndRef = useRef(null);\n  const productId = ConfigService.config.UNITY_PRODUCT_ID;\n  const aiSearchUrl = ConfigService.config.AI_SEARCH_URL;\n  const aiSearchIndexName = ConfigService.config.AI_SEARCH_INDEX_NAME;\n  const aiSearchKey = ConfigService.config.AI_SEARCH_KEY;\n  const udpAiApiBase = ConfigService.config.UDPAI_API_BASE;\n  const { enqueueSnackbar } = useSnackbar();\n  const { t } = useTranslation();\n  const youName = t('chatBot.sender.you', { defaultValue: 'You' });\n  const aiAssistantName = t('chatBot.sender.aiAssistant', {\n    defaultValue: 'AI Assistant'\n  });\n\n  const handleSendMessage = async () => {\n    addMessage(newMessageContent, { ...user, name: youName }, newMessageContent);\n    setNewMessageContent('');\n    addLoadingMessage();\n\n    try {\n      await sendMessage(newMessageContent, addMessage);\n      removeLoadingMessage();\n    } catch (error) {\n      console.error('Error sending message:', error);\n    }\n  };\n\n  const handleNewSession = async () => {\n    try {\n      await removeMessageHistory();\n      enqueueSnackbar(t('chatBot.session.cleared', { defaultValue: 'Chat Session Cleared' }), {\n        variant: 'success',\n        anchorOrigin: {\n          vertical: 'top',\n          horizontal: 'center',\n        }\n      });\n    } catch (error) {\n      console.error('Error create new chat session:', error);\n    }\n  }\n\n  const addLoadingMessage = () => {\n    const messageContent = (\n      <div className={classes.loadingContainer}>\n        <span className={classes.pulseEllipsis}>.</span>\n        <span className={classes.pulseEllipsis}>.</span>\n        <span className={classes.pulseEllipsis}>.</span>\n      </div>\n    );\n    addMessage(messageContent, { name: aiAssistantName, loading: true }, \"\");\n  };\n\n\n  useEffect(() => {\n    messageEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n  }, [messageHistory]);\n\n\n  const formatCitations = (citations) => {\n    return (\n      <div>\n        <ol>\n          {citations.map((citation) => {\n            return (\n              <li key={citation.url}>\n                <Link href={citation.url} target='_blank' rel='noopener'>\n                  <Typography variant='body2' style={{ whiteSpace: 'pre-line' }}>\n                    {citation.title}\n                  </Typography>\n                </Link>\n              </li>\n            );\n          })}\n        </ol>\n      </div>\n    );\n  };\n\n  const parseAiResponse = (response, addMessage) => {\n    try {\n      const gptResponseMessage = response.data.LLMResponse.choices[0].message;\n      const messageText = gptResponseMessage.content;\n      const citations = gptResponseMessage.context.citations;\n      const showCitations = messageText.toString().includes('[doc');\n      const textContent = messageText.toString().replaceAll('[doc', '[');\n\n      const responseMessage = (\n        <div>\n          <div style={{ wordWrap: 'break-word' }}>\n            <Typography variant='body2' style={{ whiteSpace: 'pre-line' }}>\n              {textContent}\n            </Typography>\n          </div>\n          {citations.length > 0 && showCitations && (\n            <div>\n              <br />\n              <Typography variant='body2' style={{ whiteSpace: 'pre-line' }}>\n                {t('chatBot.citations.referTo', {\n                  defaultValue: 'Refer to the XWiki documents for more info:'\n                })}\n              </Typography>\n              {formatCitations(citations)}\n            </div>\n          )}\n        </div>\n      );\n      addMessage(responseMessage, { name: aiAssistantName }, textContent);\n    } catch (e) {\n      const errorMessage = t('chatBot.errors.generic', {\n        defaultValue: 'Sorry, an error has occurred.'\n      });\n      addMessage(errorMessage, { name: aiAssistantName }, errorMessage);\n    }\n\n  };\n\n  const executeQuery = useCallback(\n    async (data, aiModelId) =>\n      apiMutate(\n        udpAiApiBase,\n        `aiservice/llm`,\n        {\n          method: 'post',\n          headers: {\n            currentProductId: productId, //temporary bypass -> //currentProductId: '1'\n          }\n        },\n        data\n      ),\n    [productId, udpAiApiBase]\n  );\n\n\n\n  const sendMessage = async (newMessageContent, addMessage) => {\n    const messageHistoryTextArray = messageHistory\n      .map(item => ({\n        role: item.createdBy.name === aiAssistantName ? 'assistant' : item.createdBy.name === youName ? 'user' : item.createdBy.name,\n        content: item.messageText\n      }));\n\n    const body = {\n      modelName: 'gpt-4o',\n      useCache: 'false',\n      payload: {\n        max_tokens: 4096,\n        temperature: 0.5,\n        n: 1,\n        presence_penalty: 0,\n        messages: [\n          {\n            role: 'system',\n            content:\n              'You are an assistant helping a user using existing knowledge supplemented by additional data.'\n          },\n          ...messageHistoryTextArray,\n          {\n            role: 'user',\n            content: newMessageContent\n          }\n        ],\n        data_sources: [\n          {\n            type: 'azure_search',\n            parameters: {\n              endpoint: aiSearchUrl,\n              // set sematic configuration name to match index name\n              semantic_configuration: aiSearchIndexName,\n              query_type: \"semantic\",\n              in_scope: false,\n              //role_information: \"You are an AI search assistant having access to wiki documentation data. Please be helpful to the user answer any questions to the best of your ability.\",\n              strictness: 1,\n              top_n_documents: 5,\n              authentication: {\n                type: 'api_key',\n                key: aiSearchKey\n              },\n              index_name: aiSearchIndexName,\n              filter: `Products/any(p: p eq '${productId}')`\n            }\n          }\n        ]\n      }\n    };\n\n    const aiResponse = await executeQuery({ data: body });\n    parseAiResponse(aiResponse, addMessage);\n  }\n\n\n  return (\n    <div style={{ display: 'flex', flexDirection: 'column', height: '100%'}}>\n      <FluentButton id='udpRecord-ChatContainer-NewSession' onClick={handleNewSession}>\n        {t('chatBot.actions.clearChat', { defaultValue: 'Clear Chat' })}\n      </FluentButton>\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '10px',\n          padding: '3px',\n          height: '100%',\n          overflowY: 'auto',\n          flexGrow: 1\n        }}\n      >\n        {messageHistory.map((message, index) => (\n          <ChatMessage key={index} message={message} />\n        ))}\n        <div ref={messageEndRef} />\n      </div>\n      <div style={{ display: 'flex', flexDirection: 'column', marginTop: '5px', position: 'sticky', bottom: 0, padding: '3px', zIndex: 1, background: 'white' }}>\n        <div style={{ flexGrow: 1 }}>\n          <AmbientTextField\n            id='udpRecord-ChatContainer-Enter'\n            multiline\n            value={newMessageContent}\n            onChange={(e) => setNewMessageContent(e.target.value)}\n            onKeyDown={(e) => {\n              if (e.key === 'Enter' && !e.shiftKey) {\n                e.preventDefault();\n                handleSendMessage();\n              }\n            }}\n          />\n        </div>\n        <FluentButton\n          id='udpRecord-ChatContainer-Send'\n          onClick={handleSendMessage}\n          autoFocus\n          variant='outlined'\n        >\n          {t('common.send', { defaultValue: 'Send' })}\n        </FluentButton>\n      </div>\n    </div>\n  );\n};\n"],"mappings":"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"}