@aws-amplify/ui-react-ai 0.2.1 → 0.3.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.
@@ -14,7 +14,7 @@ import { PromptList } from './views/default/PromptList.mjs';
14
14
  import { ComponentClassName } from '@aws-amplify/ui';
15
15
  import createProvider from './createProvider.mjs';
16
16
 
17
- function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }) {
17
+ function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, }) {
18
18
  const icons = useIcons('aiConversation');
19
19
  const defaultAvatars = {
20
20
  ai: {
@@ -52,6 +52,7 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
52
52
  ...avatars,
53
53
  },
54
54
  isLoading,
55
+ allowAttachments,
55
56
  };
56
57
  return (React.createElement(Provider, { ...providerProps },
57
58
  React.createElement(Flex, { className: ComponentClassName.AIConversation },
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+
3
+ const AttachmentContext = React.createContext(false);
4
+ const AttachmentProvider = ({ children, allowAttachments, }) => {
5
+ return (React.createElement(AttachmentContext.Provider, { value: allowAttachments ?? false }, children));
6
+ };
7
+
8
+ export { AttachmentContext, AttachmentProvider };
@@ -12,7 +12,7 @@ import createProvider from './createProvider.mjs';
12
12
  * @experimental
13
13
  */
14
14
  function createAIConversation(input = {}) {
15
- const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, } = input;
15
+ const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, } = input;
16
16
  const Provider = createProvider({
17
17
  elements,
18
18
  actions,
@@ -21,6 +21,7 @@ function createAIConversation(input = {}) {
21
21
  variant,
22
22
  controls,
23
23
  displayText,
24
+ allowAttachments,
24
25
  });
25
26
  function AIConversation(props) {
26
27
  const { messages, avatars, handleSendMessage, isLoading } = props;
@@ -13,8 +13,9 @@ import { LoadingContextProvider } from './context/LoadingContext.mjs';
13
13
  import { ResponseComponentsProvider } from './context/ResponseComponentsContext.mjs';
14
14
  import { SendMessageContextProvider } from './context/SendMessageContext.mjs';
15
15
  import './context/elements/definitions.mjs';
16
+ import { AttachmentProvider } from './context/AttachmentContext.mjs';
16
17
 
17
- function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }) {
18
+ function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, allowAttachments, }) {
18
19
  return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
19
20
  const _displayText = {
20
21
  ...defaultAIConversationDisplayTextEn,
@@ -24,14 +25,15 @@ function createProvider({ elements, actions, suggestedPrompts, responseComponent
24
25
  React__default.createElement(ControlsProvider, { controls: controls },
25
26
  React__default.createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
26
27
  React__default.createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
27
- React__default.createElement(ConversationDisplayTextProvider, { ..._displayText },
28
- React__default.createElement(ConversationInputContextProvider, null,
29
- React__default.createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
30
- React__default.createElement(AvatarsProvider, { avatars: avatars },
31
- React__default.createElement(ActionsProvider, { actions: actions },
32
- React__default.createElement(MessageVariantProvider, { variant: variant },
33
- React__default.createElement(MessagesProvider, { messages: messages },
34
- React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))));
28
+ React__default.createElement(AttachmentProvider, { allowAttachments: allowAttachments },
29
+ React__default.createElement(ConversationDisplayTextProvider, { ..._displayText },
30
+ React__default.createElement(ConversationInputContextProvider, null,
31
+ React__default.createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
32
+ React__default.createElement(AvatarsProvider, { avatars: avatars },
33
+ React__default.createElement(ActionsProvider, { actions: actions },
34
+ React__default.createElement(MessageVariantProvider, { variant: variant },
35
+ React__default.createElement(MessagesProvider, { messages: messages },
36
+ React__default.createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))))));
35
37
  };
36
38
  }
37
39
 
@@ -12,6 +12,7 @@ import '../../context/LoadingContext.mjs';
12
12
  import '../../context/ResponseComponentsContext.mjs';
13
13
  import '../../context/SendMessageContext.mjs';
14
14
  import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
+ import { useDropZone } from '@aws-amplify/ui-react-core';
15
16
 
16
17
  const { Button, Icon, View } = AIConversationElements;
17
18
  const ATTACH_FILE_BLOCK = 'ai-attach-file';
@@ -35,6 +36,17 @@ const AttachFileButton = withBaseElementProps(Button, {
35
36
  const AttachFileControl = () => {
36
37
  const hiddenInput = React__default.useRef(null);
37
38
  const { setInput } = React__default.useContext(ConversationInputContext);
39
+ const { dragState, ...dropHandlers } = useDropZone({
40
+ acceptedFileTypes: ['.jpeg'],
41
+ onDropComplete: ({ acceptedFiles }) => {
42
+ if (acceptedFiles && acceptedFiles?.length > 0 && setInput) {
43
+ setInput((prevInput) => ({
44
+ ...prevInput,
45
+ files: [...(prevInput?.files ?? []), ...acceptedFiles],
46
+ }));
47
+ }
48
+ },
49
+ });
38
50
  function handleButtonClick() {
39
51
  if (hiddenInput.current) {
40
52
  hiddenInput.current.click();
@@ -52,7 +64,7 @@ const AttachFileControl = () => {
52
64
  });
53
65
  }
54
66
  }
55
- return (React__default.createElement(AttachFileContainer, null,
67
+ return (React__default.createElement(AttachFileContainer, { ...dropHandlers },
56
68
  React__default.createElement(AttachFileButton, { onClick: handleButtonClick },
57
69
  React__default.createElement(AttachFileIcon, null)),
58
70
  React__default.createElement(VisuallyHidden, null,
@@ -15,6 +15,7 @@ import { AIConversationElements } from '../../context/elements/definitions.mjs';
15
15
  import { AttachFileControl } from './AttachFileControl.mjs';
16
16
  import { AttachmentListControl } from './AttachmentListControl.mjs';
17
17
  import { getImageTypeFromMimeType } from '../../utils.mjs';
18
+ import { AttachmentContext } from '../../context/AttachmentContext.mjs';
18
19
 
19
20
  const { Button, Icon, Label: LabelElement, TextArea, View, } = AIConversationElements;
20
21
  const FIELD_BLOCK = 'ai-field';
@@ -99,6 +100,7 @@ const InputContainer = withBaseElementProps(View, {
99
100
  const FieldControl = () => {
100
101
  const { input, setInput } = React__default.useContext(ConversationInputContext);
101
102
  const handleSendMessage = React__default.useContext(SendMessageContext);
103
+ const allowAttachments = React__default.useContext(AttachmentContext);
102
104
  const ref = React__default.useRef(null);
103
105
  const responseComponents = React__default.useContext(ResponseComponentsContext);
104
106
  const controls = React__default.useContext(ControlsContext);
@@ -147,10 +149,10 @@ const FieldControl = () => {
147
149
  }
148
150
  };
149
151
  if (controls?.Form) {
150
- return (React__default.createElement(controls.Form, { handleSubmit: handleSubmit, input: input, setInput: setInput }));
152
+ return (React__default.createElement(controls.Form, { handleSubmit: handleSubmit, input: input, setInput: setInput, allowAttachments: allowAttachments }));
151
153
  }
152
154
  return (React__default.createElement("form", { className: `${FIELD_BLOCK}__form`, onSubmit: handleSubmit, method: "post", ref: ref },
153
- React__default.createElement(AttachFileControl, null),
155
+ allowAttachments ? React__default.createElement(AttachFileControl, null) : null,
154
156
  React__default.createElement(InputContainer, null,
155
157
  React__default.createElement(VisuallyHidden, null,
156
158
  React__default.createElement(Label, null)),
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { DropZone, View, Button, VisuallyHidden, TextAreaField } from '@aws-amplify/ui-react';
2
+ import { View, Button, VisuallyHidden, TextAreaField, DropZone } from '@aws-amplify/ui-react';
3
3
  import { useIcons, IconSend, IconAttach } from '@aws-amplify/ui-react/internal';
4
4
  import { ComponentClassName } from '@aws-amplify/ui';
5
5
  import { Attachments } from './Attachments.mjs';
@@ -8,21 +8,33 @@ import { LoadingContext } from '../../context/LoadingContext.mjs';
8
8
  function isHTMLFormElement(target) {
9
9
  return 'form' in target;
10
10
  }
11
- const Form = ({ setInput, input, handleSubmit, }) => {
11
+ /**
12
+ * Will conditionally render the DropZone if allowAttachments
13
+ * is true
14
+ */
15
+ const FormWrapper = ({ children, allowAttachments, setInput, }) => {
16
+ if (allowAttachments) {
17
+ return (React.createElement(DropZone, { className: ComponentClassName.AIConversationFormDropzone, onDropComplete: ({ acceptedFiles }) => {
18
+ setInput?.((prevInput) => ({
19
+ ...prevInput,
20
+ files: [...(prevInput?.files ?? []), ...acceptedFiles],
21
+ }));
22
+ } }, children));
23
+ }
24
+ else {
25
+ return children;
26
+ }
27
+ };
28
+ const Form = ({ setInput, input, handleSubmit, allowAttachments, }) => {
12
29
  const icons = useIcons('aiConversation');
13
30
  const sendIcon = icons?.send ?? React.createElement(IconSend, null);
14
31
  const attachIcon = icons?.attach ?? React.createElement(IconAttach, null);
15
32
  const hiddenInput = React.useRef(null);
16
33
  const isLoading = React.useContext(LoadingContext);
17
34
  const isInputEmpty = !input?.text?.length && !input?.files?.length;
18
- return (React.createElement(DropZone, { className: ComponentClassName.AIConversationFormDropzone, onDropComplete: ({ acceptedFiles }) => {
19
- setInput((prevInput) => ({
20
- ...prevInput,
21
- files: [...(prevInput?.files ?? []), ...acceptedFiles],
22
- }));
23
- } },
35
+ return (React.createElement(FormWrapper, { allowAttachments: allowAttachments, setInput: setInput },
24
36
  React.createElement(View, { as: "form", className: ComponentClassName.AIConversationForm, onSubmit: handleSubmit },
25
- React.createElement(Button, { className: ComponentClassName.AIConversationFormAttach, onClick: () => {
37
+ allowAttachments ? (React.createElement(Button, { className: ComponentClassName.AIConversationFormAttach, onClick: () => {
26
38
  hiddenInput?.current?.click();
27
39
  if (hiddenInput?.current) {
28
40
  hiddenInput.current.value = '';
@@ -39,7 +51,7 @@ const Form = ({ setInput, input, handleSubmit, }) => {
39
51
  ...prevValue,
40
52
  files: [...(prevValue?.files ?? []), ...Array.from(files)],
41
53
  }));
42
- }, multiple: true, accept: "*", "data-testid": "hidden-file-input" }))),
54
+ }, multiple: true, accept: "*", "data-testid": "hidden-file-input" })))) : null,
43
55
  React.createElement(TextAreaField, { className: ComponentClassName.AIConversationFormField, label: "input", labelHidden: true, autoResize: true, flex: "1", rows: 1, value: input?.text ?? '', testId: "text-input", onKeyDown: (e) => {
44
56
  // Submit on enter key if shift is not pressed also
45
57
  const shouldSubmit = !e.shiftKey && e.key === 'Enter';
package/dist/index.js CHANGED
@@ -9,8 +9,6 @@ var ui = require('@aws-amplify/ui');
9
9
  var uiReact = require('@aws-amplify/ui-react');
10
10
  var internal = require('@aws-amplify/ui-react/internal');
11
11
 
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
-
14
12
  function _interopNamespace(e) {
15
13
  if (e && e.__esModule) return e;
16
14
  var n = Object.create(null);
@@ -29,7 +27,6 @@ function _interopNamespace(e) {
29
27
  return Object.freeze(n);
30
28
  }
31
29
 
32
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
33
30
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
31
 
35
32
  const DEFAULT_ICON_PATHS = {
@@ -54,7 +51,7 @@ const BaseIconElement = elements.defineBaseElement({
54
51
  });
55
52
  const getIconProps = ({ variant, ...props }) => {
56
53
  const pathData = variant ? DEFAULT_ICON_PATHS[variant] : undefined;
57
- const children = pathData ? (React__default["default"].createElement("path", { d: pathData, fill: "currentColor" })) : undefined;
54
+ const children = pathData ? (React__namespace["default"].createElement("path", { d: pathData, fill: "currentColor" })) : undefined;
58
55
  return {
59
56
  ...DEFAULT_ICON_ATTRIBUTES,
60
57
  ...props,
@@ -120,38 +117,38 @@ const AIConversationElements = {
120
117
  View: ViewElement,
121
118
  };
122
119
 
123
- const ActionsContext = React__default["default"].createContext(undefined);
120
+ const ActionsContext = React__namespace["default"].createContext(undefined);
124
121
  const ActionsProvider = ({ children, actions, }) => {
125
- return (React__default["default"].createElement(ActionsContext.Provider, { value: actions }, children));
122
+ return (React__namespace["default"].createElement(ActionsContext.Provider, { value: actions }, children));
126
123
  };
127
124
 
128
- const AvatarsContext = React__default["default"].createContext(undefined);
125
+ const AvatarsContext = React__namespace["default"].createContext(undefined);
129
126
  const AvatarsProvider = ({ children, avatars, }) => {
130
- return (React__default["default"].createElement(AvatarsContext.Provider, { value: avatars }, children));
127
+ return (React__namespace["default"].createElement(AvatarsContext.Provider, { value: avatars }, children));
131
128
  };
132
129
 
133
- const ConversationInputContext = React__default["default"].createContext({});
130
+ const ConversationInputContext = React__namespace["default"].createContext({});
134
131
  const ConversationInputContextProvider = ({ children, }) => {
135
- const [input, setInput] = React__default["default"].useState();
136
- const providerValue = React__default["default"].useMemo(() => ({ input, setInput }), [input, setInput]);
137
- return (React__default["default"].createElement(ConversationInputContext.Provider, { value: providerValue }, children));
132
+ const [input, setInput] = React__namespace["default"].useState();
133
+ const providerValue = React__namespace["default"].useMemo(() => ({ input, setInput }), [input, setInput]);
134
+ return (React__namespace["default"].createElement(ConversationInputContext.Provider, { value: providerValue }, children));
138
135
  };
139
136
 
140
- const MessagesContext = React__default["default"].createContext(undefined);
137
+ const MessagesContext = React__namespace["default"].createContext(undefined);
141
138
  // role of the user sending the message, assistant or user
142
- const RoleContext = React__default["default"].createContext(undefined);
139
+ const RoleContext = React__namespace["default"].createContext(undefined);
143
140
  const MessagesProvider = ({ children, messages, }) => {
144
- return (React__default["default"].createElement(MessagesContext.Provider, { value: messages }, children));
141
+ return (React__namespace["default"].createElement(MessagesContext.Provider, { value: messages }, children));
145
142
  };
146
143
 
147
- const SuggestedPromptsContext = React__default["default"].createContext(undefined);
144
+ const SuggestedPromptsContext = React__namespace["default"].createContext(undefined);
148
145
  const SuggestedPromptProvider = ({ children, suggestedPrompts, }) => {
149
- return (React__default["default"].createElement(SuggestedPromptsContext.Provider, { value: suggestedPrompts }, children));
146
+ return (React__namespace["default"].createElement(SuggestedPromptsContext.Provider, { value: suggestedPrompts }, children));
150
147
  };
151
148
 
152
- const MessageVariantContext = React__default["default"].createContext(undefined);
149
+ const MessageVariantContext = React__namespace["default"].createContext(undefined);
153
150
  const MessageVariantProvider = ({ children, variant, }) => {
154
- return (React__default["default"].createElement(MessageVariantContext.Provider, { value: variant }, children));
151
+ return (React__namespace["default"].createElement(MessageVariantContext.Provider, { value: variant }, children));
155
152
  };
156
153
 
157
154
  function formatDate(date) {
@@ -201,18 +198,18 @@ const { ConversationDisplayTextContext, ConversationDisplayTextProvider, useConv
201
198
  defaultValue: defaultAIConversationDisplayTextEn,
202
199
  });
203
200
 
204
- const ControlsContext = React__default["default"].createContext(undefined);
201
+ const ControlsContext = React__namespace["default"].createContext(undefined);
205
202
  const ControlsProvider = ({ children, controls, }) => {
206
- return (React__default["default"].createElement(ControlsContext.Provider, { value: controls }, children));
203
+ return (React__namespace["default"].createElement(ControlsContext.Provider, { value: controls }, children));
207
204
  };
208
205
 
209
- const LoadingContext = React__default["default"].createContext(undefined);
206
+ const LoadingContext = React__namespace["default"].createContext(undefined);
210
207
  const LoadingContextProvider = ({ children, isLoading, }) => {
211
- return (React__default["default"].createElement(LoadingContext.Provider, { value: isLoading }, children));
208
+ return (React__namespace["default"].createElement(LoadingContext.Provider, { value: isLoading }, children));
212
209
  };
213
210
 
214
211
  const RESPONSE_COMPONENT_PREFIX = 'AMPLIFY_UI_';
215
- const ResponseComponentsContext = React__default["default"].createContext(undefined);
212
+ const ResponseComponentsContext = React__namespace["default"].createContext(undefined);
216
213
  const prependResponseComponents = (responseComponents) => {
217
214
  if (!responseComponents)
218
215
  return responseComponents;
@@ -220,8 +217,8 @@ const prependResponseComponents = (responseComponents) => {
220
217
  prev), {});
221
218
  };
222
219
  const ResponseComponentsProvider = ({ children, responseComponents, }) => {
223
- const _responseComponents = React__default["default"].useMemo(() => prependResponseComponents(responseComponents), [responseComponents]);
224
- return (React__default["default"].createElement(ResponseComponentsContext.Provider, { value: _responseComponents }, children));
220
+ const _responseComponents = React__namespace["default"].useMemo(() => prependResponseComponents(responseComponents), [responseComponents]);
221
+ return (React__namespace["default"].createElement(ResponseComponentsContext.Provider, { value: _responseComponents }, children));
225
222
  };
226
223
  const convertResponseComponentsToToolConfiguration = (responseComponents) => {
227
224
  if (!responseComponents) {
@@ -251,9 +248,9 @@ const convertResponseComponentsToToolConfiguration = (responseComponents) => {
251
248
  return { tools };
252
249
  };
253
250
 
254
- const SendMessageContext = React__default["default"].createContext(undefined);
251
+ const SendMessageContext = React__namespace["default"].createContext(undefined);
255
252
  const SendMessageContextProvider = ({ children, handleSendMessage, }) => {
256
- return (React__default["default"].createElement(SendMessageContext.Provider, { value: handleSendMessage }, children));
253
+ return (React__namespace["default"].createElement(SendMessageContext.Provider, { value: handleSendMessage }, children));
257
254
  };
258
255
 
259
256
  const { Button: Button$5, Span: Span$3, View: View$7 } = AIConversationElements;
@@ -265,16 +262,16 @@ const ActionIcon = elements.withBaseElementProps(Span$3, {
265
262
  const ActionButtonBase = elements.withBaseElementProps(Button$5, {
266
263
  className: `${ACTIONS_BAR_BLOCK}__button`,
267
264
  });
268
- const ActionButton = React__default["default"].forwardRef(function ActionButton(props, ref) {
269
- return React__default["default"].createElement(ActionButtonBase, { ...props, ref: ref });
265
+ const ActionButton = React__namespace["default"].forwardRef(function ActionButton(props, ref) {
266
+ return React__namespace["default"].createElement(ActionButtonBase, { ...props, ref: ref });
270
267
  });
271
268
  const Container$4 = elements.withBaseElementProps(View$7, {
272
269
  className: `${ACTIONS_BAR_BLOCK}__container`,
273
270
  });
274
271
  const ActionsBarControl = ({ message, focusable, }) => {
275
- const actions = React__default["default"].useContext(ActionsContext);
276
- return (React__default["default"].createElement(Container$4, null, actions?.map((action, index) => (React__default["default"].createElement(ActionButton, { "aria-label": action.displayName, key: index, onClick: () => action.handler(message), tabIndex: focusable ? 0 : -1 },
277
- React__default["default"].createElement(ActionIcon, { "data-testid": `action-icon-${action.displayName}` }, action.icon))))));
272
+ 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 },
274
+ React__namespace["default"].createElement(ActionIcon, { "data-testid": `action-icon-${action.displayName}` }, action.icon))))));
278
275
  };
279
276
  ActionsBarControl.Button = ActionButton;
280
277
  ActionsBarControl.Container = Container$4;
@@ -285,9 +282,9 @@ const AVATAR_BLOCK = 'ai-avatar';
285
282
  const DEFAULT_USER_ICON = elements.withBaseElementProps(Icon$5, {
286
283
  variant: 'user-avatar',
287
284
  });
288
- const DEFAULT_AI_ICON = () => (React__default["default"].createElement("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
289
- React__default["default"].createElement("g", { id: "raven-logo" },
290
- React__default["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" }))));
285
+ 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
+ React__namespace["default"].createElement("g", { id: "raven-logo" },
287
+ 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" }))));
291
288
  const AvatarDisplayName = elements.withBaseElementProps(Text$4, {
292
289
  className: `${AVATAR_BLOCK}__display-name`,
293
290
  });
@@ -299,14 +296,14 @@ const Container$3 = elements.withBaseElementProps(View$6, {
299
296
  className: `${AVATAR_BLOCK}__container`,
300
297
  });
301
298
  const AvatarControl = () => {
302
- const avatars = React__default["default"].useContext(AvatarsContext);
303
- const role = React__default["default"].useContext(RoleContext);
299
+ const avatars = React__namespace["default"].useContext(AvatarsContext);
300
+ const role = React__namespace["default"].useContext(RoleContext);
304
301
  const avatar = role === 'assistant' ? avatars?.ai : avatars?.user;
305
- const defaultIcon = role === 'assistant' ? React__default["default"].createElement(DEFAULT_AI_ICON, null) : React__default["default"].createElement(DEFAULT_USER_ICON, null);
302
+ const defaultIcon = role === 'assistant' ? React__namespace["default"].createElement(DEFAULT_AI_ICON, null) : React__namespace["default"].createElement(DEFAULT_USER_ICON, null);
306
303
  const defaultDisplayName = role === 'user' ? 'User' : 'Assistant';
307
- return (React__default["default"].createElement(Container$3, { "data-testid": 'avatar' },
308
- React__default["default"].createElement(AvatarIcon, { "data-testid": `avatar-icon-${role}` }, avatar?.avatar ?? defaultIcon),
309
- React__default["default"].createElement(AvatarDisplayName, null, avatar?.username ?? defaultDisplayName)));
304
+ return (React__namespace["default"].createElement(Container$3, { "data-testid": 'avatar' },
305
+ React__namespace["default"].createElement(AvatarIcon, { "data-testid": `avatar-icon-${role}` }, avatar?.avatar ?? defaultIcon),
306
+ React__namespace["default"].createElement(AvatarDisplayName, null, avatar?.username ?? defaultDisplayName)));
310
307
  };
311
308
  AvatarControl.Container = Container$3;
312
309
  AvatarControl.DisplayName = AvatarDisplayName;
@@ -317,8 +314,8 @@ const HEADER_BLOCK = 'ai-header';
317
314
  const HeaderTextBase = elements.withBaseElementProps(Text$3, {
318
315
  className: `${HEADER_BLOCK}__text`,
319
316
  });
320
- const HeaderText$1 = React__default["default"].forwardRef(function HeaderText(props, ref) {
321
- return React__default["default"].createElement(HeaderTextBase, { ...props, ref: ref });
317
+ const HeaderText$1 = React__namespace["default"].forwardRef(function HeaderText(props, ref) {
318
+ return React__namespace["default"].createElement(HeaderTextBase, { ...props, ref: ref });
322
319
  });
323
320
  const CloseIcon = elements.withBaseElementProps(Icon$4, {
324
321
  className: `${HEADER_BLOCK}__icon`,
@@ -327,16 +324,16 @@ const CloseIcon = elements.withBaseElementProps(Icon$4, {
327
324
  const CloseButtonBase = elements.withBaseElementProps(Button$4, {
328
325
  className: `${HEADER_BLOCK}__button`,
329
326
  });
330
- const CloseButton = React__default["default"].forwardRef(function CloseButton(props, ref) {
331
- return React__default["default"].createElement(CloseButtonBase, { ...props, ref: ref });
327
+ const CloseButton = React__namespace["default"].forwardRef(function CloseButton(props, ref) {
328
+ return React__namespace["default"].createElement(CloseButtonBase, { ...props, ref: ref });
332
329
  });
333
330
  const Container$2 = elements.withBaseElementProps(View$5, {
334
331
  className: `${HEADER_BLOCK}__container`,
335
332
  });
336
- const HeaderControl = () => (React__default["default"].createElement(Container$2, null,
337
- React__default["default"].createElement(HeaderText$1, null, "Raven Chat"),
338
- React__default["default"].createElement(CloseButton, null,
339
- React__default["default"].createElement(CloseIcon, null))));
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))));
340
337
  HeaderControl.Container = Container$2;
341
338
  HeaderControl.Text = HeaderText$1;
342
339
  HeaderControl.Button = CloseButton;
@@ -361,8 +358,19 @@ const AttachFileButton = elements.withBaseElementProps(Button$3, {
361
358
  variant: 'attach',
362
359
  });
363
360
  const AttachFileControl = () => {
364
- const hiddenInput = React__default["default"].useRef(null);
365
- const { setInput } = React__default["default"].useContext(ConversationInputContext);
361
+ const hiddenInput = React__namespace["default"].useRef(null);
362
+ const { setInput } = React__namespace["default"].useContext(ConversationInputContext);
363
+ const { dragState, ...dropHandlers } = uiReactCore.useDropZone({
364
+ acceptedFileTypes: ['.jpeg'],
365
+ onDropComplete: ({ acceptedFiles }) => {
366
+ if (acceptedFiles && acceptedFiles?.length > 0 && setInput) {
367
+ setInput((prevInput) => ({
368
+ ...prevInput,
369
+ files: [...(prevInput?.files ?? []), ...acceptedFiles],
370
+ }));
371
+ }
372
+ },
373
+ });
366
374
  function handleButtonClick() {
367
375
  if (hiddenInput.current) {
368
376
  hiddenInput.current.click();
@@ -380,11 +388,11 @@ const AttachFileControl = () => {
380
388
  });
381
389
  }
382
390
  }
383
- return (React__default["default"].createElement(AttachFileContainer, null,
384
- React__default["default"].createElement(AttachFileButton, { onClick: handleButtonClick },
385
- React__default["default"].createElement(AttachFileIcon, null)),
386
- React__default["default"].createElement(VisuallyHidden$1, null,
387
- React__default["default"].createElement("input", { accept: ".jpeg,.png,.webp,.gif", "data-testid": "hidden-file-input", onChange: handleFileChange, ref: hiddenInput, type: "file", multiple: true }))));
391
+ return (React__namespace["default"].createElement(AttachFileContainer, { ...dropHandlers },
392
+ React__namespace["default"].createElement(AttachFileButton, { onClick: handleButtonClick },
393
+ React__namespace["default"].createElement(AttachFileIcon, null)),
394
+ React__namespace["default"].createElement(VisuallyHidden$1, null,
395
+ React__namespace["default"].createElement("input", { accept: ".jpeg,.png,.webp,.gif", "data-testid": "hidden-file-input", onChange: handleFileChange, ref: hiddenInput, type: "file", multiple: true }))));
388
396
  };
389
397
  AttachFileControl.Icon = AttachFileIcon;
390
398
  AttachFileControl.Button = AttachFileButton;
@@ -406,8 +414,8 @@ const RemoveButton = elements.withBaseElementProps(Button$2, {
406
414
  type: 'button',
407
415
  });
408
416
  const RemoveButtonControl = ({ onRemove }) => {
409
- return (React__default["default"].createElement(RemoveButton, { onClick: onRemove },
410
- React__default["default"].createElement(RemoveIcon, null)));
417
+ return (React__namespace["default"].createElement(RemoveButton, { onClick: onRemove },
418
+ React__namespace["default"].createElement(RemoveIcon, null)));
411
419
  };
412
420
  RemoveButtonControl.Icon = RemoveIcon;
413
421
  RemoveButtonControl.Button = RemoveButton;
@@ -430,10 +438,10 @@ const TextContainer = elements.withBaseElementProps(View$3, {
430
438
  className: `${IMAGE_TEXT_BLOCK}__container`,
431
439
  });
432
440
  const TextControl = ({ fileName, fileSize }) => {
433
- return (React__default["default"].createElement(TextContainer, null,
434
- React__default["default"].createElement(FileNameText, null, fileName),
435
- React__default["default"].createElement(Separator$1, null),
436
- React__default["default"].createElement(FileSizeText, null, fileSize)));
441
+ return (React__namespace["default"].createElement(TextContainer, null,
442
+ React__namespace["default"].createElement(FileNameText, null, fileName),
443
+ React__namespace["default"].createElement(Separator$1, null),
444
+ React__namespace["default"].createElement(FileSizeText, null, fileSize)));
437
445
  };
438
446
  TextControl.Container = TextContainer;
439
447
  TextControl.FileName = FileNameText;
@@ -443,10 +451,10 @@ const Container$1 = elements.withBaseElementProps(ListItem, {
443
451
  className: `${IMAGE_ITEM_BLOCK}__list-item`,
444
452
  });
445
453
  const AttachmentControl = ({ image, onRemove }) => {
446
- return (React__default["default"].createElement(Container$1, null,
447
- React__default["default"].createElement(ImageIcon, null),
448
- React__default["default"].createElement(TextControl, { fileName: image.name, fileSize: image.size }),
449
- React__default["default"].createElement(RemoveButtonControl, { onRemove: onRemove })));
454
+ return (React__namespace["default"].createElement(Container$1, null,
455
+ React__namespace["default"].createElement(ImageIcon, null),
456
+ React__namespace["default"].createElement(TextControl, { fileName: image.name, fileSize: image.size }),
457
+ React__namespace["default"].createElement(RemoveButtonControl, { onRemove: onRemove })));
450
458
  };
451
459
  AttachmentControl.Container = Container$1;
452
460
  AttachmentControl.ImageIcon = ImageIcon;
@@ -456,8 +464,8 @@ const UnorderedList = elements.withBaseElementProps(ListElement, {
456
464
  className: `${IMAGE_LIST_BLOCK}__unordered-list`,
457
465
  });
458
466
  const AttachmentListControl = () => {
459
- const { input, setInput } = React__default["default"].useContext(ConversationInputContext);
460
- return (React__default["default"].createElement(UnorderedList, null, input?.files?.map((file, index) => {
467
+ const { input, setInput } = React__namespace["default"].useContext(ConversationInputContext);
468
+ return (React__namespace["default"].createElement(UnorderedList, null, input?.files?.map((file, index) => {
461
469
  const onRemove = () => {
462
470
  if (setInput) {
463
471
  setInput((prevInput) => ({
@@ -466,12 +474,17 @@ const AttachmentListControl = () => {
466
474
  }));
467
475
  }
468
476
  };
469
- return (React__default["default"].createElement(AttachmentControl, { key: index, image: file, onRemove: onRemove }));
477
+ return (React__namespace["default"].createElement(AttachmentControl, { key: index, image: file, onRemove: onRemove }));
470
478
  })));
471
479
  };
472
480
  AttachmentListControl.List = UnorderedList;
473
481
  AttachmentListControl.Item = AttachmentControl;
474
482
 
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
+
475
488
  const { Button: Button$1, Icon: Icon$1, Label: LabelElement, TextArea, View: View$2, } = AIConversationElements;
476
489
  const FIELD_BLOCK = 'ai-field';
477
490
  const SendIcon = elements.withBaseElementProps(Icon$1, {
@@ -482,11 +495,11 @@ const SendButtonBase = elements.withBaseElementProps(Button$1, {
482
495
  'aria-label': 'Send message',
483
496
  className: `${FIELD_BLOCK}__button ${FIELD_BLOCK}__button--send`,
484
497
  });
485
- const SendButton = React__default["default"].forwardRef(function SendButton(props, ref) {
486
- const { input } = React__default["default"].useContext(ConversationInputContext);
487
- const isLoading = React__default["default"].useContext(LoadingContext);
498
+ const SendButton = React__namespace["default"].forwardRef(function SendButton(props, ref) {
499
+ const { input } = React__namespace["default"].useContext(ConversationInputContext);
500
+ const isLoading = React__namespace["default"].useContext(LoadingContext);
488
501
  const hasInput = !!input?.text || !!input?.files?.length;
489
- return (React__default["default"].createElement(SendButtonBase, { ...props,
502
+ return (React__namespace["default"].createElement(SendButtonBase, { ...props,
490
503
  // we intentionally || in the case where isLoading is false we should use the value of hasInput
491
504
  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
492
505
  disabled: isLoading || !hasInput, type: "submit", ref: ref, "data-testid": "send-button" }));
@@ -505,7 +518,7 @@ const Label = elements.withBaseElementProps(LabelElement, {
505
518
  htmlFor: 'text-input',
506
519
  });
507
520
  const useHandleResize = (textAreaRef) => {
508
- React__default["default"].useEffect(() => {
521
+ React__namespace["default"].useEffect(() => {
509
522
  const { current } = textAreaRef;
510
523
  const handleResize = () => {
511
524
  if (current) {
@@ -524,18 +537,18 @@ const useHandleResize = (textAreaRef) => {
524
537
  };
525
538
  }, [textAreaRef]);
526
539
  };
527
- const TextInput = React__default["default"].forwardRef(function TextInput(props, ref) {
528
- const { setInput } = React__default["default"].useContext(ConversationInputContext);
529
- const messages = React__default["default"].useContext(MessagesContext);
530
- const textAreaRef = React__default["default"].useRef(null);
540
+ const TextInput = React__namespace["default"].forwardRef(function TextInput(props, ref) {
541
+ const { setInput } = React__namespace["default"].useContext(ConversationInputContext);
542
+ const messages = React__namespace["default"].useContext(MessagesContext);
543
+ const textAreaRef = React__namespace["default"].useRef(null);
531
544
  useHandleResize(textAreaRef);
532
545
  const isFirstMessage = !messages || messages.length === 0;
533
- React__default["default"].useEffect(() => {
546
+ React__namespace["default"].useEffect(() => {
534
547
  if (textAreaRef && textAreaRef.current) {
535
548
  textAreaRef.current.focus();
536
549
  }
537
550
  }, [textAreaRef]);
538
- return (React__default["default"].createElement(TextAreaBase, { ...props, "data-testid": "text-input", id: "text-input", onChange: (e) => props.onChange ??
551
+ return (React__namespace["default"].createElement(TextAreaBase, { ...props, "data-testid": "text-input", id: "text-input", onChange: (e) => props.onChange ??
539
552
  (setInput &&
540
553
  setInput((prevInput) => ({ ...prevInput, text: e.target.value }))), placeholder: props.placeholder ?? isFirstMessage
541
554
  ? 'Ask anything...'
@@ -553,11 +566,12 @@ const InputContainer = elements.withBaseElementProps(View$2, {
553
566
  className: `${FIELD_BLOCK}__input-container`,
554
567
  });
555
568
  const FieldControl = () => {
556
- const { input, setInput } = React__default["default"].useContext(ConversationInputContext);
557
- const handleSendMessage = React__default["default"].useContext(SendMessageContext);
558
- const ref = React__default["default"].useRef(null);
559
- const responseComponents = React__default["default"].useContext(ResponseComponentsContext);
560
- const controls = React__default["default"].useContext(ControlsContext);
569
+ const { input, setInput } = React__namespace["default"].useContext(ConversationInputContext);
570
+ const handleSendMessage = React__namespace["default"].useContext(SendMessageContext);
571
+ const allowAttachments = React__namespace["default"].useContext(AttachmentContext);
572
+ const ref = React__namespace["default"].useRef(null);
573
+ const responseComponents = React__namespace["default"].useContext(ResponseComponentsContext);
574
+ const controls = React__namespace["default"].useContext(ControlsContext);
561
575
  const submitMessage = async () => {
562
576
  ref.current?.reset();
563
577
  const submittedContent = [];
@@ -603,17 +617,17 @@ const FieldControl = () => {
603
617
  }
604
618
  };
605
619
  if (controls?.Form) {
606
- return (React__default["default"].createElement(controls.Form, { handleSubmit: handleSubmit, input: input, setInput: setInput }));
620
+ return (React__namespace["default"].createElement(controls.Form, { handleSubmit: handleSubmit, input: input, setInput: setInput, allowAttachments: allowAttachments }));
607
621
  }
608
- return (React__default["default"].createElement("form", { className: `${FIELD_BLOCK}__form`, onSubmit: handleSubmit, method: "post", ref: ref },
609
- React__default["default"].createElement(AttachFileControl, null),
610
- React__default["default"].createElement(InputContainer, null,
611
- React__default["default"].createElement(VisuallyHidden, null,
612
- React__default["default"].createElement(Label, null)),
613
- React__default["default"].createElement(TextInput, { onKeyDown: handleOnKeyDown }),
614
- React__default["default"].createElement(AttachmentListControl, null)),
615
- React__default["default"].createElement(SendButton, null,
616
- React__default["default"].createElement(SendIcon, null))));
622
+ return (React__namespace["default"].createElement("form", { className: `${FIELD_BLOCK}__form`, onSubmit: handleSubmit, method: "post", ref: ref },
623
+ allowAttachments ? React__namespace["default"].createElement(AttachFileControl, null) : null,
624
+ React__namespace["default"].createElement(InputContainer, null,
625
+ React__namespace["default"].createElement(VisuallyHidden, null,
626
+ React__namespace["default"].createElement(Label, null)),
627
+ React__namespace["default"].createElement(TextInput, { onKeyDown: handleOnKeyDown }),
628
+ React__namespace["default"].createElement(AttachmentListControl, null)),
629
+ React__namespace["default"].createElement(SendButton, null,
630
+ React__namespace["default"].createElement(SendIcon, null))));
617
631
  };
618
632
  FieldControl.AttachFile = AttachFileControl;
619
633
  FieldControl.InputContainer = InputContainer;
@@ -628,26 +642,26 @@ const MESSAGE_BLOCK = 'ai-message';
628
642
  const MediaContentBase = elements.withBaseElementProps(Image, {
629
643
  alt: 'Image attachment',
630
644
  });
631
- const MediaContent = React__default["default"].forwardRef(function MediaContent(props, ref) {
632
- const variant = React__default["default"].useContext(MessageVariantContext);
633
- const role = React__default["default"].useContext(RoleContext);
634
- return (React__default["default"].createElement(MediaContentBase, { ref: ref, className: `${MESSAGE_BLOCK}__image ${MESSAGE_BLOCK}__image--${variant} ${MESSAGE_BLOCK}__image--${role}`, ...props }));
645
+ const MediaContent = React__namespace["default"].forwardRef(function MediaContent(props, ref) {
646
+ const variant = React__namespace["default"].useContext(MessageVariantContext);
647
+ const role = React__namespace["default"].useContext(RoleContext);
648
+ return (React__namespace["default"].createElement(MediaContentBase, { ref: ref, className: `${MESSAGE_BLOCK}__image ${MESSAGE_BLOCK}__image--${variant} ${MESSAGE_BLOCK}__image--${role}`, ...props }));
635
649
  });
636
- const TextContent = React__default["default"].forwardRef(function TextContent(props, ref) {
637
- return React__default["default"].createElement(Text$1, { ref: ref, className: `${MESSAGE_BLOCK}__text`, ...props });
650
+ 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 });
638
652
  });
639
- const ContentContainer = React__default["default"].forwardRef(function ContentContainer(props, ref) {
640
- const variant = React__default["default"].useContext(MessageVariantContext);
641
- return (React__default["default"].createElement(View$1, { "data-testid": 'content', className: `${MESSAGE_BLOCK}__content ${MESSAGE_BLOCK}__content--${variant}`, ref: ref, ...props }));
653
+ const ContentContainer = React__namespace["default"].forwardRef(function ContentContainer(props, ref) {
654
+ const variant = React__namespace["default"].useContext(MessageVariantContext);
655
+ return (React__namespace["default"].createElement(View$1, { "data-testid": 'content', className: `${MESSAGE_BLOCK}__content ${MESSAGE_BLOCK}__content--${variant}`, ref: ref, ...props }));
642
656
  });
643
657
  const MessageControl = ({ message }) => {
644
- const responseComponents = React__default["default"].useContext(ResponseComponentsContext);
645
- return (React__default["default"].createElement(ContentContainer, null, message.content.map((content, index) => {
658
+ const responseComponents = React__namespace["default"].useContext(ResponseComponentsContext);
659
+ return (React__namespace["default"].createElement(ContentContainer, null, message.content.map((content, index) => {
646
660
  if (content.text) {
647
- return (React__default["default"].createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
661
+ return (React__namespace["default"].createElement(TextContent, { "data-testid": 'text-content', key: index }, content.text));
648
662
  }
649
663
  else if (content.image) {
650
- return (React__default["default"].createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
664
+ return (React__namespace["default"].createElement(MediaContent, { "data-testid": 'image-content', key: index, src: convertBufferToBase64(content.image?.source.bytes, content.image?.format) }));
651
665
  }
652
666
  else if (content.toolUse) {
653
667
  // For now tool use is limited to custom response components
@@ -660,7 +674,7 @@ const MessageControl = ({ message }) => {
660
674
  else {
661
675
  const response = responseComponents[name];
662
676
  const CustomComponent = response.component;
663
- return React__default["default"].createElement(CustomComponent, { ...input, key: index });
677
+ return React__namespace["default"].createElement(CustomComponent, { ...input, key: index });
664
678
  }
665
679
  }
666
680
  })));
@@ -676,27 +690,27 @@ const Separator = elements.withBaseElementProps(Span, {
676
690
  const Timestamp = elements.withBaseElementProps(Text$1, {
677
691
  className: `${MESSAGE_BLOCK}__timestamp`,
678
692
  });
679
- const HeaderContainer = React__default["default"].forwardRef(function HeaderContainer(props, ref) {
680
- const variant = React__default["default"].useContext(MessageVariantContext);
681
- return (React__default["default"].createElement(View$1, { ref: ref, className: `${MESSAGE_BLOCK}__header__container ${MESSAGE_BLOCK}__header__container--${variant}`, ...props }));
693
+ const HeaderContainer = React__namespace["default"].forwardRef(function HeaderContainer(props, ref) {
694
+ const variant = React__namespace["default"].useContext(MessageVariantContext);
695
+ return (React__namespace["default"].createElement(View$1, { ref: ref, className: `${MESSAGE_BLOCK}__header__container ${MESSAGE_BLOCK}__header__container--${variant}`, ...props }));
682
696
  });
683
- const MessageContainer = React__default["default"].forwardRef(function MessageContainer(props, ref) {
684
- const variant = React__default["default"].useContext(MessageVariantContext);
685
- const role = React__default["default"].useContext(RoleContext);
686
- return (React__default["default"].createElement(View$1, { ref: ref, className: `${MESSAGE_BLOCK} ${MESSAGE_BLOCK}--${variant} ${MESSAGE_BLOCK}--${role}`, ...props }));
697
+ const MessageContainer = React__namespace["default"].forwardRef(function MessageContainer(props, ref) {
698
+ const variant = React__namespace["default"].useContext(MessageVariantContext);
699
+ const role = React__namespace["default"].useContext(RoleContext);
700
+ return (React__namespace["default"].createElement(View$1, { ref: ref, className: `${MESSAGE_BLOCK} ${MESSAGE_BLOCK}--${variant} ${MESSAGE_BLOCK}--${role}`, ...props }));
687
701
  });
688
- const Layout = React__default["default"].forwardRef(function Layout(props, ref) {
689
- const variant = React__default["default"].useContext(MessageVariantContext);
690
- return (React__default["default"].createElement(View$1, { ref: ref, className: `${MESSAGES_BLOCK}__container ${MESSAGES_BLOCK}__container--${variant}`, "aria-live": 'assertive', ...props }));
702
+ const Layout = React__namespace["default"].forwardRef(function Layout(props, ref) {
703
+ const variant = React__namespace["default"].useContext(MessageVariantContext);
704
+ return (React__namespace["default"].createElement(View$1, { ref: ref, className: `${MESSAGES_BLOCK}__container ${MESSAGES_BLOCK}__container--${variant}`, "aria-live": 'assertive', ...props }));
691
705
  });
692
706
  const MessagesControl = ({ renderMessage }) => {
693
- const messages = React__default["default"].useContext(MessagesContext);
694
- const controls = React__default["default"].useContext(ControlsContext);
707
+ const messages = React__namespace["default"].useContext(MessagesContext);
708
+ const controls = React__namespace["default"].useContext(ControlsContext);
695
709
  const { getMessageTimestampText } = useConversationDisplayText();
696
- const messagesRef = React__default["default"].useRef([]);
697
- const [focusedItemIndex, setFocusedItemIndex] = React__default["default"].useState(messages ? messages.length - 1 : 0);
710
+ const messagesRef = React__namespace["default"].useRef([]);
711
+ const [focusedItemIndex, setFocusedItemIndex] = React__namespace["default"].useState(messages ? messages.length - 1 : 0);
698
712
  const handleFocus = (index) => setFocusedItemIndex(index);
699
- const onKeyDown = React__default["default"].useCallback((index, { key }) => {
713
+ const onKeyDown = React__namespace["default"].useCallback((index, { key }) => {
700
714
  let newIndex;
701
715
  switch (key) {
702
716
  case 'ArrowUp':
@@ -723,20 +737,20 @@ const MessagesControl = ({ renderMessage }) => {
723
737
  return;
724
738
  }, [messages]);
725
739
  if (controls?.MessageList) {
726
- return React__default["default"].createElement(controls.MessageList, { messages: messages });
740
+ return React__namespace["default"].createElement(controls.MessageList, { messages: messages });
727
741
  }
728
742
  const messagesWithRenderableContent = messages?.filter((message) => message.content.some((content) => content.image ??
729
743
  content.text ??
730
744
  content.toolUse?.name.startsWith(RESPONSE_COMPONENT_PREFIX))) ?? [];
731
- return (React__default["default"].createElement(Layout, null, messagesWithRenderableContent?.map((message, index) => {
732
- return renderMessage ? (renderMessage(message)) : (React__default["default"].createElement(RoleContext.Provider, { value: message.role, key: `message-${index}` },
733
- React__default["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) },
734
- React__default["default"].createElement(HeaderContainer, null,
735
- React__default["default"].createElement(AvatarControl, null),
736
- React__default["default"].createElement(Separator, null),
737
- React__default["default"].createElement(Timestamp, null, getMessageTimestampText(new Date(message.createdAt)))),
738
- React__default["default"].createElement(MessageControl, { message: message }),
739
- message.role === 'assistant' ? (React__default["default"].createElement(ActionsBarControl, { message: message, focusable: focusedItemIndex === index })) : null)));
745
+ 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}` },
747
+ 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
+ React__namespace["default"].createElement(HeaderContainer, null,
749
+ React__namespace["default"].createElement(AvatarControl, null),
750
+ React__namespace["default"].createElement(Separator, null),
751
+ React__namespace["default"].createElement(Timestamp, null, getMessageTimestampText(new Date(message.createdAt)))),
752
+ React__namespace["default"].createElement(MessageControl, { message: message }),
753
+ message.role === 'assistant' ? (React__namespace["default"].createElement(ActionsBarControl, { message: message, focusable: focusedItemIndex === index })) : null)));
740
754
  })));
741
755
  };
742
756
  MessagesControl.ActionsBar = ActionsBarControl;
@@ -756,13 +770,13 @@ const PromptCard = elements.withBaseElementProps(Button, {
756
770
  type: 'button',
757
771
  });
758
772
  const AIIconProps = () => ({
759
- children: (React__default["default"].createElement(React__default["default"].Fragment, null,
760
- React__default["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" }),
761
- React__default["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)" }),
762
- React__default["default"].createElement("defs", null,
763
- React__default["default"].createElement("linearGradient", { id: "paint0_linear_395_1815", x1: "20", y1: "0.978638", x2: "20", y2: "39.0213", gradientUnits: "userSpaceOnUse" },
764
- React__default["default"].createElement("stop", { stopColor: "#7DD6E8" }),
765
- React__default["default"].createElement("stop", { offset: "1", stopColor: "#BF40BF" }))))),
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" }))))),
766
780
  className: `${PROMPT_CONTROL}__icon`,
767
781
  width: '40',
768
782
  height: '40',
@@ -777,41 +791,41 @@ const HeaderText = elements.withBaseElementProps(Heading, {
777
791
  const PromptGroupBase = elements.withBaseElementProps(View, {
778
792
  className: `${PROMPT_CONTROL}__buttongroup`,
779
793
  });
780
- const PromptGroup = React__default["default"].forwardRef(function ButtonGroup(props, ref) {
781
- const suggestedPromptsArray = React__default["default"].useContext(SuggestedPromptsContext);
782
- const { setInput } = React__default["default"].useContext(ConversationInputContext);
794
+ const PromptGroup = React__namespace["default"].forwardRef(function ButtonGroup(props, ref) {
795
+ const suggestedPromptsArray = React__namespace["default"].useContext(SuggestedPromptsContext);
796
+ const { setInput } = React__namespace["default"].useContext(ConversationInputContext);
783
797
  if (!suggestedPromptsArray) {
784
798
  return;
785
799
  }
786
- return (React__default["default"].createElement(PromptGroupBase, { ...props, ref: ref }, suggestedPromptsArray.map((prompt, index) => {
787
- return (React__default["default"].createElement(PromptCard, { key: index, "aria-label": prompt.inputText, onClick: () => setInput &&
800
+ return (React__namespace["default"].createElement(PromptGroupBase, { ...props, ref: ref }, suggestedPromptsArray.map((prompt, index) => {
801
+ return (React__namespace["default"].createElement(PromptCard, { key: index, "aria-label": prompt.inputText, onClick: () => setInput &&
788
802
  setInput((prevInput) => ({
789
803
  ...prevInput,
790
804
  text: prompt.inputText,
791
805
  })) },
792
- React__default["default"].createElement(Text, { className: ui.classNames(`${PROMPT_CARD}__header`, `${PROMPT_CARD}__text`) }, prompt.header),
793
- React__default["default"].createElement(Text, { className: `${PROMPT_CARD}__text` }, prompt.inputText)));
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)));
794
808
  })));
795
809
  });
796
810
  const Container = elements.withBaseElementProps(View, {
797
811
  className: `${PROMPT_BLOCK}__container`,
798
812
  });
799
813
  const PromptControl = () => {
800
- const suggestedPromptsArray = React__default["default"].useContext(SuggestedPromptsContext);
801
- const controls = React__default["default"].useContext(ControlsContext);
802
- const { setInput } = React__default["default"].useContext(ConversationInputContext);
814
+ const suggestedPromptsArray = React__namespace["default"].useContext(SuggestedPromptsContext);
815
+ const controls = React__namespace["default"].useContext(ControlsContext);
816
+ const { setInput } = React__namespace["default"].useContext(ConversationInputContext);
803
817
  if (controls?.PromptList) {
804
- return (React__default["default"].createElement(controls.PromptList, { setInput: setInput, suggestedPrompts: suggestedPromptsArray }));
818
+ return (React__namespace["default"].createElement(controls.PromptList, { setInput: setInput, suggestedPrompts: suggestedPromptsArray }));
805
819
  }
806
- return (React__default["default"].createElement(Container, null,
807
- React__default["default"].createElement(AIIcon, null),
808
- React__default["default"].createElement(HeaderText, null, "How can I help you today?"),
809
- React__default["default"].createElement(PromptGroup, null)));
820
+ 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
+ React__namespace["default"].createElement(PromptGroup, null)));
810
824
  };
811
825
  const AutoHidablePromptControl = () => {
812
- const messages = React__default["default"].useContext(MessagesContext);
826
+ const messages = React__namespace["default"].useContext(MessagesContext);
813
827
  if (!messages || messages.length === 0) {
814
- return React__default["default"].createElement(PromptControl, null);
828
+ return React__namespace["default"].createElement(PromptControl, null);
815
829
  }
816
830
  };
817
831
  PromptControl.Container = Container;
@@ -821,33 +835,34 @@ PromptControl.PromptGroup = PromptGroup;
821
835
  PromptControl.PromptCard = PromptCard;
822
836
 
823
837
  function Conversation() {
824
- return (React__default["default"].createElement(ViewElement, null,
825
- React__default["default"].createElement(HeaderControl, null),
826
- React__default["default"].createElement(ViewElement, null,
827
- React__default["default"].createElement(AutoHidablePromptControl, null),
828
- React__default["default"].createElement(MessagesControl, null)),
829
- React__default["default"].createElement(ViewElement, null,
830
- React__default["default"].createElement(FieldControl, null))));
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))));
831
845
  }
832
846
 
833
- function createProvider({ elements: elements$1, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }) {
847
+ function createProvider({ elements: elements$1, actions, suggestedPrompts, responseComponents, variant, controls, displayText, allowAttachments, }) {
834
848
  return function Provider({ children, messages, avatars, handleSendMessage, isLoading, }) {
835
849
  const _displayText = {
836
850
  ...defaultAIConversationDisplayTextEn,
837
851
  ...displayText,
838
852
  };
839
- return (React__default["default"].createElement(elements.ElementsProvider, { elements: elements$1 },
840
- React__default["default"].createElement(ControlsProvider, { controls: controls },
841
- React__default["default"].createElement(SuggestedPromptProvider, { suggestedPrompts: suggestedPrompts },
842
- React__default["default"].createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
843
- React__default["default"].createElement(ConversationDisplayTextProvider, { ..._displayText },
844
- React__default["default"].createElement(ConversationInputContextProvider, null,
845
- React__default["default"].createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
846
- React__default["default"].createElement(AvatarsProvider, { avatars: avatars },
847
- React__default["default"].createElement(ActionsProvider, { actions: actions },
848
- React__default["default"].createElement(MessageVariantProvider, { variant: variant },
849
- React__default["default"].createElement(MessagesProvider, { messages: messages },
850
- React__default["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children)))))))))))));
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 },
856
+ React__namespace["default"].createElement(ResponseComponentsProvider, { responseComponents: responseComponents },
857
+ React__namespace["default"].createElement(AttachmentProvider, { allowAttachments: allowAttachments },
858
+ React__namespace["default"].createElement(ConversationDisplayTextProvider, { ..._displayText },
859
+ React__namespace["default"].createElement(ConversationInputContextProvider, null,
860
+ React__namespace["default"].createElement(SendMessageContextProvider, { handleSendMessage: handleSendMessage },
861
+ React__namespace["default"].createElement(AvatarsProvider, { avatars: avatars },
862
+ React__namespace["default"].createElement(ActionsProvider, { actions: actions },
863
+ React__namespace["default"].createElement(MessageVariantProvider, { variant: variant },
864
+ React__namespace["default"].createElement(MessagesProvider, { messages: messages },
865
+ React__namespace["default"].createElement(LoadingContextProvider, { isLoading: isLoading }, children))))))))))))));
851
866
  };
852
867
  }
853
868
 
@@ -855,7 +870,7 @@ function createProvider({ elements: elements$1, actions, suggestedPrompts, respo
855
870
  * @experimental
856
871
  */
857
872
  function createAIConversation(input = {}) {
858
- const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, } = input;
873
+ const { elements, suggestedPrompts, actions, responseComponents, variant, controls, displayText, allowAttachments, } = input;
859
874
  const Provider = createProvider({
860
875
  elements,
861
876
  actions,
@@ -864,11 +879,12 @@ function createAIConversation(input = {}) {
864
879
  variant,
865
880
  controls,
866
881
  displayText,
882
+ allowAttachments,
867
883
  });
868
884
  function AIConversation(props) {
869
885
  const { messages, avatars, handleSendMessage, isLoading } = props;
870
- return (React__default["default"].createElement(Provider, { messages: messages, avatars: avatars, handleSendMessage: handleSendMessage, isLoading: isLoading },
871
- React__default["default"].createElement(Conversation, null)));
886
+ return (React__namespace["default"].createElement(Provider, { messages: messages, avatars: avatars, handleSendMessage: handleSendMessage, isLoading: isLoading },
887
+ React__namespace["default"].createElement(Conversation, null)));
872
888
  }
873
889
  const Controls = {
874
890
  ActionsBar: ActionsBarControl,
@@ -955,21 +971,33 @@ const Attachments = ({ files, setInput, }) => {
955
971
  function isHTMLFormElement(target) {
956
972
  return 'form' in target;
957
973
  }
958
- const Form = ({ setInput, input, handleSubmit, }) => {
974
+ /**
975
+ * Will conditionally render the DropZone if allowAttachments
976
+ * is true
977
+ */
978
+ const FormWrapper = ({ children, allowAttachments, setInput, }) => {
979
+ if (allowAttachments) {
980
+ return (React__namespace.createElement(uiReact.DropZone, { className: ui.ComponentClassName.AIConversationFormDropzone, onDropComplete: ({ acceptedFiles }) => {
981
+ setInput?.((prevInput) => ({
982
+ ...prevInput,
983
+ files: [...(prevInput?.files ?? []), ...acceptedFiles],
984
+ }));
985
+ } }, children));
986
+ }
987
+ else {
988
+ return children;
989
+ }
990
+ };
991
+ const Form = ({ setInput, input, handleSubmit, allowAttachments, }) => {
959
992
  const icons = internal.useIcons('aiConversation');
960
993
  const sendIcon = icons?.send ?? React__namespace.createElement(internal.IconSend, null);
961
994
  const attachIcon = icons?.attach ?? React__namespace.createElement(internal.IconAttach, null);
962
995
  const hiddenInput = React__namespace.useRef(null);
963
996
  const isLoading = React__namespace.useContext(LoadingContext);
964
997
  const isInputEmpty = !input?.text?.length && !input?.files?.length;
965
- return (React__namespace.createElement(uiReact.DropZone, { className: ui.ComponentClassName.AIConversationFormDropzone, onDropComplete: ({ acceptedFiles }) => {
966
- setInput((prevInput) => ({
967
- ...prevInput,
968
- files: [...(prevInput?.files ?? []), ...acceptedFiles],
969
- }));
970
- } },
998
+ return (React__namespace.createElement(FormWrapper, { allowAttachments: allowAttachments, setInput: setInput },
971
999
  React__namespace.createElement(uiReact.View, { as: "form", className: ui.ComponentClassName.AIConversationForm, onSubmit: handleSubmit },
972
- React__namespace.createElement(uiReact.Button, { className: ui.ComponentClassName.AIConversationFormAttach, onClick: () => {
1000
+ allowAttachments ? (React__namespace.createElement(uiReact.Button, { className: ui.ComponentClassName.AIConversationFormAttach, onClick: () => {
973
1001
  hiddenInput?.current?.click();
974
1002
  if (hiddenInput?.current) {
975
1003
  hiddenInput.current.value = '';
@@ -986,7 +1014,7 @@ const Form = ({ setInput, input, handleSubmit, }) => {
986
1014
  ...prevValue,
987
1015
  files: [...(prevValue?.files ?? []), ...Array.from(files)],
988
1016
  }));
989
- }, multiple: true, accept: "*", "data-testid": "hidden-file-input" }))),
1017
+ }, multiple: true, accept: "*", "data-testid": "hidden-file-input" })))) : null,
990
1018
  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", onKeyDown: (e) => {
991
1019
  // Submit on enter key if shift is not pressed also
992
1020
  const shouldSubmit = !e.shiftKey && e.key === 'Enter';
@@ -1019,7 +1047,7 @@ const PromptList = ({ setInput, suggestedPrompts = [], }) => {
1019
1047
  })));
1020
1048
  };
1021
1049
 
1022
- function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }) {
1050
+ function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, }) {
1023
1051
  const icons = internal.useIcons('aiConversation');
1024
1052
  const defaultAvatars = {
1025
1053
  ai: {
@@ -1057,6 +1085,7 @@ function AIConversationBase({ actions, avatars, controls, handleSendMessage, mes
1057
1085
  ...avatars,
1058
1086
  },
1059
1087
  isLoading,
1088
+ allowAttachments,
1060
1089
  };
1061
1090
  return (React__namespace.createElement(Provider, { ...providerProps },
1062
1091
  React__namespace.createElement(uiReact.Flex, { className: ui.ComponentClassName.AIConversation },
@@ -1074,10 +1103,10 @@ const AIConversation = Object.assign(AIConversationBase, {
1074
1103
  Form,
1075
1104
  });
1076
1105
 
1077
- const AIContext = React__default["default"].createContext(undefined);
1106
+ const AIContext = React__namespace["default"].createContext(undefined);
1078
1107
  const useAIContext = () => {
1079
- const context = React__default["default"].useContext(AIContext);
1080
- const [routeToConversationsMap, setRouteToConversationsMap] = React__default["default"].useState({});
1108
+ const context = React__namespace["default"].useContext(AIContext);
1109
+ const [routeToConversationsMap, setRouteToConversationsMap] = React__namespace["default"].useState({});
1081
1110
  if (context) {
1082
1111
  return context;
1083
1112
  }
@@ -1088,7 +1117,7 @@ const useAIContext = () => {
1088
1117
  */
1089
1118
  const AIContextProvider = ({ children, }) => {
1090
1119
  const context = useAIContext();
1091
- return React__default["default"].createElement(AIContext.Provider, { value: context }, children);
1120
+ return React__namespace["default"].createElement(AIContext.Provider, { value: context }, children);
1092
1121
  };
1093
1122
 
1094
1123
  function createUseAIGeneration(client) {
@@ -1127,13 +1156,13 @@ function createUseAIConversation(client) {
1127
1156
  const messagesFromAIContext = input.id
1128
1157
  ? routeToConversationsMap[routeName]?.[input.id]
1129
1158
  : undefined;
1130
- const [localMessages, setLocalMessages] = React__default["default"].useState(messagesFromAIContext ?? []);
1131
- const [conversation, setConversation] = React__default["default"].useState(undefined);
1132
- const [waitingForAIResponse, setWaitingForAIResponse] = React__default["default"].useState(false);
1133
- const [errorMessage, setErrorMessage] = React__default["default"].useState();
1134
- const [hasError, setHasError] = React__default["default"].useState(false);
1159
+ const [localMessages, setLocalMessages] = React__namespace["default"].useState(messagesFromAIContext ?? []);
1160
+ const [conversation, setConversation] = React__namespace["default"].useState(undefined);
1161
+ const [waitingForAIResponse, setWaitingForAIResponse] = React__namespace["default"].useState(false);
1162
+ const [errorMessage, setErrorMessage] = React__namespace["default"].useState();
1163
+ const [hasError, setHasError] = React__namespace["default"].useState(false);
1135
1164
  // On hook initialization get conversation and load all messages
1136
- React__default["default"].useEffect(() => {
1165
+ React__namespace["default"].useEffect(() => {
1137
1166
  async function initialize() {
1138
1167
  const { data: conversation } = input.id
1139
1168
  ? await clientRoute.get({ id: input.id })
@@ -1159,11 +1188,11 @@ function createUseAIConversation(client) {
1159
1188
  initialize();
1160
1189
  }, [clientRoute, input.id, routeName, setRouteToConversationsMap]);
1161
1190
  // Update messages to match what is in AIContext if they aren't equal
1162
- React__default["default"].useEffect(() => {
1191
+ React__namespace["default"].useEffect(() => {
1163
1192
  if (!!messagesFromAIContext && messagesFromAIContext !== localMessages)
1164
1193
  setLocalMessages(messagesFromAIContext);
1165
1194
  }, [messagesFromAIContext, localMessages]);
1166
- const sendMessage = React__default["default"].useCallback((input) => {
1195
+ const sendMessage = React__namespace["default"].useCallback((input) => {
1167
1196
  const { content, aiContext, toolConfiguration } = input;
1168
1197
  conversation
1169
1198
  ?.sendMessage({ content, aiContext, toolConfiguration })
@@ -1193,7 +1222,7 @@ function createUseAIConversation(client) {
1193
1222
  setErrorMessage(`error sending message ${reason}`);
1194
1223
  });
1195
1224
  }, [conversation, routeName, setRouteToConversationsMap]);
1196
- const subscribe = React__default["default"].useCallback((handleStoreChange) => {
1225
+ const subscribe = React__namespace["default"].useCallback((handleStoreChange) => {
1197
1226
  const subscription = conversation &&
1198
1227
  conversation.onMessage((message) => {
1199
1228
  if (input.onResponse)
@@ -1220,10 +1249,10 @@ function createUseAIConversation(client) {
1220
1249
  subscription?.unsubscribe();
1221
1250
  };
1222
1251
  }, [conversation, routeName, setRouteToConversationsMap, input]);
1223
- const getSnapshot = React__default["default"].useCallback(() => localMessages, [localMessages]);
1252
+ const getSnapshot = React__namespace["default"].useCallback(() => localMessages, [localMessages]);
1224
1253
  // Using useSyncExternalStore to subscribe to external data updates
1225
1254
  // Have to provide third optional argument in next - https://github.com/vercel/next.js/issues/54685
1226
- const messagesFromStore = React__default["default"].useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1255
+ const messagesFromStore = React__namespace["default"].useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1227
1256
  return [
1228
1257
  {
1229
1258
  data: { messages: messagesFromStore },
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { AIConversationInput, AIConversationProps } from './types';
3
3
  interface AIConversationBaseProps extends AIConversationProps, AIConversationInput {
4
4
  }
5
- declare function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, }: AIConversationBaseProps): JSX.Element;
5
+ declare function AIConversationBase({ actions, avatars, controls, handleSendMessage, messages, responseComponents, suggestedPrompts, variant, isLoading, displayText, allowAttachments, }: AIConversationBaseProps): JSX.Element;
6
6
  /**
7
7
  * @experimental
8
8
  */
@@ -16,6 +16,7 @@ export declare const AIConversation: typeof AIConversationBase & {
16
16
  }> | undefined;
17
17
  Form: NonNullable<React.ComponentType<{
18
18
  handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
19
+ allowAttachments?: boolean | undefined;
19
20
  } & Required<import("./context").ConversationInputContext>> | undefined>;
20
21
  };
21
22
  export {};
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ export declare const AttachmentContext: React.Context<boolean>;
3
+ export declare const AttachmentProvider: ({ children, allowAttachments, }: {
4
+ children?: React.ReactNode;
5
+ allowAttachments?: boolean | undefined;
6
+ }) => JSX.Element;
@@ -5,6 +5,7 @@ import { ConversationMessage } from '../../../types';
5
5
  export interface ControlsContextProps {
6
6
  Form?: React.ComponentType<{
7
7
  handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
8
+ allowAttachments?: boolean;
8
9
  } & Required<ConversationInputContext>>;
9
10
  MessageList?: React.ComponentType<{
10
11
  messages: ConversationMessage[];
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
2
  import { AIConversationInput, AIConversationProps } from './types';
3
- export default function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, }: Pick<AIConversationInput, 'elements' | 'actions' | 'suggestedPrompts' | 'responseComponents' | 'variant' | 'controls' | 'displayText'>): ({ children, messages, avatars, handleSendMessage, isLoading, }: {
3
+ export default function createProvider({ elements, actions, suggestedPrompts, responseComponents, variant, controls, displayText, allowAttachments, }: Pick<AIConversationInput, 'elements' | 'actions' | 'suggestedPrompts' | 'responseComponents' | 'variant' | 'controls' | 'displayText' | 'allowAttachments'>): ({ children, messages, avatars, handleSendMessage, isLoading, }: {
4
4
  children?: React.ReactNode;
5
5
  } & Pick<AIConversationProps, "avatars" | "messages" | "isLoading" | "handleSendMessage">) => React.JSX.Element;
@@ -21,6 +21,7 @@ export interface AIConversationInput {
21
21
  responseComponents?: ResponseComponents;
22
22
  variant?: MessageVariant;
23
23
  controls?: ControlsContextProps;
24
+ allowAttachments?: boolean;
24
25
  }
25
26
  export interface AIConversationProps {
26
27
  messages: ConversationMessage[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aws-amplify/ui-react-ai",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/esm/index.mjs",
6
6
  "exports": {
@@ -34,7 +34,7 @@
34
34
  "check:esm": "node --input-type=module --eval 'import \"@aws-amplify/ui-react-ai\"'",
35
35
  "clean": "rimraf dist node_modules",
36
36
  "dev": "yarn build:rollup --watch",
37
- "lint": "yarn typecheck && eslint src",
37
+ "lint": "yarn typecheck && eslint .",
38
38
  "prebuild": "rimraf dist",
39
39
  "size": "yarn size-limit",
40
40
  "test": "jest",
@@ -48,12 +48,11 @@
48
48
  "react-dom": "^16.14.0 || ^17.0 || ^18.0"
49
49
  },
50
50
  "dependencies": {
51
- "@aws-amplify/ui": "^6.6.1",
52
- "@aws-amplify/ui-react": "^6.5.1",
53
- "@aws-amplify/ui-react-core": "^3.0.25"
51
+ "@aws-amplify/ui": "^6.6.2",
52
+ "@aws-amplify/ui-react": "^6.5.2",
53
+ "@aws-amplify/ui-react-core": "^3.0.26"
54
54
  },
55
55
  "devDependencies": {
56
- "@rollup/plugin-commonjs": "^22.0.1",
57
56
  "@types/jest-when": "^3.5.0",
58
57
  "jest-when": "^3.5.1"
59
58
  }