@memori.ai/memori-react 9.0.0-rc.0 → 9.0.0-rc.2
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/CHANGELOG.md +36 -0
- package/README.md +430 -171
- package/dist/components/Auth/Auth.js +2 -1
- package/dist/components/Auth/Auth.js.map +1 -1
- package/dist/components/ChatBubble/ChatBubble.css +262 -11
- package/dist/components/ChatBubble/ChatBubble.js +25 -20
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatHistory.css +22 -1
- package/dist/components/ChatHistoryDrawer/ChatHistory.js +10 -4
- package/dist/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/dist/components/ContentPreviewModal/ContentPreviewModal.css +1 -1
- package/dist/components/FilePreview/FilePreview.css +1 -0
- package/dist/components/Header/Header.css +55 -4
- package/dist/components/Header/Header.js +12 -3
- package/dist/components/Header/Header.js.map +1 -1
- package/dist/components/KnownFacts/KnownFacts.css +20 -5
- package/dist/components/KnownFacts/KnownFacts.js +1 -1
- package/dist/components/KnownFacts/KnownFacts.js.map +1 -1
- package/dist/components/LoginModal/LoginModal.css +270 -0
- package/{esm/components/LoginDrawer/LoginDrawer.d.ts → dist/components/LoginModal/LoginModal.d.ts} +4 -3
- package/dist/components/LoginModal/LoginModal.js +355 -0
- package/dist/components/LoginModal/LoginModal.js.map +1 -0
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/components/TabSwitch.css +2 -2
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +1 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +6 -1
- package/dist/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +1 -0
- package/dist/components/MemoriWidget/MemoriWidget.js +10 -5
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/Snippet/Snippet.js +7 -40
- package/dist/components/Snippet/Snippet.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.css +3 -2
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js +4 -3
- package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/website-assistant.css +54 -8
- package/dist/components/layouts/fullpage.css +4 -4
- package/dist/components/layouts/hidden-chat.css +1 -0
- package/dist/components/layouts/zoomed-full-body.css +4 -4
- package/dist/helpers/enhanceBubbleCodeBlocks.d.ts +5 -0
- package/dist/helpers/enhanceBubbleCodeBlocks.js +97 -0
- package/dist/helpers/enhanceBubbleCodeBlocks.js.map +1 -0
- package/dist/helpers/message.js +1 -0
- package/dist/helpers/message.js.map +1 -1
- package/dist/helpers/prism.d.ts +16 -0
- package/dist/helpers/prism.js +78 -0
- package/dist/helpers/prism.js.map +1 -0
- package/dist/locales/de.json +12 -0
- package/dist/locales/en.json +15 -4
- package/dist/locales/es.json +12 -2
- package/dist/locales/fr.json +11 -1
- package/dist/locales/it.json +13 -2
- package/dist/styles.css +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/Auth/Auth.js +2 -1
- package/esm/components/Auth/Auth.js.map +1 -1
- package/esm/components/ChatBubble/ChatBubble.css +262 -11
- package/esm/components/ChatBubble/ChatBubble.js +26 -21
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/ChatHistoryDrawer/ChatHistory.css +22 -1
- package/esm/components/ChatHistoryDrawer/ChatHistory.js +10 -4
- package/esm/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/esm/components/ContentPreviewModal/ContentPreviewModal.css +1 -1
- package/esm/components/FilePreview/FilePreview.css +1 -0
- package/esm/components/Header/Header.css +55 -4
- package/esm/components/Header/Header.js +13 -4
- package/esm/components/Header/Header.js.map +1 -1
- package/esm/components/KnownFacts/KnownFacts.css +20 -5
- package/esm/components/KnownFacts/KnownFacts.js +1 -1
- package/esm/components/KnownFacts/KnownFacts.js.map +1 -1
- package/esm/components/LoginModal/LoginModal.css +270 -0
- package/{dist/components/LoginDrawer/LoginDrawer.d.ts → esm/components/LoginModal/LoginModal.d.ts} +4 -3
- package/esm/components/LoginModal/LoginModal.js +352 -0
- package/esm/components/LoginModal/LoginModal.js.map +1 -0
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/components/TabSwitch.css +2 -2
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +1 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js +6 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +1 -0
- package/esm/components/MemoriWidget/MemoriWidget.js +10 -5
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/Snippet/Snippet.js +7 -40
- package/esm/components/Snippet/Snippet.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.css +3 -2
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js +4 -3
- package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/website-assistant.css +54 -8
- package/esm/components/layouts/fullpage.css +4 -4
- package/esm/components/layouts/hidden-chat.css +1 -0
- package/esm/components/layouts/zoomed-full-body.css +4 -4
- package/esm/helpers/enhanceBubbleCodeBlocks.d.ts +5 -0
- package/esm/helpers/enhanceBubbleCodeBlocks.js +94 -0
- package/esm/helpers/enhanceBubbleCodeBlocks.js.map +1 -0
- package/esm/helpers/message.js +1 -0
- package/esm/helpers/message.js.map +1 -1
- package/esm/helpers/prism.d.ts +16 -0
- package/esm/helpers/prism.js +74 -0
- package/esm/helpers/prism.js.map +1 -0
- package/esm/locales/de.json +12 -0
- package/esm/locales/en.json +15 -4
- package/esm/locales/es.json +12 -2
- package/esm/locales/fr.json +11 -1
- package/esm/locales/it.json +13 -2
- package/esm/styles.css +1 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +2 -2
- package/dist/components/LoginDrawer/LoginDrawer.css +0 -1781
- package/dist/components/LoginDrawer/LoginDrawer.js +0 -409
- package/dist/components/LoginDrawer/LoginDrawer.js.map +0 -1
- package/esm/components/LoginDrawer/LoginDrawer.css +0 -1781
- package/esm/components/LoginDrawer/LoginDrawer.js +0 -406
- package/esm/components/LoginDrawer/LoginDrawer.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,9 +6,58 @@
|
|
|
6
6
|
|
|
7
7
|
Library to integrate an Agent from [Memori](https://memori.ai) in a React app.
|
|
8
8
|
|
|
9
|
-
Web Platform: [AIsuru](https://aisuru.com)
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
- Web Platform: [AIsuru](https://aisuru.com)
|
|
10
|
+
- Storybook (live demo of components and layouts): [memori-ai.github.io/memori-react](https://memori-ai.github.io/memori-react/)
|
|
11
|
+
|
|
12
|
+
<p>
|
|
13
|
+
<img alt="Full page layout, light theme" src="./docs/fullpage.png" width="49%" />
|
|
14
|
+
<img alt="Full page layout, dark theme" src="./docs/fullpage-dark.png" width="49%" />
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## Table of contents
|
|
18
|
+
|
|
19
|
+
- [Getting started](#getting-started)
|
|
20
|
+
- [Requirements](#requirements)
|
|
21
|
+
- [Installation](#installation)
|
|
22
|
+
- [Quick start](#quick-start)
|
|
23
|
+
- [Configuration](#configuration)
|
|
24
|
+
- [Props](#props)
|
|
25
|
+
- [Integration config](#integration-config)
|
|
26
|
+
- [Layouts](#layouts)
|
|
27
|
+
- [FULLPAGE](#fullpage)
|
|
28
|
+
- [CHAT](#chat)
|
|
29
|
+
- [WEBSITE_ASSISTANT](#website_assistant)
|
|
30
|
+
- [HIDDEN_CHAT](#hidden_chat)
|
|
31
|
+
- [TOTEM](#totem)
|
|
32
|
+
- [ZOOMED_FULL_BODY](#zoomed_full_body)
|
|
33
|
+
- [Mobile](#mobile)
|
|
34
|
+
- [Customization](#customization)
|
|
35
|
+
- [Styling](#styling)
|
|
36
|
+
- [Custom layout](#custom-layout)
|
|
37
|
+
- [Component overrides](#component-overrides)
|
|
38
|
+
- [Custom media renderer](#custom-media-renderer)
|
|
39
|
+
- [Features](#features)
|
|
40
|
+
- [Chat history](#chat-history)
|
|
41
|
+
- [Artifacts](#artifacts)
|
|
42
|
+
- [PII detection](#pii-detection)
|
|
43
|
+
- [JavaScript API](#javascript-api)
|
|
44
|
+
- [Conversation state](#conversation-state)
|
|
45
|
+
- [Send messages programmatically](#send-messages-programmatically)
|
|
46
|
+
- [DOM events](#dom-events)
|
|
47
|
+
- [Artifact API](#artifact-api)
|
|
48
|
+
- [Development](#development)
|
|
49
|
+
- [See also](#see-also)
|
|
50
|
+
- [License](#license)
|
|
51
|
+
|
|
52
|
+
## Getting started
|
|
53
|
+
|
|
54
|
+
### Requirements
|
|
55
|
+
|
|
56
|
+
- React `>=17` (peer dependency)
|
|
57
|
+
- TypeScript `>=4.8` (peer dependency, optional)
|
|
58
|
+
- Node `>=16` for local development
|
|
59
|
+
|
|
60
|
+
### Installation
|
|
12
61
|
|
|
13
62
|
```bash
|
|
14
63
|
yarn add @memori.ai/memori-react
|
|
@@ -18,17 +67,12 @@ yarn add @memori.ai/memori-react
|
|
|
18
67
|
npm install @memori.ai/memori-react
|
|
19
68
|
```
|
|
20
69
|
|
|
21
|
-
|
|
70
|
+
### Quick start
|
|
22
71
|
|
|
23
|
-
Import the component:
|
|
72
|
+
Import the component and the CSS:
|
|
24
73
|
|
|
25
74
|
```tsx
|
|
26
75
|
import Memori from '@memori.ai/memori-react';
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Import the CSS:
|
|
30
|
-
|
|
31
|
-
```tsx
|
|
32
76
|
import '@memori.ai/memori-react/dist/styles.css';
|
|
33
77
|
```
|
|
34
78
|
|
|
@@ -51,6 +95,8 @@ const App = () => (
|
|
|
51
95
|
);
|
|
52
96
|
```
|
|
53
97
|
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
54
100
|
### Props
|
|
55
101
|
|
|
56
102
|
| Prop | Required | Type | Default | Description |
|
|
@@ -63,165 +109,284 @@ const App = () => (
|
|
|
63
109
|
| `sessionID` | | `string` | | Initial Session ID, UUID which refers to the session to the Memori and identifies a conversation and its permissions (giver, receiver, anonymous). A session would be started autonomously with the params set, but if you have an existing and valid sessionID you can pass it as already opened one. Use this at your risk, as session recovery might break or start session as anon user. In most cases, you shoudn't use this prop. |
|
|
64
110
|
| `authToken` | | `string` | | Authentication token from user login, needed for giver sessions to upload assets |
|
|
65
111
|
| `integrationID` | | `string` | | Integration ID, UUID which refers to the public page layout |
|
|
66
|
-
| `integration` | | `Integration` | | Integration object
|
|
112
|
+
| `integration` | | `Integration` | | Integration object, see [Integration config](#integration-config) |
|
|
67
113
|
| `secretToken` | | `string` | | Secret token, the password of a private or secret Memori |
|
|
68
|
-
| `height` | | `string`
|
|
114
|
+
| `height` | | `string \| number` | "100%" | Height of the Memori. Pass `"100vh"` for a full-page fallback when the host has no definite height. |
|
|
115
|
+
| `layout` | | `string` | | Layout of the Memori: `"FULLPAGE"` (default, alias `"DEFAULT"`), `"CHAT"`, `"WEBSITE_ASSISTANT"`, `"TOTEM"`, `"HIDDEN_CHAT"`, or `"ZOOMED_FULL_BODY"`. See [Layouts](#layouts). |
|
|
116
|
+
| `customLayout` | | `React.FC<LayoutProps>` | | Custom layout component, see [Custom layout](#custom-layout) |
|
|
117
|
+
| `avatar3dHidden` | | `boolean` | `true` for `WEBSITE_ASSISTANT` | Hide the 3D avatar. Defaults to `true` for the `WEBSITE_ASSISTANT` layout (expanded panel); set to `false` to show it there. |
|
|
69
118
|
| `showShare` | | `bool` | `true` | Show the share button |
|
|
70
119
|
| `showCopyButton` | | `bool` | `true` | Show the copy button on messages |
|
|
71
120
|
| `showTranslationOriginal` | | `bool` | `false` | Show button to see original text when translated |
|
|
72
121
|
| `showSettings` | | `bool` | `true` | Show the settings panel button |
|
|
122
|
+
| `showChatHistory` | | `bool` | `true` | Show the chat history drawer button (past sessions), see [Chat history](#chat-history). Can also be set via integration config. |
|
|
73
123
|
| `showTypingText` | | `bool` | `false` | Show default sentences while loading text (see: Typing stories) |
|
|
74
124
|
| `showLogin` | | `bool` | `true` | Show the login button |
|
|
75
125
|
| `showClear` | | `bool` | `false` | Show clear chat history button |
|
|
76
126
|
| `showOnlyLastMessages` | | `bool` | `true` or `false` \* | Show only last 2 messages. (\*) Defaults to `true` for `TOTEM` and `WEBSITE_ASSISTANT` layouts, `false` otherwise |
|
|
127
|
+
| `showInputs` | | `bool` | `true` | Show the chat inputs (textarea, send and microphone buttons). Set to `false` for read-only / scripted conversations driven by `typeMessage`. |
|
|
128
|
+
| `showDates` | | `bool` | `false` | Show the timestamp on the Agent's messages |
|
|
129
|
+
| `showContextPerLine` | | `bool` | `false` | Show the context variables active for each message |
|
|
130
|
+
| `showMessageConsumption` | | `bool` | `false` | Show the AI consumption (LLM usage) per message. Can also be set via integration config. |
|
|
77
131
|
| `showUpload` | | `bool` | `true` | Show the upload button within the chat |
|
|
78
|
-
| `maxTotalMessagePayload` | | `number` | 300000 | Max **per-document** content length (character count). Kept for backward compatibility: it no longer applies to the sum of all attached documents. |
|
|
79
|
-
| `disablePastedText` | | `boolean` | `false` | When true, pasted text is not added as a document attachment; only normal textarea paste occurs. |
|
|
80
|
-
| `maxTextareaCharacters` | | `number` | | Max characters allowed in the chat textarea. When set, shows a counter (e.g. "0 / 500") above the textarea, enforces the limit, and disables paste-as-attachment by default. |
|
|
81
132
|
| `showReasoning` | | `bool` | `false` | Show reasoning output |
|
|
133
|
+
| `maxTotalMessagePayload` | | `number` | 300000 | Max **per-document** content length (character count). Kept for backward compatibility: it no longer applies to the sum of all attached documents. |
|
|
134
|
+
| `maxTextareaCharacters` | | `number` | | Max characters allowed in the chat textarea. When set, shows a counter (e.g. "0 / 500") above the textarea, enforces the limit, and disables paste-as-attachment by default. |
|
|
82
135
|
| `baseURL` | | `string` | | Base URL of the Memori, example: "https://aisuru.com" |
|
|
83
136
|
| `apiURL` | | `string` | "https://backend.memori.ai" | URL of the Memori Backend API |
|
|
84
137
|
| `engineURL` | | `string` | "https://engine.memori.ai" | URL of the Memori Engine API |
|
|
85
138
|
| `tag` | | `string` | | Tag of the person opening the session to the Memori, could be the giver or a receiver |
|
|
86
139
|
| `pin` | | `string` | | PIN of the person opening the session to the Memori, could be the giver or a receiver |
|
|
87
|
-
| `context` | | `string`
|
|
140
|
+
| `context` | | `{ [key: string]: string }` | | Initial context of the conversation, object of context variables, example: `{ SOURCE: 'website' }`. If omitted, `contextVars` from the integration config is used. |
|
|
88
141
|
| `initialQuestion` | | `string` | | Initial question to ask to the Memori, starts the conversation as this would be sent to the Memori |
|
|
89
|
-
| `
|
|
142
|
+
| `additionalInfo` | | `{ [key: string]: string }` | | Additional info sent when opening the session (`additionalInfo` of the Engine `openSession` call). A `loginToken` key here takes precedence over `authToken`. |
|
|
143
|
+
| `autoStart` | | `boolean` | `false` \*\* | Automatically start the conversation when the component is mounted. (\*\*) Defaults to `true` for `HIDDEN_CHAT`; always `false` for `WEBSITE_ASSISTANT`. |
|
|
144
|
+
| `uiLang` | | `'en' \| 'it' \| 'es' \| 'fr' \| 'de'` | browser language | Language of the UI, es: "en" or "it". Uppercase variants (`'IT'`, `'EN'`, ...) are accepted. Falls back to the browser language, then `"en"`. |
|
|
90
145
|
| `multilingual` | | `bool` | `false` | Enable multilingual mode, if enabled the user can switch between spoken languages |
|
|
91
146
|
| `spokenLang` | | `string` | | Language of the spoken text, as defaults to user selection. Example: "en" or "it" |
|
|
92
|
-
| `onStateChange` | | `function` | | Callback function called when the state of the Memori changes |
|
|
93
147
|
| `enableAudio` | | `boolean` | `true` | Enable audio output. Defaults to true if otherwise indicated by props or integration config. |
|
|
94
148
|
| `defaultSpeakerActive` | | `boolean` | `true` | Default value for the speaker activation |
|
|
95
|
-
| `disableTextEnteredEvents` | | `boolean` | `false` | Disable MemoriTextEntered events listeners for `typeMessage` functions, useful to avoid issues with multiple widgets in page. |
|
|
96
149
|
| `useMathFormatting` | | `boolean` | `false` | Apply math formatting to the messages, defaults to false if otherwise indicated by props or integration config. |
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `customMediaRenderer` | | `(mimeType: string) => JSX.Element \| null` | | Custom media renderer, see [
|
|
150
|
+
| `onStateChange` | | `function` | | Callback function called when the state of the Memori changes, see [Conversation state](#conversation-state) |
|
|
151
|
+
| `disableTextEnteredEvents` | | `boolean` | `false` | Disable MemoriTextEntered events listeners for `typeMessage` functions, useful to avoid issues with multiple widgets in page. |
|
|
152
|
+
| `customMediaRenderer` | | `(mimeType: string) => JSX.Element \| null` | | Custom media renderer, see [Custom media renderer](#custom-media-renderer) |
|
|
100
153
|
| `additionalSettings` | | `JSX.Element` | | Custom JSX or component to render within the settings drawer |
|
|
101
|
-
| `userAvatar` | | `string`
|
|
102
|
-
| `
|
|
154
|
+
| `userAvatar` | | `string \| JSX.Element` | | Custom URL or React element to use as user avatar |
|
|
155
|
+
| `applyVarsToRoot` | | `boolean` | `false` | Also apply the integration CSS variables (brand color, etc.) to `:root`, not only to the widget scopes. Useful when rendering Memori UI elements outside the widget container. |
|
|
103
156
|
|
|
104
157
|
\*: one of these pairs is required: `memoriName` + `ownerUserName`, `memoriID` + `ownerUserID`
|
|
105
158
|
|
|
106
|
-
###
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
159
|
+
### Integration config
|
|
160
|
+
|
|
161
|
+
An **integration** is the configuration of a public page / landing experience created from the Memori backend. You can pass it explicitly with the `integration` prop, or select one of the Memori's integrations with `integrationID` (if neither is set, the published `LANDING_EXPERIENCE` integration is used, when present).
|
|
162
|
+
|
|
163
|
+
The integration object has a `customData` string containing JSON. The keys read by the widget are:
|
|
164
|
+
|
|
165
|
+
| Key | Type | Description |
|
|
166
|
+
| ------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
167
|
+
| `layout` | `string \| { name, piiDetection? }` | Layout name, or an object with `name` and a [PII detection](#pii-detection) config |
|
|
168
|
+
| `theme` | `'light' \| 'dark'` | Widget theme, see [Dark theme](#dark-theme). Default `light` |
|
|
169
|
+
| `lang` | `string` | Default conversation language, used when the `spokenLang` prop is not set |
|
|
170
|
+
| `uiLang` | `string` | Fallback conversation language, after `lang` |
|
|
171
|
+
| `buttonBgColor` | `string` | Brand primary color, injected as `--memori-primary-color`, see [Styling](#styling) |
|
|
172
|
+
| `buttonTextColor` | `string` | Text color on primary backgrounds, injected as `--memori-primary-content` |
|
|
173
|
+
| `globalBackground` | `string` | URL of a background image for the chat |
|
|
174
|
+
| `blurBackground` | `boolean` | Blur the global background behind the chat. Default `true` |
|
|
175
|
+
| `contextVars` | `string` | Initial context variables as `"KEY: value, KEY2: value2"`, used when the `context` prop is not set |
|
|
176
|
+
| `initialQuestion` | `string` | Initial question, used when the `initialQuestion` prop is not set |
|
|
177
|
+
| `showChatHistory` | `boolean` | Same as the prop |
|
|
178
|
+
| `showUpload` | `boolean` | Same as the prop |
|
|
179
|
+
| `showReasoning` | `boolean` | Same as the prop |
|
|
180
|
+
| `showMessageConsumption` | `boolean` | Same as the prop |
|
|
181
|
+
| `avatar_3d_hidden` | `boolean` | Same as the `avatar3dHidden` prop |
|
|
182
|
+
| `totemContentMaxWidth` | `number \| string` | `TOTEM` only: max-width of the content axis (avatar + panel + status), px or CSS length |
|
|
183
|
+
| `whiteListedDomains` | `string[]` | Regex list of hostnames allowed to render the widget (tenant name and aliases are always allowed). The widget renders nothing elsewhere |
|
|
184
|
+
| `ignoreClientAttributes` | `boolean` | When `true`, the `show*`, `multilingual`, `enableAudio`, `defaultSpeakerActive`, `useMathFormatting`, `context`, `initialQuestion` and `tag`/`pin` props are ignored in favour of the integration values |
|
|
112
185
|
|
|
113
186
|
```tsx
|
|
114
|
-
<Memori layout="FULLPAGE" ... />
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**Via the `integration` prop:** the integration object must have a `customData` string containing JSON. That JSON can include a `layout` field: either a **string** (layout name) or an **object** `{ name: LayoutName, piiDetection?: PiiDetectionConfig }` to enable [PII detection](#pii-detection). Used when you use a public page / landing experience from the backend.
|
|
118
|
-
|
|
119
|
-
```tsx
|
|
120
|
-
// Integration with layout name only
|
|
121
187
|
const integration = {
|
|
122
188
|
integrationID: '...',
|
|
123
189
|
customData: JSON.stringify({
|
|
124
190
|
layout: 'FULLPAGE',
|
|
191
|
+
theme: 'dark',
|
|
125
192
|
lang: 'it',
|
|
126
|
-
|
|
193
|
+
buttonBgColor: '#6667ab',
|
|
194
|
+
buttonTextColor: '#ffffff',
|
|
127
195
|
}),
|
|
128
196
|
};
|
|
197
|
+
|
|
129
198
|
<Memori integration={integration} ... />
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
When a prop and the corresponding integration key are both set, the **prop wins** (unless `ignoreClientAttributes` is `true`).
|
|
202
|
+
|
|
203
|
+
## Layouts
|
|
130
204
|
|
|
131
|
-
|
|
205
|
+
The Memori can be displayed in six layouts: `FULLPAGE`, `CHAT`, `WEBSITE_ASSISTANT`, `HIDDEN_CHAT`, `TOTEM`, and `ZOOMED_FULL_BODY`. If you don't specify a layout (via the `layout` prop or via integration config), the default is `FULLPAGE`.
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
// As a prop (takes precedence over the integration)
|
|
209
|
+
<Memori layout="CHAT" ... />
|
|
210
|
+
|
|
211
|
+
// Via integration config
|
|
132
212
|
const integration = {
|
|
133
213
|
integrationID: '...',
|
|
134
|
-
customData: JSON.stringify({
|
|
135
|
-
layout: {
|
|
136
|
-
name: 'FULLPAGE',
|
|
137
|
-
piiDetection: {
|
|
138
|
-
enabled: true,
|
|
139
|
-
rules: [
|
|
140
|
-
{
|
|
141
|
-
id: 'email',
|
|
142
|
-
label: 'Email',
|
|
143
|
-
pattern: '\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b',
|
|
144
|
-
message: { it: 'Contiene email.', en: 'Contains email.' },
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
errorMessage: { it: 'Dati sensibili.', en: 'Sensitive data.' },
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
lang: 'it',
|
|
151
|
-
}),
|
|
214
|
+
customData: JSON.stringify({ layout: 'CHAT' }),
|
|
152
215
|
};
|
|
153
216
|
<Memori integration={integration} ... />
|
|
154
217
|
```
|
|
155
218
|
|
|
156
|
-
|
|
219
|
+
All layouts support the light and dark [theme](#dark-theme).
|
|
157
220
|
|
|
158
|
-
|
|
221
|
+
### FULLPAGE
|
|
159
222
|
|
|
160
|
-
|
|
223
|
+
Two-column layout: 3D avatar on the left, start panel / chat on the right, with a branded header.
|
|
161
224
|
|
|
162
|
-
|
|
225
|
+
<p>
|
|
226
|
+
<img alt="Full page layout, light theme" src="./docs/fullpage.png" width="49%" />
|
|
227
|
+
<img alt="Full page layout, dark theme" src="./docs/fullpage-dark.png" width="49%" />
|
|
228
|
+
</p>
|
|
163
229
|
|
|
164
|
-
|
|
230
|
+
### CHAT
|
|
165
231
|
|
|
166
|
-
|
|
167
|
-
| ----- | ------ | ------------ |
|
|
168
|
-
| `enabled` | `boolean` | When `true`, PII check runs before sending. |
|
|
169
|
-
| `rules` | `array` | List of `{ id, label, pattern, message }`. `pattern` is a regex string; `message` is `{ [lang]: string }` (e.g. `{ it: "...", en: "..." }`). Rules with the same `id` are deduplicated in the error text. |
|
|
170
|
-
| `errorMessage` | `object` | Main line shown in the bubble: `{ [lang]: string }`. |
|
|
232
|
+
Chat only, no avatar. Header with chat history, fullscreen, audio, location, share and login controls; start panel as a central card.
|
|
171
233
|
|
|
172
|
-
|
|
234
|
+
<p>
|
|
235
|
+
<img alt="Chat layout, light theme" src="./docs/chat.png" width="49%" />
|
|
236
|
+
<img alt="Chat layout, dark theme" src="./docs/chat-dark.png" width="49%" />
|
|
237
|
+
</p>
|
|
173
238
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
239
|
+
### WEBSITE_ASSISTANT
|
|
240
|
+
|
|
241
|
+
Floating launcher on the host page; the widget opens as a side panel with the start panel and the chat. The 3D avatar is hidden by default (`avatar3dHidden`). `autoStart` is always `false` and `showOnlyLastMessages` defaults to `true`.
|
|
242
|
+
|
|
243
|
+
<p>
|
|
244
|
+
<img alt="Website assistant layout, light theme" src="./docs/website-assistant.png" width="49%" />
|
|
245
|
+
<img alt="Website assistant layout, dark theme" src="./docs/website-assistant-dark.png" width="49%" />
|
|
246
|
+
</p>
|
|
247
|
+
|
|
248
|
+
### HIDDEN_CHAT
|
|
249
|
+
|
|
250
|
+
Only the launcher is visible; the chat opens on demand as a compact sidebar. `autoStart` defaults to `true`.
|
|
251
|
+
|
|
252
|
+
<p>
|
|
253
|
+
<img alt="Hidden chat layout, light theme" src="./docs/hidden-chat.png" width="24%" />
|
|
254
|
+
<img alt="Hidden chat layout, dark theme" src="./docs/hidden-chat-dark.png" width="24%" />
|
|
255
|
+
</p>
|
|
256
|
+
|
|
257
|
+
### TOTEM
|
|
258
|
+
|
|
259
|
+
Kiosk layout: full-body avatar with the start panel / chat card overlaid at the bottom and a vertical control bar. `showOnlyLastMessages` defaults to `true`. Use `totemContentMaxWidth` (integration config) to fit vertical screens.
|
|
260
|
+
|
|
261
|
+
<p>
|
|
262
|
+
<img alt="Totem layout, light theme" src="./docs/totem.png" width="58%" />
|
|
263
|
+
<img alt="Totem layout, dark theme" src="./docs/totem-dark.png" width="30%" />
|
|
264
|
+
</p>
|
|
265
|
+
|
|
266
|
+
### ZOOMED_FULL_BODY
|
|
267
|
+
|
|
268
|
+
Full-body avatar zoomed in, chat overlaid.
|
|
269
|
+
|
|
270
|
+
<img alt="Zoomed full body layout" src="./docs/zoomed-avatar.png" width="600" />
|
|
271
|
+
|
|
272
|
+
### Mobile
|
|
273
|
+
|
|
274
|
+
On small screens the header collapses to a compact bar (mute + menu); the menu opens a side panel with user info, session details and the navigation items (chat history, fullscreen, share, exit).
|
|
275
|
+
|
|
276
|
+
<img alt="Mobile layout" src="./docs/mobile-header.png" width="240" />
|
|
277
|
+
|
|
278
|
+
## Customization
|
|
279
|
+
|
|
280
|
+
### Styling
|
|
281
|
+
|
|
282
|
+
The widget is built on the [@memori.ai/ui](https://www.npmjs.com/package/@memori.ai/ui) design system and its CSS is organized in cascade layers, in this order: `memori.theme` < `memori.components` < `memori.overrides`. Your own overrides should live in `@layer memori.overrides` (or outside any layer, which always wins over layered styles).
|
|
283
|
+
|
|
284
|
+
#### Brand color
|
|
285
|
+
|
|
286
|
+
The main brand hook is `--memori-primary-color`. All primary-derived tokens (`hover`, `active`, `disabled`, `subtle`, borders, focus ring, shadows) are computed from it with `color-mix()`, so you usually only need to set this one:
|
|
287
|
+
|
|
288
|
+
```css
|
|
289
|
+
memori-client,
|
|
290
|
+
.memori-widget,
|
|
291
|
+
#headlessui-portal-root {
|
|
292
|
+
--memori-primary-color: rgb(102, 103, 171);
|
|
293
|
+
--memori-primary-content: #fff; /* text/icon color on primary backgrounds */
|
|
189
294
|
}
|
|
190
295
|
```
|
|
191
296
|
|
|
192
|
-
|
|
297
|
+
Set it on the widget scopes (`.memori-widget`, `memori-client`, portal roots), not only on `:root`: derived tokens are resolved where they are declared, so a `:root`-only override would leave disabled/subtle UI on the default brand. When an integration is passed, the widget already injects `buttonBgColor` / `buttonTextColor` from `customData` as these two variables (see `applyVarsToRoot` to also apply them to `:root`).
|
|
193
298
|
|
|
194
|
-
####
|
|
299
|
+
#### Design tokens
|
|
195
300
|
|
|
196
|
-
|
|
301
|
+
The most commonly used tokens you may override:
|
|
197
302
|
|
|
198
|
-
|
|
303
|
+
```css
|
|
304
|
+
.memori-widget {
|
|
305
|
+
/* Brand */
|
|
306
|
+
--memori-primary-color: rgb(130 70 175);
|
|
307
|
+
--memori-primary-content: #fff;
|
|
308
|
+
|
|
309
|
+
/* Surfaces & text */
|
|
310
|
+
--memori-main-background: oklch(97.1% 0 0deg);
|
|
311
|
+
--memori-secondary-background: oklch(100% 0 0deg);
|
|
312
|
+
--memori-text-color: oklch(20% 0.05 240deg);
|
|
313
|
+
--memori-border-color: color-mix(in oklch, oklch(45% 0.05 240deg), transparent 84%);
|
|
314
|
+
|
|
315
|
+
/* Typography */
|
|
316
|
+
--memori-font-family: 'Lexend Deca', sans-serif;
|
|
317
|
+
--memori-text-size-sm: 0.875rem;
|
|
318
|
+
--memori-text-size-md: 1rem;
|
|
319
|
+
|
|
320
|
+
/* Shape & spacing */
|
|
321
|
+
--memori-radius-control: 0.75rem; /* buttons, inputs */
|
|
322
|
+
--memori-radius-surface: 1.25rem; /* cards, bubbles, drawers */
|
|
323
|
+
--memori-spacing-xs: 4px;
|
|
324
|
+
--memori-spacing-sm: 8px;
|
|
325
|
+
--memori-spacing-md: 16px;
|
|
326
|
+
--memori-spacing-lg: 24px;
|
|
327
|
+
|
|
328
|
+
/* Layout */
|
|
329
|
+
--memori-layout-max-width: 1280px;
|
|
330
|
+
--memori-conversation-max-width: 48rem;
|
|
331
|
+
--memori-conversation-inline-padding: var(--memori-spacing-md);
|
|
332
|
+
|
|
333
|
+
/* Motion */
|
|
334
|
+
--memori-motion-duration-fast: 0.15s;
|
|
335
|
+
--memori-motion-duration-normal: 0.2s;
|
|
336
|
+
--memori-motion-ease-out: cubic-bezier(0.33, 1, 0.68, 1);
|
|
337
|
+
}
|
|
338
|
+
```
|
|
199
339
|
|
|
200
|
-
|
|
340
|
+
Values shown are the light-theme defaults.
|
|
201
341
|
|
|
202
|
-
|
|
342
|
+
Derived tokens that are rebound automatically from `--memori-primary-color` (override only if you need a specific value): `--memori-primary`, `--memori-primary-hover`, `--memori-primary-active`, `--memori-primary-disabled`, `--memori-primary-subtle`, `--memori-primary-subtle-hover`, `--memori-primary-alpha`, `--memori-border-primary`, `--memori-border-primary-hover`, `--memori-focus-ring-color`, `--memori-focus-ring`, `--memori-shadow-primary`.
|
|
203
343
|
|
|
204
|
-
|
|
344
|
+
Semantic colors from `@memori.ai/ui`: `--memori-error`, `--memori-success`, `--memori-info`, `--memori-neutral`, `--memori-secondary`.
|
|
205
345
|
|
|
206
|
-
####
|
|
346
|
+
#### Dark theme
|
|
207
347
|
|
|
208
|
-
|
|
348
|
+
The theme is resolved from the integration config (`customData.theme: 'light' | 'dark'`, default `light`) and stamped as `data-theme` on the widget root and on portaled popups. You can also force it from the host:
|
|
209
349
|
|
|
210
|
-
|
|
350
|
+
```html
|
|
351
|
+
<div data-theme="dark">
|
|
352
|
+
<!-- Memori widget here -->
|
|
353
|
+
</div>
|
|
354
|
+
```
|
|
211
355
|
|
|
212
|
-
|
|
356
|
+
Dark-specific primary-derived tokens are recomputed automatically; override them under `[data-theme='dark'] .memori-widget` if needed.
|
|
213
357
|
|
|
214
|
-
####
|
|
358
|
+
#### Reference
|
|
215
359
|
|
|
216
|
-
|
|
360
|
+
You can review the default styles and the full list of tokens in the [styles.css](https://github.com/memori-ai/memori-react/blob/main/src/styles.css) file and in the `@memori.ai/ui` stylesheet (`node_modules/@memori.ai/ui/dist/memori-ai-ui.css`). Per-component classes follow the `memori-<component>` naming (e.g. `.memori-chat--wrapper`, `.memori-chat--bubble`, `.memori-header`, `.memori--start-panel`); the widget root also gets `memori-layout-<layout>` and `memori-controls-<position>` modifiers.
|
|
217
361
|
|
|
218
|
-
|
|
362
|
+
### Custom layout
|
|
219
363
|
|
|
220
364
|
You can override the default layout by passing a custom layout component to the `customLayout` prop.
|
|
221
365
|
|
|
222
|
-
The custom layout component must be a React functional component that accepts a [LayoutProps](https://github.com/memori-ai/memori-react/blob/
|
|
366
|
+
The custom layout component must be a React functional component that accepts a [LayoutProps](https://github.com/memori-ai/memori-react/blob/main/src/components/MemoriWidget/MemoriWidget.tsx) object as props (search for `export interface LayoutProps`).
|
|
367
|
+
|
|
368
|
+
Available `LayoutProps`:
|
|
369
|
+
|
|
370
|
+
| Prop | Type | Description |
|
|
371
|
+
| -------------------------------- | --------------------------- | --------------------------------------------------------------------------------------- |
|
|
372
|
+
| `Header` / `headerProps` | component / props | Header with share, settings, chat history, login buttons |
|
|
373
|
+
| `Avatar` / `avatarProps` | component / props | 2D/3D avatar |
|
|
374
|
+
| `Chat` / `chatProps` | component / props | Chat (history, inputs, attachments) |
|
|
375
|
+
| `StartPanel` / `startPanelProps` | component / props | Panel shown before the session starts |
|
|
376
|
+
| `integrationStyle` | `JSX.Element \| null` | `<style>` element with integration CSS variables, render it once |
|
|
377
|
+
| `integrationBackground` | `JSX.Element \| null` | Background element from integration config |
|
|
378
|
+
| `poweredBy` | `JSX.Element \| null` | "Powered by" badge |
|
|
379
|
+
| `sessionId` | `string` | Current session ID, `undefined` before the session starts |
|
|
380
|
+
| `hasUserActivatedSpeak` | `boolean` | `true` once the user has started the conversation |
|
|
381
|
+
| `showUpload` | `boolean` | Whether the upload button is enabled |
|
|
382
|
+
| `loading` | `boolean` | Widget is loading (session opening, memori loading) |
|
|
383
|
+
| `autoStart` | `boolean` | Resolved `autoStart` value |
|
|
384
|
+
| `onSidebarToggle` | `(isOpen: boolean) => void` | Callback to notify the widget when a sidebar is opened/closed |
|
|
385
|
+
| `avatar3dHidden` | `boolean \| string` | Resolved `avatar3dHidden` value |
|
|
386
|
+
| `totemContentMaxWidth` | `number \| string` | `TOTEM` only: max-width of the content axis (avatar + panel + status), px or CSS length |
|
|
223
387
|
|
|
224
388
|
```tsx
|
|
389
|
+
import { Spin } from '@memori.ai/ui';
|
|
225
390
|
import { LayoutProps } from '@memori.ai/memori-react/dist/components/MemoriWidget/MemoriWidget';
|
|
226
391
|
|
|
227
392
|
const MyCustomLayout: React.FC<LayoutProps> = ({
|
|
@@ -235,8 +400,6 @@ const MyCustomLayout: React.FC<LayoutProps> = ({
|
|
|
235
400
|
startPanelProps,
|
|
236
401
|
integrationStyle,
|
|
237
402
|
integrationBackground,
|
|
238
|
-
ChangeMode,
|
|
239
|
-
changeModeProps,
|
|
240
403
|
sessionId,
|
|
241
404
|
hasUserActivatedSpeak,
|
|
242
405
|
loading = false,
|
|
@@ -264,46 +427,13 @@ const MyCustomLayout: React.FC<LayoutProps> = ({
|
|
|
264
427
|
And then pass it to the `customLayout` prop:
|
|
265
428
|
|
|
266
429
|
```tsx
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
## Styling
|
|
274
|
-
|
|
275
|
-
You can override the default styles of the Memori by customizing the following CSS custom properties:
|
|
276
|
-
|
|
277
|
-
```css
|
|
278
|
-
memori-client,
|
|
279
|
-
#headlessui-portal-root,
|
|
280
|
-
.memori-widget {
|
|
281
|
-
--memori-primary: rgb(102, 103, 171);
|
|
282
|
-
--memori-primary-text: #fff;
|
|
283
|
-
--memori-inner-content-pad: 1rem;
|
|
284
|
-
--memori-inner-bg: transparent;
|
|
285
|
-
--memori-chat-bubble-bg: #ffffff60;
|
|
286
|
-
--memori-text-color: #000;
|
|
287
|
-
--memori-button-bg: #fff;
|
|
288
|
-
--memori-button-text: #000;
|
|
289
|
-
--memori-button-padding: 0.5rem 1.5rem;
|
|
290
|
-
--memori-button-border-color: #d9d9d9;
|
|
291
|
-
--memori-button-radius: 5px;
|
|
292
|
-
--memori-button-box-shadow: 0 2px 0 rgba(0, 0, 0, 0.02);
|
|
293
|
-
--memori-blur-background: 0px;
|
|
294
|
-
--memori-drawer--width: 100%;
|
|
295
|
-
--memori-drawer--width--md: 80%;
|
|
296
|
-
--memori-drawer--width--lg: 60%;
|
|
297
|
-
--memori-modal--width: 100%;
|
|
298
|
-
--memori-modal--width--md: 80%;
|
|
299
|
-
--memori-error-color: #ff4d4f;
|
|
300
|
-
--memori-button-disabled-bg: #f9f9f9;
|
|
301
|
-
}
|
|
430
|
+
<Memori
|
|
431
|
+
...
|
|
432
|
+
customLayout={MyCustomLayout}
|
|
433
|
+
/>
|
|
302
434
|
```
|
|
303
435
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
## Component overrides
|
|
436
|
+
### Component overrides
|
|
307
437
|
|
|
308
438
|
When using the `customLayout` prop, you can also override the default components used by the client.
|
|
309
439
|
|
|
@@ -348,7 +478,7 @@ const CustomLayout: React.FC<LayoutProps> = ({
|
|
|
348
478
|
);
|
|
349
479
|
```
|
|
350
480
|
|
|
351
|
-
|
|
481
|
+
### Custom media renderer
|
|
352
482
|
|
|
353
483
|
You can override the default media renderer by passing a custom function to the `customMediaRenderer` prop.
|
|
354
484
|
This can override the default media renderer for all media types or just for a specific one.
|
|
@@ -368,11 +498,94 @@ You can also use this to extend the default media renderer with additional media
|
|
|
368
498
|
/>
|
|
369
499
|
```
|
|
370
500
|
|
|
371
|
-
##
|
|
501
|
+
## Features
|
|
502
|
+
|
|
503
|
+
### Chat history
|
|
504
|
+
|
|
505
|
+
When `showChatHistory` is enabled (default), a side drawer lists the user's past conversations with the Agent, with filters, message count and attachments per chat. Selecting one resumes it in the chat.
|
|
506
|
+
|
|
507
|
+
<img alt="Chat history drawer" src="./docs/chat-history.png" width="600" />
|
|
508
|
+
|
|
509
|
+
### Artifacts
|
|
510
|
+
|
|
511
|
+
When the Agent's answer contains an `<output>` element (code, HTML, markdown, JSON, ...), the widget renders it as an **artifact**: a card in the chat that opens in a dedicated drawer with preview, copy and download actions. On desktop the drawer is a resizable side column next to the chat; on mobile it takes the full width. Multiple versions of the same artifact are tracked together.
|
|
372
512
|
|
|
373
|
-
|
|
513
|
+
<img alt="Artifacts list" src="./docs/artifacts.png" width="400" />
|
|
374
514
|
|
|
375
|
-
|
|
515
|
+
Artifacts can also be created from the host page, see [Artifact API](#artifact-api).
|
|
516
|
+
|
|
517
|
+
### PII detection
|
|
518
|
+
|
|
519
|
+
PII detection is **only available via integration config**: pass an integration whose `customData` JSON has `layout` as an object with `name` and `piiDetection`. It is not configurable via the `layout` prop.
|
|
520
|
+
|
|
521
|
+
When enabled, the widget checks each message (including attached document text) against the configured regex **rules** before sending. If any rule matches, the message is **not** sent and a single red error bubble is shown with the main `errorMessage` plus the matched rules' messages, in the chat's selected language (when `multilingual` is enabled).
|
|
522
|
+
|
|
523
|
+
**Config shape** (inside `integration.customData.layout.piiDetection`):
|
|
524
|
+
|
|
525
|
+
| Field | Type | Description |
|
|
526
|
+
| -------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
527
|
+
| `enabled` | `boolean` | When `true`, PII check runs before sending. |
|
|
528
|
+
| `rules` | `array` | List of `{ id, label, pattern, message }`. `pattern` is a regex string; `message` is `{ [lang]: string }` (e.g. `{ it: "...", en: "..." }`). Rules with the same `id` are deduplicated in the error text. |
|
|
529
|
+
| `errorMessage` | `object` | Main line shown in the bubble: `{ [lang]: string }`. |
|
|
530
|
+
|
|
531
|
+
**Example**:
|
|
532
|
+
|
|
533
|
+
```tsx
|
|
534
|
+
const integration = {
|
|
535
|
+
integrationID: '...',
|
|
536
|
+
customData: JSON.stringify({
|
|
537
|
+
layout: {
|
|
538
|
+
name: 'FULLPAGE',
|
|
539
|
+
piiDetection: {
|
|
540
|
+
enabled: true,
|
|
541
|
+
rules: [
|
|
542
|
+
{
|
|
543
|
+
id: 'email',
|
|
544
|
+
label: 'Email',
|
|
545
|
+
pattern: '\\b[A-Za-z0-9._%+\\-]+@[A-Za-z0-9.\\-]+\\.[A-Za-z]{2,}\\b',
|
|
546
|
+
message: { it: 'Contiene email.', en: 'Contains email.' },
|
|
547
|
+
},
|
|
548
|
+
],
|
|
549
|
+
errorMessage: { it: 'Dati sensibili.', en: 'Sensitive data.' },
|
|
550
|
+
},
|
|
551
|
+
},
|
|
552
|
+
lang: 'it',
|
|
553
|
+
}),
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
<Memori integration={integration} ... />
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
If both the `layout` prop and `integration.customData.layout` are provided, the `layout` prop wins for the layout name, while PII detection is still read from the integration.
|
|
560
|
+
|
|
561
|
+
Invalid or empty regex patterns are skipped; missing translations fall back to `en` then the first available value.
|
|
562
|
+
|
|
563
|
+
## JavaScript API
|
|
564
|
+
|
|
565
|
+
When rendered, the Memori widget exposes some global functions and DOM events that can be used to interact with the Agent from outside React.
|
|
566
|
+
|
|
567
|
+
### Conversation state
|
|
568
|
+
|
|
569
|
+
The `onStateChange` prop is called at every state change of the conversation:
|
|
570
|
+
|
|
571
|
+
```jsx
|
|
572
|
+
<Memori
|
|
573
|
+
...
|
|
574
|
+
onStateChange={(state) => {
|
|
575
|
+
console.log('Memori state changed:', state);
|
|
576
|
+
}}
|
|
577
|
+
/>
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
The same state is dispatched as the `MemoriNewDialogState` event on `document` (useful when working with [memori-webcomponent](https://github.com/memori-ai/memori-webcomponent)):
|
|
581
|
+
|
|
582
|
+
```js
|
|
583
|
+
document.addEventListener('MemoriNewDialogState', e => {
|
|
584
|
+
console.log('Memori state changed:', e.detail);
|
|
585
|
+
});
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
You can also read the current state at any time:
|
|
376
589
|
|
|
377
590
|
```js
|
|
378
591
|
let dialogState = getMemoriState();
|
|
@@ -380,7 +593,7 @@ let sessionID = getMemoriState().sessionID;
|
|
|
380
593
|
let dialogState = getMemoriState(myWidgetIntegrationId); // in case you have multiple widgets on the same page
|
|
381
594
|
```
|
|
382
595
|
|
|
383
|
-
|
|
596
|
+
Or manually, from the `data-memori-engine-state` attribute in the widget HTML:
|
|
384
597
|
|
|
385
598
|
```js
|
|
386
599
|
let dialogState = JSON.parse(
|
|
@@ -389,9 +602,9 @@ let dialogState = JSON.parse(
|
|
|
389
602
|
);
|
|
390
603
|
```
|
|
391
604
|
|
|
392
|
-
###
|
|
605
|
+
### Send messages programmatically
|
|
393
606
|
|
|
394
|
-
Write and send a message to the
|
|
607
|
+
Write and send a message to the Agent, such as to continue a conversation with a specific message or following an action:
|
|
395
608
|
|
|
396
609
|
```js
|
|
397
610
|
typeMessage('Hello World!');
|
|
@@ -403,24 +616,59 @@ Additional parameters:
|
|
|
403
616
|
const waitForPrevious = true; // waits for previous message to be read, default: true
|
|
404
617
|
const hidden = true; // message is not visible to the user, only the response is, default: false
|
|
405
618
|
const typingText = "Asking the unicorns' opinion..."; // text to show in the loader while the Agent is answering, defaults to none
|
|
406
|
-
|
|
619
|
+
const useLoaderTextAsMsg = false; // when true, the Agent's answer is replaced in the chat by typingText (useful for hidden "action" messages), default: false
|
|
620
|
+
typeMessage('Hello World!', waitForPrevious, hidden, typingText, useLoaderTextAsMsg);
|
|
407
621
|
```
|
|
408
622
|
|
|
409
623
|
There is also an alias function that does not show the message sent to the user, but only the Agent's response:
|
|
410
624
|
|
|
411
625
|
```js
|
|
412
626
|
const waitForPrevious = true; // waits for previous message to be read, default: true
|
|
413
|
-
typeMessageHidden('Hello World!', waitForPrevious);
|
|
627
|
+
typeMessageHidden('Hello World!', waitForPrevious, typingText, useLoaderTextAsMsg);
|
|
414
628
|
|
|
415
629
|
// alias to
|
|
416
|
-
typeMessage('Hello World!', waitForPrevious, true);
|
|
630
|
+
typeMessage('Hello World!', waitForPrevious, true, typingText, useLoaderTextAsMsg);
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
`typeBatchMessages` sends a sequence of messages one after the other, waiting for the Agent to finish answering (and speaking) each one before sending the next. Chat inputs are disabled while the batch is running:
|
|
634
|
+
|
|
635
|
+
```js
|
|
636
|
+
typeBatchMessages([
|
|
637
|
+
{ message: 'Hello!', waitForPrevious: true },
|
|
638
|
+
{ message: 'Tell me about yourself', hidden: true, typingText: 'Thinking...' },
|
|
639
|
+
{ message: 'Thanks', useLoaderTextAsMsg: false },
|
|
640
|
+
]);
|
|
417
641
|
```
|
|
418
642
|
|
|
419
|
-
|
|
643
|
+
Each item accepts the same options as `typeMessage`: `message`, `waitForPrevious`, `hidden`, `typingText`, `useLoaderTextAsMsg`.
|
|
644
|
+
|
|
645
|
+
Set the `disableTextEnteredEvents` prop to `true` on widgets that should ignore these calls (e.g. when multiple widgets are on the same page).
|
|
646
|
+
|
|
647
|
+
### DOM events
|
|
648
|
+
|
|
649
|
+
The widget dispatches and listens to the following `CustomEvent`s on `document`:
|
|
650
|
+
|
|
651
|
+
| Event | Direction | `event.detail` | Description |
|
|
652
|
+
| ---------------------- | ------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
653
|
+
| `MemoriNewDialogState` | widget → host | `DialogState` | Fired at every state change of the conversation, see [Conversation state](#conversation-state) |
|
|
654
|
+
| `MemoriEndSpeak` | widget → host | none | Fired when the Agent has finished answering (and speaking, if audio is enabled) |
|
|
655
|
+
| `artifactCreated` | widget → host | `{ artifact: ArtifactData, message: Message }` | Fired when an artifact is generated from an Agent message, see [Artifact API](#artifact-api) |
|
|
656
|
+
| `MemoriTextEntered` | host → widget | `{ text, waitForPrevious, hidden, typingText, useLoaderTextAsMsg, hasBatchQueued }` | Sends a message to the Agent. This is what `typeMessage` dispatches under the hood |
|
|
657
|
+
| `MemoriResetUIEffects` | host → widget | none | Stops TTS playback and resets pending UI timers |
|
|
658
|
+
|
|
659
|
+
```js
|
|
660
|
+
document.addEventListener('MemoriEndSpeak', () => {
|
|
661
|
+
console.log('Agent finished speaking');
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
document.addEventListener('artifactCreated', e => {
|
|
665
|
+
console.log('New artifact:', e.detail.artifact);
|
|
666
|
+
});
|
|
667
|
+
```
|
|
420
668
|
|
|
421
|
-
|
|
669
|
+
### Artifact API
|
|
422
670
|
|
|
423
|
-
|
|
671
|
+
The Memori widget exposes a global `window.MemoriArtifactAPI` that allows you to programmatically create and control [artifacts](#artifacts) from external JavaScript code. This is particularly useful for integrating with WebSockets, Action Cable, or any scenario where you need to inject and display artifacts dynamically.
|
|
424
672
|
|
|
425
673
|
```javascript
|
|
426
674
|
// Create and open a simple artifact
|
|
@@ -435,39 +683,50 @@ const state = window.MemoriArtifactAPI.getState();
|
|
|
435
683
|
console.log('Drawer open?', state.isDrawerOpen);
|
|
436
684
|
```
|
|
437
685
|
|
|
438
|
-
|
|
686
|
+
Available methods:
|
|
439
687
|
|
|
440
688
|
- `createAndOpenArtifact(content, mimeType?, title?)` - Create and open an artifact with simple parameters
|
|
441
|
-
- `openArtifact(artifact)` - Open an artifact with a complete ArtifactData object
|
|
442
|
-
- `createFromOutputElement(outputElement)` - Process a single `<output>` element from DOM
|
|
689
|
+
- `openArtifact(artifact)` - Open an artifact with a complete `ArtifactData` object
|
|
690
|
+
- `createFromOutputElement(outputElement)` - Process a single `<output>` element from DOM, returns the artifact id
|
|
443
691
|
- `closeArtifact()` - Close the current artifact drawer
|
|
444
692
|
- `toggleFullscreen()` - Toggle fullscreen mode
|
|
445
|
-
- `getState()` - Get the current state of the artifact system
|
|
446
|
-
|
|
447
|
-
## Conversation state change event
|
|
693
|
+
- `getState()` - Get the current state of the artifact system: `{ currentArtifact, isDrawerOpen, isFullscreen, isChatLogPanelPresentation }`
|
|
448
694
|
|
|
449
|
-
|
|
695
|
+
`ArtifactData` shape:
|
|
450
696
|
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
697
|
+
```ts
|
|
698
|
+
interface ArtifactData {
|
|
699
|
+
id: string; // unique id of this version
|
|
700
|
+
artifactId: string; // stable id across versions of the same artifact
|
|
701
|
+
content: string;
|
|
702
|
+
mimeType: string; // e.g. 'html', 'markdown', 'javascript', 'json', ...
|
|
703
|
+
title: string;
|
|
704
|
+
timestamp: Date;
|
|
705
|
+
size: number;
|
|
706
|
+
}
|
|
458
707
|
```
|
|
459
708
|
|
|
460
|
-
|
|
709
|
+
## Development
|
|
461
710
|
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
711
|
+
```bash
|
|
712
|
+
corepack enable && yarn install --immutable
|
|
713
|
+
|
|
714
|
+
yarn storybook # run Storybook on http://localhost:6006
|
|
715
|
+
yarn test # run tests in watch mode
|
|
716
|
+
yarn test:ci # run tests once (CI)
|
|
717
|
+
yarn lint # eslint + stylelint
|
|
718
|
+
yarn typecheck # tsc --noEmit
|
|
719
|
+
yarn build # build dist/ (CJS) and esm/ (ESM) + styles.css
|
|
466
720
|
```
|
|
467
721
|
|
|
468
|
-
|
|
722
|
+
Commits follow the [Conventional Commits](https://www.conventionalcommits.org/) spec (enforced by commitlint via husky); the [CHANGELOG](./CHANGELOG.md) is generated from them with release-it.
|
|
469
723
|
|
|
470
724
|
## See also
|
|
471
725
|
|
|
472
726
|
- [memori-api-client](https://github.com/memori-ai/memori-api-client) - API client for Memori
|
|
473
727
|
- [memori-webcomponent](https://github.com/memori-ai/memori-webcomponent) - Web component for Memori, uses this library
|
|
728
|
+
- [@memori.ai/ui](https://www.npmjs.com/package/@memori.ai/ui) - Design system used by this library
|
|
729
|
+
|
|
730
|
+
## License
|
|
731
|
+
|
|
732
|
+
[Apache-2.0](./LICENSE) © Memori Srl
|