@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.
Files changed (22) hide show
  1. package/dist/esm/components/AIConversation/AIConversation.mjs +2 -1
  2. package/dist/esm/components/AIConversation/context/DisplayTextContext.mjs +9 -0
  3. package/dist/esm/components/AIConversation/createAIConversation.mjs +2 -1
  4. package/dist/esm/components/AIConversation/createProvider.mjs +19 -11
  5. package/dist/esm/components/AIConversation/displayText.mjs +7 -0
  6. package/dist/esm/components/AIConversation/views/Controls/ActionsBarControl.mjs +5 -0
  7. package/dist/esm/components/AIConversation/views/Controls/AttachFileControl.mjs +5 -0
  8. package/dist/esm/components/AIConversation/views/Controls/AttachmentListControl.mjs +5 -0
  9. package/dist/esm/components/AIConversation/views/Controls/AvatarControl.mjs +5 -0
  10. package/dist/esm/components/AIConversation/views/Controls/FieldControl.mjs +6 -5
  11. package/dist/esm/components/AIConversation/views/Controls/MessagesControl.mjs +8 -4
  12. package/dist/esm/components/AIConversation/views/Controls/PromptControl.mjs +5 -1
  13. package/dist/esm/components/AIConversation/views/default/MessageList.mjs +7 -2
  14. package/dist/index.js +117 -99
  15. package/dist/types/components/AIConversation/AIConversation.d.ts +2 -2
  16. package/dist/types/components/AIConversation/context/DisplayTextContext.d.ts +5 -0
  17. package/dist/types/components/AIConversation/context/index.d.ts +11 -7
  18. package/dist/types/components/AIConversation/createProvider.d.ts +2 -2
  19. package/dist/types/components/AIConversation/displayText.d.ts +2 -2
  20. package/dist/types/components/AIConversation/index.d.ts +2 -1
  21. package/dist/types/index.d.ts +3 -3
  22. 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 { ResponseComponentsProvider } from './context/ResponseComponentsContext.mjs';
10
- import { SendMessageContextProvider } from './context/SendMessageContext.mjs';
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(ConversationInputContextProvider, null,
21
- React__default.createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
22
- React__default.createElement(AvatarsProvider, { avatars: avatars },
23
- React__default.createElement(ActionsProvider, { actions: actions },
24
- React__default.createElement(MessageVariantProvider, { variant: variant },
25
- React__default.createElement(MessagesProvider, { messages: messages },
26
- React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))));
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
 
@@ -0,0 +1,7 @@
1
+ import { formatDate } from './utils.mjs';
2
+
3
+ const defaultAIConversationDisplayTextEn = {
4
+ getMessageTimestampText: (date) => formatDate(date),
5
+ };
6
+
7
+ export { defaultAIConversationDisplayTextEn };
@@ -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.from(Buffer.from(buffer)) },
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, formatDate } from '../../utils.mjs';
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, formatDate(new Date(message.createdAt)))),
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 }, formatDate(new Date(message.createdAt)))));
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.from(Buffer.from(buffer)) },
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, formatDate(new Date(message.createdAt)))),
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(ConversationInputContextProvider, null,
817
- React__default["default"].createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
818
- React__default["default"].createElement(AvatarsProvider, { avatars: avatars },
819
- React__default["default"].createElement(ActionsProvider, { actions: actions },
820
- React__default["default"].createElement(MessageVariantProvider, { variant: variant },
821
- React__default["default"].createElement(MessagesProvider, { messages: messages },
822
- React__default["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))));
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 }, formatDate(new Date(message.createdAt)))));
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/ConversationInputContext").ConversationInput | undefined>> | undefined;
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
- import { ActionsContext } from './ActionsContext';
2
- import { AvatarsContext } from './AvatarsContext';
3
- import { ConversationInputContext } from './ConversationInputContext';
4
- import { MessagesContext, RoleContext } from './MessagesContext';
5
- import { SuggestedPromptsContext } from './SuggestedPromptsContext';
6
- import { MessageVariantContext } from './MessageVariantContext';
7
- export { ActionsContext, AvatarsContext, ConversationInputContext, MessagesContext, RoleContext, SuggestedPromptsContext, MessageVariantContext, };
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" | "handleSendMessage" | "isLoading">) => React.JSX.Element;
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
- conversationHeaderText?: string;
3
+ getMessageTimestampText?: (date: Date) => string;
4
4
  };
5
- export declare const defaultAIConversationDisplayText: Required<AIConversationDisplayText>;
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
- export { createAIConversation, AIConversation };
3
+ import { Avatars, CustomAction, ResponseComponent, SuggestedPrompt } from './types';
4
+ export { createAIConversation, AIConversation, Avatars, CustomAction, ResponseComponent, SuggestedPrompt, };
@@ -1,3 +1,3 @@
1
- import { createAIConversation, AIConversation } from './components';
2
- import { createAIHooks, AIContextProvider } from './hooks';
3
- export { createAIConversation, createAIHooks, AIContextProvider, AIConversation, };
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.0",
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.0",
51
- "@aws-amplify/ui-react": "^6.3.0",
52
- "@aws-amplify/ui-react-core": "^3.0.21"
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",