From c696f75a4621cb57d9d312547112fd39e637c589 Mon Sep 17 00:00:00 2001 From: Ritvik Budhiraja Date: Thu, 28 Aug 2025 16:16:57 +0530 Subject: [PATCH 1/4] working changes --- .../react-core/src/hooks/useThreadActions.ts | 1 + .../src/internal/useThreadManagerStore.ts | 1 + .../react-core/src/types/chatManager.ts | 4 +- js/packages/react-core/src/types/message.ts | 12 ++++++ .../react-core/src/useThreadManager.ts | 9 +++++ .../src/components/CrayonChat/CrayonChat.tsx | 12 +++++- .../react-ui/src/components/Shell/Thread.tsx | 37 +++++++++++++++++-- .../react-ui/src/hooks/useComposerState.ts | 8 +++- js/packages/stream/src/openai.ts | 24 ++++++++++-- 9 files changed, 98 insertions(+), 10 deletions(-) diff --git a/js/packages/react-core/src/hooks/useThreadActions.ts b/js/packages/react-core/src/hooks/useThreadActions.ts index 4dba8bf7..de270350 100644 --- a/js/packages/react-core/src/hooks/useThreadActions.ts +++ b/js/packages/react-core/src/hooks/useThreadActions.ts @@ -17,5 +17,6 @@ export const useThreadActions = (): ThreadActions => { setMessages: useStore(threadManager, (store) => store.setMessages), onCancel: useStore(threadManager, (store) => store.onCancel), deleteMessage: useStore(threadManager, (store) => store.deleteMessage), + processFileUpload: useStore(threadManager, (store) => store.processFileUpload), }; }; diff --git a/js/packages/react-core/src/internal/useThreadManagerStore.ts b/js/packages/react-core/src/internal/useThreadManagerStore.ts index 3f1693f3..00880529 100644 --- a/js/packages/react-core/src/internal/useThreadManagerStore.ts +++ b/js/packages/react-core/src/internal/useThreadManagerStore.ts @@ -22,6 +22,7 @@ export const useThreadManagerStore = (inputThreadManager: ThreadManager) => { appendMessages: (...props) => inputThreadManagerRef.current.appendMessages(...props), setMessages: (...props) => inputThreadManagerRef.current.setMessages(...props), deleteMessage: (...props) => inputThreadManagerRef.current.deleteMessage(...props), + processFileUpload: (...props) => inputThreadManagerRef.current.processFileUpload(...props), })), ); diff --git a/js/packages/react-core/src/types/chatManager.ts b/js/packages/react-core/src/types/chatManager.ts index 30c217e8..57ccc736 100644 --- a/js/packages/react-core/src/types/chatManager.ts +++ b/js/packages/react-core/src/types/chatManager.ts @@ -1,4 +1,4 @@ -import { CreateMessage, Message, UserMessage } from "./message"; +import { CreateMessage, Message, UploadedFile, UserMessage } from "./message"; import { ResponseTemplate } from "./responseTemplate"; /** @@ -37,6 +37,8 @@ export type ThreadActions = { setMessages: (messages: Message[]) => void; /** Deletes a message from the thread */ deleteMessage: (messageId: string) => void; + /** Processes a file upload */ + processFileUpload: (files: File[]) => Promise; }; /** diff --git a/js/packages/react-core/src/types/message.ts b/js/packages/react-core/src/types/message.ts index ee83b123..e91734a1 100644 --- a/js/packages/react-core/src/types/message.ts +++ b/js/packages/react-core/src/types/message.ts @@ -10,6 +10,16 @@ type Common = { isVisuallyHidden?: boolean; }; +/** + * @inline + */ +export type UploadedFile = { + /** The name of the file */ + name: string; + /** The id of the file */ + fileId: string; +}; + /** * A type that represents a message sent by the user * @@ -23,6 +33,8 @@ export type UserMessage = Common & { message?: string; /** Additional data associated with the message */ context?: JSONValue[]; + /** The files that are associated with the message */ + files?: UploadedFile[]; }; /** diff --git a/js/packages/react-core/src/useThreadManager.ts b/js/packages/react-core/src/useThreadManager.ts index fa33e322..42edd979 100644 --- a/js/packages/react-core/src/useThreadManager.ts +++ b/js/packages/react-core/src/useThreadManager.ts @@ -1,6 +1,7 @@ import { useEffect, useMemo, useRef } from "react"; import { createStore, useStore } from "zustand"; import { CreateMessage, Message, ResponseTemplate, ThreadManager } from "./types"; +import { UploadedFile } from "./types/message"; /** * Parameters to be passed to the {@link useThreadManager} hook @@ -19,10 +20,13 @@ export type UseThreadManagerParams = { message: CreateMessage; threadManager: ThreadManager; abortController: AbortController; + filesUploaded?: UploadedFile[]; }) => Promise; /** A function that defines how a message should be updated. Useful for integrating a backend API to update a message. */ onUpdateMessage?: (props: { message: Message }) => void; /** A list of response templates available to the thread. */ + /** A function that defines how files should be uploaded. Useful for integrating a backend API to upload files. */ + onProcessFileUpload?: (props: { files: File[] }) => Promise; responseTemplates: ResponseTemplate[]; }; @@ -77,6 +81,7 @@ export const useThreadManager = (params: UseThreadManagerParams): ThreadManager message, threadManager: store.getState(), abortController, + filesUploaded: message.files, }); store.getState().appendMessages(...newMessages); @@ -108,6 +113,10 @@ export const useThreadManager = (params: UseThreadManagerParams): ThreadManager const messages = store.getState().messages.filter((m) => m.id !== messageId); set({ messages }); }, + processFileUpload: async (files: File[]) => { + const response = await propsRef.current.onProcessFileUpload?.({ files }); + return response ?? []; + }, responseTemplates: propsRef.current.responseTemplates.reduce( (acc, template) => { acc[template.name] = template; diff --git a/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx b/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx index 8f6333f7..397de674 100644 --- a/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx +++ b/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx @@ -7,6 +7,7 @@ import { Thread, ThreadListManager, ThreadManager, + UploadedFile, UserMessage, useThreadListManager, useThreadManager, @@ -25,6 +26,7 @@ type CrayonChatProps = { messages: Message[]; abortController: AbortController; }) => Promise; + processFileUpload?: (params: { files: File[] }) => Promise; onUpdateMessage?: (props: { message: Message }) => void; processStreamedMessage?: typeof processStreamedMessage; responseTemplates?: ResponseTemplate[]; @@ -52,6 +54,7 @@ const DummyThemeProvider = ({ children }: { children: React.ReactNode }) => { export const CrayonChat = ({ processMessage, + processFileUpload, threadManager: userThreadManager, threadListManager: userThreadListManager, logoUrl = "https://crayonai.org/img/logo.png", @@ -98,9 +101,10 @@ export const CrayonChat = ({ return Promise.resolve(messages); }, onUpdateMessage: onUpdateMessage, - onProcessMessage: async ({ message, abortController, threadManager }) => { + onProcessMessage: async ({ message, abortController, threadManager, filesUploaded }) => { const newMessage: UserMessage = { id: crypto.randomUUID(), + files: filesUploaded, ...message, }; threadManager.appendMessages(newMessage); @@ -128,6 +132,12 @@ export const CrayonChat = ({ return []; }, + onProcessFileUpload: async ({ files }) => { + invariant(processFileUpload, "processFileUpload is required"); + + const response = await processFileUpload({ files }); + return response; + }, responseTemplates: responseTemplates ?? [], }); diff --git a/js/packages/react-ui/src/components/Shell/Thread.tsx b/js/packages/react-ui/src/components/Shell/Thread.tsx index 1a7c9a03..2f79e905 100644 --- a/js/packages/react-ui/src/components/Shell/Thread.tsx +++ b/js/packages/react-ui/src/components/Shell/Thread.tsx @@ -6,7 +6,7 @@ import { useThreadState, } from "@crayonai/react-core"; import clsx from "clsx"; -import { ArrowRight, Square } from "lucide-react"; +import { ArrowRight, Plus, Square } from "lucide-react"; import React, { memo, useLayoutEffect, useRef } from "react"; import { useComposerState } from "../../hooks/useComposerState"; import { ScrollVariant, useScrollToBottom } from "../../hooks/useScrollToBottom"; @@ -197,10 +197,23 @@ export const Messages = ({ }; export const Composer = ({ className }: { className?: string }) => { - const { textContent, setTextContent } = useComposerState(); - const { processMessage, onCancel } = useThreadActions(); + const { textContent, setTextContent, uploadedFiles, setUploadedFiles } = useComposerState(); + const { processMessage, onCancel, processFileUpload } = useThreadActions(); const { isRunning, isLoadingMessages } = useThreadState(); const inputRef = useRef(null); + const fileInputRef = useRef(null); + + const handleUpload = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent) => { + if (e.target.files) { + const files = Array.from(e.target.files); + const result = await processFileUpload(files); + setUploadedFiles({ files: result }); + } + }; const handleSubmit = () => { if (!textContent.trim() || isRunning || isLoadingMessages) { @@ -211,8 +224,10 @@ export const Composer = ({ className }: { className?: string }) => { type: "prompt", role: "user", message: textContent, + files: uploadedFiles?.files ?? [], }); + setUploadedFiles({ files: [] }); setTextContent(""); }; @@ -242,6 +257,22 @@ export const Composer = ({ className }: { className?: string }) => { } }} /> + + + + {(!isRunning || !!handleUpload) && ( + } + /> + )} + : } diff --git a/js/packages/react-ui/src/hooks/useComposerState.ts b/js/packages/react-ui/src/hooks/useComposerState.ts index 902cb7fb..c9d69aec 100644 --- a/js/packages/react-ui/src/hooks/useComposerState.ts +++ b/js/packages/react-ui/src/hooks/useComposerState.ts @@ -1,7 +1,13 @@ +import { UploadedFile } from "@crayonai/react-core"; import { useState } from "react"; +type FileUploadResponse = { + files: UploadedFile[]; +}; + export const useComposerState = () => { const [textContent, setTextContent] = useState(""); + const [uploadedFiles, setUploadedFiles] = useState(null); - return { textContent, setTextContent }; + return { textContent, setTextContent, uploadedFiles, setUploadedFiles }; }; diff --git a/js/packages/stream/src/openai.ts b/js/packages/stream/src/openai.ts index a1de744a..97c09f27 100644 --- a/js/packages/stream/src/openai.ts +++ b/js/packages/stream/src/openai.ts @@ -53,10 +53,26 @@ export const toOpenAIMessages = (messages: any[]) => { continue; } if (message.role === "user") { - openAIMessages.push({ - role: message.role, - content: message.message, - }); + if (message.files && message.files.length > 0) { + openAIMessages.push({ + role: message.role, + content: JSON.stringify([ + ...message.files.map((file: { name: string; fileId: string }) => ({ + type: "file", + file: { filename: file.name, file_id: file.fileId }, + })), + { + type: "text", + text: message.message, + }, + ]), + }); + } else { + openAIMessages.push({ + role: message.role, + content: message.message, + }); + } } else if (message.role === "assistant") { openAIMessages.push({ role: message.role, From c16150f35b9b921e0d543c1e7c6fe45b5e44de10 Mon Sep 17 00:00:00 2001 From: Ritvik Budhiraja Date: Thu, 28 Aug 2025 23:47:34 +0530 Subject: [PATCH 2/4] added to copilot agent --- .../src/components/CopilotShell/Thread.tsx | 43 +++++++++++++++++-- .../components/CrayonChat/ComposedCopilot.tsx | 4 +- .../CrayonChat/ComposedStandalone.tsx | 4 +- .../src/components/CrayonChat/CrayonChat.tsx | 3 ++ .../react-ui/src/components/Shell/Thread.tsx | 24 +++++++---- 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/js/packages/react-ui/src/components/CopilotShell/Thread.tsx b/js/packages/react-ui/src/components/CopilotShell/Thread.tsx index f3cf94ef..763f91bd 100644 --- a/js/packages/react-ui/src/components/CopilotShell/Thread.tsx +++ b/js/packages/react-ui/src/components/CopilotShell/Thread.tsx @@ -6,7 +6,7 @@ import { useThreadState, } from "@crayonai/react-core"; import clsx from "clsx"; -import { ArrowRight, Square } from "lucide-react"; +import { ArrowRight, Plus, Square } from "lucide-react"; import React, { memo, useLayoutEffect, useRef } from "react"; import { useComposerState } from "../../hooks/useComposerState"; import { ScrollVariant, useScrollToBottom } from "../../hooks/useScrollToBottom"; @@ -193,11 +193,30 @@ export const Messages = ({ ); }; -export const Composer = ({ className }: { className?: string }) => { - const { textContent, setTextContent } = useComposerState(); - const { processMessage, onCancel } = useThreadActions(); +export const Composer = ({ + className, + enableFileUpload, +}: { + className?: string; + enableFileUpload: boolean; +}) => { + const { textContent, setTextContent, uploadedFiles, setUploadedFiles } = useComposerState(); + const { processMessage, onCancel, processFileUpload } = useThreadActions(); const { isRunning } = useThreadState(); const inputRef = useRef(null); + const fileInputRef = useRef(null); + + const handleUpload = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent) => { + if (e.target.files) { + const files = Array.from(e.target.files); + const result = await processFileUpload(files); + setUploadedFiles({ files: result }); + } + }; const handleSubmit = () => { if (!textContent.trim() || isRunning) { @@ -208,6 +227,7 @@ export const Composer = ({ className }: { className?: string }) => { type: "prompt", role: "user", message: textContent, + files: uploadedFiles?.files ?? [], }); setTextContent(""); @@ -239,6 +259,21 @@ export const Composer = ({ className }: { className?: string }) => { } }} /> + {enableFileUpload && ( + + )} + {(!isRunning || !!handleUpload) && enableFileUpload && ( + } + /> + )} : } diff --git a/js/packages/react-ui/src/components/CrayonChat/ComposedCopilot.tsx b/js/packages/react-ui/src/components/CrayonChat/ComposedCopilot.tsx index 8d702d12..3fd44b11 100644 --- a/js/packages/react-ui/src/components/CrayonChat/ComposedCopilot.tsx +++ b/js/packages/react-ui/src/components/CrayonChat/ComposedCopilot.tsx @@ -13,6 +13,7 @@ interface ComposedCopilotProps { agentName?: string; messageLoadingComponent?: () => React.ReactNode; scrollVariant: ScrollVariant; + enableFileUpload: boolean; } export const ComposedCopilot = ({ @@ -20,6 +21,7 @@ export const ComposedCopilot = ({ agentName = "My Agent", messageLoadingComponent: MessageLoadingComponent = MessageLoading, scrollVariant, + enableFileUpload, }: ComposedCopilotProps) => { return ( @@ -28,7 +30,7 @@ export const ComposedCopilot = ({ } /> - + ); diff --git a/js/packages/react-ui/src/components/CrayonChat/ComposedStandalone.tsx b/js/packages/react-ui/src/components/CrayonChat/ComposedStandalone.tsx index 4d8b697d..64e21b93 100644 --- a/js/packages/react-ui/src/components/CrayonChat/ComposedStandalone.tsx +++ b/js/packages/react-ui/src/components/CrayonChat/ComposedStandalone.tsx @@ -19,6 +19,7 @@ interface ComposedStandaloneProps { agentName?: string; messageLoadingComponent?: () => React.ReactNode; scrollVariant: ScrollVariant; + enableFileUpload: boolean; } export const ComposedStandalone = ({ @@ -26,6 +27,7 @@ export const ComposedStandalone = ({ agentName = "My Agent", messageLoadingComponent: MessageLoadingComponent = MessageLoading, scrollVariant, + enableFileUpload, }: ComposedStandaloneProps) => { return ( @@ -42,7 +44,7 @@ export const ComposedStandalone = ({ } /> - + ); diff --git a/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx b/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx index 397de674..e7b1425b 100644 --- a/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx +++ b/js/packages/react-ui/src/components/CrayonChat/CrayonChat.tsx @@ -142,6 +142,7 @@ export const CrayonChat = ({ }); const threadManager = userThreadManager ?? defaultThreadManager; + const enableFileUpload = processFileUpload ? true : false; useEffect(() => { if (threadListManager.selectedThreadId) { @@ -158,6 +159,7 @@ export const CrayonChat = ({ agentName={agentName} messageLoadingComponent={messageLoadingComponent} scrollVariant={scrollVariant} + enableFileUpload={enableFileUpload} /> ) : ( )} diff --git a/js/packages/react-ui/src/components/Shell/Thread.tsx b/js/packages/react-ui/src/components/Shell/Thread.tsx index 2f79e905..5d2bb69a 100644 --- a/js/packages/react-ui/src/components/Shell/Thread.tsx +++ b/js/packages/react-ui/src/components/Shell/Thread.tsx @@ -196,7 +196,13 @@ export const Messages = ({ ); }; -export const Composer = ({ className }: { className?: string }) => { +export const Composer = ({ + className, + enableFileUpload, +}: { + className?: string; + enableFileUpload: boolean; +}) => { const { textContent, setTextContent, uploadedFiles, setUploadedFiles } = useComposerState(); const { processMessage, onCancel, processFileUpload } = useThreadActions(); const { isRunning, isLoadingMessages } = useThreadState(); @@ -258,14 +264,16 @@ export const Composer = ({ className }: { className?: string }) => { }} /> - + {enableFileUpload && ( + + )} - {(!isRunning || !!handleUpload) && ( + {(!isRunning || !!handleUpload) && enableFileUpload && ( Date: Fri, 29 Aug 2025 15:08:03 +0530 Subject: [PATCH 3/4] working changes --- .../react-ui/src/components/Shell/Thread.tsx | 31 +++++++++++++++++-- .../react-ui/src/components/Shell/thread.scss | 27 ++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/js/packages/react-ui/src/components/Shell/Thread.tsx b/js/packages/react-ui/src/components/Shell/Thread.tsx index 5d2bb69a..3d3844d3 100644 --- a/js/packages/react-ui/src/components/Shell/Thread.tsx +++ b/js/packages/react-ui/src/components/Shell/Thread.tsx @@ -1,6 +1,7 @@ import { Message, MessageProvider, + UserMessage, useThreadActions, useThreadManagerSelector, useThreadState, @@ -111,10 +112,34 @@ export const AssistantMessageContainer = ({ export const UserMessageContainer = ({ children, className, + message, }: { children?: React.ReactNode; className?: string; + message?: UserMessage; }) => { + if (message) { + return ( +
+
+ {message.files && message.files.length > 0 && ( +
+ {message.files.map((file, index) => ( +
+ 📎 {file.name} +
+ ))} +
+ )} +
+ {message.message &&
{message.message}
} +
+
+
+ ); + } + + // if no message object is provided, use the children return (
{children}
@@ -158,7 +183,7 @@ export const RenderMessage = memo( ); } - return {message.message}; + return {message.message}; }, ); @@ -198,10 +223,10 @@ export const Messages = ({ export const Composer = ({ className, - enableFileUpload, + enableFileUpload = false, }: { className?: string; - enableFileUpload: boolean; + enableFileUpload?: boolean; }) => { const { textContent, setTextContent, uploadedFiles, setUploadedFiles } = useComposerState(); const { processMessage, onCancel, processFileUpload } = useThreadActions(); diff --git a/js/packages/react-ui/src/components/Shell/thread.scss b/js/packages/react-ui/src/components/Shell/thread.scss index 8d0a23ef..ab63c7a1 100644 --- a/js/packages/react-ui/src/components/Shell/thread.scss +++ b/js/packages/react-ui/src/components/Shell/thread.scss @@ -83,6 +83,13 @@ $center-align-spacing: calc(32px + cssUtils.$spacing-s); padding: 0; } + &__content-wrapper { + display: flex; + flex-direction: column; + gap: cssUtils.$spacing-xs; + justify-content: flex-end; + } + &__content { @include cssUtils.typography(primary, default); padding: cssUtils.$spacing-m cssUtils.$spacing-l; @@ -91,8 +98,28 @@ $center-align-spacing: calc(32px + cssUtils.$spacing-s); border-radius: cssUtils.$rounded-2xl; overflow-wrap: break-word; max-width: 100%; + width: fit-content; height: fit-content; } + + &__files { + @include cssUtils.typography(primary, default); + padding: cssUtils.$spacing-m cssUtils.$spacing-l; + background-color: cssUtils.$chat-user-response-bg; + color: cssUtils.$chat-user-response-text; + border-radius: cssUtils.$rounded-2xl; + overflow-wrap: break-word; + max-width: 100%; + height: fit-content; + } + + &__file { + @include cssUtils.typography(primary, default); + padding: cssUtils.$spacing-m cssUtils.$spacing-l; + background-color: cssUtils.$chat-user-response-text; + color: cssUtils.$chat-user-response-bg; + border-radius: cssUtils.$rounded-2xl; + } } .crayon-shell-thread-composer { From 4c14535cc3fb76b849267eaabc3116844a634f2f Mon Sep 17 00:00:00 2001 From: Ritvik Budhiraja Date: Fri, 29 Aug 2025 15:51:40 +0530 Subject: [PATCH 4/4] working changes --- js/packages/react-core/src/useThreadManager.ts | 6 +++++- .../react-ui/src/components/CopilotShell/Thread.tsx | 4 ++-- js/packages/react-ui/src/components/Shell/thread.scss | 10 ++++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/js/packages/react-core/src/useThreadManager.ts b/js/packages/react-core/src/useThreadManager.ts index 42edd979..5546b51d 100644 --- a/js/packages/react-core/src/useThreadManager.ts +++ b/js/packages/react-core/src/useThreadManager.ts @@ -26,7 +26,10 @@ export type UseThreadManagerParams = { onUpdateMessage?: (props: { message: Message }) => void; /** A list of response templates available to the thread. */ /** A function that defines how files should be uploaded. Useful for integrating a backend API to upload files. */ - onProcessFileUpload?: (props: { files: File[] }) => Promise; + onProcessFileUpload?: (props: { + files: File[]; + abortController?: AbortController; + }) => Promise; responseTemplates: ResponseTemplate[]; }; @@ -58,6 +61,7 @@ export const useThreadManager = (params: UseThreadManagerParams): ThreadManager abortController: null, isRunning: false, isLoadingMessages: false, + isUploading: false, setMessages: (messages: Message[]) => { set({ messages }); }, diff --git a/js/packages/react-ui/src/components/CopilotShell/Thread.tsx b/js/packages/react-ui/src/components/CopilotShell/Thread.tsx index 763f91bd..e2e67c61 100644 --- a/js/packages/react-ui/src/components/CopilotShell/Thread.tsx +++ b/js/packages/react-ui/src/components/CopilotShell/Thread.tsx @@ -195,10 +195,10 @@ export const Messages = ({ export const Composer = ({ className, - enableFileUpload, + enableFileUpload = false, }: { className?: string; - enableFileUpload: boolean; + enableFileUpload?: boolean; }) => { const { textContent, setTextContent, uploadedFiles, setUploadedFiles } = useComposerState(); const { processMessage, onCancel, processFileUpload } = useThreadActions(); diff --git a/js/packages/react-ui/src/components/Shell/thread.scss b/js/packages/react-ui/src/components/Shell/thread.scss index ab63c7a1..f20de484 100644 --- a/js/packages/react-ui/src/components/Shell/thread.scss +++ b/js/packages/react-ui/src/components/Shell/thread.scss @@ -88,6 +88,8 @@ $center-align-spacing: calc(32px + cssUtils.$spacing-s); flex-direction: column; gap: cssUtils.$spacing-xs; justify-content: flex-end; + align-items: flex-end; + max-width: 100%; } &__content { @@ -104,11 +106,15 @@ $center-align-spacing: calc(32px + cssUtils.$spacing-s); &__files { @include cssUtils.typography(primary, default); - padding: cssUtils.$spacing-m cssUtils.$spacing-l; + display: flex; + flex-direction: column; + gap: cssUtils.$spacing-xs; + padding: cssUtils.$spacing-m cssUtils.$spacing-m; background-color: cssUtils.$chat-user-response-bg; color: cssUtils.$chat-user-response-text; border-radius: cssUtils.$rounded-2xl; overflow-wrap: break-word; + width: fit-content; max-width: 100%; height: fit-content; } @@ -118,7 +124,7 @@ $center-align-spacing: calc(32px + cssUtils.$spacing-s); padding: cssUtils.$spacing-m cssUtils.$spacing-l; background-color: cssUtils.$chat-user-response-text; color: cssUtils.$chat-user-response-bg; - border-radius: cssUtils.$rounded-2xl; + border-radius: cssUtils.$rounded-xl; } }