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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/esm/components/AIConversation/AIConversation.mjs +31 -27
  2. package/dist/esm/components/AIConversation/{createProvider.mjs → AIConversationProvider.mjs} +15 -14
  3. package/dist/esm/components/AIConversation/context/MessageRenderContext.mjs +9 -0
  4. package/dist/esm/components/AIConversation/context/WelcomeMessageContext.mjs +8 -0
  5. package/dist/esm/components/AIConversation/createAIConversation.mjs +34 -31
  6. package/dist/esm/components/AIConversation/views/Controls/ActionsBarControl.mjs +3 -0
  7. package/dist/esm/components/AIConversation/views/Controls/AttachFileControl.mjs +3 -0
  8. package/dist/esm/components/AIConversation/views/Controls/AttachmentListControl.mjs +3 -0
  9. package/dist/esm/components/AIConversation/views/Controls/AvatarControl.mjs +3 -0
  10. package/dist/esm/components/AIConversation/views/Controls/DefaultMessageControl.mjs +29 -0
  11. package/dist/esm/components/AIConversation/views/Controls/{FieldControl.mjs → FormControl.mjs} +11 -9
  12. package/dist/esm/components/AIConversation/views/Controls/MessagesControl.mjs +25 -18
  13. package/dist/esm/components/AIConversation/views/Controls/PromptControl.mjs +7 -36
  14. package/dist/esm/components/AIConversation/views/default/MessageList.mjs +3 -0
  15. package/dist/esm/components/AIConversation/views/default/PromptList.mjs +1 -1
  16. package/dist/esm/hooks/useAIGeneration.mjs +29 -15
  17. package/dist/esm/version.mjs +3 -0
  18. package/dist/index.js +263 -284
  19. package/dist/types/components/AIConversation/AIConversation.d.ts +2 -16
  20. package/dist/types/components/AIConversation/AIConversationProvider.d.ts +6 -0
  21. package/dist/types/components/AIConversation/context/MessageRenderContext.d.ts +5 -0
  22. package/dist/types/components/AIConversation/context/WelcomeMessageContext.d.ts +8 -0
  23. package/dist/types/components/AIConversation/context/index.d.ts +3 -0
  24. package/dist/types/components/AIConversation/types.d.ts +21 -13
  25. package/dist/types/components/AIConversation/utils.d.ts +2 -2
  26. package/dist/types/components/AIConversation/views/Controls/DefaultMessageControl.d.ts +2 -0
  27. package/dist/types/components/AIConversation/views/Controls/{FieldControl.d.ts → FormControl.d.ts} +2 -2
  28. package/dist/types/components/AIConversation/views/Controls/MessagesControl.d.ts +2 -4
  29. package/dist/types/components/AIConversation/views/Controls/PromptControl.d.ts +0 -3
  30. package/dist/types/components/AIConversation/views/Controls/index.d.ts +3 -4
  31. package/dist/types/components/AIConversation/views/index.d.ts +2 -3
  32. package/dist/types/hooks/useAIGeneration.d.ts +12 -2
  33. package/dist/types/types.d.ts +6 -6
  34. package/dist/types/version.d.ts +1 -0
  35. package/package.json +20 -6
  36. package/dist/esm/components/AIConversation/views/Controls/HeaderControl.mjs +0 -34
  37. package/dist/esm/components/AIConversation/views/ConversationView.mjs +0 -20
  38. package/dist/types/components/AIConversation/createProvider.d.ts +0 -5
  39. package/dist/types/components/AIConversation/views/Controls/HeaderControl.d.ts +0 -9
  40. package/dist/types/components/AIConversation/views/ConversationView.d.ts +0 -2
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var React = require('react');
6
6
  var elements = require('@aws-amplify/ui-react-core/elements');
7
7
  var uiReactCore = require('@aws-amplify/ui-react-core');
8
- var ui = require('@aws-amplify/ui');
9
8
  var uiReact = require('@aws-amplify/ui-react');
10
9
  var internal = require('@aws-amplify/ui-react/internal');
10
+ var ui = require('@aws-amplify/ui');
11
11
 
12
12
  function _interopNamespace(e) {
13
13
  if (e && e.__esModule) return e;
@@ -29,94 +29,6 @@ function _interopNamespace(e) {
29
29
 
30
30
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
31
31
 
32
- const DEFAULT_ICON_PATHS = {
33
- attach: 'M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z',
34
- close: 'm256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z',
35
- image: 'M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z',
36
- 'send-message': 'M120-160v-640l760 320-760 320Zm80-120 474-200-474-200v140l240 60-240 60v140Zm0 0v-400 400Z',
37
- 'user-avatar': 'M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Zm80-80h480v-32q0-11-5.5-20T700-306q-54-27-109-40.5T480-360q-56 0-111 13.5T260-306q-9 5-14.5 14t-5.5 20v32Zm240-320q33 0 56.5-23.5T560-640q0-33-23.5-56.5T480-720q-33 0-56.5 23.5T400-640q0 33 23.5 56.5T480-560Zm0-80Zm0 400Z',
38
- };
39
- const DEFAULT_ICON_ATTRIBUTES = {
40
- 'aria-hidden': true,
41
- width: '24',
42
- height: '24',
43
- // `viewBox` coordinates map to `path` data in DEFAULT_ICON_PATHS
44
- viewBox: '0 -960 960 960',
45
- fill: 'none',
46
- xmlns: 'http://www.w3.org/2000/svg',
47
- };
48
- const BaseIconElement = elements.defineBaseElement({
49
- type: 'svg',
50
- displayName: 'Icon',
51
- });
52
- const getIconProps = ({ variant, ...props }) => {
53
- const pathData = variant ? DEFAULT_ICON_PATHS[variant] : undefined;
54
- const children = pathData ? (React__namespace["default"].createElement("path", { d: pathData, fill: "currentColor" })) : undefined;
55
- return {
56
- ...DEFAULT_ICON_ATTRIBUTES,
57
- ...props,
58
- children: props.children ?? children,
59
- variant,
60
- };
61
- };
62
- const IconElement = elements.withBaseElementProps(BaseIconElement, getIconProps);
63
-
64
- const LabelElement$1 = elements.defineBaseElement({
65
- type: 'label',
66
- displayName: 'Label',
67
- });
68
- const TextElement = elements.defineBaseElement({
69
- type: 'p',
70
- displayName: 'Text',
71
- });
72
- const UnorderedListElement = elements.defineBaseElement({
73
- type: 'ul',
74
- displayName: 'UnorderedList',
75
- });
76
- const ListItemElement = elements.defineBaseElement({
77
- type: 'li',
78
- displayName: 'ListItem',
79
- });
80
- const HeadingElement = elements.defineBaseElement({
81
- type: 'h2',
82
- displayName: 'Title',
83
- });
84
- const ImageElement = elements.defineBaseElement({
85
- type: 'img',
86
- displayName: 'Image',
87
- });
88
- const InputElement = elements.defineBaseElement({
89
- type: 'input',
90
- displayName: 'Input',
91
- });
92
- const ButtonElement = elements.defineBaseElement({ type: 'button', displayName: 'Button' });
93
- const ViewElement = elements.defineBaseElement({
94
- type: 'div',
95
- displayName: 'View',
96
- });
97
- const SpanElement = elements.defineBaseElement({
98
- type: 'span',
99
- displayName: 'Span',
100
- });
101
- const TextAreaElement = elements.defineBaseElement({
102
- type: 'textarea',
103
- displayName: 'TextArea',
104
- });
105
- const AIConversationElements = {
106
- Button: ButtonElement,
107
- Heading: HeadingElement,
108
- Icon: IconElement,
109
- Input: InputElement,
110
- Image: ImageElement,
111
- Label: LabelElement$1,
112
- ListItem: ListItemElement,
113
- Span: SpanElement,
114
- Text: TextElement,
115
- TextArea: TextAreaElement,
116
- UnorderedList: UnorderedListElement,
117
- View: ViewElement,
118
- };
119
-
120
32
  const ActionsContext = React__namespace["default"].createContext(undefined);
121
33
  const ActionsProvider = ({ children, actions, }) => {
122
34
  return (React__namespace["default"].createElement(ActionsContext.Provider, { value: actions }, children));
@@ -253,46 +165,150 @@ const SendMessageContextProvider = ({ children, handleSendMessage, }) => {
253
165
  return (React__namespace["default"].createElement(SendMessageContext.Provider, { value: handleSendMessage }, children));
254
166
  };
255
167
 
256
- const { Button: Button$5, Span: Span$3, View: View$7 } = AIConversationElements;
168
+ const { MessageRendererContext, MessageRendererProvider, useMessageRenderer, } = uiReactCore.createContextUtilities({
169
+ contextName: 'MessageRenderer',
170
+ defaultValue: undefined,
171
+ errorMessage: '`useMessageRenderer` must be used with an AIConversation component',
172
+ });
173
+
174
+ const AttachmentContext = React__namespace.createContext(false);
175
+ const AttachmentProvider = ({ children, allowAttachments, }) => {
176
+ return (React__namespace.createElement(AttachmentContext.Provider, { value: allowAttachments ?? false }, children));
177
+ };
178
+
179
+ const WelcomeMessageContext = React__namespace.createContext(undefined);
180
+ const WelcomeMessageProvider = ({ children, welcomeMessage, }) => {
181
+ return (React__namespace.createElement(WelcomeMessageContext.Provider, { value: welcomeMessage }, children));
182
+ };
183
+
184
+ const DEFAULT_ICON_PATHS = {
185
+ attach: 'M720-330q0 104-73 177T470-80q-104 0-177-73t-73-177v-370q0-75 52.5-127.5T400-880q75 0 127.5 52.5T580-700v350q0 46-32 78t-78 32q-46 0-78-32t-32-78v-370h80v370q0 13 8.5 21.5T470-320q13 0 21.5-8.5T500-350v-350q-1-42-29.5-71T400-800q-42 0-71 29t-29 71v370q-1 71 49 120.5T470-160q70 0 119-49.5T640-330v-390h80v390Z',
186
+ close: 'm256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z',
187
+ image: 'M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm40-80h480L570-480 450-320l-90-120-120 160Zm-40 80v-560 560Z',
188
+ 'send-message': 'M120-160v-640l760 320-760 320Zm80-120 474-200-474-200v140l240 60-240 60v140Zm0 0v-400 400Z',
189
+ 'user-avatar': 'M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Zm80-80h480v-32q0-11-5.5-20T700-306q-54-27-109-40.5T480-360q-56 0-111 13.5T260-306q-9 5-14.5 14t-5.5 20v32Zm240-320q33 0 56.5-23.5T560-640q0-33-23.5-56.5T480-720q-33 0-56.5 23.5T400-640q0 33 23.5 56.5T480-560Zm0-80Zm0 400Z',
190
+ };
191
+ const DEFAULT_ICON_ATTRIBUTES = {
192
+ 'aria-hidden': true,
193
+ width: '24',
194
+ height: '24',
195
+ // `viewBox` coordinates map to `path` data in DEFAULT_ICON_PATHS
196
+ viewBox: '0 -960 960 960',
197
+ fill: 'none',
198
+ xmlns: 'http://www.w3.org/2000/svg',
199
+ };
200
+ const BaseIconElement = elements.defineBaseElement({
201
+ type: 'svg',
202
+ displayName: 'Icon',
203
+ });
204
+ const getIconProps = ({ variant, ...props }) => {
205
+ const pathData = variant ? DEFAULT_ICON_PATHS[variant] : undefined;
206
+ const children = pathData ? (React__namespace["default"].createElement("path", { d: pathData, fill: "currentColor" })) : undefined;
207
+ return {
208
+ ...DEFAULT_ICON_ATTRIBUTES,
209
+ ...props,
210
+ children: props.children ?? children,
211
+ variant,
212
+ };
213
+ };
214
+ const IconElement = elements.withBaseElementProps(BaseIconElement, getIconProps);
215
+
216
+ const LabelElement$1 = elements.defineBaseElement({
217
+ type: 'label',
218
+ displayName: 'Label',
219
+ });
220
+ const TextElement = elements.defineBaseElement({
221
+ type: 'p',
222
+ displayName: 'Text',
223
+ });
224
+ const UnorderedListElement = elements.defineBaseElement({
225
+ type: 'ul',
226
+ displayName: 'UnorderedList',
227
+ });
228
+ const ListItemElement = elements.defineBaseElement({
229
+ type: 'li',
230
+ displayName: 'ListItem',
231
+ });
232
+ const HeadingElement = elements.defineBaseElement({
233
+ type: 'h2',
234
+ displayName: 'Title',
235
+ });
236
+ const ImageElement = elements.defineBaseElement({
237
+ type: 'img',
238
+ displayName: 'Image',
239
+ });
240
+ const InputElement = elements.defineBaseElement({
241
+ type: 'input',
242
+ displayName: 'Input',
243
+ });
244
+ const ButtonElement = elements.defineBaseElement({ type: 'button', displayName: 'Button' });
245
+ const ViewElement = elements.defineBaseElement({
246
+ type: 'div',
247
+ displayName: 'View',
248
+ });
249
+ const SpanElement = elements.defineBaseElement({
250
+ type: 'span',
251
+ displayName: 'Span',
252
+ });
253
+ const TextAreaElement = elements.defineBaseElement({
254
+ type: 'textarea',
255
+ displayName: 'TextArea',
256
+ });
257
+ const AIConversationElements = {
258
+ Button: ButtonElement,
259
+ Heading: HeadingElement,
260
+ Icon: IconElement,
261
+ Input: InputElement,
262
+ Image: ImageElement,
263
+ Label: LabelElement$1,
264
+ ListItem: ListItemElement,
265
+ Span: SpanElement,
266
+ Text: TextElement,
267
+ TextArea: TextAreaElement,
268
+ UnorderedList: UnorderedListElement,
269
+ View: ViewElement,
270
+ };
271
+
272
+ const { Button: Button$4, Span: Span$3, View: View$6 } = AIConversationElements;
257
273
  const ACTIONS_BAR_BLOCK = 'ai-actions-bar';
258
274
  const ActionIcon = elements.withBaseElementProps(Span$3, {
259
275
  'aria-hidden': 'true',
260
276
  className: `${ACTIONS_BAR_BLOCK}__icon`,
261
277
  });
262
- const ActionButtonBase = elements.withBaseElementProps(Button$5, {
278
+ const ActionButtonBase = elements.withBaseElementProps(Button$4, {
263
279
  className: `${ACTIONS_BAR_BLOCK}__button`,
264
280
  });
265
281
  const ActionButton = React__namespace["default"].forwardRef(function ActionButton(props, ref) {
266
282
  return React__namespace["default"].createElement(ActionButtonBase, { ...props, ref: ref });
267
283
  });
268
- const Container$4 = elements.withBaseElementProps(View$7, {
284
+ const Container$3 = elements.withBaseElementProps(View$6, {
269
285
  className: `${ACTIONS_BAR_BLOCK}__container`,
270
286
  });
271
287
  const ActionsBarControl = ({ message, focusable, }) => {
272
288
  const actions = React__namespace["default"].useContext(ActionsContext);
273
- return (React__namespace["default"].createElement(Container$4, null, actions?.map((action, index) => (React__namespace["default"].createElement(ActionButton, { "aria-label": action.displayName, key: index, onClick: () => action.handler(message), tabIndex: focusable ? 0 : -1 },
289
+ return (React__namespace["default"].createElement(Container$3, null, actions?.map((action, index) => (React__namespace["default"].createElement(ActionButton, { "aria-label": action.displayName, key: index, onClick: () => action.handler(message), tabIndex: focusable ? 0 : -1 },
274
290
  React__namespace["default"].createElement(ActionIcon, { "data-testid": `action-icon-${action.displayName}` }, action.icon))))));
275
291
  };
276
292
  ActionsBarControl.Button = ActionButton;
277
- ActionsBarControl.Container = Container$4;
293
+ ActionsBarControl.Container = Container$3;
278
294
  ActionsBarControl.Icon = ActionIcon;
279
295
 
280
- const { Icon: Icon$5, Span: Span$2, Text: Text$4, View: View$6 } = AIConversationElements;
296
+ const { Icon: Icon$3, Span: Span$2, Text: Text$2, View: View$5 } = AIConversationElements;
281
297
  const AVATAR_BLOCK = 'ai-avatar';
282
- const DEFAULT_USER_ICON = elements.withBaseElementProps(Icon$5, {
298
+ const DEFAULT_USER_ICON = elements.withBaseElementProps(Icon$3, {
283
299
  variant: 'user-avatar',
284
300
  });
285
301
  const DEFAULT_AI_ICON = () => (React__namespace["default"].createElement("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
286
302
  React__namespace["default"].createElement("g", { id: "raven-logo" },
287
303
  React__namespace["default"].createElement("path", { id: "Subtract", fillRule: "evenodd", clipRule: "evenodd", d: "M16 1.29833C14.7624 0.583803 13.2376 0.583804 12 1.29833L4.00006 5.91711C2.76246 6.63165 2.00006 7.95216 2.00006 9.38122V18.6188C2.00006 20.0478 2.76246 21.3684 4.00006 22.0829L12 26.7017C13.2376 27.4162 14.7624 27.4162 16 26.7017L24 22.0829C25.2376 21.3684 26 20.0478 26 18.6188V9.38122C26 7.95215 25.2376 6.63164 24 5.91711L16 1.29833ZM14.9379 6.37317C14.6157 5.50255 13.3843 5.50255 13.0622 6.37317L11.4151 10.8243C11.3138 11.098 11.098 11.3138 10.8243 11.4151L6.37317 13.0621C5.50256 13.3843 5.50256 14.6157 6.37317 14.9378L10.8243 16.5849C11.098 16.6862 11.3138 16.902 11.4151 17.1757L13.0622 21.6268C13.3843 22.4974 14.6157 22.4974 14.9379 21.6268L16.5849 17.1757C16.6862 16.902 16.902 16.6862 17.1757 16.5849L21.6268 14.9378C22.4974 14.6157 22.4974 13.3843 21.6268 13.0621L17.1757 11.4151C16.902 11.3138 16.6862 11.098 16.5849 10.8243L14.9379 6.37317Z", fill: "#0D1A26" }))));
288
- const AvatarDisplayName = elements.withBaseElementProps(Text$4, {
304
+ const AvatarDisplayName = elements.withBaseElementProps(Text$2, {
289
305
  className: `${AVATAR_BLOCK}__display-name`,
290
306
  });
291
307
  const AvatarIcon = elements.withBaseElementProps(Span$2, {
292
308
  'aria-hidden': true,
293
309
  className: `${AVATAR_BLOCK}__icon`,
294
310
  });
295
- const Container$3 = elements.withBaseElementProps(View$6, {
311
+ const Container$2 = elements.withBaseElementProps(View$5, {
296
312
  className: `${AVATAR_BLOCK}__container`,
297
313
  });
298
314
  const AvatarControl = () => {
@@ -301,47 +317,18 @@ const AvatarControl = () => {
301
317
  const avatar = role === 'assistant' ? avatars?.ai : avatars?.user;
302
318
  const defaultIcon = role === 'assistant' ? React__namespace["default"].createElement(DEFAULT_AI_ICON, null) : React__namespace["default"].createElement(DEFAULT_USER_ICON, null);
303
319
  const defaultDisplayName = role === 'user' ? 'User' : 'Assistant';
304
- return (React__namespace["default"].createElement(Container$3, { "data-testid": 'avatar' },
320
+ return (React__namespace["default"].createElement(Container$2, { "data-testid": 'avatar' },
305
321
  React__namespace["default"].createElement(AvatarIcon, { "data-testid": `avatar-icon-${role}` }, avatar?.avatar ?? defaultIcon),
306
322
  React__namespace["default"].createElement(AvatarDisplayName, null, avatar?.username ?? defaultDisplayName)));
307
323
  };
308
- AvatarControl.Container = Container$3;
324
+ AvatarControl.Container = Container$2;
309
325
  AvatarControl.DisplayName = AvatarDisplayName;
310
326
  AvatarControl.Icon = AvatarIcon;
311
327
 
312
- const { View: View$5, Button: Button$4, Icon: Icon$4, Text: Text$3 } = AIConversationElements;
313
- const HEADER_BLOCK = 'ai-header';
314
- const HeaderTextBase = elements.withBaseElementProps(Text$3, {
315
- className: `${HEADER_BLOCK}__text`,
316
- });
317
- const HeaderText$1 = React__namespace["default"].forwardRef(function HeaderText(props, ref) {
318
- return React__namespace["default"].createElement(HeaderTextBase, { ...props, ref: ref });
319
- });
320
- const CloseIcon = elements.withBaseElementProps(Icon$4, {
321
- className: `${HEADER_BLOCK}__icon`,
322
- variant: 'close',
323
- });
324
- const CloseButtonBase = elements.withBaseElementProps(Button$4, {
325
- className: `${HEADER_BLOCK}__button`,
326
- });
327
- const CloseButton = React__namespace["default"].forwardRef(function CloseButton(props, ref) {
328
- return React__namespace["default"].createElement(CloseButtonBase, { ...props, ref: ref });
329
- });
330
- const Container$2 = elements.withBaseElementProps(View$5, {
331
- className: `${HEADER_BLOCK}__container`,
332
- });
333
- const HeaderControl = () => (React__namespace["default"].createElement(Container$2, null,
334
- React__namespace["default"].createElement(HeaderText$1, null, "Raven Chat"),
335
- React__namespace["default"].createElement(CloseButton, null,
336
- React__namespace["default"].createElement(CloseIcon, null))));
337
- HeaderControl.Container = Container$2;
338
- HeaderControl.Text = HeaderText$1;
339
- HeaderControl.Button = CloseButton;
340
-
341
- const { Button: Button$3, Icon: Icon$3, View: View$4 } = AIConversationElements;
328
+ const { Button: Button$3, Icon: Icon$2, View: View$4 } = AIConversationElements;
342
329
  const ATTACH_FILE_BLOCK = 'ai-attach-file';
343
330
  const FIELD_BLOCK$1 = 'ai-field';
344
- const AttachFileIcon = elements.withBaseElementProps(Icon$3, {
331
+ const AttachFileIcon = elements.withBaseElementProps(Icon$2, {
345
332
  className: `${ATTACH_FILE_BLOCK}__icon`,
346
333
  variant: 'attach',
347
334
  });
@@ -398,12 +385,12 @@ AttachFileControl.Icon = AttachFileIcon;
398
385
  AttachFileControl.Button = AttachFileButton;
399
386
  AttachFileControl.Container = AttachFileContainer;
400
387
 
401
- const { Button: Button$2, Icon: Icon$2, ListItem, UnorderedList: ListElement, Span: Span$1, Text: Text$2, View: View$3, } = AIConversationElements;
388
+ const { Button: Button$2, Icon: Icon$1, ListItem, UnorderedList: ListElement, Span: Span$1, Text: Text$1, View: View$3, } = AIConversationElements;
402
389
  const IMAGE_LIST_BLOCK = 'ai-attachment-list';
403
390
  const IMAGE_ITEM_BLOCK = 'ai-attachment';
404
391
  const REMOVE_IMAGE_BLOCK = 'ai-remove-attachment';
405
392
  const IMAGE_TEXT_BLOCK = 'ai-attachment-text';
406
- const RemoveIcon = elements.withBaseElementProps(Icon$2, {
393
+ const RemoveIcon = elements.withBaseElementProps(Icon$1, {
407
394
  className: `${REMOVE_IMAGE_BLOCK}__icon`,
408
395
  variant: 'close',
409
396
  });
@@ -419,14 +406,14 @@ const RemoveButtonControl = ({ onRemove }) => {
419
406
  };
420
407
  RemoveButtonControl.Icon = RemoveIcon;
421
408
  RemoveButtonControl.Button = RemoveButton;
422
- const ImageIcon = elements.withBaseElementProps(Icon$2, {
409
+ const ImageIcon = elements.withBaseElementProps(Icon$1, {
423
410
  className: `${IMAGE_ITEM_BLOCK}__icon`,
424
411
  variant: 'image',
425
412
  });
426
- const FileNameText = elements.withBaseElementProps(Text$2, {
413
+ const FileNameText = elements.withBaseElementProps(Text$1, {
427
414
  className: `${IMAGE_TEXT_BLOCK}__file-name`,
428
415
  });
429
- const FileSizeText = elements.withBaseElementProps(Text$2, {
416
+ const FileSizeText = elements.withBaseElementProps(Text$1, {
430
417
  className: `${IMAGE_TEXT_BLOCK}__file-size`,
431
418
  });
432
419
  const Separator$1 = elements.withBaseElementProps(Span$1, {
@@ -480,14 +467,9 @@ const AttachmentListControl = () => {
480
467
  AttachmentListControl.List = UnorderedList;
481
468
  AttachmentListControl.Item = AttachmentControl;
482
469
 
483
- const AttachmentContext = React__namespace.createContext(false);
484
- const AttachmentProvider = ({ children, allowAttachments, }) => {
485
- return (React__namespace.createElement(AttachmentContext.Provider, { value: allowAttachments ?? false }, children));
486
- };
487
-
488
- const { Button: Button$1, Icon: Icon$1, Label: LabelElement, TextArea, View: View$2, } = AIConversationElements;
470
+ const { Button: Button$1, Icon, Label: LabelElement, TextArea, View: View$2, } = AIConversationElements;
489
471
  const FIELD_BLOCK = 'ai-field';
490
- const SendIcon = elements.withBaseElementProps(Icon$1, {
472
+ const SendIcon = elements.withBaseElementProps(Icon, {
491
473
  className: `${FIELD_BLOCK}__icon`,
492
474
  variant: 'send-message',
493
475
  });
@@ -565,7 +547,7 @@ const TextInput = React__namespace["default"].forwardRef(function TextInput(prop
565
547
  const InputContainer = elements.withBaseElementProps(View$2, {
566
548
  className: `${FIELD_BLOCK}__input-container`,
567
549
  });
568
- const FieldControl = () => {
550
+ const FormControl = () => {
569
551
  const { input, setInput } = React__namespace["default"].useContext(ConversationInputContext);
570
552
  const handleSendMessage = React__namespace["default"].useContext(SendMessageContext);
571
553
  const allowAttachments = React__namespace["default"].useContext(AttachmentContext);
@@ -629,14 +611,14 @@ const FieldControl = () => {
629
611
  React__namespace["default"].createElement(SendButton, null,
630
612
  React__namespace["default"].createElement(SendIcon, null))));
631
613
  };
632
- FieldControl.AttachFile = AttachFileControl;
633
- FieldControl.InputContainer = InputContainer;
634
- FieldControl.Label = Label;
635
- FieldControl.TextInput = TextInput;
636
- FieldControl.SendButton = SendButton;
637
- FieldControl.SendIcon = SendIcon;
614
+ FormControl.AttachFile = AttachFileControl;
615
+ FormControl.InputContainer = InputContainer;
616
+ FormControl.Label = Label;
617
+ FormControl.TextInput = TextInput;
618
+ FormControl.SendButton = SendButton;
619
+ FormControl.SendIcon = SendIcon;
638
620
 
639
- const { Image, Span, Text: Text$1, View: View$1 } = AIConversationElements;
621
+ const { Image, Span, Text, View: View$1 } = AIConversationElements;
640
622
  const MESSAGES_BLOCK = 'ai-messages';
641
623
  const MESSAGE_BLOCK = 'ai-message';
642
624
  const MediaContentBase = elements.withBaseElementProps(Image, {
@@ -648,34 +630,38 @@ const MediaContent = React__namespace["default"].forwardRef(function MediaConten
648
630
  return (React__namespace["default"].createElement(MediaContentBase, { ref: ref, className: `${MESSAGE_BLOCK}__image ${MESSAGE_BLOCK}__image--${variant} ${MESSAGE_BLOCK}__image--${role}`, ...props }));
649
631
  });
650
632
  const TextContent = React__namespace["default"].forwardRef(function TextContent(props, ref) {
651
- return React__namespace["default"].createElement(Text$1, { ref: ref, className: `${MESSAGE_BLOCK}__text`, ...props });
633
+ return React__namespace["default"].createElement(Text, { ref: ref, className: `${MESSAGE_BLOCK}__text`, ...props });
652
634
  });
653
635
  const ContentContainer = React__namespace["default"].forwardRef(function ContentContainer(props, ref) {
654
636
  const variant = React__namespace["default"].useContext(MessageVariantContext);
655
637
  return (React__namespace["default"].createElement(View$1, { "data-testid": 'content', className: `${MESSAGE_BLOCK}__content ${MESSAGE_BLOCK}__content--${variant}`, ref: ref, ...props }));
656
638
  });
657
- const MessageControl = ({ message }) => {
639
+ const ToolContent = ({ toolUse, }) => {
658
640
  const responseComponents = React__namespace["default"].useContext(ResponseComponentsContext);
641
+ // For now tool use is limited to custom response components
642
+ const { name, input } = toolUse;
643
+ if (!responseComponents ||
644
+ !name ||
645
+ !name.startsWith(RESPONSE_COMPONENT_PREFIX)) {
646
+ return;
647
+ }
648
+ else {
649
+ const response = responseComponents[name];
650
+ const CustomComponent = response.component;
651
+ return React__namespace["default"].createElement(CustomComponent, { ...input });
652
+ }
653
+ };
654
+ const MessageControl = ({ message }) => {
655
+ const messageRenderer = React__namespace["default"].useContext(MessageRendererContext);
659
656
  return (React__namespace["default"].createElement(ContentContainer, null, message.content.map((content, index) => {
660
657
  if (content.text) {
661
- return (React__namespace["default"].createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
658
+ return messageRenderer?.text ? (React__namespace["default"].createElement(React__namespace["default"].Fragment, { key: index }, messageRenderer.text({ text: content.text }))) : (React__namespace["default"].createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
662
659
  }
663
660
  else if (content.image) {
664
- return (React__namespace["default"].createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
661
+ return messageRenderer?.image ? (React__namespace["default"].createElement(React__namespace["default"].Fragment, { key: index }, messageRenderer?.image({ image: content.image }))) : (React__namespace["default"].createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
665
662
  }
666
663
  else if (content.toolUse) {
667
- // For now tool use is limited to custom response components
668
- const { name, input } = content.toolUse;
669
- if (!responseComponents ||
670
- !name ||
671
- !name.startsWith(RESPONSE_COMPONENT_PREFIX)) {
672
- return;
673
- }
674
- else {
675
- const response = responseComponents[name];
676
- const CustomComponent = response.component;
677
- return React__namespace["default"].createElement(CustomComponent, { ...input, key: index });
678
- }
664
+ return React__namespace["default"].createElement(ToolContent, { toolUse: content.toolUse, key: index });
679
665
  }
680
666
  })));
681
667
  };
@@ -687,7 +673,7 @@ const Separator = elements.withBaseElementProps(Span, {
687
673
  children: '|',
688
674
  className: `${MESSAGE_BLOCK}__separator`,
689
675
  });
690
- const Timestamp = elements.withBaseElementProps(Text$1, {
676
+ const Timestamp = elements.withBaseElementProps(Text, {
691
677
  className: `${MESSAGE_BLOCK}__timestamp`,
692
678
  });
693
679
  const HeaderContainer = React__namespace["default"].forwardRef(function HeaderContainer(props, ref) {
@@ -703,7 +689,7 @@ const Layout = React__namespace["default"].forwardRef(function Layout(props, ref
703
689
  const variant = React__namespace["default"].useContext(MessageVariantContext);
704
690
  return (React__namespace["default"].createElement(View$1, { ref: ref, className: `${MESSAGES_BLOCK}__container ${MESSAGES_BLOCK}__container--${variant}`, "aria-live": 'assertive', ...props }));
705
691
  });
706
- const MessagesControl = ({ renderMessage }) => {
692
+ const MessagesControl = () => {
707
693
  const messages = React__namespace["default"].useContext(MessagesContext);
708
694
  const controls = React__namespace["default"].useContext(ControlsContext);
709
695
  const { getMessageTimestampText } = useConversationDisplayText();
@@ -743,7 +729,7 @@ const MessagesControl = ({ renderMessage }) => {
743
729
  content.text ??
744
730
  content.toolUse?.name.startsWith(RESPONSE_COMPONENT_PREFIX))) ?? [];
745
731
  return (React__namespace["default"].createElement(Layout, null, messagesWithRenderableContent?.map((message, index) => {
746
- return renderMessage ? (renderMessage(message)) : (React__namespace["default"].createElement(RoleContext.Provider, { value: message.role, key: `message-${index}` },
732
+ return (React__namespace["default"].createElement(RoleContext.Provider, { value: message.role, key: `message-${index}` },
747
733
  React__namespace["default"].createElement(MessageContainer, { "data-testid": `message`, key: `message-${index}`, tabIndex: focusedItemIndex === index ? 0 : -1, onFocus: () => handleFocus(index), onKeyDown: (event) => onKeyDown(index, event), ref: (el) => (messagesRef.current[index] = el) },
748
734
  React__namespace["default"].createElement(HeaderContainer, null,
749
735
  React__namespace["default"].createElement(AvatarControl, null),
@@ -761,7 +747,7 @@ MessagesControl.Layout = Layout;
761
747
  MessagesControl.Message = MessageControl;
762
748
  MessagesControl.Separator = Separator;
763
749
 
764
- const { View, Button, Text, Heading, Icon } = AIConversationElements;
750
+ const { View, Button } = AIConversationElements;
765
751
  const PROMPT_BLOCK = 'ai-prompts';
766
752
  const PROMPT_CONTROL = `${PROMPT_BLOCK}__prompt`;
767
753
  const PROMPT_CARD = `${PROMPT_CONTROL}__card`;
@@ -769,25 +755,6 @@ const PromptCard = elements.withBaseElementProps(Button, {
769
755
  className: PROMPT_CARD,
770
756
  type: 'button',
771
757
  });
772
- const AIIconProps = () => ({
773
- children: (React__namespace["default"].createElement(React__namespace["default"].Fragment, null,
774
- React__namespace["default"].createElement("path", { d: "M17.5 1.64858C19.047 0.755412 20.953 0.755412 22.5 1.64858L34.6428 8.65923C36.1898 9.55239 37.1428 11.203 37.1428 12.9894V27.0107C37.1428 28.797 36.1898 30.4476 34.6428 31.3408L22.5 38.3514C20.953 39.2446 19.047 39.2446 17.5 38.3514L5.35718 31.3408C3.81017 30.4476 2.85718 28.797 2.85718 27.0107V12.9894C2.85718 11.203 3.81017 9.55239 5.35718 8.65923L17.5 1.64858Z", fill: "white" }),
775
- React__namespace["default"].createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M22.5 1.64851C20.953 0.755347 19.047 0.755347 17.5 1.64851L5.35718 8.65916C3.81017 9.55233 2.85718 11.203 2.85718 12.9893V27.0106C2.85718 28.7969 3.81017 30.4476 5.35718 31.3407L17.5 38.3514C19.047 39.2445 20.953 39.2445 22.5 38.3514L34.6428 31.3407C36.1898 30.4476 37.1428 28.7969 37.1428 27.0106V12.9893C37.1428 11.203 36.1898 9.55233 34.6428 8.65916L22.5 1.64851ZM20.9378 8.01826C20.6156 7.14764 19.3843 7.14764 19.0621 8.01825L16.2388 15.648C16.1375 15.9217 15.9217 16.1375 15.648 16.2388L8.01826 19.0621C7.14765 19.3842 7.14765 20.6156 8.01826 20.9378L15.648 23.7611C15.9217 23.8623 16.1375 24.0782 16.2388 24.3519L19.0621 31.9816C19.3843 32.8522 20.6156 32.8522 20.9378 31.9816L23.7611 24.3519C23.8624 24.0782 24.0782 23.8623 24.3519 23.7611L31.9816 20.9378C32.8523 20.6156 32.8523 19.3842 31.9816 19.0621L24.3519 16.2388C24.0782 16.1375 23.8624 15.9217 23.7611 15.648L20.9378 8.01826Z", fill: "url(#paint0_linear_395_1815)" }),
776
- React__namespace["default"].createElement("defs", null,
777
- React__namespace["default"].createElement("linearGradient", { id: "paint0_linear_395_1815", x1: "20", y1: "0.978638", x2: "20", y2: "39.0213", gradientUnits: "userSpaceOnUse" },
778
- React__namespace["default"].createElement("stop", { stopColor: "#7DD6E8" }),
779
- React__namespace["default"].createElement("stop", { offset: "1", stopColor: "#BF40BF" }))))),
780
- className: `${PROMPT_CONTROL}__icon`,
781
- width: '40',
782
- height: '40',
783
- viewBox: '0 0 40 40',
784
- fill: 'none',
785
- xmlns: 'http://www.w3.org/2000/svg',
786
- });
787
- const AIIcon = elements.withBaseElementProps(Icon, AIIconProps);
788
- const HeaderText = elements.withBaseElementProps(Heading, {
789
- className: `${PROMPT_CONTROL}__header`,
790
- });
791
758
  const PromptGroupBase = elements.withBaseElementProps(View, {
792
759
  className: `${PROMPT_CONTROL}__buttongroup`,
793
760
  });
@@ -802,9 +769,7 @@ const PromptGroup = React__namespace["default"].forwardRef(function ButtonGroup(
802
769
  setInput((prevInput) => ({
803
770
  ...prevInput,
804
771
  text: prompt.inputText,
805
- })) },
806
- React__namespace["default"].createElement(Text, { className: ui.classNames(`${PROMPT_CARD}__header`, `${PROMPT_CARD}__text`) }, prompt.header),
807
- React__namespace["default"].createElement(Text, { className: `${PROMPT_CARD}__text` }, prompt.inputText)));
772
+ })) }, prompt.component));
808
773
  })));
809
774
  });
810
775
  const Container = elements.withBaseElementProps(View, {
@@ -818,41 +783,21 @@ const PromptControl = () => {
818
783
  return (React__namespace["default"].createElement(controls.PromptList, { setInput: setInput, suggestedPrompts: suggestedPromptsArray }));
819
784
  }
820
785
  return (React__namespace["default"].createElement(Container, null,
821
- React__namespace["default"].createElement(AIIcon, null),
822
- React__namespace["default"].createElement(HeaderText, null, "How can I help you today?"),
823
786
  React__namespace["default"].createElement(PromptGroup, null)));
824
787
  };
825
- const AutoHidablePromptControl = () => {
826
- const messages = React__namespace["default"].useContext(MessagesContext);
827
- if (!messages || messages.length === 0) {
828
- return React__namespace["default"].createElement(PromptControl, null);
829
- }
830
- };
831
788
  PromptControl.Container = Container;
832
- PromptControl.Header = HeaderText;
833
- PromptControl.Icon = AIIcon;
834
789
  PromptControl.PromptGroup = PromptGroup;
835
790
  PromptControl.PromptCard = PromptCard;
836
791
 
837
- function Conversation() {
838
- return (React__namespace["default"].createElement(ViewElement, null,
839
- React__namespace["default"].createElement(HeaderControl, null),
840
- React__namespace["default"].createElement(ViewElement, null,
841
- React__namespace["default"].createElement(AutoHidablePromptControl, null),
842
- React__namespace["default"].createElement(MessagesControl, null)),
843
- React__namespace["default"].createElement(ViewElement, null,
844
- React__namespace["default"].createElement(FieldControl, null))));
845
- }
846
-
847
- function createProvider({ elements: elements$1, actions, suggestedPrompts, responseComponents, variant, controls, displayText, allowAttachments, }) {
848
- return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
849
- const _displayText = {
850
- ...defaultAIConversationDisplayTextEn,
851
- ...displayText,
852
- };
853
- return (React__namespace["default"].createElement(elements.ElementsProvider, { elements: elements$1 },
854
- React__namespace["default"].createElement(ControlsProvider, { controls: controls },
855
- React__namespace["default"].createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
792
+ const AIConversationProvider = ({ actions, allowAttachments, avatars, children, controls, displayText, elements: elements$1, handleSendMessage, isLoading, messages, responseComponents, suggestedPrompts, variant, welcomeMessage, }) => {
793
+ const _displayText = {
794
+ ...defaultAIConversationDisplayTextEn,
795
+ ...displayText,
796
+ };
797
+ return (React__namespace["default"].createElement(elements.ElementsProvider, { elements: elements$1 },
798
+ React__namespace["default"].createElement(ControlsProvider, { controls: controls },
799
+ React__namespace["default"].createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
800
+ React__namespace["default"].createElement(WelcomeMessageProvider, { welcomeMessage: welcomeMessage },
856
801
  React__namespace["default"].createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
857
802
  React__namespace["default"].createElement(AttachmentProvider, { allowAttachments: allowAttachments },
858
803
  React__namespace["default"].createElement(ConversationDisplayTextProvider, { ..._displayText },
@@ -862,41 +807,53 @@ function createProvider({ elements: elements$1, actions, suggestedPrompts, respo
862
807
  React__namespace["default"].createElement(ActionsProvider, { actions: actions },
863
808
  React__namespace["default"].createElement(MessageVariantProvider, { variant: variant },
864
809
  React__namespace["default"].createElement(MessagesProvider, { messages: messages },
865
- React__namespace["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))))));
866
- };
867
- }
810
+ React__namespace["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))))));
811
+ };
812
+
813
+ const DefaultMessageControl = () => {
814
+ const messages = React__namespace.useContext(MessagesContext);
815
+ const welcomeMessage = React__namespace.useContext(WelcomeMessageContext);
816
+ if (!messages || messages.length === 0) {
817
+ return (React__namespace.createElement(React__namespace.Fragment, null,
818
+ welcomeMessage,
819
+ React__namespace.createElement(PromptControl, null)));
820
+ }
821
+ };
868
822
 
869
823
  /**
870
824
  * @experimental
871
825
  */
872
826
  function createAIConversation(input = {}) {
873
- const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, } = input;
874
- const Provider = createProvider({
875
- elements,
876
- actions,
877
- suggestedPrompts,
878
- responseComponents,
879
- variant,
880
- controls,
881
- displayText,
882
- allowAttachments,
883
- });
827
+ const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, messageRenderer, } = input;
884
828
  function AIConversation(props) {
885
829
  const { messages, avatars, handleSendMessage, isLoading } = props;
886
- return (React__namespace["default"].createElement(Provider, { messages: messages, avatars: avatars, handleSendMessage: handleSendMessage, isLoading: isLoading },
887
- React__namespace["default"].createElement(Conversation, null)));
830
+ const providerProps = {
831
+ elements,
832
+ actions,
833
+ suggestedPrompts,
834
+ responseComponents,
835
+ variant,
836
+ controls,
837
+ displayText,
838
+ allowAttachments,
839
+ messages,
840
+ avatars,
841
+ handleSendMessage,
842
+ isLoading,
843
+ messageRenderer,
844
+ };
845
+ return (React__namespace["default"].createElement(AIConversationProvider, { ...providerProps },
846
+ React__namespace["default"].createElement(ViewElement, null,
847
+ React__namespace["default"].createElement(ViewElement, null,
848
+ React__namespace["default"].createElement(DefaultMessageControl, null),
849
+ React__namespace["default"].createElement(MessagesControl, null)),
850
+ React__namespace["default"].createElement(ViewElement, null,
851
+ React__namespace["default"].createElement(FormControl, null)))));
888
852
  }
889
- const Controls = {
890
- ActionsBar: ActionsBarControl,
891
- Avatars: AvatarControl,
892
- Field: FieldControl,
893
- Header: HeaderControl,
894
- Messages: MessagesControl,
895
- SuggestedPrompts: PromptControl,
896
- };
897
- AIConversation.Provider = Provider;
898
- AIConversation.Conversation = Conversation;
899
- AIConversation.Controls = Controls;
853
+ AIConversation.Provider = AIConversationProvider;
854
+ AIConversation.DefaultMessage = DefaultMessageControl;
855
+ AIConversation.Messages = MessagesControl;
856
+ AIConversation.Form = FormControl;
900
857
  return { AIConversation };
901
858
  }
902
859
 
@@ -1043,11 +1000,18 @@ const PromptList = ({ setInput, suggestedPrompts = [], }) => {
1043
1000
  ...prevInput,
1044
1001
  text: prompt.inputText,
1045
1002
  }));
1046
- } }, prompt.header));
1003
+ } }, prompt.component));
1047
1004
  })));
1048
1005
  };
1049
1006
 
1050
- function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, }) {
1007
+ const VERSION = '0.4.0';
1008
+
1009
+ function Provider({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, messageRenderer, children, }) {
1010
+ uiReactCore.useSetUserAgent({
1011
+ componentName: 'AIConversation',
1012
+ packageName: 'react-ai',
1013
+ version: VERSION,
1014
+ });
1051
1015
  const icons = internal.useIcons('aiConversation');
1052
1016
  const defaultAvatars = {
1053
1017
  ai: {
@@ -1059,11 +1023,16 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
1059
1023
  avatar: icons?.user ?? React__namespace.createElement(internal.IconUser, null),
1060
1024
  },
1061
1025
  };
1062
- const Provider = createProvider({
1026
+ const providerProps = {
1027
+ messages,
1028
+ handleSendMessage,
1029
+ avatars: {
1030
+ ...defaultAvatars,
1031
+ ...avatars,
1032
+ },
1033
+ isLoading,
1063
1034
  elements: {
1064
- Text: React__namespace.forwardRef(function _Text(props, ref) {
1065
- return React__namespace.createElement(uiReact.Text, { ...props, ref: ref });
1066
- }),
1035
+ Text: uiReact.Text,
1067
1036
  },
1068
1037
  actions,
1069
1038
  suggestedPrompts,
@@ -1077,30 +1046,26 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
1077
1046
  },
1078
1047
  displayText,
1079
1048
  allowAttachments,
1080
- });
1081
- const providerProps = {
1082
- messages,
1083
- handleSendMessage,
1084
- avatars: {
1085
- ...defaultAvatars,
1086
- ...avatars,
1087
- },
1088
- isLoading,
1049
+ messageRenderer,
1089
1050
  };
1090
- return (React__namespace.createElement(Provider, { ...providerProps },
1051
+ return (React__namespace.createElement(AIConversationProvider, { ...providerProps }, children));
1052
+ }
1053
+ function AIConversationBase(props) {
1054
+ return (React__namespace.createElement(Provider, { ...props },
1091
1055
  React__namespace.createElement(uiReact.Flex, { className: ui.ComponentClassName.AIConversation },
1092
1056
  React__namespace.createElement(uiReact.ScrollView, { autoScroll: "smooth", flex: "1" },
1093
- React__namespace.createElement(AutoHidablePromptControl, null),
1057
+ React__namespace.createElement(DefaultMessageControl, null),
1094
1058
  React__namespace.createElement(MessagesControl, null)),
1095
- React__namespace.createElement(FieldControl, null))));
1059
+ React__namespace.createElement(FormControl, null))));
1096
1060
  }
1097
1061
  /**
1098
1062
  * @experimental
1099
1063
  */
1100
1064
  const AIConversation = Object.assign(AIConversationBase, {
1101
- MessageList,
1102
- PromptList,
1103
- Form,
1065
+ Provider,
1066
+ DefaultMessage: DefaultMessageControl,
1067
+ Messages: MessagesControl,
1068
+ Form: FormControl,
1104
1069
  });
1105
1070
 
1106
1071
  const AIContext = React__namespace["default"].createContext(undefined);
@@ -1120,22 +1085,36 @@ const AIContextProvider = ({ children, }) => {
1120
1085
  return React__namespace["default"].createElement(AIContext.Provider, { value: context }, children);
1121
1086
  };
1122
1087
 
1088
+ // default state
1089
+ const INITIAL_STATE = {
1090
+ hasError: false,
1091
+ isLoading: false,
1092
+ messages: undefined,
1093
+ };
1094
+ const LOADING_STATE = { hasError: false, isLoading: true, messages: undefined };
1095
+ const ERROR_STATE = { hasError: true, isLoading: false };
1123
1096
  function createUseAIGeneration(client) {
1124
1097
  const useAIGeneration = (routeName) => {
1125
- const handleGenerate = client.generations[routeName];
1126
- const updateAIGenerationStateAction = async (_prev, input) => {
1127
- const result = await handleGenerate(input);
1128
- // handleGenerate returns a Promised wrapper around Schema[Key]['returnType'] which includes data, errors, and clientExtensions
1129
- // The type of data is Schema[Key]['returnType'] which useDataState also wraps in a data return
1130
- // TODO: follow up with how to type handleGenerate to properly return the promise wrapper shape
1131
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1132
- const data = result.data;
1133
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
1134
- const graphqlErrors = result.errors;
1135
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment
1136
- return { ...data, ...(graphqlErrors ? { graphqlErrors } : {}) };
1137
- };
1138
- return uiReactCore.useDataState(updateAIGenerationStateAction, {});
1098
+ const [dataState, setDataState] = React__namespace.useState(() => ({
1099
+ ...INITIAL_STATE,
1100
+ data: undefined,
1101
+ }));
1102
+ const handleGeneration = React__namespace.useCallback(async (input) => {
1103
+ setDataState(({ data }) => ({ ...LOADING_STATE, data }));
1104
+ const result = await client.generations[routeName](input);
1105
+ const { data, errors } = result;
1106
+ if (errors) {
1107
+ setDataState({
1108
+ ...ERROR_STATE,
1109
+ data,
1110
+ messages: errors,
1111
+ });
1112
+ }
1113
+ else {
1114
+ setDataState({ ...INITIAL_STATE, data });
1115
+ }
1116
+ }, [routeName]);
1117
+ return [dataState, handleGeneration];
1139
1118
  };
1140
1119
  return useAIGeneration;
1141
1120
  }