diff --git a/apps/sim/app/api/copilot/chat/route.ts b/apps/sim/app/api/copilot/chat/route.ts
index e42fb317a4..6b5bfad14d 100644
--- a/apps/sim/app/api/copilot/chat/route.ts
+++ b/apps/sim/app/api/copilot/chat/route.ts
@@ -244,7 +244,7 @@ export async function POST(req: NextRequest) {
stream: stream,
streamToolCalls: true,
mode: mode,
- ...(createNewChat && session?.user?.name && { userName: session.user.name }),
+ ...(session?.user?.name && { userName: session.user.name }),
}),
})
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
index 4bf460d61f..f70e8ec1ad 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/panel.tsx
@@ -90,7 +90,12 @@ export function Panel() {
// Load chats for the current workflow - let the store handle caching
if (activeWorkflowId) {
await loadChats(forceRefresh)
- validateCurrentChat()
+
+ // Only validate current chat if we're not actively streaming
+ // This prevents clearing the current conversation during a stream
+ if (!isSendingMessage) {
+ validateCurrentChat()
+ }
// Mark this workflow as loaded for the legacy ref
lastLoadedWorkflowRef.current = activeWorkflowId
@@ -106,6 +111,7 @@ export function Panel() {
loadChats,
validateCurrentChat,
isLoadingChats,
+ isSendingMessage,
]
)
@@ -121,9 +127,10 @@ export function Panel() {
// Open dropdown immediately for better UX
setIsHistoryDropdownOpen(open)
- // If opening, ensure data is loaded but don't force refresh unless needed
- if (open && activeWorkflowId) {
- // Only load if we don't have fresh chats for this workflow
+ // If opening and there's an active stream, don't do any data loading at all
+ // Just show what's already loaded to avoid any interference
+ if (open && activeWorkflowId && !isSendingMessage) {
+ // Only load if we don't have fresh chats for this workflow AND we're not streaming
if (!areChatsFresh(activeWorkflowId)) {
// Don't await - let it load in background while dropdown is already open
ensureCopilotDataLoaded(false).catch((error) => {
@@ -131,8 +138,13 @@ export function Panel() {
})
}
}
+
+ // If streaming, just log that we're showing cached data
+ if (open && isSendingMessage) {
+ console.log('Chat history opened during stream - showing cached data only')
+ }
},
- [ensureCopilotDataLoaded, activeWorkflowId, areChatsFresh]
+ [ensureCopilotDataLoaded, activeWorkflowId, areChatsFresh, isSendingMessage]
)
// Group chats by day
@@ -412,7 +424,11 @@ export function Panel() {
{
- selectChat(chat)
+ // Only call selectChat if it's a different chat
+ // This prevents aborting streams when clicking the currently active chat
+ if (currentChat?.id !== chat.id) {
+ selectChat(chat)
+ }
setIsHistoryDropdownOpen(false)
}}
className={`group mx-1 flex h-8 cursor-pointer items-center rounded-lg px-2 py-1.5 text-left transition-colors ${
diff --git a/apps/sim/stores/copilot/store.ts b/apps/sim/stores/copilot/store.ts
index a85c048577..d49749b129 100644
--- a/apps/sim/stores/copilot/store.ts
+++ b/apps/sim/stores/copilot/store.ts
@@ -1597,13 +1597,30 @@ export const useCopilotStore = create()(
(chat: CopilotChat) => chat.id === currentChat.id
)
if (updatedCurrentChat) {
- set({
- currentChat: updatedCurrentChat,
- messages: ensureToolCallDisplayNames(updatedCurrentChat.messages || []),
- })
- logger.info(
- `Preserved current chat selection: ${updatedCurrentChat.title || 'Untitled'} (${updatedCurrentChat.messages?.length || 0} messages)`
- )
+ const { isSendingMessage } = get()
+
+ // If we're currently streaming, preserve the current messages state
+ // to avoid overwriting streaming content with stale database state
+ if (isSendingMessage) {
+ set({
+ currentChat: {
+ ...updatedCurrentChat,
+ messages: get().messages, // Preserve current streaming messages
+ },
+ })
+ logger.info(
+ `Preserved current chat and streaming messages during active stream: ${updatedCurrentChat.title || 'Untitled'}`
+ )
+ } else {
+ // Safe to update messages when not streaming
+ set({
+ currentChat: updatedCurrentChat,
+ messages: ensureToolCallDisplayNames(updatedCurrentChat.messages || []),
+ })
+ logger.info(
+ `Updated current chat with latest database state: ${updatedCurrentChat.title || 'Untitled'} (${updatedCurrentChat.messages?.length || 0} messages)`
+ )
+ }
// Load checkpoints for the preserved chat
try {
@@ -1614,22 +1631,31 @@ export const useCopilotStore = create()(
}
} else {
// Only auto-select most recent chat if no current chat or current chat is stale
- const mostRecentChat = data.chats[0]
- set({
- currentChat: mostRecentChat,
- messages: ensureToolCallDisplayNames(mostRecentChat.messages || []),
- })
- logger.info(
- `Auto-selected most recent chat for workflow ${workflowId}: ${mostRecentChat.title || 'Untitled'}`
- )
+ // But don't auto-select during streaming to avoid disrupting the conversation
+ const { isSendingMessage } = get()
- // Load checkpoints for the auto-selected chat
- try {
- await get().loadMessageCheckpoints(mostRecentChat.id)
- } catch (checkpointError) {
- logger.error(
- 'Failed to load checkpoints for auto-selected chat:',
- checkpointError
+ if (!isSendingMessage) {
+ const mostRecentChat = data.chats[0]
+ set({
+ currentChat: mostRecentChat,
+ messages: ensureToolCallDisplayNames(mostRecentChat.messages || []),
+ })
+ logger.info(
+ `Auto-selected most recent chat for workflow ${workflowId}: ${mostRecentChat.title || 'Untitled'}`
+ )
+
+ // Load checkpoints for the auto-selected chat
+ try {
+ await get().loadMessageCheckpoints(mostRecentChat.id)
+ } catch (checkpointError) {
+ logger.error(
+ 'Failed to load checkpoints for auto-selected chat:',
+ checkpointError
+ )
+ }
+ } else {
+ logger.info(
+ `Skipped auto-selecting chat during active stream for workflow ${workflowId}`
)
}
}