Skip to content

Commit

Permalink
Merge pull request #33 from memori-ai/feat_upload_documents
Browse files Browse the repository at this point in the history
Feat upload documents
  • Loading branch information
nzambello authored Dec 20, 2024
2 parents 7e32f25 + 532e419 commit 63e86a0
Show file tree
Hide file tree
Showing 27 changed files with 1,103 additions and 89 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const App = () => (
| `showLogin` | | `bool` | `true` | Show the login button |
| `showClear` | | `bool` | `false` | Show clear chat history button |
| `showOnlyLastMessages` | | `bool` | `true` or `false` \* | Show only last 2 messages. (\*) Defaults to `true` for `TOTEM` and `WEBSITE_ASSISTANT` layouts, `false` otherwise |
| `showUpload` | | `bool` | `true` | Show the upload button within the chat |
| `baseURL` | | `string` | | Base URL of the Memori, example: "https://aisuru.com" |
| `apiURL` | | `string` | "https://backend.memori.ai" | URL of the Memori Backend API |
| `engineURL` | | `string` | "https://engine.memori.ai" | URL of the Memori Engine API |
Expand All @@ -90,7 +91,7 @@ const App = () => (
| `disableTextEnteredEvents` | | `boolean` | `false` | Disable MemoriTextEntered events listeners for `typeMessage` functions, useful to avoid issues with multiple widgets in page. |
| `useMathFormatting` | | `boolean` | `false` | Apply math formatting to the messages, defaults to false if otherwise indicated by props or integration config. |
| `AZURE_COGNITIVE_SERVICES_TTS_KEY` | | `string` | | Azure Cognitive Services TTS key, used to generate the audio of the Memori and for STT recognition |
| `layout` | | `string` | | Layout of the Memori, can be "FULLPAGE" (default), "CHAT", "WEBSITE_ASSISTANT", "TOTEM", "HIDDEN_CHAT" or "ZOOMED_FULL_BODY". see [below](#layouts) |
| `layout` | | `string` | | Layout of the Memori, can be "FULLPAGE" (default), "CHAT", "WEBSITE_ASSISTANT", "TOTEM", "HIDDEN_CHAT" or "ZOOMED_FULL_BODY". see [below](#layouts) |
| `customLayout` | | `React.FC<LayoutProps>` | | Custom layout component, see [below](#custom-layout) |
| `customMediaRenderer` | | `(mimeType: string) => JSX.Element \| null` | | Custom media renderer, see [below](#custom-media-renderer) |
| `additionalSettings` | | `JSX.Element` | | Custom JSX or component to render within the settings drawer |
Expand Down
12 changes: 12 additions & 0 deletions __mocks__/convertapi-js.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const ConvertApi = {
auth: jest.fn(() => ({
createParams: jest.fn(() => ({
add: jest.fn()
})),
convert: jest.fn(() => Promise.resolve({
files: [{ Url: 'mock-url' }]
}))
}))
};

export default ConvertApi;
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ module.exports = {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
uuid: require.resolve('uuid'),
'@react-leaflet/core': require.resolve('./__mocks__/react-leaflet-core.js'),
'convertapi-js': require.resolve('./__mocks__/convertapi-js.js'),
},
transformIgnorePatterns: [
'/node_modules/([email protected]/memori-api-client)',
'/node_modules/(?!microsoft-cognitiveservices-speech-sdk)',
'/node_modules/(?!uuid)',
'/node_modules/(?!@react-leaflet/core)',
'/node_modules/(?!(convertapi-js|convertapi-js-node)/)',
],
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
"@react-three/drei": "8.20.2",
"@react-three/fiber": "7.0.25",
"classnames": "2.5.1",
"convertapi-js": "^1.0.8",
"dompurify": "^3.2.1",
"ellipsed": "1.6.0",
"i18next": "22.0.6",
Expand Down
26 changes: 16 additions & 10 deletions src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export interface Props {
pushMessage: (message: Message) => void;
simulateUserPrompt: (text: string, translatedText?: string) => void;
showDates?: boolean;
showUpload?: boolean;
showContextPerLine?: boolean;
showAIicon?: boolean;
showTranslationOriginal?: boolean;
Expand All @@ -56,7 +57,16 @@ export interface Props {
showMicrophone?: boolean;
userMessage?: string;
onChangeUserMessage: (userMessage: string) => void;
sendMessage: (msg: string) => void;
sendMessage: (
msg: string,
media?: {
mediumID: string;
mimeType: string;
content: string;
title?: string;
properties?: { [key: string]: any };
}
) => void;
listening?: boolean;
setEnableFocusChatInput: (enableFocusChatInput: boolean) => void;
isPlayingAudio?: boolean;
Expand Down Expand Up @@ -115,6 +125,7 @@ const Chat: React.FC<Props> = ({
customMediaRenderer,
user,
userAvatar,
showUpload = false,
experts,
useMathFormatting = false,
}) => {
Expand Down Expand Up @@ -162,14 +173,6 @@ const Chat: React.FC<Props> = ({
scrollToBottom();
}
};
const onTextareaPressEnter = () => {
if (sendOnEnter === 'keypress' && userMessage?.length > 0) {
stopListening();
sendMessage(userMessage);
onChangeUserMessage('');
resetTranscript();
}
};

return (
<div
Expand Down Expand Up @@ -233,6 +236,7 @@ const Chat: React.FC<Props> = ({
showCopyButton={showCopyButton}
useMathFormatting={useMathFormatting}
/>

{showDates && !!message.timestamp && (
<small
className={`memori-chat--timestamp ${
Expand All @@ -252,6 +256,7 @@ const Chat: React.FC<Props> = ({
)}
</small>
)}

{showContextPerLine &&
!!Object.keys(message.contextVars ?? {}).length && (
<div className="memori-chat--context-vars">
Expand Down Expand Up @@ -363,6 +368,7 @@ const Chat: React.FC<Props> = ({

{showInputs && (
<ChatInputs
resetTranscript={resetTranscript}
userMessage={userMessage}
onChangeUserMessage={onChangeUserMessage}
dialogState={dialogState}
Expand All @@ -372,9 +378,9 @@ const Chat: React.FC<Props> = ({
microphoneMode={microphoneMode}
sendOnEnter={sendOnEnter}
setSendOnEnter={setSendOnEnter}
showUpload={showUpload}
attachmentsMenuOpen={attachmentsMenuOpen}
setAttachmentsMenuOpen={setAttachmentsMenuOpen}
onTextareaPressEnter={onTextareaPressEnter}
onTextareaFocus={onTextareaFocus}
onTextareaBlur={onTextareaBlur}
startListening={startListening}
Expand Down
20 changes: 20 additions & 0 deletions src/components/ChatBubble/ChatBubble.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Copy from '../icons/Copy';
import Code from '../icons/Code';
import WhyThisAnswer from '../WhyThisAnswer/WhyThisAnswer';
import { cleanUrl, stripHTML, stripOutputTags } from '../../helpers/utils';
import FilePreview from '../FilePreview/FilePreview';

import markedLinkifyIt from 'marked-linkify-it';
import markedKatex from 'marked-katex-extension';
Expand Down Expand Up @@ -266,6 +267,7 @@ const ChatBubble: React.FC<Props> = ({
})
}
onError={e => {
// Fallback image handling if primary source fails
e.currentTarget.src =
memori.avatarURL && memori.avatarURL.length > 0
? getResourceUrl({
Expand All @@ -285,6 +287,7 @@ const ChatBubble: React.FC<Props> = ({
/>
</Transition.Child>
)}

<Transition.Child
as="div"
className={cx('memori-chat--bubble', {
Expand Down Expand Up @@ -312,6 +315,7 @@ const ChatBubble: React.FC<Props> = ({
className="memori-chat--bubble-content"
dangerouslySetInnerHTML={{ __html: renderedText }}
/>

{((!message.fromUser && showCopyButton) ||
(message.generatedByAI && showAIicon) ||
(showFeedback && simulateUserPrompt)) && (
Expand All @@ -326,6 +330,7 @@ const ChatBubble: React.FC<Props> = ({
onClick={() => navigator.clipboard.writeText(plainText)}
/>
)}

{!message.fromUser &&
showCopyButton &&
plainText !== message.text && (
Expand Down Expand Up @@ -402,6 +407,21 @@ const ChatBubble: React.FC<Props> = ({
)}
</div>
)}

{message.fromUser &&
message.media?.length &&
message.media[0].properties?.isAttachedFile && (
<FilePreview
previewFiles={message.media.map(m => ({
name: m.title ?? '',
id: m.mediumID,
content: m.content ?? '',
}))}
removeFile={() => {}}
allowRemove={false}
isMessagePreview={true}
/>
)}
</Transition.Child>

{message.fromUser && (
Expand Down
5 changes: 5 additions & 0 deletions src/components/ChatInputs/ChatInputs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ ContinuousSpeechListening.args = {
microphoneMode: 'CONTINUOUS',
};

export const WithUploadButton = Template.bind({});
WithUploadButton.args = {
showUpload: true,
};

export const WithoutMicrophone = Template.bind({});
WithoutMicrophone.args = {
dialogState,
Expand Down
12 changes: 6 additions & 6 deletions src/components/ChatInputs/ChatInputs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ it('renders ChatInputs unchanged', () => {
userMessage=""
onChangeUserMessage={jest.fn()}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -20,6 +19,7 @@ it('renders ChatInputs unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={true}
/>
);
Expand All @@ -33,7 +33,6 @@ it('renders ChatInputs with user message unchanged', () => {
onChangeUserMessage={jest.fn()}
dialogState={dialogState}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -43,6 +42,7 @@ it('renders ChatInputs with user message unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={true}
/>
);
Expand All @@ -59,7 +59,6 @@ it('renders ChatInputs on instruct unchanged', () => {
acceptsMedia: true,
}}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -70,6 +69,7 @@ it('renders ChatInputs on instruct unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={true}
/>
);
Expand All @@ -83,7 +83,6 @@ it('renders ChatInputs listening unchanged', () => {
onChangeUserMessage={jest.fn()}
dialogState={dialogState}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -93,6 +92,7 @@ it('renders ChatInputs listening unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={true}
/>
);
Expand All @@ -106,7 +106,6 @@ it('renders ChatInputs without microphone button unchanged', () => {
onChangeUserMessage={jest.fn()}
dialogState={dialogState}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -116,6 +115,7 @@ it('renders ChatInputs without microphone button unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={false}
/>
);
Expand All @@ -132,7 +132,6 @@ it('renders ChatInputs disabled unchanged', () => {
state: 'X3',
}}
sendMessage={jest.fn()}
onTextareaPressEnter={jest.fn()}
onTextareaFocus={jest.fn()}
onTextareaBlur={jest.fn()}
setAttachmentsMenuOpen={jest.fn()}
Expand All @@ -142,6 +141,7 @@ it('renders ChatInputs disabled unchanged', () => {
stopAudio={jest.fn()}
startListening={jest.fn()}
stopListening={jest.fn()}
resetTranscript={jest.fn()}
showMicrophone={true}
/>
);
Expand Down
Loading

0 comments on commit 63e86a0

Please sign in to comment.