Skip to content

Commit fc162ab

Browse files
authored
fix(deployed-chat): fix page crash on chat stream completion (#1892)
1 parent bc25ea2 commit fc162ab

File tree

1 file changed

+52
-55
lines changed

1 file changed

+52
-55
lines changed

apps/sim/app/chat/components/message/message.tsx

Lines changed: 52 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ export const ClientChatMessage = memo(
3939
// we can use the content directly without parsing
4040
const cleanTextContent = message.content
4141

42-
// For user messages (on the right)
43-
if (message.type === 'user') {
44-
return (
42+
const content =
43+
message.type === 'user' ? (
4544
<div className='px-4 py-5' data-message-id={message.id}>
4645
<div className='mx-auto max-w-3xl'>
4746
{/* File attachments displayed above the message */}
@@ -162,62 +161,60 @@ export const ClientChatMessage = memo(
162161
)}
163162
</div>
164163
</div>
165-
)
166-
}
167-
168-
// For assistant messages (on the left)
169-
return (
170-
<div className='px-4 pt-5 pb-2' data-message-id={message.id}>
171-
<div className='mx-auto max-w-3xl'>
172-
<div className='flex flex-col space-y-3'>
173-
{/* Direct content rendering - tool calls are now handled via SSE events */}
174-
<div>
175-
<div className='break-words text-base'>
176-
{isJsonObject ? (
177-
<pre className='text-gray-800 dark:text-gray-100'>
178-
{JSON.stringify(cleanTextContent, null, 2)}
179-
</pre>
180-
) : (
181-
<EnhancedMarkdownRenderer content={cleanTextContent as string} />
182-
)}
164+
) : (
165+
<div className='px-4 pt-5 pb-2' data-message-id={message.id}>
166+
<div className='mx-auto max-w-3xl'>
167+
<div className='flex flex-col space-y-3'>
168+
{/* Direct content rendering - tool calls are now handled via SSE events */}
169+
<div>
170+
<div className='break-words text-base'>
171+
{isJsonObject ? (
172+
<pre className='text-gray-800 dark:text-gray-100'>
173+
{JSON.stringify(cleanTextContent, null, 2)}
174+
</pre>
175+
) : (
176+
<EnhancedMarkdownRenderer content={cleanTextContent as string} />
177+
)}
178+
</div>
183179
</div>
180+
{message.type === 'assistant' && !isJsonObject && !message.isInitialMessage && (
181+
<div className='flex items-center justify-start space-x-2'>
182+
{/* Copy Button - Only show when not streaming */}
183+
{!message.isStreaming && (
184+
<Tooltip.Root delayDuration={300}>
185+
<Tooltip.Trigger asChild>
186+
<button
187+
className='text-muted-foreground transition-colors hover:bg-muted'
188+
onClick={() => {
189+
const contentToCopy =
190+
typeof cleanTextContent === 'string'
191+
? cleanTextContent
192+
: JSON.stringify(cleanTextContent, null, 2)
193+
navigator.clipboard.writeText(contentToCopy)
194+
setIsCopied(true)
195+
setTimeout(() => setIsCopied(false), 2000)
196+
}}
197+
>
198+
{isCopied ? (
199+
<Check className='h-3 w-3' strokeWidth={2} />
200+
) : (
201+
<Copy className='h-3 w-3' strokeWidth={2} />
202+
)}
203+
</button>
204+
</Tooltip.Trigger>
205+
<Tooltip.Content side='top' align='center' sideOffset={5}>
206+
{isCopied ? 'Copied!' : 'Copy to clipboard'}
207+
</Tooltip.Content>
208+
</Tooltip.Root>
209+
)}
210+
</div>
211+
)}
184212
</div>
185-
{message.type === 'assistant' && !isJsonObject && !message.isInitialMessage && (
186-
<div className='flex items-center justify-start space-x-2'>
187-
{/* Copy Button - Only show when not streaming */}
188-
{!message.isStreaming && (
189-
<Tooltip.Root delayDuration={300}>
190-
<Tooltip.Trigger asChild>
191-
<button
192-
className='text-muted-foreground transition-colors hover:bg-muted'
193-
onClick={() => {
194-
const contentToCopy =
195-
typeof cleanTextContent === 'string'
196-
? cleanTextContent
197-
: JSON.stringify(cleanTextContent, null, 2)
198-
navigator.clipboard.writeText(contentToCopy)
199-
setIsCopied(true)
200-
setTimeout(() => setIsCopied(false), 2000)
201-
}}
202-
>
203-
{isCopied ? (
204-
<Check className='h-3 w-3' strokeWidth={2} />
205-
) : (
206-
<Copy className='h-3 w-3' strokeWidth={2} />
207-
)}
208-
</button>
209-
</Tooltip.Trigger>
210-
<Tooltip.Content side='top' align='center' sideOffset={5}>
211-
{isCopied ? 'Copied!' : 'Copy to clipboard'}
212-
</Tooltip.Content>
213-
</Tooltip.Root>
214-
)}
215-
</div>
216-
)}
217213
</div>
218214
</div>
219-
</div>
220-
)
215+
)
216+
217+
return <Tooltip.Provider>{content}</Tooltip.Provider>
221218
},
222219
(prevProps, nextProps) => {
223220
return (

0 commit comments

Comments
 (0)