@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.
- package/README.md +21 -15
- package/dist/esm/components/AIConversation/AIConversation.mjs +8 -13
- package/dist/esm/components/AIConversation/context/elements/definitions.mjs +4 -7
- package/dist/esm/components/AIConversation/useConversationScrollProps.mjs +31 -0
- package/dist/esm/components/AIConversation/views/default/Form.mjs +14 -1
- package/dist/esm/hooks/useAIConversation.mjs +16 -16
- package/dist/esm/hooks/useAIGeneration.mjs +5 -12
- package/dist/esm/version.mjs +1 -1
- package/dist/index.js +72 -48
- package/dist/types/components/AIConversation/AIConversation.d.ts +1 -1
- package/dist/types/components/AIConversation/AIConversationProvider.d.ts +1 -1
- package/dist/types/components/AIConversation/context/ActionsContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/AttachmentContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/AvatarsContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/ControlsContext.d.ts +3 -3
- package/dist/types/components/AIConversation/context/DisplayTextContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/FallbackComponentContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/MessageRenderContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/MessageVariantContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/MessagesContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/ResponseComponentsContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/SendMessageContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/SuggestedPromptsContext.d.ts +1 -1
- package/dist/types/components/AIConversation/context/index.d.ts +6 -3
- package/dist/types/components/AIConversation/createAIConversation.d.ts +1 -1
- package/dist/types/components/AIConversation/displayText.d.ts +1 -1
- package/dist/types/components/AIConversation/index.d.ts +4 -3
- package/dist/types/components/AIConversation/types.d.ts +7 -7
- package/dist/types/components/AIConversation/useConversationScrollProps.d.ts +6 -0
- package/dist/types/components/AIConversation/utils.d.ts +1 -1
- package/dist/types/components/AIConversation/views/Controls/ActionsBarControl.d.ts +1 -1
- package/dist/types/components/AIConversation/views/Controls/MessagesControl.d.ts +1 -1
- package/dist/types/components/AIConversation/views/default/Attachments.d.ts +1 -1
- package/dist/types/components/AIConversation/views/default/Form.d.ts +1 -1
- package/dist/types/components/AIConversation/views/default/MessageList.d.ts +1 -1
- package/dist/types/components/AIConversation/views/default/PromptList.d.ts +1 -1
- package/dist/types/hooks/contentFromEvents.d.ts +1 -1
- package/dist/types/hooks/createAIHooks.d.ts +3 -3
- package/dist/types/hooks/exhaustivelyListMessages.d.ts +1 -1
- package/dist/types/hooks/shared.d.ts +8 -6
- package/dist/types/hooks/useAIConversation.d.ts +3 -3
- package/dist/types/hooks/useAIGeneration.d.ts +4 -4
- package/dist/types/index.d.ts +3 -2
- package/dist/types/version.d.ts +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
# Amplify UI
|
|
1
|
+
# Amplify UI React AI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The React AI package provides components and utilities for AI-powered conversations and interactions in Amplify connected applications.
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
7
|
+
### Core Components
|
|
11
8
|
|
|
12
|
-
-
|
|
9
|
+
- `AIConversation` - Component for AI-powered conversations
|
|
10
|
+
- `createAIConversation` - Factory function for creating AI conversation components
|
|
11
|
+
|
|
12
|
+
### Utility Functions
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
- `createAIHooks` - Factory function for creating AI-related hooks
|
|
15
15
|
|
|
16
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
36
|
-
|
|
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, {
|
|
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
|
-
|
|
20
|
+
defineBaseElementWithRef({
|
|
21
21
|
type: 'h2',
|
|
22
22
|
displayName: 'Title',
|
|
23
23
|
});
|
|
24
|
-
|
|
24
|
+
defineBaseElementWithRef({
|
|
25
25
|
type: 'img',
|
|
26
26
|
displayName: 'Image',
|
|
27
27
|
});
|
|
28
|
-
|
|
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,
|
|
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),
|
|
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 [
|
|
30
|
+
const [clientState, setClientState] = React__default.useState(() => ({
|
|
31
31
|
...INITIAL_STATE,
|
|
32
32
|
data: { messages: [], conversation: undefined },
|
|
33
33
|
}));
|
|
34
|
-
const { conversation } =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
+
setClientState({
|
|
67
67
|
...INITIAL_STATE,
|
|
68
68
|
data: { messages, conversation },
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
|
|
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
|
-
|
|
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
|
-
|
|
104
|
+
setClientState({
|
|
105
105
|
...INITIAL_STATE,
|
|
106
106
|
data: { messages: [], conversation: undefined },
|
|
107
107
|
});
|
|
108
108
|
};
|
|
109
|
-
}, [clientRoute, id,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
223
|
+
}, [conversation, onInitialize, onMessage, setClientState]);
|
|
224
224
|
const handleSendMessage = React__default.useCallback((input) => {
|
|
225
225
|
const { content } = input;
|
|
226
226
|
if (conversation) {
|
|
227
|
-
|
|
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
|
-
|
|
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 [
|
|
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 [
|
|
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
|
-
|
|
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
|
-
|
|
16
|
-
...ERROR_STATE,
|
|
17
|
-
data,
|
|
18
|
-
messages: errors,
|
|
19
|
-
});
|
|
12
|
+
setClientState({ ...ERROR_STATE, data, messages: errors });
|
|
20
13
|
}
|
|
21
14
|
else {
|
|
22
|
-
|
|
15
|
+
setClientState({ ...INITIAL_STATE, data });
|
|
23
16
|
}
|
|
24
17
|
}, [routeName]);
|
|
25
|
-
return [
|
|
18
|
+
return [clientState, handleGeneration];
|
|
26
19
|
};
|
|
27
20
|
return useAIGeneration;
|
|
28
21
|
}
|
package/dist/esm/version.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -342,15 +342,15 @@ const ListItemElement = elements.defineBaseElementWithRef({
|
|
|
342
342
|
type: 'li',
|
|
343
343
|
displayName: 'ListItem',
|
|
344
344
|
});
|
|
345
|
-
|
|
345
|
+
elements.defineBaseElementWithRef({
|
|
346
346
|
type: 'h2',
|
|
347
347
|
displayName: 'Title',
|
|
348
348
|
});
|
|
349
|
-
|
|
349
|
+
elements.defineBaseElementWithRef({
|
|
350
350
|
type: 'img',
|
|
351
351
|
displayName: 'Image',
|
|
352
352
|
});
|
|
353
|
-
|
|
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),
|
|
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.
|
|
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
|
-
|
|
1219
|
-
|
|
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, {
|
|
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 [
|
|
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
|
-
|
|
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
|
-
|
|
1267
|
-
...ERROR_STATE,
|
|
1268
|
-
data,
|
|
1269
|
-
messages: errors,
|
|
1270
|
-
});
|
|
1294
|
+
setClientState({ ...ERROR_STATE, data, messages: errors });
|
|
1271
1295
|
}
|
|
1272
1296
|
else {
|
|
1273
|
-
|
|
1297
|
+
setClientState({ ...INITIAL_STATE, data });
|
|
1274
1298
|
}
|
|
1275
1299
|
}, [routeName]);
|
|
1276
|
-
return [
|
|
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 [
|
|
1367
|
+
const [clientState, setClientState] = React__namespace["default"].useState(() => ({
|
|
1344
1368
|
...INITIAL_STATE,
|
|
1345
1369
|
data: { messages: [], conversation: undefined },
|
|
1346
1370
|
}));
|
|
1347
|
-
const { conversation } =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1403
|
+
setClientState({
|
|
1380
1404
|
...INITIAL_STATE,
|
|
1381
1405
|
data: { messages, conversation },
|
|
1382
1406
|
});
|
|
1383
1407
|
}
|
|
1384
1408
|
else {
|
|
1385
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1441
|
+
setClientState({
|
|
1418
1442
|
...INITIAL_STATE,
|
|
1419
1443
|
data: { messages: [], conversation: undefined },
|
|
1420
1444
|
});
|
|
1421
1445
|
};
|
|
1422
|
-
}, [clientRoute, id,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
1560
|
+
}, [conversation, onInitialize, onMessage, setClientState]);
|
|
1537
1561
|
const handleSendMessage = React__namespace["default"].useCallback((input) => {
|
|
1538
1562
|
const { content } = input;
|
|
1539
1563
|
if (conversation) {
|
|
1540
|
-
|
|
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
|
-
|
|
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 [
|
|
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,
|
|
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 {
|
|
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 {
|
|
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,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 {
|
|
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,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
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 {
|
|
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) => [
|
|
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 {
|
|
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<
|
|
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<
|
|
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'>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export {
|
|
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';
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
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.
|
|
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.
|
|
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.
|
|
52
|
-
"@aws-amplify/ui-react": "^6.11.
|
|
53
|
-
"@aws-amplify/ui-react-core": "^3.4.
|
|
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
|
{
|