@aws-amplify/ui-react-ai 0.1.0 → 0.1.1
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/esm/components/AIConversation/AIConversation.mjs +2 -1
- package/dist/esm/components/AIConversation/context/DisplayTextContext.mjs +9 -0
- package/dist/esm/components/AIConversation/createAIConversation.mjs +2 -1
- package/dist/esm/components/AIConversation/createProvider.mjs +19 -11
- package/dist/esm/components/AIConversation/displayText.mjs +7 -0
- package/dist/esm/components/AIConversation/views/Controls/ActionsBarControl.mjs +5 -0
- package/dist/esm/components/AIConversation/views/Controls/AttachFileControl.mjs +5 -0
- package/dist/esm/components/AIConversation/views/Controls/AttachmentListControl.mjs +5 -0
- package/dist/esm/components/AIConversation/views/Controls/AvatarControl.mjs +5 -0
- package/dist/esm/components/AIConversation/views/Controls/FieldControl.mjs +6 -5
- package/dist/esm/components/AIConversation/views/Controls/MessagesControl.mjs +8 -4
- package/dist/esm/components/AIConversation/views/Controls/PromptControl.mjs +5 -1
- package/dist/esm/components/AIConversation/views/default/MessageList.mjs +7 -2
- package/dist/index.js +117 -99
- package/dist/types/components/AIConversation/AIConversation.d.ts +2 -2
- package/dist/types/components/AIConversation/context/DisplayTextContext.d.ts +5 -0
- package/dist/types/components/AIConversation/context/index.d.ts +11 -7
- package/dist/types/components/AIConversation/createProvider.d.ts +2 -2
- package/dist/types/components/AIConversation/displayText.d.ts +2 -2
- package/dist/types/components/AIConversation/index.d.ts +2 -1
- package/dist/types/index.d.ts +3 -3
- package/package.json +4 -4
|
@@ -14,7 +14,7 @@ import { PromptList } from './views/default/PromptList.mjs';
|
|
|
14
14
|
import { ComponentClassName } from '@aws-amplify/ui';
|
|
15
15
|
import createProvider from './createProvider.mjs';
|
|
16
16
|
|
|
17
|
-
function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, }) {
|
|
17
|
+
function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }) {
|
|
18
18
|
const icons = useIcons('aiConversation');
|
|
19
19
|
const defaultAvatars = {
|
|
20
20
|
ai: {
|
|
@@ -42,6 +42,7 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
|
|
|
42
42
|
Form,
|
|
43
43
|
...controls,
|
|
44
44
|
},
|
|
45
|
+
displayText,
|
|
45
46
|
});
|
|
46
47
|
const providerProps = {
|
|
47
48
|
messages,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContextUtilities } from '@aws-amplify/ui-react-core';
|
|
2
|
+
import { defaultAIConversationDisplayTextEn } from '../displayText.mjs';
|
|
3
|
+
|
|
4
|
+
const { ConversationDisplayTextContext, ConversationDisplayTextProvider, useConversationDisplayText, } = createContextUtilities({
|
|
5
|
+
contextName: 'ConversationDisplayText',
|
|
6
|
+
defaultValue: defaultAIConversationDisplayTextEn,
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export { ConversationDisplayTextContext, ConversationDisplayTextProvider, useConversationDisplayText };
|
|
@@ -12,7 +12,7 @@ import createProvider from './createProvider.mjs';
|
|
|
12
12
|
* @experimental
|
|
13
13
|
*/
|
|
14
14
|
function createAIConversation(input = {}) {
|
|
15
|
-
const { elements, suggestedPrompts, actions, responseComponents, variant, controls, } = input;
|
|
15
|
+
const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, } = input;
|
|
16
16
|
const Provider = createProvider({
|
|
17
17
|
elements,
|
|
18
18
|
actions,
|
|
@@ -20,6 +20,7 @@ function createAIConversation(input = {}) {
|
|
|
20
20
|
responseComponents,
|
|
21
21
|
variant,
|
|
22
22
|
controls,
|
|
23
|
+
displayText,
|
|
23
24
|
});
|
|
24
25
|
function AIConversation(props) {
|
|
25
26
|
const { messages, avatars, handleSendMessage, isLoading } = props;
|
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
import React__default from 'react';
|
|
2
2
|
import { ElementsProvider } from '@aws-amplify/ui-react-core/elements';
|
|
3
|
+
import { defaultAIConversationDisplayTextEn } from './displayText.mjs';
|
|
3
4
|
import { ActionsProvider } from './context/ActionsContext.mjs';
|
|
4
5
|
import { AvatarsProvider } from './context/AvatarsContext.mjs';
|
|
5
6
|
import { ConversationInputContextProvider } from './context/ConversationInputContext.mjs';
|
|
6
7
|
import { MessagesProvider } from './context/MessagesContext.mjs';
|
|
7
|
-
import { MessageVariantProvider } from './context/MessageVariantContext.mjs';
|
|
8
8
|
import { SuggestedPromptProvider } from './context/SuggestedPromptsContext.mjs';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { MessageVariantProvider } from './context/MessageVariantContext.mjs';
|
|
10
|
+
import { ConversationDisplayTextProvider } from './context/DisplayTextContext.mjs';
|
|
11
11
|
import { ControlsProvider } from './context/ControlsContext.mjs';
|
|
12
12
|
import { LoadingContextProvider } from './context/LoadingContext.mjs';
|
|
13
|
+
import { ResponseComponentsProvider } from './context/ResponseComponentsContext.mjs';
|
|
14
|
+
import { SendMessageContextProvider } from './context/SendMessageContext.mjs';
|
|
15
|
+
import './context/elements/definitions.mjs';
|
|
13
16
|
|
|
14
|
-
function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, }) {
|
|
17
|
+
function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }) {
|
|
15
18
|
return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
|
|
19
|
+
const _displayText = {
|
|
20
|
+
...defaultAIConversationDisplayTextEn,
|
|
21
|
+
...displayText,
|
|
22
|
+
};
|
|
16
23
|
return (React__default.createElement(ElementsProvider, { elements: elements },
|
|
17
24
|
React__default.createElement(ControlsProvider, { controls: controls },
|
|
18
25
|
React__default.createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
|
|
19
26
|
React__default.createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
|
|
20
|
-
React__default.createElement(
|
|
21
|
-
React__default.createElement(
|
|
22
|
-
React__default.createElement(
|
|
23
|
-
React__default.createElement(
|
|
24
|
-
React__default.createElement(
|
|
25
|
-
React__default.createElement(
|
|
26
|
-
React__default.createElement(
|
|
27
|
+
React__default.createElement(ConversationDisplayTextProvider, { ..._displayText },
|
|
28
|
+
React__default.createElement(ConversationInputContextProvider, null,
|
|
29
|
+
React__default.createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
|
|
30
|
+
React__default.createElement(AvatarsProvider, { avatars: avatars },
|
|
31
|
+
React__default.createElement(ActionsProvider, { actions: actions },
|
|
32
|
+
React__default.createElement(MessageVariantProvider, { variant: variant },
|
|
33
|
+
React__default.createElement(MessagesProvider, { messages: messages },
|
|
34
|
+
React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))));
|
|
27
35
|
};
|
|
28
36
|
}
|
|
29
37
|
|
|
@@ -6,6 +6,11 @@ import '../../context/ConversationInputContext.mjs';
|
|
|
6
6
|
import '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
|
|
11
16
|
const { Button, Span, View } = AIConversationElements;
|
|
@@ -6,6 +6,11 @@ import { ConversationInputContext } from '../../context/ConversationInputContext
|
|
|
6
6
|
import '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
|
|
11
16
|
const { Button, Icon, View } = AIConversationElements;
|
|
@@ -6,6 +6,11 @@ import { ConversationInputContext } from '../../context/ConversationInputContext
|
|
|
6
6
|
import '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
|
|
11
16
|
const { Button, Icon, ListItem, UnorderedList: ListElement, Span, Text, View, } = AIConversationElements;
|
|
@@ -6,6 +6,11 @@ import '../../context/ConversationInputContext.mjs';
|
|
|
6
6
|
import { RoleContext } from '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
|
|
11
16
|
const { Icon, Span, Text, View } = AIConversationElements;
|
|
@@ -6,14 +6,15 @@ import { ConversationInputContext } from '../../context/ConversationInputContext
|
|
|
6
6
|
import { MessagesContext } from '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
11
|
+
import { LoadingContext } from '../../context/LoadingContext.mjs';
|
|
12
|
+
import { ResponseComponentsContext, convertResponseComponentsToToolConfiguration } from '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import { SendMessageContext } from '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
import { AttachFileControl } from './AttachFileControl.mjs';
|
|
11
16
|
import { AttachmentListControl } from './AttachmentListControl.mjs';
|
|
12
|
-
import { SendMessageContext } from '../../context/SendMessageContext.mjs';
|
|
13
|
-
import { ResponseComponentsContext, convertResponseComponentsToToolConfiguration } from '../../context/ResponseComponentsContext.mjs';
|
|
14
|
-
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
15
17
|
import { getImageTypeFromMimeType } from '../../utils.mjs';
|
|
16
|
-
import { LoadingContext } from '../../context/LoadingContext.mjs';
|
|
17
18
|
|
|
18
19
|
const { Button, Icon, Label: LabelElement, TextArea, View, } = AIConversationElements;
|
|
19
20
|
const FIELD_BLOCK = 'ai-field';
|
|
@@ -116,7 +117,7 @@ const FieldControl = () => {
|
|
|
116
117
|
const fileContent = {
|
|
117
118
|
image: {
|
|
118
119
|
format: getImageTypeFromMimeType(file.type),
|
|
119
|
-
source: { bytes: Uint8Array
|
|
120
|
+
source: { bytes: new Uint8Array(buffer) },
|
|
120
121
|
},
|
|
121
122
|
};
|
|
122
123
|
submittedContent.push(fileContent);
|
|
@@ -6,12 +6,15 @@ import '../../context/ConversationInputContext.mjs';
|
|
|
6
6
|
import { RoleContext, MessagesContext } from '../../context/MessagesContext.mjs';
|
|
7
7
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import { MessageVariantContext } from '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import { useConversationDisplayText } from '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import { ResponseComponentsContext } from '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
|
-
import { convertBufferToBase64
|
|
15
|
+
import { convertBufferToBase64 } from '../../utils.mjs';
|
|
11
16
|
import { ActionsBarControl } from './ActionsBarControl.mjs';
|
|
12
17
|
import { AvatarControl } from './AvatarControl.mjs';
|
|
13
|
-
import { ResponseComponentsContext } from '../../context/ResponseComponentsContext.mjs';
|
|
14
|
-
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
15
18
|
|
|
16
19
|
const { Image, Span, Text, View } = AIConversationElements;
|
|
17
20
|
const MESSAGES_BLOCK = 'ai-messages';
|
|
@@ -81,6 +84,7 @@ const Layout = React__default.forwardRef(function Layout(props, ref) {
|
|
|
81
84
|
const MessagesControl = ({ renderMessage }) => {
|
|
82
85
|
const messages = React__default.useContext(MessagesContext);
|
|
83
86
|
const controls = React__default.useContext(ControlsContext);
|
|
87
|
+
const { getMessageTimestampText } = useConversationDisplayText();
|
|
84
88
|
const messagesRef = React__default.useRef([]);
|
|
85
89
|
const [focusedItemIndex, setFocusedItemIndex] = React__default.useState(messages ? messages.length - 1 : 0);
|
|
86
90
|
const handleFocus = (index) => setFocusedItemIndex(index);
|
|
@@ -119,7 +123,7 @@ const MessagesControl = ({ renderMessage }) => {
|
|
|
119
123
|
React__default.createElement(HeaderContainer, null,
|
|
120
124
|
React__default.createElement(AvatarControl, null),
|
|
121
125
|
React__default.createElement(Separator, null),
|
|
122
|
-
React__default.createElement(Timestamp, null,
|
|
126
|
+
React__default.createElement(Timestamp, null, getMessageTimestampText(new Date(message.createdAt)))),
|
|
123
127
|
React__default.createElement(MessageControl, { message: message }),
|
|
124
128
|
message.role === 'assistant' ? (React__default.createElement(ActionsBarControl, { message: message, focusable: focusedItemIndex === index })) : null)));
|
|
125
129
|
})));
|
|
@@ -6,9 +6,13 @@ import { ConversationInputContext } from '../../context/ConversationInputContext
|
|
|
6
6
|
import { MessagesContext } from '../../context/MessagesContext.mjs';
|
|
7
7
|
import { SuggestedPromptsContext } from '../../context/SuggestedPromptsContext.mjs';
|
|
8
8
|
import '../../context/MessageVariantContext.mjs';
|
|
9
|
+
import '../../context/DisplayTextContext.mjs';
|
|
10
|
+
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
11
|
+
import '../../context/LoadingContext.mjs';
|
|
12
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
13
|
+
import '../../context/SendMessageContext.mjs';
|
|
9
14
|
import { AIConversationElements } from '../../context/elements/definitions.mjs';
|
|
10
15
|
import { classNames } from '@aws-amplify/ui';
|
|
11
|
-
import { ControlsContext } from '../../context/ControlsContext.mjs';
|
|
12
16
|
|
|
13
17
|
const { View, Button, Text, Heading, Icon } = AIConversationElements;
|
|
14
18
|
const PROMPT_BLOCK = 'ai-prompts';
|
|
@@ -7,19 +7,24 @@ import '../../context/ConversationInputContext.mjs';
|
|
|
7
7
|
import { RoleContext } from '../../context/MessagesContext.mjs';
|
|
8
8
|
import '../../context/SuggestedPromptsContext.mjs';
|
|
9
9
|
import { MessageVariantContext } from '../../context/MessageVariantContext.mjs';
|
|
10
|
+
import { useConversationDisplayText } from '../../context/DisplayTextContext.mjs';
|
|
11
|
+
import '../../context/ControlsContext.mjs';
|
|
12
|
+
import '../../context/LoadingContext.mjs';
|
|
13
|
+
import '../../context/ResponseComponentsContext.mjs';
|
|
14
|
+
import '../../context/SendMessageContext.mjs';
|
|
10
15
|
import '../../context/elements/definitions.mjs';
|
|
11
|
-
import { formatDate } from '../../utils.mjs';
|
|
12
16
|
import { ComponentClassName, classNames, classNameModifier } from '@aws-amplify/ui';
|
|
13
17
|
|
|
14
18
|
const MessageMeta = ({ message }) => {
|
|
15
19
|
// need to pass this in as props in order for it to be overridable
|
|
16
20
|
const avatars = React.useContext(AvatarsContext);
|
|
17
21
|
const role = React.useContext(RoleContext);
|
|
22
|
+
const { getMessageTimestampText } = useConversationDisplayText();
|
|
18
23
|
// maybe rename 'avatar' to something else
|
|
19
24
|
const avatar = role === 'assistant' ? avatars?.ai : avatars?.user;
|
|
20
25
|
return (React.createElement(View, { className: ComponentClassName.AIConversationMessageSender },
|
|
21
26
|
React.createElement(Text, { className: ComponentClassName.AIConversationMessageSenderUsername }, avatar?.username),
|
|
22
|
-
React.createElement(Text, { className: ComponentClassName.AIConversationMessageSenderTimestamp },
|
|
27
|
+
React.createElement(Text, { className: ComponentClassName.AIConversationMessageSenderTimestamp }, getMessageTimestampText(new Date(message.createdAt)))));
|
|
23
28
|
};
|
|
24
29
|
const Message = ({ message }) => {
|
|
25
30
|
const avatars = React.useContext(AvatarsContext);
|
package/dist/index.js
CHANGED
|
@@ -4,10 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var elements = require('@aws-amplify/ui-react-core/elements');
|
|
7
|
+
var uiReactCore = require('@aws-amplify/ui-react-core');
|
|
7
8
|
var ui = require('@aws-amplify/ui');
|
|
8
9
|
var uiReact = require('@aws-amplify/ui-react');
|
|
9
10
|
var internal = require('@aws-amplify/ui-react/internal');
|
|
10
|
-
var uiReactCore = require('@aws-amplify/ui-react-core');
|
|
11
11
|
|
|
12
12
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
13
13
|
|
|
@@ -154,6 +154,100 @@ const MessageVariantProvider = ({ children, variant, }) => {
|
|
|
154
154
|
return (React__default["default"].createElement(MessageVariantContext.Provider, { value: variant }, children));
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
+
function formatDate(date) {
|
|
158
|
+
const dateString = date.toLocaleDateString('en-US', {
|
|
159
|
+
weekday: 'short',
|
|
160
|
+
month: 'short',
|
|
161
|
+
day: 'numeric',
|
|
162
|
+
});
|
|
163
|
+
const timeString = date.toLocaleTimeString('en-US', {
|
|
164
|
+
hour: 'numeric',
|
|
165
|
+
minute: 'numeric',
|
|
166
|
+
hour12: true,
|
|
167
|
+
});
|
|
168
|
+
return `${dateString} at ${timeString}`;
|
|
169
|
+
}
|
|
170
|
+
function arrayBufferToBase64(buffer) {
|
|
171
|
+
let binary = '';
|
|
172
|
+
const bytes = new Uint8Array(buffer);
|
|
173
|
+
const len = bytes.byteLength;
|
|
174
|
+
for (let i = 0; i < len; i++) {
|
|
175
|
+
binary += String.fromCharCode(bytes[i]);
|
|
176
|
+
}
|
|
177
|
+
return window.btoa(binary);
|
|
178
|
+
}
|
|
179
|
+
function convertBufferToBase64(buffer, format) {
|
|
180
|
+
let base64string = '';
|
|
181
|
+
// Use node-based buffer if available
|
|
182
|
+
// fall back on browser if not
|
|
183
|
+
if (typeof Buffer !== 'undefined') {
|
|
184
|
+
base64string = Buffer.from(new Uint8Array(buffer)).toString('base64');
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
base64string = arrayBufferToBase64(buffer);
|
|
188
|
+
}
|
|
189
|
+
return `data:image/${format};base64,${base64string}`;
|
|
190
|
+
}
|
|
191
|
+
function getImageTypeFromMimeType(mimeType) {
|
|
192
|
+
return mimeType.split('/')[1];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const defaultAIConversationDisplayTextEn = {
|
|
196
|
+
getMessageTimestampText: (date) => formatDate(date),
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const { ConversationDisplayTextContext, ConversationDisplayTextProvider, useConversationDisplayText, } = uiReactCore.createContextUtilities({
|
|
200
|
+
contextName: 'ConversationDisplayText',
|
|
201
|
+
defaultValue: defaultAIConversationDisplayTextEn,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const ControlsContext = React__default["default"].createContext(undefined);
|
|
205
|
+
const ControlsProvider = ({ children, controls, }) => {
|
|
206
|
+
return (React__default["default"].createElement(ControlsContext.Provider, { value: controls }, children));
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const LoadingContext = React__default["default"].createContext(undefined);
|
|
210
|
+
const LoadingContextProvider = ({ children, isLoading, }) => {
|
|
211
|
+
return (React__default["default"].createElement(LoadingContext.Provider, { value: isLoading }, children));
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const ResponseComponentsContext = React__default["default"].createContext(undefined);
|
|
215
|
+
const ResponseComponentsProvider = ({ children, responseComponents, }) => {
|
|
216
|
+
return (React__default["default"].createElement(ResponseComponentsContext.Provider, { value: responseComponents }, children));
|
|
217
|
+
};
|
|
218
|
+
const convertResponseComponentsToToolConfiguration = (responseComponents) => {
|
|
219
|
+
if (!responseComponents) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const tools = {};
|
|
223
|
+
Object.keys(responseComponents).forEach((toolName) => {
|
|
224
|
+
const { props } = responseComponents[toolName];
|
|
225
|
+
const requiredProps = [];
|
|
226
|
+
Object.keys(props).forEach((propName) => {
|
|
227
|
+
if (props[propName].required)
|
|
228
|
+
requiredProps.push(propName);
|
|
229
|
+
});
|
|
230
|
+
tools[toolName] = {
|
|
231
|
+
description: responseComponents[toolName].description,
|
|
232
|
+
inputSchema: {
|
|
233
|
+
json: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
required: requiredProps,
|
|
236
|
+
properties: {
|
|
237
|
+
...props,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
return { tools };
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const SendMessageContext = React__default["default"].createContext(undefined);
|
|
247
|
+
const SendMessageContextProvider = ({ children, handleSendMessage, }) => {
|
|
248
|
+
return (React__default["default"].createElement(SendMessageContext.Provider, { value: handleSendMessage }, children));
|
|
249
|
+
};
|
|
250
|
+
|
|
157
251
|
const { Button: Button$5, Span: Span$3, View: View$7 } = AIConversationElements;
|
|
158
252
|
const ACTIONS_BAR_BLOCK = 'ai-actions-bar';
|
|
159
253
|
const ActionIcon = elements.withBaseElementProps(Span$3, {
|
|
@@ -370,91 +464,6 @@ const AttachmentListControl = () => {
|
|
|
370
464
|
AttachmentListControl.List = UnorderedList;
|
|
371
465
|
AttachmentListControl.Item = AttachmentControl;
|
|
372
466
|
|
|
373
|
-
const SendMessageContext = React__default["default"].createContext(undefined);
|
|
374
|
-
const SendMessageContextProvider = ({ children, handleSendMessage, }) => {
|
|
375
|
-
return (React__default["default"].createElement(SendMessageContext.Provider, { value: handleSendMessage }, children));
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
const ResponseComponentsContext = React__default["default"].createContext(undefined);
|
|
379
|
-
const ResponseComponentsProvider = ({ children, responseComponents, }) => {
|
|
380
|
-
return (React__default["default"].createElement(ResponseComponentsContext.Provider, { value: responseComponents }, children));
|
|
381
|
-
};
|
|
382
|
-
const convertResponseComponentsToToolConfiguration = (responseComponents) => {
|
|
383
|
-
if (!responseComponents) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
const tools = {};
|
|
387
|
-
Object.keys(responseComponents).forEach((toolName) => {
|
|
388
|
-
const { props } = responseComponents[toolName];
|
|
389
|
-
const requiredProps = [];
|
|
390
|
-
Object.keys(props).forEach((propName) => {
|
|
391
|
-
if (props[propName].required)
|
|
392
|
-
requiredProps.push(propName);
|
|
393
|
-
});
|
|
394
|
-
tools[toolName] = {
|
|
395
|
-
description: responseComponents[toolName].description,
|
|
396
|
-
inputSchema: {
|
|
397
|
-
json: {
|
|
398
|
-
type: 'object',
|
|
399
|
-
required: requiredProps,
|
|
400
|
-
properties: {
|
|
401
|
-
...props,
|
|
402
|
-
},
|
|
403
|
-
},
|
|
404
|
-
},
|
|
405
|
-
};
|
|
406
|
-
});
|
|
407
|
-
return { tools };
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
const ControlsContext = React__default["default"].createContext(undefined);
|
|
411
|
-
const ControlsProvider = ({ children, controls, }) => {
|
|
412
|
-
return (React__default["default"].createElement(ControlsContext.Provider, { value: controls }, children));
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
function formatDate(date) {
|
|
416
|
-
const dateString = date.toLocaleDateString('en-US', {
|
|
417
|
-
weekday: 'short',
|
|
418
|
-
month: 'short',
|
|
419
|
-
day: 'numeric',
|
|
420
|
-
});
|
|
421
|
-
const timeString = date.toLocaleTimeString('en-US', {
|
|
422
|
-
hour: 'numeric',
|
|
423
|
-
minute: 'numeric',
|
|
424
|
-
hour12: true,
|
|
425
|
-
});
|
|
426
|
-
return `${dateString} at ${timeString}`;
|
|
427
|
-
}
|
|
428
|
-
function arrayBufferToBase64(buffer) {
|
|
429
|
-
let binary = '';
|
|
430
|
-
const bytes = new Uint8Array(buffer);
|
|
431
|
-
const len = bytes.byteLength;
|
|
432
|
-
for (let i = 0; i < len; i++) {
|
|
433
|
-
binary += String.fromCharCode(bytes[i]);
|
|
434
|
-
}
|
|
435
|
-
return window.btoa(binary);
|
|
436
|
-
}
|
|
437
|
-
function convertBufferToBase64(buffer, format) {
|
|
438
|
-
let base64string = '';
|
|
439
|
-
// Use node-based buffer if available
|
|
440
|
-
// fall back on browser if not
|
|
441
|
-
if (typeof Buffer !== 'undefined') {
|
|
442
|
-
base64string = Buffer.from(new Uint8Array(buffer)).toString('base64');
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
base64string = arrayBufferToBase64(buffer);
|
|
446
|
-
}
|
|
447
|
-
return `data:image/${format};base64,${base64string}`;
|
|
448
|
-
}
|
|
449
|
-
function getImageTypeFromMimeType(mimeType) {
|
|
450
|
-
return mimeType.split('/')[1];
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const LoadingContext = React__default["default"].createContext(undefined);
|
|
454
|
-
const LoadingContextProvider = ({ children, isLoading, }) => {
|
|
455
|
-
return (React__default["default"].createElement(LoadingContext.Provider, { value: isLoading }, children));
|
|
456
|
-
};
|
|
457
|
-
|
|
458
467
|
const { Button: Button$1, Icon: Icon$1, Label: LabelElement, TextArea, View: View$2, } = AIConversationElements;
|
|
459
468
|
const FIELD_BLOCK = 'ai-field';
|
|
460
469
|
const SendIcon = elements.withBaseElementProps(Icon$1, {
|
|
@@ -556,7 +565,7 @@ const FieldControl = () => {
|
|
|
556
565
|
const fileContent = {
|
|
557
566
|
image: {
|
|
558
567
|
format: getImageTypeFromMimeType(file.type),
|
|
559
|
-
source: { bytes: Uint8Array
|
|
568
|
+
source: { bytes: new Uint8Array(buffer) },
|
|
560
569
|
},
|
|
561
570
|
};
|
|
562
571
|
submittedContent.push(fileContent);
|
|
@@ -673,6 +682,7 @@ const Layout = React__default["default"].forwardRef(function Layout(props, ref)
|
|
|
673
682
|
const MessagesControl = ({ renderMessage }) => {
|
|
674
683
|
const messages = React__default["default"].useContext(MessagesContext);
|
|
675
684
|
const controls = React__default["default"].useContext(ControlsContext);
|
|
685
|
+
const { getMessageTimestampText } = useConversationDisplayText();
|
|
676
686
|
const messagesRef = React__default["default"].useRef([]);
|
|
677
687
|
const [focusedItemIndex, setFocusedItemIndex] = React__default["default"].useState(messages ? messages.length - 1 : 0);
|
|
678
688
|
const handleFocus = (index) => setFocusedItemIndex(index);
|
|
@@ -711,7 +721,7 @@ const MessagesControl = ({ renderMessage }) => {
|
|
|
711
721
|
React__default["default"].createElement(HeaderContainer, null,
|
|
712
722
|
React__default["default"].createElement(AvatarControl, null),
|
|
713
723
|
React__default["default"].createElement(Separator, null),
|
|
714
|
-
React__default["default"].createElement(Timestamp, null,
|
|
724
|
+
React__default["default"].createElement(Timestamp, null, getMessageTimestampText(new Date(message.createdAt)))),
|
|
715
725
|
React__default["default"].createElement(MessageControl, { message: message }),
|
|
716
726
|
message.role === 'assistant' ? (React__default["default"].createElement(ActionsBarControl, { message: message, focusable: focusedItemIndex === index })) : null)));
|
|
717
727
|
})));
|
|
@@ -807,19 +817,24 @@ function Conversation() {
|
|
|
807
817
|
React__default["default"].createElement(FieldControl, null))));
|
|
808
818
|
}
|
|
809
819
|
|
|
810
|
-
function createProvider({ elements: elements$1, actions, suggestedPrompts, responseComponents, variant, controls, }) {
|
|
820
|
+
function createProvider({ elements: elements$1, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }) {
|
|
811
821
|
return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
|
|
822
|
+
const _displayText = {
|
|
823
|
+
...defaultAIConversationDisplayTextEn,
|
|
824
|
+
...displayText,
|
|
825
|
+
};
|
|
812
826
|
return (React__default["default"].createElement(elements.ElementsProvider, { elements: elements$1 },
|
|
813
827
|
React__default["default"].createElement(ControlsProvider, { controls: controls },
|
|
814
828
|
React__default["default"].createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
|
|
815
829
|
React__default["default"].createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
|
|
816
|
-
React__default["default"].createElement(
|
|
817
|
-
React__default["default"].createElement(
|
|
818
|
-
React__default["default"].createElement(
|
|
819
|
-
React__default["default"].createElement(
|
|
820
|
-
React__default["default"].createElement(
|
|
821
|
-
React__default["default"].createElement(
|
|
822
|
-
React__default["default"].createElement(
|
|
830
|
+
React__default["default"].createElement(ConversationDisplayTextProvider, { ..._displayText },
|
|
831
|
+
React__default["default"].createElement(ConversationInputContextProvider, null,
|
|
832
|
+
React__default["default"].createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
|
|
833
|
+
React__default["default"].createElement(AvatarsProvider, { avatars: avatars },
|
|
834
|
+
React__default["default"].createElement(ActionsProvider, { actions: actions },
|
|
835
|
+
React__default["default"].createElement(MessageVariantProvider, { variant: variant },
|
|
836
|
+
React__default["default"].createElement(MessagesProvider, { messages: messages },
|
|
837
|
+
React__default["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))));
|
|
823
838
|
};
|
|
824
839
|
}
|
|
825
840
|
|
|
@@ -827,7 +842,7 @@ function createProvider({ elements: elements$1, actions, suggestedPrompts, respo
|
|
|
827
842
|
* @experimental
|
|
828
843
|
*/
|
|
829
844
|
function createAIConversation(input = {}) {
|
|
830
|
-
const { elements, suggestedPrompts, actions, responseComponents, variant, controls, } = input;
|
|
845
|
+
const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, } = input;
|
|
831
846
|
const Provider = createProvider({
|
|
832
847
|
elements,
|
|
833
848
|
actions,
|
|
@@ -835,6 +850,7 @@ function createAIConversation(input = {}) {
|
|
|
835
850
|
responseComponents,
|
|
836
851
|
variant,
|
|
837
852
|
controls,
|
|
853
|
+
displayText,
|
|
838
854
|
});
|
|
839
855
|
function AIConversation(props) {
|
|
840
856
|
const { messages, avatars, handleSendMessage, isLoading } = props;
|
|
@@ -859,11 +875,12 @@ const MessageMeta = ({ message }) => {
|
|
|
859
875
|
// need to pass this in as props in order for it to be overridable
|
|
860
876
|
const avatars = React__namespace.useContext(AvatarsContext);
|
|
861
877
|
const role = React__namespace.useContext(RoleContext);
|
|
878
|
+
const { getMessageTimestampText } = useConversationDisplayText();
|
|
862
879
|
// maybe rename 'avatar' to something else
|
|
863
880
|
const avatar = role === 'assistant' ? avatars?.ai : avatars?.user;
|
|
864
881
|
return (React__namespace.createElement(uiReact.View, { className: ui.ComponentClassName.AIConversationMessageSender },
|
|
865
882
|
React__namespace.createElement(uiReact.Text, { className: ui.ComponentClassName.AIConversationMessageSenderUsername }, avatar?.username),
|
|
866
|
-
React__namespace.createElement(uiReact.Text, { className: ui.ComponentClassName.AIConversationMessageSenderTimestamp },
|
|
883
|
+
React__namespace.createElement(uiReact.Text, { className: ui.ComponentClassName.AIConversationMessageSenderTimestamp }, getMessageTimestampText(new Date(message.createdAt)))));
|
|
867
884
|
};
|
|
868
885
|
const Message = ({ message }) => {
|
|
869
886
|
const avatars = React__namespace.useContext(AvatarsContext);
|
|
@@ -969,7 +986,7 @@ const PromptList = ({ setInput, suggestedPrompts = [], }) => {
|
|
|
969
986
|
})));
|
|
970
987
|
};
|
|
971
988
|
|
|
972
|
-
function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, }) {
|
|
989
|
+
function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }) {
|
|
973
990
|
const icons = internal.useIcons('aiConversation');
|
|
974
991
|
const defaultAvatars = {
|
|
975
992
|
ai: {
|
|
@@ -997,6 +1014,7 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
|
|
|
997
1014
|
Form,
|
|
998
1015
|
...controls,
|
|
999
1016
|
},
|
|
1017
|
+
displayText,
|
|
1000
1018
|
});
|
|
1001
1019
|
const providerProps = {
|
|
1002
1020
|
messages,
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { AIConversationInput, AIConversationProps } from './types';
|
|
3
3
|
interface AIConversationBaseProps extends AIConversationProps, AIConversationInput {
|
|
4
4
|
}
|
|
5
|
-
declare function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, }: AIConversationBaseProps): JSX.Element;
|
|
5
|
+
declare function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }: AIConversationBaseProps): JSX.Element;
|
|
6
6
|
/**
|
|
7
7
|
* @experimental
|
|
8
8
|
*/
|
|
@@ -12,7 +12,7 @@ export declare const AIConversation: typeof AIConversationBase & {
|
|
|
12
12
|
}> | undefined;
|
|
13
13
|
PromptList: React.ComponentType<{
|
|
14
14
|
suggestedPrompts?: import("./types").SuggestedPrompt[] | undefined;
|
|
15
|
-
setInput: React.Dispatch<React.SetStateAction<import("./context
|
|
15
|
+
setInput: React.Dispatch<React.SetStateAction<import("./context").ConversationInput | undefined>> | undefined;
|
|
16
16
|
}> | undefined;
|
|
17
17
|
Form: React.ComponentType<{
|
|
18
18
|
handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ConversationDisplayText } from '../displayText';
|
|
3
|
+
export declare const ConversationDisplayTextContext: import("react").Context<Required<ConversationDisplayText> | undefined>, ConversationDisplayTextProvider: import("react").ComponentType<import("react").PropsWithChildren<Required<ConversationDisplayText>>>, useConversationDisplayText: (params?: {
|
|
4
|
+
errorMessage?: string | undefined;
|
|
5
|
+
} | undefined) => Required<ConversationDisplayText>;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export {
|
|
1
|
+
export { ActionsContext, ActionsProvider } from './ActionsContext';
|
|
2
|
+
export { AvatarsContext, AvatarsProvider } from './AvatarsContext';
|
|
3
|
+
export { ConversationInputContext, ConversationInput, ConversationInputContextProvider, } from './ConversationInputContext';
|
|
4
|
+
export { MessagesContext, RoleContext, MessagesProvider, } from './MessagesContext';
|
|
5
|
+
export { SuggestedPromptsContext, SuggestedPromptProvider, } from './SuggestedPromptsContext';
|
|
6
|
+
export { MessageVariantContext, MessageVariantProvider, } from './MessageVariantContext';
|
|
7
|
+
export { ConversationDisplayTextContext, useConversationDisplayText, ConversationDisplayTextProvider, } from './DisplayTextContext';
|
|
8
|
+
export { ControlsContext, ControlsContextProps, ControlsProvider, } from './ControlsContext';
|
|
9
|
+
export { LoadingContextProvider } from './LoadingContext';
|
|
10
|
+
export { ResponseComponentsProvider } from './ResponseComponentsContext';
|
|
11
|
+
export { SendMessageContextProvider } from './SendMessageContext';
|
|
8
12
|
export * from './elements';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { AIConversationInput, AIConversationProps } from './types';
|
|
3
|
-
export default function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, }: Pick<AIConversationInput, 'elements' | 'actions' | 'suggestedPrompts' | 'responseComponents' | 'variant' | 'controls'>): ({ children, messages, avatars, handleSendMessage, isLoading, }: {
|
|
3
|
+
export default function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }: Pick<AIConversationInput, 'elements' | 'actions' | 'suggestedPrompts' | 'responseComponents' | 'variant' | 'controls' | 'displayText'>): ({ children, messages, avatars, handleSendMessage, isLoading, }: {
|
|
4
4
|
children?: React.ReactNode;
|
|
5
|
-
} & Pick<AIConversationProps, "avatars" | "messages" | "
|
|
5
|
+
} & Pick<AIConversationProps, "avatars" | "messages" | "isLoading" | "handleSendMessage">) => React.JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DisplayTextTemplate } from '@aws-amplify/ui';
|
|
2
2
|
export type ConversationDisplayText = {
|
|
3
|
-
|
|
3
|
+
getMessageTimestampText?: (date: Date) => string;
|
|
4
4
|
};
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const defaultAIConversationDisplayTextEn: Required<AIConversationDisplayText>;
|
|
6
6
|
export type AIConversationDisplayText = DisplayTextTemplate<ConversationDisplayText>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { createAIConversation } from './createAIConversation';
|
|
2
2
|
import { AIConversation } from './AIConversation';
|
|
3
|
-
|
|
3
|
+
import { Avatars, CustomAction, ResponseComponent, SuggestedPrompt } from './types';
|
|
4
|
+
export { createAIConversation, AIConversation, Avatars, CustomAction, ResponseComponent, SuggestedPrompt, };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export {
|
|
1
|
+
export { createAIConversation, AIConversation, Avatars, CustomAction, ResponseComponent, SuggestedPrompt, } from './components';
|
|
2
|
+
export { createAIHooks, AIContextProvider } from './hooks';
|
|
3
|
+
export { ConversationMessage, ConversationMessageContent, SendMessage, SendMesageParameters, } from './types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-amplify/ui-react-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/esm/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"react-dom": "^16.14.0 || ^17.0 || ^18.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@aws-amplify/ui": "^6.4.
|
|
51
|
-
"@aws-amplify/ui-react": "^6.3.
|
|
52
|
-
"@aws-amplify/ui-react-core": "^3.0.
|
|
50
|
+
"@aws-amplify/ui": "^6.4.1",
|
|
51
|
+
"@aws-amplify/ui-react": "^6.3.1",
|
|
52
|
+
"@aws-amplify/ui-react-core": "^3.0.22"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@rollup/plugin-commonjs": "^22.0.1",
|