@aws-amplify/ui-react-ai 1.4.0 → 1.5.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 (45) hide show
  1. package/README.md +21 -15
  2. package/dist/esm/components/AIConversation/AIConversation.mjs +8 -13
  3. package/dist/esm/components/AIConversation/context/elements/definitions.mjs +4 -7
  4. package/dist/esm/components/AIConversation/useConversationScrollProps.mjs +31 -0
  5. package/dist/esm/components/AIConversation/views/default/Form.mjs +14 -1
  6. package/dist/esm/hooks/useAIConversation.mjs +16 -16
  7. package/dist/esm/hooks/useAIGeneration.mjs +5 -12
  8. package/dist/esm/version.mjs +1 -1
  9. package/dist/index.js +72 -48
  10. package/dist/types/components/AIConversation/AIConversation.d.ts +1 -1
  11. package/dist/types/components/AIConversation/AIConversationProvider.d.ts +1 -1
  12. package/dist/types/components/AIConversation/context/ActionsContext.d.ts +1 -1
  13. package/dist/types/components/AIConversation/context/AttachmentContext.d.ts +1 -1
  14. package/dist/types/components/AIConversation/context/AvatarsContext.d.ts +1 -1
  15. package/dist/types/components/AIConversation/context/ControlsContext.d.ts +3 -3
  16. package/dist/types/components/AIConversation/context/DisplayTextContext.d.ts +1 -1
  17. package/dist/types/components/AIConversation/context/FallbackComponentContext.d.ts +1 -1
  18. package/dist/types/components/AIConversation/context/MessageRenderContext.d.ts +1 -1
  19. package/dist/types/components/AIConversation/context/MessageVariantContext.d.ts +1 -1
  20. package/dist/types/components/AIConversation/context/MessagesContext.d.ts +1 -1
  21. package/dist/types/components/AIConversation/context/ResponseComponentsContext.d.ts +1 -1
  22. package/dist/types/components/AIConversation/context/SendMessageContext.d.ts +1 -1
  23. package/dist/types/components/AIConversation/context/SuggestedPromptsContext.d.ts +1 -1
  24. package/dist/types/components/AIConversation/context/index.d.ts +6 -3
  25. package/dist/types/components/AIConversation/createAIConversation.d.ts +1 -1
  26. package/dist/types/components/AIConversation/displayText.d.ts +1 -1
  27. package/dist/types/components/AIConversation/index.d.ts +4 -3
  28. package/dist/types/components/AIConversation/types.d.ts +7 -7
  29. package/dist/types/components/AIConversation/useConversationScrollProps.d.ts +6 -0
  30. package/dist/types/components/AIConversation/utils.d.ts +1 -1
  31. package/dist/types/components/AIConversation/views/Controls/ActionsBarControl.d.ts +1 -1
  32. package/dist/types/components/AIConversation/views/Controls/MessagesControl.d.ts +1 -1
  33. package/dist/types/components/AIConversation/views/default/Attachments.d.ts +1 -1
  34. package/dist/types/components/AIConversation/views/default/Form.d.ts +1 -1
  35. package/dist/types/components/AIConversation/views/default/MessageList.d.ts +1 -1
  36. package/dist/types/components/AIConversation/views/default/PromptList.d.ts +1 -1
  37. package/dist/types/hooks/contentFromEvents.d.ts +1 -1
  38. package/dist/types/hooks/createAIHooks.d.ts +3 -3
  39. package/dist/types/hooks/exhaustivelyListMessages.d.ts +1 -1
  40. package/dist/types/hooks/shared.d.ts +8 -6
  41. package/dist/types/hooks/useAIConversation.d.ts +3 -3
  42. package/dist/types/hooks/useAIGeneration.d.ts +4 -4
  43. package/dist/types/index.d.ts +3 -2
  44. package/dist/types/version.d.ts +1 -1
  45. package/package.json +5 -5
package/README.md CHANGED
@@ -1,23 +1,29 @@
1
- # Amplify UI
1
+ # Amplify UI React AI
2
2
 
3
- Amplify UI is an open-source UI library with cloud-connected components that are endlessly customizable, accessible, and can integrate into _any_ application. Amplify UI consists of:
3
+ The React AI package provides components and utilities for AI-powered conversations and interactions in Amplify connected applications.
4
4
 
5
- 1. Connected components that simplify complex cloud-connected workflows, like Authenticator.
6
- 2. Primitive components that create consistency across Amplify UI and allow you to build complete applications that fit your brand, like Buttons and Badges.
7
- 3. Data-bound components that make it easy to display dynamic data, like DataStoreCollections.
8
- 4. Theming capabilities that allow you to customize the appearance of Amplify UI to match your brand.
5
+ ## Contents
9
6
 
10
- ## React Documentation
7
+ ### Core Components
11
8
 
12
- - https://ui.docs.amplify.aws/react
9
+ - `AIConversation` - Component for AI-powered conversations
10
+ - `createAIConversation` - Factory function for creating AI conversation components
11
+
12
+ ### Utility Functions
13
13
 
14
- ## Features 🚀
14
+ - `createAIHooks` - Factory function for creating AI-related hooks
15
15
 
16
- - **Better developer experience** Connected-components like Authenticator are being written with framework-specific implementations so that they follow framework conventions and are easier to integrate into your application.
17
- - **Endlessly customizable** Every detail of Amplify UI is customizable to match your brand. Style all of Amplify UI with themes, override components with your own, or build your own UI and use Amplify for complex state management.
18
- - **Accessible** Amplify UI components follow [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) and [WAI-ARIA](https://www.w3.org/TR/wai-aria-1.2/) best practices and guidelines such as color contrast, keyboard navigation, accessible labels, and focus management.
19
- - **Primitive components (React only right now)** Primitive components are used in the connected components, like Authenticator, you can also customize them and use them to build the rest of your UI.
16
+ ### Type Definitions
20
17
 
21
- ## We love contributors!!
18
+ - `Avatars` - Type for avatar configurations
19
+ - `CustomAction` - Type for custom actions
20
+ - `ResponseComponent` - Type for response components
21
+ - `SuggestedPrompt` - Type for suggested prompts
22
+ - `ConversationMessage` - Type for conversation messages
23
+ - `ConversationMessageContent` - Type for conversation message content
24
+ - `SendMessage` - Type for send message function
25
+ - `SendMesageParameters` - Type for send message parameters
22
26
 
23
- See our contributing guide [CONTRIBUTING.md](/CONTRIBUTING.md) to help us scale Amplify UI!
27
+ ## React Documentation
28
+
29
+ - https://ui.docs.amplify.aws/react
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { Flex, ScrollView } from '@aws-amplify/ui-react';
3
- import { useIcons, IconAssistant, IconUser } from '@aws-amplify/ui-react/internal';
3
+ import { useIcons, IconUser, IconAssistant } from '@aws-amplify/ui-react/internal';
4
+ import useConversationScrollProps from './useConversationScrollProps.mjs';
4
5
  import { MessagesControl } from './views/Controls/MessagesControl.mjs';
5
6
  import { FormControl } from './views/Controls/FormControl.mjs';
6
7
  import { MessageList } from './views/default/MessageList.mjs';
@@ -12,7 +13,7 @@ import { useSetUserAgent } from '@aws-amplify/ui-react-core';
12
13
  import { VERSION } from '../../version.mjs';
13
14
  import { DefaultMessageControl } from './views/Controls/DefaultMessageControl.mjs';
14
15
 
15
- function AIConversationBase({ avatars, controls, ...rest }) {
16
+ function AIConversationBase({ avatars, controls, messages, ...rest }) {
16
17
  useSetUserAgent({
17
18
  componentName: 'AIConversation',
18
19
  packageName: 'react-ai',
@@ -31,20 +32,14 @@ function AIConversationBase({ avatars, controls, ...rest }) {
31
32
  };
32
33
  const providerProps = {
33
34
  ...rest,
34
- avatars: {
35
- ...defaultAvatars,
36
- ...avatars,
37
- },
38
- controls: {
39
- MessageList,
40
- PromptList,
41
- Form,
42
- ...controls,
43
- },
35
+ avatars: { ...defaultAvatars, ...avatars },
36
+ controls: { MessageList, PromptList, Form, ...controls },
37
+ messages,
44
38
  };
39
+ const scrollProps = useConversationScrollProps(messages);
45
40
  return (React.createElement(AIConversationProvider, { ...providerProps },
46
41
  React.createElement(Flex, { className: ComponentClassName.AIConversation, testId: "ai-conversation" },
47
- React.createElement(ScrollView, { autoScroll: "smooth", flex: "1" },
42
+ React.createElement(ScrollView, { ...scrollProps, flex: "1" },
48
43
  React.createElement(DefaultMessageControl, null),
49
44
  React.createElement(MessagesControl, null)),
50
45
  React.createElement(FormControl, null))));
@@ -17,15 +17,15 @@ const ListItemElement = defineBaseElementWithRef({
17
17
  type: 'li',
18
18
  displayName: 'ListItem',
19
19
  });
20
- const HeadingElement = defineBaseElementWithRef({
20
+ defineBaseElementWithRef({
21
21
  type: 'h2',
22
22
  displayName: 'Title',
23
23
  });
24
- const ImageElement = defineBaseElementWithRef({
24
+ defineBaseElementWithRef({
25
25
  type: 'img',
26
26
  displayName: 'Image',
27
27
  });
28
- const InputElement = defineBaseElementWithRef({
28
+ defineBaseElementWithRef({
29
29
  type: 'input',
30
30
  displayName: 'Input',
31
31
  });
@@ -44,10 +44,7 @@ const TextAreaElement = defineBaseElementWithRef({
44
44
  });
45
45
  const AIConversationElements = {
46
46
  Button: ButtonElement,
47
- Heading: HeadingElement,
48
47
  Icon: IconElement,
49
- Input: InputElement,
50
- Image: ImageElement,
51
48
  Label: LabelElement,
52
49
  ListItem: ListItemElement,
53
50
  Span: SpanElement,
@@ -57,4 +54,4 @@ const AIConversationElements = {
57
54
  View: ViewElement,
58
55
  };
59
56
 
60
- export { AIConversationElements, ButtonElement, HeadingElement, ImageElement, InputElement, LabelElement, ListItemElement, SpanElement, TextAreaElement, TextElement, UnorderedListElement, ViewElement };
57
+ export { AIConversationElements, ButtonElement, LabelElement, ListItemElement, SpanElement, TextAreaElement, TextElement, UnorderedListElement, ViewElement };
@@ -0,0 +1,31 @@
1
+ import * as React from 'react';
2
+ import { useHasValueUpdated } from '@aws-amplify/ui-react-core';
3
+
4
+ function useConversationScrollProps(messages) {
5
+ const [autoScroll, setAutoScroll] = React.useState('smooth');
6
+ const messagesLength = messages.length;
7
+ const hasMessagesLengthChanged = useHasValueUpdated(messagesLength, true);
8
+ const lastScrollTop = React.useRef();
9
+ const onScroll = ({ currentTarget }) => {
10
+ if (autoScroll !== 'smooth')
11
+ return;
12
+ const { scrollTop } = currentTarget;
13
+ // set `autoScroll` and `lastScrollTop` to `undefined` on user scroll up
14
+ if (lastScrollTop.current && scrollTop < lastScrollTop.current) {
15
+ setAutoScroll(undefined);
16
+ lastScrollTop.current = undefined;
17
+ }
18
+ else {
19
+ lastScrollTop.current = scrollTop;
20
+ }
21
+ };
22
+ React.useEffect(() => {
23
+ // reset `autoScroll` to 'smooth' on new message
24
+ if (hasMessagesLengthChanged) {
25
+ setAutoScroll('smooth');
26
+ }
27
+ }, [hasMessagesLengthChanged]);
28
+ return { autoScroll, onScroll };
29
+ }
30
+
31
+ export { useConversationScrollProps as default };
@@ -46,7 +46,20 @@ const Form = ({ setInput, input, handleSubmit, allowAttachments, onValidate, isL
46
46
  }
47
47
  onValidate(Array.from(e.target.files));
48
48
  }, multiple: true, accept: [...validFileTypes].map((type) => `.${type}`).join(','), "data-testid": "hidden-file-input" })))) : null,
49
- React.createElement(TextAreaField, { className: ComponentClassName.AIConversationFormField, label: "input", labelHidden: true, autoResize: true, flex: "1", rows: 1, value: input?.text ?? '', testId: "text-input", onCompositionStart: () => setComposing(true), onCompositionEnd: () => setComposing(false), onKeyDown: (e) => {
49
+ React.createElement(TextAreaField, { className: ComponentClassName.AIConversationFormField, label: "input", labelHidden: true, autoResize: true, flex: "1", rows: 1, value: input?.text ?? '', testId: "text-input", onCompositionStart: () => setComposing(true), onCompositionUpdate: (e) => {
50
+ const composedText = e?.currentTarget?.value || '';
51
+ setInput?.((prevValue) => ({
52
+ ...prevValue,
53
+ text: composedText,
54
+ }));
55
+ }, onCompositionEnd: (e) => {
56
+ setComposing(false);
57
+ const composedText = e?.currentTarget?.value || '';
58
+ setInput?.((prevValue) => ({
59
+ ...prevValue,
60
+ text: composedText,
61
+ }));
62
+ }, onKeyDown: (e) => {
50
63
  // Submit on enter key if shift is not pressed also
51
64
  const shouldSubmit = !e.shiftKey && e.key === 'Enter' && !composing;
52
65
  if (shouldSubmit && isHTMLFormElement(e.target)) {
@@ -27,11 +27,11 @@ function createUseAIConversation(client) {
27
27
  // it will create a new conversation when it is executed
28
28
  // we don't want to create 2 conversations
29
29
  const initRef = React__default.useRef('initial');
30
- const [dataState, setDataState] = React__default.useState(() => ({
30
+ const [clientState, setClientState] = React__default.useState(() => ({
31
31
  ...INITIAL_STATE,
32
32
  data: { messages: [], conversation: undefined },
33
33
  }));
34
- const { conversation } = dataState.data;
34
+ const { conversation } = clientState.data;
35
35
  const { id, onInitialize, onMessage } = input;
36
36
  React__default.useEffect(() => {
37
37
  async function initialize() {
@@ -43,7 +43,7 @@ function createUseAIConversation(client) {
43
43
  // Only show component loading state if we are
44
44
  // actually loading messages
45
45
  if (id) {
46
- setDataState({
46
+ setClientState({
47
47
  ...LOADING_STATE,
48
48
  data: { messages: [], conversation: undefined },
49
49
  });
@@ -52,7 +52,7 @@ function createUseAIConversation(client) {
52
52
  ? await clientRoute.get({ id })
53
53
  : await clientRoute.create();
54
54
  if (errors ?? !conversation) {
55
- setDataState({
55
+ setClientState({
56
56
  ...ERROR_STATE,
57
57
  data: { messages: [] },
58
58
  messages: errors,
@@ -63,13 +63,13 @@ function createUseAIConversation(client) {
63
63
  const { data: messages } = await exhaustivelyListMessages({
64
64
  conversation,
65
65
  });
66
- setDataState({
66
+ setClientState({
67
67
  ...INITIAL_STATE,
68
68
  data: { messages, conversation },
69
69
  });
70
70
  }
71
71
  else {
72
- setDataState({
72
+ setClientState({
73
73
  ...INITIAL_STATE,
74
74
  data: { conversation, messages: [] },
75
75
  });
@@ -87,7 +87,7 @@ function createUseAIConversation(client) {
87
87
  errorInfo: null,
88
88
  errorType: '',
89
89
  };
90
- setDataState({
90
+ setClientState({
91
91
  ...ERROR_STATE,
92
92
  data: { messages: [] },
93
93
  // TODO in MV bump: remove `messages`
@@ -101,12 +101,12 @@ function createUseAIConversation(client) {
101
101
  contentBlocksRef.current = undefined;
102
102
  if (hasStarted(initRef.current))
103
103
  return;
104
- setDataState({
104
+ setClientState({
105
105
  ...INITIAL_STATE,
106
106
  data: { messages: [], conversation: undefined },
107
107
  });
108
108
  };
109
- }, [clientRoute, id, setDataState]);
109
+ }, [clientRoute, id, setClientState]);
110
110
  // Run a separate effect that is triggered by the conversation state
111
111
  // so that we know we have a conversation object to set up the subscription
112
112
  // and also unsubscribe on cleanup
@@ -134,7 +134,7 @@ function createUseAIConversation(client) {
134
134
  // stop reason will signify end of conversation turn
135
135
  if (stopReason) {
136
136
  // remove loading state from streamed message
137
- setDataState((prev) => {
137
+ setClientState((prev) => {
138
138
  return {
139
139
  ...prev,
140
140
  data: {
@@ -181,7 +181,7 @@ function createUseAIConversation(client) {
181
181
  ];
182
182
  }
183
183
  }
184
- setDataState((prev) => {
184
+ setClientState((prev) => {
185
185
  const message = {
186
186
  id,
187
187
  conversationId,
@@ -202,7 +202,7 @@ function createUseAIConversation(client) {
202
202
  });
203
203
  },
204
204
  error: (error) => {
205
- setDataState((prev) => {
205
+ setClientState((prev) => {
206
206
  return {
207
207
  ...prev,
208
208
  ...ERROR_STATE,
@@ -220,11 +220,11 @@ function createUseAIConversation(client) {
220
220
  contentBlocksRef.current = undefined;
221
221
  subscription.unsubscribe();
222
222
  };
223
- }, [conversation, onInitialize, onMessage, setDataState]);
223
+ }, [conversation, onInitialize, onMessage, setClientState]);
224
224
  const handleSendMessage = React__default.useCallback((input) => {
225
225
  const { content } = input;
226
226
  if (conversation) {
227
- setDataState((prevState) => ({
227
+ setClientState((prevState) => ({
228
228
  ...prevState,
229
229
  data: {
230
230
  ...prevState.data,
@@ -257,7 +257,7 @@ function createUseAIConversation(client) {
257
257
  errorInfo: null,
258
258
  errorType: '',
259
259
  };
260
- setDataState((prev) => ({
260
+ setClientState((prev) => ({
261
261
  ...prev,
262
262
  ...ERROR_STATE,
263
263
  // TODO in MV bump: remove `messages`
@@ -266,7 +266,7 @@ function createUseAIConversation(client) {
266
266
  }));
267
267
  }
268
268
  }, [conversation]);
269
- return [dataState, handleSendMessage];
269
+ return [clientState, handleSendMessage];
270
270
  };
271
271
  return useAIConversation;
272
272
  }
@@ -3,26 +3,19 @@ import { INITIAL_STATE, LOADING_STATE, ERROR_STATE } from './shared.mjs';
3
3
 
4
4
  function createUseAIGeneration(client) {
5
5
  const useAIGeneration = (routeName) => {
6
- const [dataState, setDataState] = React.useState(() => ({
7
- ...INITIAL_STATE,
8
- data: undefined,
9
- }));
6
+ const [clientState, setClientState] = React.useState(() => ({ ...INITIAL_STATE, data: undefined }));
10
7
  const handleGeneration = React.useCallback(async (input) => {
11
- setDataState(({ data }) => ({ ...LOADING_STATE, data }));
8
+ setClientState(({ data }) => ({ ...LOADING_STATE, data }));
12
9
  const result = await client.generations[routeName](input);
13
10
  const { data, errors } = result;
14
11
  if (errors) {
15
- setDataState({
16
- ...ERROR_STATE,
17
- data,
18
- messages: errors,
19
- });
12
+ setClientState({ ...ERROR_STATE, data, messages: errors });
20
13
  }
21
14
  else {
22
- setDataState({ ...INITIAL_STATE, data });
15
+ setClientState({ ...INITIAL_STATE, data });
23
16
  }
24
17
  }, [routeName]);
25
- return [dataState, handleGeneration];
18
+ return [clientState, handleGeneration];
26
19
  };
27
20
  return useAIGeneration;
28
21
  }
@@ -1,3 +1,3 @@
1
- const VERSION = '1.4.0';
1
+ const VERSION = '1.5.0';
2
2
 
3
3
  export { VERSION };
package/dist/index.js CHANGED
@@ -342,15 +342,15 @@ const ListItemElement = elements.defineBaseElementWithRef({
342
342
  type: 'li',
343
343
  displayName: 'ListItem',
344
344
  });
345
- const HeadingElement = elements.defineBaseElementWithRef({
345
+ elements.defineBaseElementWithRef({
346
346
  type: 'h2',
347
347
  displayName: 'Title',
348
348
  });
349
- const ImageElement = elements.defineBaseElementWithRef({
349
+ elements.defineBaseElementWithRef({
350
350
  type: 'img',
351
351
  displayName: 'Image',
352
352
  });
353
- const InputElement = elements.defineBaseElementWithRef({
353
+ elements.defineBaseElementWithRef({
354
354
  type: 'input',
355
355
  displayName: 'Input',
356
356
  });
@@ -369,10 +369,7 @@ const TextAreaElement = elements.defineBaseElementWithRef({
369
369
  });
370
370
  const AIConversationElements = {
371
371
  Button: ButtonElement,
372
- Heading: HeadingElement,
373
372
  Icon: IconElement,
374
- Input: InputElement,
375
- Image: ImageElement,
376
373
  Label: LabelElement$1,
377
374
  ListItem: ListItemElement,
378
375
  Span: SpanElement,
@@ -1037,6 +1034,33 @@ function createAIConversation(input = {}) {
1037
1034
  return { AIConversation };
1038
1035
  }
1039
1036
 
1037
+ function useConversationScrollProps(messages) {
1038
+ const [autoScroll, setAutoScroll] = React__namespace.useState('smooth');
1039
+ const messagesLength = messages.length;
1040
+ const hasMessagesLengthChanged = uiReactCore.useHasValueUpdated(messagesLength, true);
1041
+ const lastScrollTop = React__namespace.useRef();
1042
+ const onScroll = ({ currentTarget }) => {
1043
+ if (autoScroll !== 'smooth')
1044
+ return;
1045
+ const { scrollTop } = currentTarget;
1046
+ // set `autoScroll` and `lastScrollTop` to `undefined` on user scroll up
1047
+ if (lastScrollTop.current && scrollTop < lastScrollTop.current) {
1048
+ setAutoScroll(undefined);
1049
+ lastScrollTop.current = undefined;
1050
+ }
1051
+ else {
1052
+ lastScrollTop.current = scrollTop;
1053
+ }
1054
+ };
1055
+ React__namespace.useEffect(() => {
1056
+ // reset `autoScroll` to 'smooth' on new message
1057
+ if (hasMessagesLengthChanged) {
1058
+ setAutoScroll('smooth');
1059
+ }
1060
+ }, [hasMessagesLengthChanged]);
1061
+ return { autoScroll, onScroll };
1062
+ }
1063
+
1040
1064
  const PlaceholderMessage = ({ role }) => {
1041
1065
  const variant = React__namespace.useContext(MessageVariantContext);
1042
1066
  return (React__namespace.createElement(uiReact.View, { className: ui.classNames(ui.ComponentClassName.AIConversationMessage, ui.classNameModifier(ui.ComponentClassName.AIConversationMessage, variant), ui.classNameModifier(ui.ComponentClassName.AIConversationMessage, role)) },
@@ -1163,7 +1187,20 @@ const Form = ({ setInput, input, handleSubmit, allowAttachments, onValidate, isL
1163
1187
  }
1164
1188
  onValidate(Array.from(e.target.files));
1165
1189
  }, multiple: true, accept: [...validFileTypes].map((type) => `.${type}`).join(','), "data-testid": "hidden-file-input" })))) : null,
1166
- React__namespace.createElement(uiReact.TextAreaField, { className: ui.ComponentClassName.AIConversationFormField, label: "input", labelHidden: true, autoResize: true, flex: "1", rows: 1, value: input?.text ?? '', testId: "text-input", onCompositionStart: () => setComposing(true), onCompositionEnd: () => setComposing(false), onKeyDown: (e) => {
1190
+ React__namespace.createElement(uiReact.TextAreaField, { className: ui.ComponentClassName.AIConversationFormField, label: "input", labelHidden: true, autoResize: true, flex: "1", rows: 1, value: input?.text ?? '', testId: "text-input", onCompositionStart: () => setComposing(true), onCompositionUpdate: (e) => {
1191
+ const composedText = e?.currentTarget?.value || '';
1192
+ setInput?.((prevValue) => ({
1193
+ ...prevValue,
1194
+ text: composedText,
1195
+ }));
1196
+ }, onCompositionEnd: (e) => {
1197
+ setComposing(false);
1198
+ const composedText = e?.currentTarget?.value || '';
1199
+ setInput?.((prevValue) => ({
1200
+ ...prevValue,
1201
+ text: composedText,
1202
+ }));
1203
+ }, onKeyDown: (e) => {
1167
1204
  // Submit on enter key if shift is not pressed also
1168
1205
  const shouldSubmit = !e.shiftKey && e.key === 'Enter' && !composing;
1169
1206
  if (shouldSubmit && isHTMLFormElement(e.target)) {
@@ -1193,9 +1230,9 @@ const PromptList = ({ setInput, suggestedPrompts = [], }) => {
1193
1230
  })));
1194
1231
  };
1195
1232
 
1196
- const VERSION = '1.4.0';
1233
+ const VERSION = '1.5.0';
1197
1234
 
1198
- function AIConversationBase({ avatars, controls, ...rest }) {
1235
+ function AIConversationBase({ avatars, controls, messages, ...rest }) {
1199
1236
  uiReactCore.useSetUserAgent({
1200
1237
  componentName: 'AIConversation',
1201
1238
  packageName: 'react-ai',
@@ -1214,20 +1251,14 @@ function AIConversationBase({ avatars, controls, ...rest }) {
1214
1251
  };
1215
1252
  const providerProps = {
1216
1253
  ...rest,
1217
- avatars: {
1218
- ...defaultAvatars,
1219
- ...avatars,
1220
- },
1221
- controls: {
1222
- MessageList,
1223
- PromptList,
1224
- Form,
1225
- ...controls,
1226
- },
1254
+ avatars: { ...defaultAvatars, ...avatars },
1255
+ controls: { MessageList, PromptList, Form, ...controls },
1256
+ messages,
1227
1257
  };
1258
+ const scrollProps = useConversationScrollProps(messages);
1228
1259
  return (React__namespace.createElement(AIConversationProvider, { ...providerProps },
1229
1260
  React__namespace.createElement(uiReact.Flex, { className: ui.ComponentClassName.AIConversation, testId: "ai-conversation" },
1230
- React__namespace.createElement(uiReact.ScrollView, { autoScroll: "smooth", flex: "1" },
1261
+ React__namespace.createElement(uiReact.ScrollView, { ...scrollProps, flex: "1" },
1231
1262
  React__namespace.createElement(DefaultMessageControl, null),
1232
1263
  React__namespace.createElement(MessagesControl, null)),
1233
1264
  React__namespace.createElement(FormControl, null))));
@@ -1254,26 +1285,19 @@ const ERROR_STATE = { hasError: true, isLoading: false };
1254
1285
 
1255
1286
  function createUseAIGeneration(client) {
1256
1287
  const useAIGeneration = (routeName) => {
1257
- const [dataState, setDataState] = React__namespace.useState(() => ({
1258
- ...INITIAL_STATE,
1259
- data: undefined,
1260
- }));
1288
+ const [clientState, setClientState] = React__namespace.useState(() => ({ ...INITIAL_STATE, data: undefined }));
1261
1289
  const handleGeneration = React__namespace.useCallback(async (input) => {
1262
- setDataState(({ data }) => ({ ...LOADING_STATE, data }));
1290
+ setClientState(({ data }) => ({ ...LOADING_STATE, data }));
1263
1291
  const result = await client.generations[routeName](input);
1264
1292
  const { data, errors } = result;
1265
1293
  if (errors) {
1266
- setDataState({
1267
- ...ERROR_STATE,
1268
- data,
1269
- messages: errors,
1270
- });
1294
+ setClientState({ ...ERROR_STATE, data, messages: errors });
1271
1295
  }
1272
1296
  else {
1273
- setDataState({ ...INITIAL_STATE, data });
1297
+ setClientState({ ...INITIAL_STATE, data });
1274
1298
  }
1275
1299
  }, [routeName]);
1276
- return [dataState, handleGeneration];
1300
+ return [clientState, handleGeneration];
1277
1301
  };
1278
1302
  return useAIGeneration;
1279
1303
  }
@@ -1340,11 +1364,11 @@ function createUseAIConversation(client) {
1340
1364
  // it will create a new conversation when it is executed
1341
1365
  // we don't want to create 2 conversations
1342
1366
  const initRef = React__namespace["default"].useRef('initial');
1343
- const [dataState, setDataState] = React__namespace["default"].useState(() => ({
1367
+ const [clientState, setClientState] = React__namespace["default"].useState(() => ({
1344
1368
  ...INITIAL_STATE,
1345
1369
  data: { messages: [], conversation: undefined },
1346
1370
  }));
1347
- const { conversation } = dataState.data;
1371
+ const { conversation } = clientState.data;
1348
1372
  const { id, onInitialize, onMessage } = input;
1349
1373
  React__namespace["default"].useEffect(() => {
1350
1374
  async function initialize() {
@@ -1356,7 +1380,7 @@ function createUseAIConversation(client) {
1356
1380
  // Only show component loading state if we are
1357
1381
  // actually loading messages
1358
1382
  if (id) {
1359
- setDataState({
1383
+ setClientState({
1360
1384
  ...LOADING_STATE,
1361
1385
  data: { messages: [], conversation: undefined },
1362
1386
  });
@@ -1365,7 +1389,7 @@ function createUseAIConversation(client) {
1365
1389
  ? await clientRoute.get({ id })
1366
1390
  : await clientRoute.create();
1367
1391
  if (errors ?? !conversation) {
1368
- setDataState({
1392
+ setClientState({
1369
1393
  ...ERROR_STATE,
1370
1394
  data: { messages: [] },
1371
1395
  messages: errors,
@@ -1376,13 +1400,13 @@ function createUseAIConversation(client) {
1376
1400
  const { data: messages } = await exhaustivelyListMessages({
1377
1401
  conversation,
1378
1402
  });
1379
- setDataState({
1403
+ setClientState({
1380
1404
  ...INITIAL_STATE,
1381
1405
  data: { messages, conversation },
1382
1406
  });
1383
1407
  }
1384
1408
  else {
1385
- setDataState({
1409
+ setClientState({
1386
1410
  ...INITIAL_STATE,
1387
1411
  data: { conversation, messages: [] },
1388
1412
  });
@@ -1400,7 +1424,7 @@ function createUseAIConversation(client) {
1400
1424
  errorInfo: null,
1401
1425
  errorType: '',
1402
1426
  };
1403
- setDataState({
1427
+ setClientState({
1404
1428
  ...ERROR_STATE,
1405
1429
  data: { messages: [] },
1406
1430
  // TODO in MV bump: remove `messages`
@@ -1414,12 +1438,12 @@ function createUseAIConversation(client) {
1414
1438
  contentBlocksRef.current = undefined;
1415
1439
  if (hasStarted(initRef.current))
1416
1440
  return;
1417
- setDataState({
1441
+ setClientState({
1418
1442
  ...INITIAL_STATE,
1419
1443
  data: { messages: [], conversation: undefined },
1420
1444
  });
1421
1445
  };
1422
- }, [clientRoute, id, setDataState]);
1446
+ }, [clientRoute, id, setClientState]);
1423
1447
  // Run a separate effect that is triggered by the conversation state
1424
1448
  // so that we know we have a conversation object to set up the subscription
1425
1449
  // and also unsubscribe on cleanup
@@ -1447,7 +1471,7 @@ function createUseAIConversation(client) {
1447
1471
  // stop reason will signify end of conversation turn
1448
1472
  if (stopReason) {
1449
1473
  // remove loading state from streamed message
1450
- setDataState((prev) => {
1474
+ setClientState((prev) => {
1451
1475
  return {
1452
1476
  ...prev,
1453
1477
  data: {
@@ -1494,7 +1518,7 @@ function createUseAIConversation(client) {
1494
1518
  ];
1495
1519
  }
1496
1520
  }
1497
- setDataState((prev) => {
1521
+ setClientState((prev) => {
1498
1522
  const message = {
1499
1523
  id,
1500
1524
  conversationId,
@@ -1515,7 +1539,7 @@ function createUseAIConversation(client) {
1515
1539
  });
1516
1540
  },
1517
1541
  error: (error) => {
1518
- setDataState((prev) => {
1542
+ setClientState((prev) => {
1519
1543
  return {
1520
1544
  ...prev,
1521
1545
  ...ERROR_STATE,
@@ -1533,11 +1557,11 @@ function createUseAIConversation(client) {
1533
1557
  contentBlocksRef.current = undefined;
1534
1558
  subscription.unsubscribe();
1535
1559
  };
1536
- }, [conversation, onInitialize, onMessage, setDataState]);
1560
+ }, [conversation, onInitialize, onMessage, setClientState]);
1537
1561
  const handleSendMessage = React__namespace["default"].useCallback((input) => {
1538
1562
  const { content } = input;
1539
1563
  if (conversation) {
1540
- setDataState((prevState) => ({
1564
+ setClientState((prevState) => ({
1541
1565
  ...prevState,
1542
1566
  data: {
1543
1567
  ...prevState.data,
@@ -1570,7 +1594,7 @@ function createUseAIConversation(client) {
1570
1594
  errorInfo: null,
1571
1595
  errorType: '',
1572
1596
  };
1573
- setDataState((prev) => ({
1597
+ setClientState((prev) => ({
1574
1598
  ...prev,
1575
1599
  ...ERROR_STATE,
1576
1600
  // TODO in MV bump: remove `messages`
@@ -1579,7 +1603,7 @@ function createUseAIConversation(client) {
1579
1603
  }));
1580
1604
  }
1581
1605
  }, [conversation]);
1582
- return [dataState, handleSendMessage];
1606
+ return [clientState, handleSendMessage];
1583
1607
  };
1584
1608
  return useAIConversation;
1585
1609
  }
@@ -1,4 +1,4 @@
1
- import { AIConversation as AIConversationType, AIConversationInput, AIConversationProps } from './types';
1
+ import type { AIConversation as AIConversationType, AIConversationInput, AIConversationProps } from './types';
2
2
  interface AIConversationBaseProps extends AIConversationProps, AIConversationInput {
3
3
  }
4
4
  export declare const AIConversation: AIConversationType<AIConversationBaseProps>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { AIConversationInput, AIConversationProps } from './types';
2
+ import type { AIConversationInput, AIConversationProps } from './types';
3
3
  export interface AIConversationProviderProps extends AIConversationInput, AIConversationProps {
4
4
  children?: React.ReactNode;
5
5
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { CustomAction } from '../types';
2
+ import type { CustomAction } from '../types';
3
3
  export declare const ActionsContext: React.Context<CustomAction[] | undefined>;
4
4
  export declare const ActionsProvider: ({ children, actions, }: {
5
5
  children?: React.ReactNode;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { AIConversationInput } from '../types';
2
+ import type { AIConversationInput } from '../types';
3
3
  export interface AttachmentContextProps extends Pick<AIConversationInput, 'allowAttachments' | 'maxAttachments' | 'maxAttachmentSize'> {
4
4
  }
5
5
  export declare const AttachmentContext: React.Context<Required<AttachmentContextProps>>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Avatars } from '../types';
2
+ import type { Avatars } from '../types';
3
3
  export declare const AvatarsContext: React.Context<Avatars | undefined>;
4
4
  export declare const AvatarsProvider: ({ children, avatars, }: {
5
5
  children?: React.ReactNode;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { ConversationInputContextProps } from './ConversationInputContext';
3
- import { SuggestedPrompt } from '../types';
4
- import { ConversationMessage } from '../../../types';
2
+ import type { ConversationInputContextProps } from './ConversationInputContext';
3
+ import type { SuggestedPrompt } from '../types';
4
+ import type { ConversationMessage } from '../../../types';
5
5
  export interface ControlsContextProps {
6
6
  Form?: React.ComponentType<{
7
7
  handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
@@ -1,4 +1,4 @@
1
- import { ConversationDisplayText } from '../displayText';
1
+ import type { ConversationDisplayText } from '../displayText';
2
2
  export declare const ConversationDisplayTextContext: import("react").Context<Required<ConversationDisplayText>>, ConversationDisplayTextProvider: import("react").ComponentType<import("react").PropsWithChildren<Required<ConversationDisplayText>>>, useConversationDisplayText: (params?: {
3
3
  errorMessage?: string | undefined;
4
4
  } | undefined) => Required<ConversationDisplayText>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { AIConversationInput } from '../types';
2
+ import type { AIConversationInput } from '../types';
3
3
  export declare const FallbackComponentContext: React.Context<React.ComponentType<any> | undefined>;
4
4
  export declare const FallbackComponentProvider: ({ children, FallbackComponent, }: {
5
5
  children?: React.ReactNode;
@@ -1,4 +1,4 @@
1
- import { MessageRenderer } from '../types';
1
+ import type { MessageRenderer } from '../types';
2
2
  export declare const MessageRendererContext: import("react").Context<MessageRenderer>, MessageRendererProvider: import("react").ComponentType<import("react").PropsWithChildren<MessageRenderer>>, useMessageRenderer: (params?: {
3
3
  errorMessage?: string | undefined;
4
4
  } | undefined) => MessageRenderer;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { MessageVariant } from '../types';
2
+ import type { MessageVariant } from '../types';
3
3
  export declare const MessageVariantContext: React.Context<MessageVariant | undefined>;
4
4
  export declare const MessageVariantProvider: ({ children, variant, }: {
5
5
  children?: React.ReactNode;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ConversationMessage } from '../../../types';
2
+ import type { ConversationMessage } from '../../../types';
3
3
  type MessagesContextProps = ConversationMessage[] | undefined;
4
4
  export declare const MessagesContext: React.Context<MessagesContextProps>;
5
5
  export declare const RoleContext: React.Context<"user" | "assistant" | undefined>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ToolConfiguration, ResponseComponents } from '../../../types';
2
+ import type { ToolConfiguration, ResponseComponents } from '../../../types';
3
3
  type ResponseComponentsContextProps = ResponseComponents | undefined;
4
4
  export declare const RESPONSE_COMPONENT_PREFIX = "AMPLIFY_UI_";
5
5
  export declare const ResponseComponentsContext: React.Context<ResponseComponentsContextProps>;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { SendMessage } from '../../../types';
2
+ import type { SendMessage } from '../../../types';
3
3
  export declare const SendMessageContext: React.Context<SendMessage | undefined>;
4
4
  export declare const SendMessageContextProvider: ({ children, handleSendMessage, }: {
5
5
  children?: React.ReactNode;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { SuggestedPrompt } from '../types';
2
+ import type { SuggestedPrompt } from '../types';
3
3
  type SuggestedPromptsContextProps = SuggestedPrompt[] | undefined;
4
4
  export declare const SuggestedPromptsContext: React.Context<SuggestedPromptsContextProps>;
5
5
  export declare const SuggestedPromptProvider: ({ children, suggestedPrompts, }: {
@@ -1,17 +1,20 @@
1
1
  export { AIContextContext, AIContextProvider } from './AIContextContext';
2
2
  export { ActionsContext, ActionsProvider } from './ActionsContext';
3
3
  export { AvatarsContext, AvatarsProvider } from './AvatarsContext';
4
- export { ConversationInputContextProps, ConversationInputContext, ConversationInput, ConversationInputContextProvider, } from './ConversationInputContext';
4
+ export type { ConversationInputContextProps, ConversationInput, } from './ConversationInputContext';
5
+ export { ConversationInputContext, ConversationInputContextProvider, } from './ConversationInputContext';
5
6
  export { MessagesContext, RoleContext, MessagesProvider, } from './MessagesContext';
6
7
  export { SuggestedPromptsContext, SuggestedPromptProvider, } from './SuggestedPromptsContext';
7
8
  export { MessageVariantContext, MessageVariantProvider, } from './MessageVariantContext';
8
9
  export { ConversationDisplayTextContext, useConversationDisplayText, ConversationDisplayTextProvider, } from './DisplayTextContext';
9
- export { ControlsContext, ControlsContextProps, ControlsProvider, } from './ControlsContext';
10
+ export type { ControlsContextProps } from './ControlsContext';
11
+ export { ControlsContext, ControlsProvider } from './ControlsContext';
10
12
  export { LoadingContextProvider } from './LoadingContext';
11
13
  export { ResponseComponentsProvider, RESPONSE_COMPONENT_PREFIX, } from './ResponseComponentsContext';
12
14
  export { SendMessageContextProvider } from './SendMessageContext';
13
15
  export { MessageRendererProvider, MessageRendererContext, useMessageRenderer, } from './MessageRenderContext';
14
- export { AttachmentProvider, AttachmentContext, AttachmentContextProps, } from './AttachmentContext';
16
+ export type { AttachmentContextProps } from './AttachmentContext';
17
+ export { AttachmentProvider, AttachmentContext } from './AttachmentContext';
15
18
  export { WelcomeMessageContext, WelcomeMessageProvider, } from './WelcomeMessageContext';
16
19
  export { FallbackComponentContext, FallbackComponentProvider, } from './FallbackComponentContext';
17
20
  export * from './elements';
@@ -1,4 +1,4 @@
1
- import { AIConversationInput, AIConversation } from './types';
1
+ import type { AIConversationInput, AIConversation } from './types';
2
2
  export declare function createAIConversation(input?: AIConversationInput): {
3
3
  AIConversation: AIConversation;
4
4
  };
@@ -1,4 +1,4 @@
1
- import { DisplayTextTemplate } from '@aws-amplify/ui';
1
+ import type { DisplayTextTemplate } from '@aws-amplify/ui';
2
2
  export type ConversationDisplayText = {
3
3
  getMessageTimestampText?: (date: Date) => string;
4
4
  getMaxAttachmentErrorText?: (count: number) => string;
@@ -1,5 +1,6 @@
1
1
  import { createAIConversation } from './createAIConversation';
2
2
  import { AIConversation } from './AIConversation';
3
- import { Avatars, CustomAction, SuggestedPrompt } from './types';
4
- import { ResponseComponent } from '../../types';
5
- export { createAIConversation, AIConversation, Avatars, CustomAction, ResponseComponent, SuggestedPrompt, };
3
+ import type { Avatars, CustomAction, SuggestedPrompt } from './types';
4
+ import type { ResponseComponent } from '../../types';
5
+ export type { Avatars, CustomAction, ResponseComponent, SuggestedPrompt };
6
+ export { createAIConversation, AIConversation };
@@ -1,10 +1,10 @@
1
- import React from 'react';
2
- import { ActionsBarControl, AvatarControl, FormControl, MessagesControl, PromptControl } from './views';
3
- import { DisplayTextTemplate } from '@aws-amplify/ui';
4
- import { AIConversationDisplayText } from './displayText';
5
- import { ConversationMessage, SendMessage, ResponseComponents, TextContentBlock, ImageContentBlock } from '../../types';
6
- import { ControlsContextProps } from './context/ControlsContext';
7
- import { AIConversationProviderProps } from './AIConversationProvider';
1
+ import type React from 'react';
2
+ import type { ActionsBarControl, AvatarControl, FormControl, MessagesControl, PromptControl } from './views';
3
+ import type { DisplayTextTemplate } from '@aws-amplify/ui';
4
+ import type { AIConversationDisplayText } from './displayText';
5
+ import type { ConversationMessage, SendMessage, ResponseComponents, TextContentBlock, ImageContentBlock } from '../../types';
6
+ import type { ControlsContextProps } from './context/ControlsContext';
7
+ import type { AIConversationProviderProps } from './AIConversationProvider';
8
8
  export interface Controls {
9
9
  Avatars: AvatarControl;
10
10
  ActionsBar: ActionsBarControl;
@@ -0,0 +1,6 @@
1
+ import type { ScrollViewProps } from '@aws-amplify/ui-react';
2
+ import type { ConversationMessage } from '../../types';
3
+ interface ConverationScrollProps extends Pick<ScrollViewProps, 'onScroll' | 'autoScroll'> {
4
+ }
5
+ export default function useConversationScrollProps(messages: ConversationMessage[]): ConverationScrollProps;
6
+ export {};
@@ -1,4 +1,4 @@
1
- import { ImageContentBlock, DocumentContentBlock } from '../../types';
1
+ import type { ImageContentBlock, DocumentContentBlock } from '../../types';
2
2
  export declare function formatDate(date: Date): string;
3
3
  export declare function convertBufferToBase64(buffer: ArrayBuffer, format: ImageContentBlock['format']): string;
4
4
  export declare function getAttachmentFormat(file: File): string;
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { AIConversationElements } from '../../context/elements';
3
- import { ConversationMessage } from '../../../../types';
3
+ import type { ConversationMessage } from '../../../../types';
4
4
  export declare const ActionsBarControl: ActionsBarControl;
5
5
  export interface ActionsBarControl {
6
6
  (props: {
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { AIConversationElements } from '../../context/elements';
3
3
  import { ActionsBarControl } from './ActionsBarControl';
4
4
  import { AvatarControl } from './AvatarControl';
5
- import { ConversationMessage } from '../../../../types';
5
+ import type { ConversationMessage } from '../../../../types';
6
6
  export declare const DocumentContent: ({ format, name, source, }: NonNullable<ConversationMessage['content'][number]['document']>) => React.JSX.Element;
7
7
  export declare const MessageControl: MessageControl;
8
8
  interface MessageControl {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ConversationInputContextProps } from '../../context';
2
+ import type { ConversationInputContextProps } from '../../context';
3
3
  export declare const Attachments: ({ files, setInput, }: {
4
4
  files?: File[] | undefined;
5
5
  setInput: ConversationInputContextProps['setInput'];
@@ -1,2 +1,2 @@
1
- import { ControlsContextProps } from '../../context/ControlsContext';
1
+ import type { ControlsContextProps } from '../../context/ControlsContext';
2
2
  export declare const Form: Required<ControlsContextProps>['Form'];
@@ -1,2 +1,2 @@
1
- import { ControlsContextProps } from '../../context/ControlsContext';
1
+ import type { ControlsContextProps } from '../../context/ControlsContext';
2
2
  export declare const MessageList: Required<ControlsContextProps>['MessageList'];
@@ -1,2 +1,2 @@
1
- import { ControlsContextProps } from '../../context/ControlsContext';
1
+ import type { ControlsContextProps } from '../../context/ControlsContext';
2
2
  export declare const PromptList: Required<ControlsContextProps>['PromptList'];
@@ -1,2 +1,2 @@
1
- import { ConversationMessage, ConversationStreamEvent } from '../types';
1
+ import type { ConversationMessage, ConversationStreamEvent } from '../types';
2
2
  export declare const contentFromEvents: (contentBlocks?: ConversationStreamEvent[][]) => ConversationMessage['content'];
@@ -1,6 +1,6 @@
1
- import { UseAIGenerationHookWrapper } from './useAIGeneration';
2
- import { UseAIConversationHook } from './useAIConversation';
3
- import { getSchema } from '../types';
1
+ import type { UseAIGenerationHookWrapper } from './useAIGeneration';
2
+ import type { UseAIConversationHook } from './useAIConversation';
3
+ import type { getSchema } from '../types';
4
4
  type UseAIHooks<Client extends Record<'generations' | 'conversations', Record<string, any>>, Schema extends Record<any, any>> = {
5
5
  useAIConversation: UseAIConversationHook<Extract<keyof Client['conversations'], string>>;
6
6
  } & UseAIGenerationHookWrapper<keyof Client['generations'], Schema>;
@@ -1,4 +1,4 @@
1
- import { Conversation, ConversationMessage } from '../types';
1
+ import type { Conversation, ConversationMessage } from '../types';
2
2
  interface ExhaustivelyListMessagesParams {
3
3
  conversation: Conversation;
4
4
  messages?: ConversationMessage[];
@@ -1,6 +1,8 @@
1
- import { DataState } from '@aws-amplify/ui-react-core';
2
- import { GraphQLFormattedError } from '../types';
3
- export type DataClientState<T> = Omit<DataState<T>, 'message'> & {
1
+ import type { GraphQLFormattedError } from '../types';
2
+ export interface AiClientState<T> {
3
+ data: T;
4
+ hasError: boolean;
5
+ isLoading: boolean;
4
6
  /**
5
7
  * @deprecated will be removed in a future major version. Superseded by `errors`
6
8
  * @description errors returned from the websocket connection
@@ -10,11 +12,11 @@ export type DataClientState<T> = Omit<DataState<T>, 'message'> & {
10
12
  * @description errors returned from the websocket connection
11
13
  */
12
14
  errors?: GraphQLFormattedError[];
13
- };
14
- export type DataClientResponse<T> = {
15
+ }
16
+ export interface AiClientResponse<T> {
15
17
  data: T | null;
16
18
  errors?: GraphQLFormattedError[];
17
- };
19
+ }
18
20
  export declare const INITIAL_STATE: {
19
21
  hasError: boolean;
20
22
  isLoading: boolean;
@@ -1,5 +1,5 @@
1
- import { Conversation, ConversationMessage, ConversationRoute, SendMessage } from '../types';
2
- import { DataClientState } from './shared';
1
+ import type { Conversation, ConversationMessage, ConversationRoute, SendMessage } from '../types';
2
+ import type { AiClientState } from './shared';
3
3
  interface UseAIConversationInput {
4
4
  id?: string;
5
5
  onMessage?: (message: ConversationMessage) => void;
@@ -9,6 +9,6 @@ interface AIConversationState {
9
9
  messages: ConversationMessage[];
10
10
  conversation?: Conversation;
11
11
  }
12
- export type UseAIConversationHook<T extends string> = (routeName: T, input?: UseAIConversationInput) => [DataClientState<AIConversationState>, SendMessage];
12
+ export type UseAIConversationHook<T extends string> = (routeName: T, input?: UseAIConversationInput) => [AiClientState<AIConversationState>, SendMessage];
13
13
  export declare function createUseAIConversation<T extends Record<'conversations', Record<string, ConversationRoute>>>(client: T): UseAIConversationHook<Extract<keyof T['conversations'], string>>;
14
14
  export {};
@@ -1,14 +1,14 @@
1
1
  import type { ClientExtensions } from '@aws-amplify/data-schema/runtime';
2
- import { getSchema } from '../types';
3
- import { DataClientState } from './shared';
2
+ import type { getSchema } from '../types';
3
+ import type { AiClientState } from './shared';
4
4
  export interface UseAIGenerationHookWrapper<Key extends keyof AIGenerationClient<Schema>['generations'], Schema extends Record<any, any>> {
5
5
  useAIGeneration: <U extends Key>(routeName: U) => [
6
- Awaited<DataClientState<Schema[U]['returnType']>>,
6
+ Awaited<AiClientState<Schema[U]['returnType']>>,
7
7
  (input: Schema[U]['args']) => void
8
8
  ];
9
9
  }
10
10
  export type UseAIGenerationHook<Key extends keyof AIGenerationClient<Schema>['generations'], Schema extends Record<any, any>> = (routeName: Key) => [
11
- Awaited<DataClientState<Schema[Key]['returnType']>>,
11
+ Awaited<AiClientState<Schema[Key]['returnType']>>,
12
12
  (input: Schema[Key]['args']) => void
13
13
  ];
14
14
  type AIGenerationClient<T extends Record<any, any>> = Pick<ClientExtensions<T>, 'generations'>;
@@ -1,3 +1,4 @@
1
- export { createAIConversation, AIConversation, Avatars, CustomAction, ResponseComponent, SuggestedPrompt, } from './components';
1
+ export type { Avatars, CustomAction, ResponseComponent, SuggestedPrompt, } from './components';
2
+ export { createAIConversation, AIConversation } from './components';
2
3
  export { createAIHooks } from './hooks';
3
- export { ConversationMessage, ConversationMessageContent, SendMessage, SendMesageParameters, } from './types';
4
+ export type { ConversationMessage, ConversationMessageContent, SendMessage, SendMesageParameters, } from './types';
@@ -1 +1 @@
1
- export declare const VERSION = "1.4.0";
1
+ export declare const VERSION = "1.5.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-amplify/ui-react-ai",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/esm/index.mjs",
6
6
  "exports": {
@@ -43,14 +43,14 @@
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@aws-amplify/data-schema": "^1.19.0",
46
- "aws-amplify": "^6.9.0",
46
+ "aws-amplify": "^6.14.3",
47
47
  "react": "^16.14 || ^17 || ^18 || ^19",
48
48
  "react-dom": "^16.14 || ^17 || ^18 || ^19"
49
49
  },
50
50
  "dependencies": {
51
- "@aws-amplify/ui": "^6.10.1",
52
- "@aws-amplify/ui-react": "^6.11.0",
53
- "@aws-amplify/ui-react-core": "^3.4.1"
51
+ "@aws-amplify/ui": "^6.10.3",
52
+ "@aws-amplify/ui-react": "^6.11.2",
53
+ "@aws-amplify/ui-react-core": "^3.4.3"
54
54
  },
55
55
  "size-limit": [
56
56
  {