@aws-amplify/ui-react-ai 0.3.1 → 0.4.0

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 (40) hide show
  1. package/dist/esm/components/AIConversation/AIConversation.mjs +31 -27
  2. package/dist/esm/components/AIConversation/{createProvider.mjs → AIConversationProvider.mjs} +15 -14
  3. package/dist/esm/components/AIConversation/context/MessageRenderContext.mjs +9 -0
  4. package/dist/esm/components/AIConversation/context/WelcomeMessageContext.mjs +8 -0
  5. package/dist/esm/components/AIConversation/createAIConversation.mjs +34 -31
  6. package/dist/esm/components/AIConversation/views/Controls/ActionsBarControl.mjs +3 -0
  7. package/dist/esm/components/AIConversation/views/Controls/AttachFileControl.mjs +3 -0
  8. package/dist/esm/components/AIConversation/views/Controls/AttachmentListControl.mjs +3 -0
  9. package/dist/esm/components/AIConversation/views/Controls/AvatarControl.mjs +3 -0
  10. package/dist/esm/components/AIConversation/views/Controls/DefaultMessageControl.mjs +29 -0
  11. package/dist/esm/components/AIConversation/views/Controls/{FieldControl.mjs → FormControl.mjs} +11 -9
  12. package/dist/esm/components/AIConversation/views/Controls/MessagesControl.mjs +25 -18
  13. package/dist/esm/components/AIConversation/views/Controls/PromptControl.mjs +7 -36
  14. package/dist/esm/components/AIConversation/views/default/MessageList.mjs +3 -0
  15. package/dist/esm/components/AIConversation/views/default/PromptList.mjs +1 -1
  16. package/dist/esm/hooks/useAIGeneration.mjs +29 -15
  17. package/dist/esm/version.mjs +3 -0
  18. package/dist/index.js +263 -284
  19. package/dist/types/components/AIConversation/AIConversation.d.ts +2 -16
  20. package/dist/types/components/AIConversation/AIConversationProvider.d.ts +6 -0
  21. package/dist/types/components/AIConversation/context/MessageRenderContext.d.ts +5 -0
  22. package/dist/types/components/AIConversation/context/WelcomeMessageContext.d.ts +8 -0
  23. package/dist/types/components/AIConversation/context/index.d.ts +3 -0
  24. package/dist/types/components/AIConversation/types.d.ts +21 -13
  25. package/dist/types/components/AIConversation/utils.d.ts +2 -2
  26. package/dist/types/components/AIConversation/views/Controls/DefaultMessageControl.d.ts +2 -0
  27. package/dist/types/components/AIConversation/views/Controls/{FieldControl.d.ts → FormControl.d.ts} +2 -2
  28. package/dist/types/components/AIConversation/views/Controls/MessagesControl.d.ts +2 -4
  29. package/dist/types/components/AIConversation/views/Controls/PromptControl.d.ts +0 -3
  30. package/dist/types/components/AIConversation/views/Controls/index.d.ts +3 -4
  31. package/dist/types/components/AIConversation/views/index.d.ts +2 -3
  32. package/dist/types/hooks/useAIGeneration.d.ts +12 -2
  33. package/dist/types/types.d.ts +6 -6
  34. package/dist/types/version.d.ts +1 -0
  35. package/package.json +20 -6
  36. package/dist/esm/components/AIConversation/views/Controls/HeaderControl.mjs +0 -34
  37. package/dist/esm/components/AIConversation/views/ConversationView.mjs +0 -20
  38. package/dist/types/components/AIConversation/createProvider.d.ts +0 -5
  39. package/dist/types/components/AIConversation/views/Controls/HeaderControl.d.ts +0 -9
  40. package/dist/types/components/AIConversation/views/ConversationView.d.ts +0 -2
@@ -2,19 +2,22 @@ import * as React from 'react';
2
2
  import { Text, Flex, ScrollView } from '@aws-amplify/ui-react';
3
3
  import { useIcons, IconAssistant, IconUser } from '@aws-amplify/ui-react/internal';
4
4
  import { MessagesControl } from './views/Controls/MessagesControl.mjs';
5
- import './context/elements/definitions.mjs';
6
- import './views/Controls/ActionsBarControl.mjs';
7
- import './views/Controls/AvatarControl.mjs';
8
- import './views/Controls/HeaderControl.mjs';
9
- import { FieldControl } from './views/Controls/FieldControl.mjs';
10
- import { AutoHidablePromptControl } from './views/Controls/PromptControl.mjs';
5
+ import { FormControl } from './views/Controls/FormControl.mjs';
11
6
  import { MessageList } from './views/default/MessageList.mjs';
12
7
  import { Form } from './views/default/Form.mjs';
13
8
  import { PromptList } from './views/default/PromptList.mjs';
14
9
  import { ComponentClassName } from '@aws-amplify/ui';
15
- import createProvider from './createProvider.mjs';
10
+ import { AIConversationProvider } from './AIConversationProvider.mjs';
11
+ import { useSetUserAgent } from '@aws-amplify/ui-react-core';
12
+ import { VERSION } from '../../version.mjs';
13
+ import { DefaultMessageControl } from './views/Controls/DefaultMessageControl.mjs';
16
14
 
17
- function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, }) {
15
+ function Provider({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, messageRenderer, children, }) {
16
+ useSetUserAgent({
17
+ componentName: 'AIConversation',
18
+ packageName: 'react-ai',
19
+ version: VERSION,
20
+ });
18
21
  const icons = useIcons('aiConversation');
19
22
  const defaultAvatars = {
20
23
  ai: {
@@ -26,11 +29,16 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
26
29
  avatar: icons?.user ?? React.createElement(IconUser, null),
27
30
  },
28
31
  };
29
- const Provider = createProvider({
32
+ const providerProps = {
33
+ messages,
34
+ handleSendMessage,
35
+ avatars: {
36
+ ...defaultAvatars,
37
+ ...avatars,
38
+ },
39
+ isLoading,
30
40
  elements: {
31
- Text: React.forwardRef(function _Text(props, ref) {
32
- return React.createElement(Text, { ...props, ref: ref });
33
- }),
41
+ Text,
34
42
  },
35
43
  actions,
36
44
  suggestedPrompts,
@@ -44,30 +52,26 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
44
52
  },
45
53
  displayText,
46
54
  allowAttachments,
47
- });
48
- const providerProps = {
49
- messages,
50
- handleSendMessage,
51
- avatars: {
52
- ...defaultAvatars,
53
- ...avatars,
54
- },
55
- isLoading,
55
+ messageRenderer,
56
56
  };
57
- return (React.createElement(Provider, { ...providerProps },
57
+ return (React.createElement(AIConversationProvider, { ...providerProps }, children));
58
+ }
59
+ function AIConversationBase(props) {
60
+ return (React.createElement(Provider, { ...props },
58
61
  React.createElement(Flex, { className: ComponentClassName.AIConversation },
59
62
  React.createElement(ScrollView, { autoScroll: "smooth", flex: "1" },
60
- React.createElement(AutoHidablePromptControl, null),
63
+ React.createElement(DefaultMessageControl, null),
61
64
  React.createElement(MessagesControl, null)),
62
- React.createElement(FieldControl, null))));
65
+ React.createElement(FormControl, null))));
63
66
  }
64
67
  /**
65
68
  * @experimental
66
69
  */
67
70
  const AIConversation = Object.assign(AIConversationBase, {
68
- MessageList,
69
- PromptList,
70
- Form,
71
+ Provider,
72
+ DefaultMessage: DefaultMessageControl,
73
+ Messages: MessagesControl,
74
+ Form: FormControl,
71
75
  });
72
76
 
73
77
  export { AIConversation };
@@ -12,18 +12,20 @@ import { ControlsProvider } from './context/ControlsContext.mjs';
12
12
  import { LoadingContextProvider } from './context/LoadingContext.mjs';
13
13
  import { ResponseComponentsProvider } from './context/ResponseComponentsContext.mjs';
14
14
  import { SendMessageContextProvider } from './context/SendMessageContext.mjs';
15
- import './context/elements/definitions.mjs';
15
+ import './context/MessageRenderContext.mjs';
16
16
  import { AttachmentProvider } from './context/AttachmentContext.mjs';
17
+ import { WelcomeMessageProvider } from './context/WelcomeMessageContext.mjs';
18
+ import './context/elements/definitions.mjs';
17
19
 
18
- function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, allowAttachments, }) {
19
- return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
20
- const _displayText = {
21
- ...defaultAIConversationDisplayTextEn,
22
- ...displayText,
23
- };
24
- return (React__default.createElement(ElementsProvider, { elements: elements },
25
- React__default.createElement(ControlsProvider, { controls: controls },
26
- React__default.createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
20
+ const AIConversationProvider = ({ actions, allowAttachments, avatars, children, controls, displayText, elements, handleSendMessage, isLoading, messages, responseComponents, suggestedPrompts, variant, welcomeMessage, }) => {
21
+ const _displayText = {
22
+ ...defaultAIConversationDisplayTextEn,
23
+ ...displayText,
24
+ };
25
+ return (React__default.createElement(ElementsProvider, { elements: elements },
26
+ React__default.createElement(ControlsProvider, { controls: controls },
27
+ React__default.createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
28
+ React__default.createElement(WelcomeMessageProvider, { welcomeMessage: welcomeMessage },
27
29
  React__default.createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
28
30
  React__default.createElement(AttachmentProvider, { allowAttachments: allowAttachments },
29
31
  React__default.createElement(ConversationDisplayTextProvider, { ..._displayText },
@@ -33,8 +35,7 @@ function createProvider({ elements, actions, suggestedPrompts, responseComponent
33
35
  React__default.createElement(ActionsProvider, { actions: actions },
34
36
  React__default.createElement(MessageVariantProvider, { variant: variant },
35
37
  React__default.createElement(MessagesProvider, { messages: messages },
36
- React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))))));
37
- };
38
- }
38
+ React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))))));
39
+ };
39
40
 
40
- export { createProvider as default };
41
+ export { AIConversationProvider };
@@ -0,0 +1,9 @@
1
+ import { createContextUtilities } from '@aws-amplify/ui-react-core';
2
+
3
+ const { MessageRendererContext, MessageRendererProvider, useMessageRenderer, } = createContextUtilities({
4
+ contextName: 'MessageRenderer',
5
+ defaultValue: undefined,
6
+ errorMessage: '`useMessageRenderer` must be used with an AIConversation component',
7
+ });
8
+
9
+ export { MessageRendererContext, MessageRendererProvider, useMessageRenderer };
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+
3
+ const WelcomeMessageContext = React.createContext(undefined);
4
+ const WelcomeMessageProvider = ({ children, welcomeMessage, }) => {
5
+ return (React.createElement(WelcomeMessageContext.Provider, { value: welcomeMessage }, children));
6
+ };
7
+
8
+ export { WelcomeMessageContext, WelcomeMessageProvider };
@@ -1,44 +1,47 @@
1
1
  import React__default from 'react';
2
- import Conversation from './views/ConversationView.mjs';
3
- import { ActionsBarControl } from './views/Controls/ActionsBarControl.mjs';
4
- import { AvatarControl } from './views/Controls/AvatarControl.mjs';
5
- import { HeaderControl } from './views/Controls/HeaderControl.mjs';
6
- import { FieldControl } from './views/Controls/FieldControl.mjs';
2
+ import './views/Controls/ActionsBarControl.mjs';
3
+ import './views/Controls/AvatarControl.mjs';
4
+ import { FormControl } from './views/Controls/FormControl.mjs';
7
5
  import { MessagesControl } from './views/Controls/MessagesControl.mjs';
8
- import { PromptControl } from './views/Controls/PromptControl.mjs';
9
- import createProvider from './createProvider.mjs';
6
+ import './views/Controls/PromptControl.mjs';
7
+ import { ViewElement } from './context/elements/definitions.mjs';
8
+ import { AIConversationProvider } from './AIConversationProvider.mjs';
9
+ import { DefaultMessageControl } from './views/Controls/DefaultMessageControl.mjs';
10
10
 
11
11
  /**
12
12
  * @experimental
13
13
  */
14
14
  function createAIConversation(input = {}) {
15
- const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, } = input;
16
- const Provider = createProvider({
17
- elements,
18
- actions,
19
- suggestedPrompts,
20
- responseComponents,
21
- variant,
22
- controls,
23
- displayText,
24
- allowAttachments,
25
- });
15
+ const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, messageRenderer, } = input;
26
16
  function AIConversation(props) {
27
17
  const { messages, avatars, handleSendMessage, isLoading } = props;
28
- return (React__default.createElement(Provider, { messages: messages, avatars: avatars, handleSendMessage: handleSendMessage, isLoading: isLoading },
29
- React__default.createElement(Conversation, null)));
18
+ const providerProps = {
19
+ elements,
20
+ actions,
21
+ suggestedPrompts,
22
+ responseComponents,
23
+ variant,
24
+ controls,
25
+ displayText,
26
+ allowAttachments,
27
+ messages,
28
+ avatars,
29
+ handleSendMessage,
30
+ isLoading,
31
+ messageRenderer,
32
+ };
33
+ return (React__default.createElement(AIConversationProvider, { ...providerProps },
34
+ React__default.createElement(ViewElement, null,
35
+ React__default.createElement(ViewElement, null,
36
+ React__default.createElement(DefaultMessageControl, null),
37
+ React__default.createElement(MessagesControl, null)),
38
+ React__default.createElement(ViewElement, null,
39
+ React__default.createElement(FormControl, null)))));
30
40
  }
31
- const Controls = {
32
- ActionsBar: ActionsBarControl,
33
- Avatars: AvatarControl,
34
- Field: FieldControl,
35
- Header: HeaderControl,
36
- Messages: MessagesControl,
37
- SuggestedPrompts: PromptControl,
38
- };
39
- AIConversation.Provider = Provider;
40
- AIConversation.Conversation = Conversation;
41
- AIConversation.Controls = Controls;
41
+ AIConversation.Provider = AIConversationProvider;
42
+ AIConversation.DefaultMessage = DefaultMessageControl;
43
+ AIConversation.Messages = MessagesControl;
44
+ AIConversation.Form = FormControl;
42
45
  return { AIConversation };
43
46
  }
44
47
 
@@ -11,6 +11,9 @@ import '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
 
16
19
  const { Button, Span, View } = AIConversationElements;
@@ -11,6 +11,9 @@ import '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
  import { useDropZone } from '@aws-amplify/ui-react-core';
16
19
 
@@ -11,6 +11,9 @@ import '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
 
16
19
  const { Button, Icon, ListItem, UnorderedList: ListElement, Span, Text, View, } = AIConversationElements;
@@ -11,6 +11,9 @@ import '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
 
16
19
  const { Icon, Span, Text, View } = AIConversationElements;
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import '../../context/ActionsContext.mjs';
3
+ import '../../context/AvatarsContext.mjs';
4
+ import '../../context/ConversationInputContext.mjs';
5
+ import { MessagesContext } from '../../context/MessagesContext.mjs';
6
+ import '../../context/SuggestedPromptsContext.mjs';
7
+ import '../../context/MessageVariantContext.mjs';
8
+ import '../../context/DisplayTextContext.mjs';
9
+ import '../../context/ControlsContext.mjs';
10
+ import '../../context/LoadingContext.mjs';
11
+ import '../../context/ResponseComponentsContext.mjs';
12
+ import '../../context/SendMessageContext.mjs';
13
+ import '../../context/MessageRenderContext.mjs';
14
+ import '../../context/AttachmentContext.mjs';
15
+ import { WelcomeMessageContext } from '../../context/WelcomeMessageContext.mjs';
16
+ import '../../context/elements/definitions.mjs';
17
+ import { PromptControl } from './PromptControl.mjs';
18
+
19
+ const DefaultMessageControl = () => {
20
+ const messages = React.useContext(MessagesContext);
21
+ const welcomeMessage = React.useContext(WelcomeMessageContext);
22
+ if (!messages || messages.length === 0) {
23
+ return (React.createElement(React.Fragment, null,
24
+ welcomeMessage,
25
+ React.createElement(PromptControl, null)));
26
+ }
27
+ };
28
+
29
+ export { DefaultMessageControl };
@@ -11,11 +11,13 @@ import { ControlsContext } from '../../context/ControlsContext.mjs';
11
11
  import { LoadingContext } from '../../context/LoadingContext.mjs';
12
12
  import { ResponseComponentsContext, convertResponseComponentsToToolConfiguration } from '../../context/ResponseComponentsContext.mjs';
13
13
  import { SendMessageContext } from '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import { AttachmentContext } from '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
  import { AttachFileControl } from './AttachFileControl.mjs';
16
19
  import { AttachmentListControl } from './AttachmentListControl.mjs';
17
20
  import { getImageTypeFromMimeType } from '../../utils.mjs';
18
- import { AttachmentContext } from '../../context/AttachmentContext.mjs';
19
21
 
20
22
  const { Button, Icon, Label: LabelElement, TextArea, View, } = AIConversationElements;
21
23
  const FIELD_BLOCK = 'ai-field';
@@ -97,7 +99,7 @@ const TextInput = React__default.forwardRef(function TextInput(props, ref) {
97
99
  const InputContainer = withBaseElementProps(View, {
98
100
  className: `${FIELD_BLOCK}__input-container`,
99
101
  });
100
- const FieldControl = () => {
102
+ const FormControl = () => {
101
103
  const { input, setInput } = React__default.useContext(ConversationInputContext);
102
104
  const handleSendMessage = React__default.useContext(SendMessageContext);
103
105
  const allowAttachments = React__default.useContext(AttachmentContext);
@@ -161,11 +163,11 @@ const FieldControl = () => {
161
163
  React__default.createElement(SendButton, null,
162
164
  React__default.createElement(SendIcon, null))));
163
165
  };
164
- FieldControl.AttachFile = AttachFileControl;
165
- FieldControl.InputContainer = InputContainer;
166
- FieldControl.Label = Label;
167
- FieldControl.TextInput = TextInput;
168
- FieldControl.SendButton = SendButton;
169
- FieldControl.SendIcon = SendIcon;
166
+ FormControl.AttachFile = AttachFileControl;
167
+ FormControl.InputContainer = InputContainer;
168
+ FormControl.Label = Label;
169
+ FormControl.TextInput = TextInput;
170
+ FormControl.SendButton = SendButton;
171
+ FormControl.SendIcon = SendIcon;
170
172
 
171
- export { FieldControl };
173
+ export { FormControl };
@@ -9,8 +9,11 @@ import { MessageVariantContext } from '../../context/MessageVariantContext.mjs';
9
9
  import { useConversationDisplayText } from '../../context/DisplayTextContext.mjs';
10
10
  import { ControlsContext } from '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
- import { ResponseComponentsContext, RESPONSE_COMPONENT_PREFIX } from '../../context/ResponseComponentsContext.mjs';
12
+ import { RESPONSE_COMPONENT_PREFIX, ResponseComponentsContext } from '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import { MessageRendererContext } from '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
18
  import { convertBufferToBase64 } from '../../utils.mjs';
16
19
  import { ActionsBarControl } from './ActionsBarControl.mjs';
@@ -34,28 +37,32 @@ const ContentContainer = React__default.forwardRef(function ContentContainer(pro
34
37
  const variant = React__default.useContext(MessageVariantContext);
35
38
  return (React__default.createElement(View, { "data-testid": 'content', className: `${MESSAGE_BLOCK}__content ${MESSAGE_BLOCK}__content--${variant}`, ref: ref, ...props }));
36
39
  });
37
- const MessageControl = ({ message }) => {
40
+ const ToolContent = ({ toolUse, }) => {
38
41
  const responseComponents = React__default.useContext(ResponseComponentsContext);
42
+ // For now tool use is limited to custom response components
43
+ const { name, input } = toolUse;
44
+ if (!responseComponents ||
45
+ !name ||
46
+ !name.startsWith(RESPONSE_COMPONENT_PREFIX)) {
47
+ return;
48
+ }
49
+ else {
50
+ const response = responseComponents[name];
51
+ const CustomComponent = response.component;
52
+ return React__default.createElement(CustomComponent, { ...input });
53
+ }
54
+ };
55
+ const MessageControl = ({ message }) => {
56
+ const messageRenderer = React__default.useContext(MessageRendererContext);
39
57
  return (React__default.createElement(ContentContainer, null, message.content.map((content, index) => {
40
58
  if (content.text) {
41
- return (React__default.createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
59
+ return messageRenderer?.text ? (React__default.createElement(React__default.Fragment, { key: index }, messageRenderer.text({ text: content.text }))) : (React__default.createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
42
60
  }
43
61
  else if (content.image) {
44
- return (React__default.createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
62
+ return messageRenderer?.image ? (React__default.createElement(React__default.Fragment, { key: index }, messageRenderer?.image({ image: content.image }))) : (React__default.createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
45
63
  }
46
64
  else if (content.toolUse) {
47
- // For now tool use is limited to custom response components
48
- const { name, input } = content.toolUse;
49
- if (!responseComponents ||
50
- !name ||
51
- !name.startsWith(RESPONSE_COMPONENT_PREFIX)) {
52
- return;
53
- }
54
- else {
55
- const response = responseComponents[name];
56
- const CustomComponent = response.component;
57
- return React__default.createElement(CustomComponent, { ...input, key: index });
58
- }
65
+ return React__default.createElement(ToolContent, { toolUse: content.toolUse, key: index });
59
66
  }
60
67
  })));
61
68
  };
@@ -83,7 +90,7 @@ const Layout = React__default.forwardRef(function Layout(props, ref) {
83
90
  const variant = React__default.useContext(MessageVariantContext);
84
91
  return (React__default.createElement(View, { ref: ref, className: `${MESSAGES_BLOCK}__container ${MESSAGES_BLOCK}__container--${variant}`, "aria-live": 'assertive', ...props }));
85
92
  });
86
- const MessagesControl = ({ renderMessage }) => {
93
+ const MessagesControl = () => {
87
94
  const messages = React__default.useContext(MessagesContext);
88
95
  const controls = React__default.useContext(ControlsContext);
89
96
  const { getMessageTimestampText } = useConversationDisplayText();
@@ -123,7 +130,7 @@ const MessagesControl = ({ renderMessage }) => {
123
130
  content.text ??
124
131
  content.toolUse?.name.startsWith(RESPONSE_COMPONENT_PREFIX))) ?? [];
125
132
  return (React__default.createElement(Layout, null, messagesWithRenderableContent?.map((message, index) => {
126
- return renderMessage ? (renderMessage(message)) : (React__default.createElement(RoleContext.Provider, { value: message.role, key: `message-${index}` },
133
+ return (React__default.createElement(RoleContext.Provider, { value: message.role, key: `message-${index}` },
127
134
  React__default.createElement(MessageContainer, { "data-testid": `message`, key: `message-${index}`, tabIndex: focusedItemIndex === index ? 0 : -1, onFocus: () => handleFocus(index), onKeyDown: (event) => onKeyDown(index, event), ref: (el) => (messagesRef.current[index] = el) },
128
135
  React__default.createElement(HeaderContainer, null,
129
136
  React__default.createElement(AvatarControl, null),
@@ -3,7 +3,7 @@ import { withBaseElementProps } from '@aws-amplify/ui-react-core/elements';
3
3
  import '../../context/ActionsContext.mjs';
4
4
  import '../../context/AvatarsContext.mjs';
5
5
  import { ConversationInputContext } from '../../context/ConversationInputContext.mjs';
6
- import { MessagesContext } from '../../context/MessagesContext.mjs';
6
+ import '../../context/MessagesContext.mjs';
7
7
  import { SuggestedPromptsContext } from '../../context/SuggestedPromptsContext.mjs';
8
8
  import '../../context/MessageVariantContext.mjs';
9
9
  import '../../context/DisplayTextContext.mjs';
@@ -11,10 +11,12 @@ import { ControlsContext } from '../../context/ControlsContext.mjs';
11
11
  import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
+ import '../../context/MessageRenderContext.mjs';
15
+ import '../../context/AttachmentContext.mjs';
16
+ import '../../context/WelcomeMessageContext.mjs';
14
17
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
- import { classNames } from '@aws-amplify/ui';
16
18
 
17
- const { View, Button, Text, Heading, Icon } = AIConversationElements;
19
+ const { View, Button } = AIConversationElements;
18
20
  const PROMPT_BLOCK = 'ai-prompts';
19
21
  const PROMPT_CONTROL = `${PROMPT_BLOCK}__prompt`;
20
22
  const PROMPT_CARD = `${PROMPT_CONTROL}__card`;
@@ -22,25 +24,6 @@ const PromptCard = withBaseElementProps(Button, {
22
24
  className: PROMPT_CARD,
23
25
  type: 'button',
24
26
  });
25
- const AIIconProps = () => ({
26
- children: (React__default.createElement(React__default.Fragment, null,
27
- React__default.createElement("path", { d: "M17.5 1.64858C19.047 0.755412 20.953 0.755412 22.5 1.64858L34.6428 8.65923C36.1898 9.55239 37.1428 11.203 37.1428 12.9894V27.0107C37.1428 28.797 36.1898 30.4476 34.6428 31.3408L22.5 38.3514C20.953 39.2446 19.047 39.2446 17.5 38.3514L5.35718 31.3408C3.81017 30.4476 2.85718 28.797 2.85718 27.0107V12.9894C2.85718 11.203 3.81017 9.55239 5.35718 8.65923L17.5 1.64858Z", fill: "white" }),
28
- React__default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M22.5 1.64851C20.953 0.755347 19.047 0.755347 17.5 1.64851L5.35718 8.65916C3.81017 9.55233 2.85718 11.203 2.85718 12.9893V27.0106C2.85718 28.7969 3.81017 30.4476 5.35718 31.3407L17.5 38.3514C19.047 39.2445 20.953 39.2445 22.5 38.3514L34.6428 31.3407C36.1898 30.4476 37.1428 28.7969 37.1428 27.0106V12.9893C37.1428 11.203 36.1898 9.55233 34.6428 8.65916L22.5 1.64851ZM20.9378 8.01826C20.6156 7.14764 19.3843 7.14764 19.0621 8.01825L16.2388 15.648C16.1375 15.9217 15.9217 16.1375 15.648 16.2388L8.01826 19.0621C7.14765 19.3842 7.14765 20.6156 8.01826 20.9378L15.648 23.7611C15.9217 23.8623 16.1375 24.0782 16.2388 24.3519L19.0621 31.9816C19.3843 32.8522 20.6156 32.8522 20.9378 31.9816L23.7611 24.3519C23.8624 24.0782 24.0782 23.8623 24.3519 23.7611L31.9816 20.9378C32.8523 20.6156 32.8523 19.3842 31.9816 19.0621L24.3519 16.2388C24.0782 16.1375 23.8624 15.9217 23.7611 15.648L20.9378 8.01826Z", fill: "url(#paint0_linear_395_1815)" }),
29
- React__default.createElement("defs", null,
30
- React__default.createElement("linearGradient", { id: "paint0_linear_395_1815", x1: "20", y1: "0.978638", x2: "20", y2: "39.0213", gradientUnits: "userSpaceOnUse" },
31
- React__default.createElement("stop", { stopColor: "#7DD6E8" }),
32
- React__default.createElement("stop", { offset: "1", stopColor: "#BF40BF" }))))),
33
- className: `${PROMPT_CONTROL}__icon`,
34
- width: '40',
35
- height: '40',
36
- viewBox: '0 0 40 40',
37
- fill: 'none',
38
- xmlns: 'http://www.w3.org/2000/svg',
39
- });
40
- const AIIcon = withBaseElementProps(Icon, AIIconProps);
41
- const HeaderText = withBaseElementProps(Heading, {
42
- className: `${PROMPT_CONTROL}__header`,
43
- });
44
27
  const PromptGroupBase = withBaseElementProps(View, {
45
28
  className: `${PROMPT_CONTROL}__buttongroup`,
46
29
  });
@@ -55,9 +38,7 @@ const PromptGroup = React__default.forwardRef(function ButtonGroup(props, ref) {
55
38
  setInput((prevInput) => ({
56
39
  ...prevInput,
57
40
  text: prompt.inputText,
58
- })) },
59
- React__default.createElement(Text, { className: classNames(`${PROMPT_CARD}__header`, `${PROMPT_CARD}__text`) }, prompt.header),
60
- React__default.createElement(Text, { className: `${PROMPT_CARD}__text` }, prompt.inputText)));
41
+ })) }, prompt.component));
61
42
  })));
62
43
  });
63
44
  const Container = withBaseElementProps(View, {
@@ -71,20 +52,10 @@ const PromptControl = () => {
71
52
  return (React__default.createElement(controls.PromptList, { setInput: setInput, suggestedPrompts: suggestedPromptsArray }));
72
53
  }
73
54
  return (React__default.createElement(Container, null,
74
- React__default.createElement(AIIcon, null),
75
- React__default.createElement(HeaderText, null, "How can I help you today?"),
76
55
  React__default.createElement(PromptGroup, null)));
77
56
  };
78
- const AutoHidablePromptControl = () => {
79
- const messages = React__default.useContext(MessagesContext);
80
- if (!messages || messages.length === 0) {
81
- return React__default.createElement(PromptControl, null);
82
- }
83
- };
84
57
  PromptControl.Container = Container;
85
- PromptControl.Header = HeaderText;
86
- PromptControl.Icon = AIIcon;
87
58
  PromptControl.PromptGroup = PromptGroup;
88
59
  PromptControl.PromptCard = PromptCard;
89
60
 
90
- export { AutoHidablePromptControl, PromptControl };
61
+ export { PromptControl };
@@ -12,6 +12,9 @@ import '../../context/ControlsContext.mjs';
12
12
  import { LoadingContext } from '../../context/LoadingContext.mjs';
13
13
  import { RESPONSE_COMPONENT_PREFIX } from '../../context/ResponseComponentsContext.mjs';
14
14
  import '../../context/SendMessageContext.mjs';
15
+ import '../../context/MessageRenderContext.mjs';
16
+ import '../../context/AttachmentContext.mjs';
17
+ import '../../context/WelcomeMessageContext.mjs';
15
18
  import '../../context/elements/definitions.mjs';
16
19
  import { ComponentClassName, classNames, classNameModifier } from '@aws-amplify/ui';
17
20
 
@@ -9,7 +9,7 @@ const PromptList = ({ setInput, suggestedPrompts = [], }) => {
9
9
  ...prevInput,
10
10
  text: prompt.inputText,
11
11
  }));
12
- } }, prompt.header));
12
+ } }, prompt.component));
13
13
  })));
14
14
  };
15
15
 
@@ -1,21 +1,35 @@
1
- import { useDataState } from '@aws-amplify/ui-react-core';
1
+ import * as React from 'react';
2
2
 
3
+ // default state
4
+ const INITIAL_STATE = {
5
+ hasError: false,
6
+ isLoading: false,
7
+ messages: undefined,
8
+ };
9
+ const LOADING_STATE = { hasError: false, isLoading: true, messages: undefined };
10
+ const ERROR_STATE = { hasError: true, isLoading: false };
3
11
  function createUseAIGeneration(client) {
4
12
  const useAIGeneration = (routeName) => {
5
- const handleGenerate = client.generations[routeName];
6
- const updateAIGenerationStateAction = async (_prev, input) => {
7
- const result = await handleGenerate(input);
8
- // handleGenerate returns a Promised wrapper around Schema[Key]['returnType'] which includes data, errors, and clientExtensions
9
- // The type of data is Schema[Key]['returnType'] which useDataState also wraps in a data return
10
- // TODO: follow up with how to type handleGenerate to properly return the promise wrapper shape
11
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
12
- const data = result.data;
13
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
14
- const graphqlErrors = result.errors;
15
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment
16
- return { ...data, ...(graphqlErrors ? { graphqlErrors } : {}) };
17
- };
18
- return useDataState(updateAIGenerationStateAction, {});
13
+ const [dataState, setDataState] = React.useState(() => ({
14
+ ...INITIAL_STATE,
15
+ data: undefined,
16
+ }));
17
+ const handleGeneration = React.useCallback(async (input) => {
18
+ setDataState(({ data }) => ({ ...LOADING_STATE, data }));
19
+ const result = await client.generations[routeName](input);
20
+ const { data, errors } = result;
21
+ if (errors) {
22
+ setDataState({
23
+ ...ERROR_STATE,
24
+ data,
25
+ messages: errors,
26
+ });
27
+ }
28
+ else {
29
+ setDataState({ ...INITIAL_STATE, data });
30
+ }
31
+ }, [routeName]);
32
+ return [dataState, handleGeneration];
19
33
  };
20
34
  return useAIGeneration;
21
35
  }
@@ -0,0 +1,3 @@
1
+ const VERSION = '0.4.0';
2
+
3
+ export { VERSION };