From 7bc61702eccb1b0816733eb66e7aaf4c0bcbd4b2 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 4 Jun 2025 09:48:48 -0700 Subject: [PATCH] improvement(panel): added unique conversationId to chat panel (#458) * added unqiue conversationId to chat panel * ack race condition * add uploads directory to gitignore --- .gitignore | 1 + .../components/panel/components/chat/chat.tsx | 11 ++++- .../chat/components/chat-modal/chat-modal.tsx | 10 +++- apps/sim/stores/panel/chat/store.ts | 48 +++++++++++++++++-- apps/sim/stores/panel/chat/types.ts | 3 ++ 5 files changed, 64 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index eea3e74655..33e7b36c95 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ sim-standalone.tar.gz # misc .DS_Store *.pem +uploads/ # env files .env diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx b/apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx index 551b696079..5c719500c6 100644 --- a/apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx +++ b/apps/sim/app/w/[id]/components/panel/components/chat/chat.tsx @@ -31,6 +31,7 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { setSelectedWorkflowOutput, appendMessageContent, finalizeMessageStream, + getConversationId, } = useChatStore() const { entries } = useConsoleStore() const messagesEndRef = useRef(null) @@ -91,6 +92,9 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { // Store the message being sent for reference const sentMessage = chatMessage.trim() + // Get the conversationId for this workflow before adding the message + const conversationId = getConversationId(activeWorkflowId) + // Add user message addMessage({ content: sentMessage, @@ -101,8 +105,11 @@ export function Chat({ panelWidth, chatMessage, setChatMessage }: ChatProps) { // Clear input setChatMessage('') - // Execute the workflow to generate a response, passing the chat message as input - const result = await handleRunWorkflow({ input: sentMessage }) + // Execute the workflow to generate a response, passing the chat message and conversationId as input + const result = await handleRunWorkflow({ + input: sentMessage, + conversationId: conversationId, + }) // Check if we got a streaming response if (result && 'stream' in result && result.stream instanceof ReadableStream) { diff --git a/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx b/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx index 6201484082..31b887312a 100644 --- a/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx +++ b/apps/sim/app/w/[id]/components/panel/components/chat/components/chat-modal/chat-modal.tsx @@ -76,7 +76,7 @@ export function ChatModal({ open, onOpenChange, chatMessage, setChatMessage }: C const inputRef = useRef(null) const { activeWorkflowId } = useWorkflowRegistry() - const { messages, addMessage } = useChatStore() + const { messages, addMessage, getConversationId } = useChatStore() // Use the execution store state to track if a workflow is executing const { isExecuting } = useExecutionStore() @@ -113,6 +113,9 @@ export function ChatModal({ open, onOpenChange, chatMessage, setChatMessage }: C // Store the message being sent for reference const sentMessage = chatMessage.trim() + // Get the conversationId for this workflow before adding the message + const conversationId = getConversationId(activeWorkflowId) + // Add user message addMessage({ content: sentMessage, @@ -129,7 +132,10 @@ export function ChatModal({ open, onOpenChange, chatMessage, setChatMessage }: C } // Execute the workflow to generate a response - await handleRunWorkflow({ input: sentMessage }) + await handleRunWorkflow({ + input: sentMessage, + conversationId: conversationId, + }) // Ensure input stays focused even after response if (inputRef.current) { diff --git a/apps/sim/stores/panel/chat/store.ts b/apps/sim/stores/panel/chat/store.ts index 7ca5d30e3a..5dcf7c38ca 100644 --- a/apps/sim/stores/panel/chat/store.ts +++ b/apps/sim/stores/panel/chat/store.ts @@ -1,3 +1,4 @@ +import { v4 as uuidv4 } from 'uuid' import { create } from 'zustand' import { devtools, persist } from 'zustand/middleware' import type { ChatMessage, ChatStore } from './types' @@ -11,6 +12,7 @@ export const useChatStore = create()( (set, get) => ({ messages: [], selectedWorkflowOutputs: {}, + conversationIds: {}, addMessage: (message) => { set((state) => { @@ -29,11 +31,28 @@ export const useChatStore = create()( }, clearChat: (workflowId: string | null) => { - set((state) => ({ - messages: state.messages.filter( - (message) => !workflowId || message.workflowId !== workflowId - ), - })) + set((state) => { + const newState = { + messages: state.messages.filter( + (message) => !workflowId || message.workflowId !== workflowId + ), + } + + // Generate a new conversationId when clearing chat for a specific workflow + if (workflowId) { + const newConversationIds = { ...state.conversationIds } + newConversationIds[workflowId] = uuidv4() + return { + ...newState, + conversationIds: newConversationIds, + } + } + // When clearing all chats (workflowId is null), also clear all conversationIds + return { + ...newState, + conversationIds: {}, + } + }) }, getWorkflowMessages: (workflowId) => { @@ -62,6 +81,25 @@ export const useChatStore = create()( return get().selectedWorkflowOutputs[workflowId] || [] }, + getConversationId: (workflowId) => { + const state = get() + if (!state.conversationIds[workflowId]) { + // Generate a new conversation ID if one doesn't exist + return get().generateNewConversationId(workflowId) + } + return state.conversationIds[workflowId] + }, + + generateNewConversationId: (workflowId) => { + const newId = uuidv4() + set((state) => { + const newConversationIds = { ...state.conversationIds } + newConversationIds[workflowId] = newId + return { conversationIds: newConversationIds } + }) + return newId + }, + appendMessageContent: (messageId, content) => { set((state) => { const newMessages = state.messages.map((message) => { diff --git a/apps/sim/stores/panel/chat/types.ts b/apps/sim/stores/panel/chat/types.ts index 8f46cd4442..060f410500 100644 --- a/apps/sim/stores/panel/chat/types.ts +++ b/apps/sim/stores/panel/chat/types.ts @@ -16,6 +16,7 @@ export interface OutputConfig { export interface ChatStore { messages: ChatMessage[] selectedWorkflowOutputs: Record + conversationIds: Record addMessage: (message: Omit) => void clearChat: (workflowId: string | null) => void getWorkflowMessages: (workflowId: string) => ChatMessage[] @@ -23,4 +24,6 @@ export interface ChatStore { getSelectedWorkflowOutput: (workflowId: string) => string[] appendMessageContent: (messageId: string, content: string) => void finalizeMessageStream: (messageId: string) => void + getConversationId: (workflowId: string) => string + generateNewConversationId: (workflowId: string) => string }