diff --git a/apps/sim/app/api/mothership/chat/route.ts b/apps/sim/app/api/mothership/chat/route.ts index 908ce39053..209eca8f5e 100644 --- a/apps/sim/app/api/mothership/chat/route.ts +++ b/apps/sim/app/api/mothership/chat/route.ts @@ -30,6 +30,7 @@ const MothershipMessageSchema = z.object({ chatId: z.string().optional(), createNewChat: z.boolean().optional().default(false), fileAttachments: z.array(FileAttachmentSchema).optional(), + additionalContext: z.string().optional(), userTimezone: z.string().optional(), contexts: z .array( @@ -80,6 +81,7 @@ export async function POST(req: NextRequest) { chatId, createNewChat, fileAttachments, + additionalContext, contexts, userTimezone, } = MothershipMessageSchema.parse(body) @@ -96,6 +98,10 @@ export async function POST(req: NextRequest) { } } + if (additionalContext) { + agentContexts.push({ type: 'workflow_execution', content: additionalContext }) + } + let currentChat: any = null let conversationHistory: any[] = [] let actualChatId = chatId diff --git a/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts b/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts index 8743c04dbe..36f1f6481a 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts +++ b/apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.ts @@ -40,7 +40,11 @@ export interface UseChatReturn { messages: ChatMessage[] isSending: boolean error: string | null - sendMessage: (message: string, fileAttachments?: FileAttachmentForApi[]) => Promise + sendMessage: ( + message: string, + fileAttachments?: FileAttachmentForApi[], + additionalContext?: string + ) => Promise sendWorkflowResultToChat: (workflowName: string, result: ExecutionResult) => Promise stopGeneration: () => Promise resources: MothershipResource[] @@ -53,8 +57,29 @@ const STATE_TO_STATUS: Record = { error: 'error', } as const -function formatWorkflowResultMessage(_workflowName: string, _result: ExecutionResult): string { - return 'I ran the workflow, please check the logs' +const WORKFLOW_RESULT_DISPLAY_MESSAGE = 'I ran the workflow, please check the logs' + +function formatExecutionContext(workflowName: string, result: ExecutionResult): string { + const lines: string[] = [ + `[Workflow Execution: "${workflowName}"]`, + `Status: ${result.success ? 'Success' : 'Failed'}`, + ] + if (result.error) lines.push(`Error: ${result.error}`) + if (result.logs?.length) { + lines.push('', 'Block Results:') + for (const log of result.logs) { + const name = log.blockName ?? log.blockId + const type = log.blockType ?? 'unknown' + const status = log.success ? 'OK' : 'FAILED' + lines.push(`- ${name} (${type}): ${status} [${log.durationMs}ms]`) + if (log.output) lines.push(` Output: ${JSON.stringify(log.output).slice(0, 2000)}`) + if (log.error) lines.push(` Error: ${log.error}`) + } + } + if (result.output) { + lines.push('', `Final Output: ${JSON.stringify(result.output).slice(0, 3000)}`) + } + return lines.join('\n') } function mapStoredBlock(block: TaskStoredContentBlock): ContentBlock { @@ -152,7 +177,9 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet const [error, setError] = useState(null) const [resources, setResources] = useState([]) const [activeResourceId, setActiveResourceId] = useState(null) - const [queuedMessages, setQueuedMessages] = useState([]) + const [queuedMessages, setQueuedMessages] = useState< + Array<{ message: string; additionalContext?: string }> + >([]) const abortControllerRef = useRef(null) const chatIdRef = useRef(initialChatId) const appliedChatIdRef = useRef(undefined) @@ -593,7 +620,11 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet }, [chatHistory?.activeStreamId, processSSEStream, finalize]) const sendMessage = useCallback( - async (message: string, fileAttachments?: FileAttachmentForApi[]) => { + async ( + message: string, + fileAttachments?: FileAttachmentForApi[], + additionalContext?: string + ) => { if (!message.trim() || !workspaceId) return if (sendingRef.current) { @@ -664,6 +695,7 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet createNewChat: !chatIdRef.current, ...(chatIdRef.current ? { chatId: chatIdRef.current } : {}), ...(fileAttachments && fileAttachments.length > 0 ? { fileAttachments } : {}), + ...(additionalContext ? { additionalContext } : {}), userTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone, }), signal: abortController.signal, @@ -691,14 +723,17 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet const sendWorkflowResultToChat = useCallback( async (workflowName: string, result: ExecutionResult) => { - const message = formatWorkflowResultMessage(workflowName, result) + const context = formatExecutionContext(workflowName, result) if (sendingRef.current || isSending) { - setQueuedMessages((prev) => [...prev, message]) + setQueuedMessages((prev) => [ + ...prev, + { message: WORKFLOW_RESULT_DISPLAY_MESSAGE, additionalContext: context }, + ]) return } - await sendMessage(message) + await sendMessage(WORKFLOW_RESULT_DISPLAY_MESSAGE, undefined, context) }, [isSending, sendMessage] ) @@ -706,9 +741,9 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet useEffect(() => { if (isSending || queuedMessages.length === 0) return - const [nextMessage, ...rest] = queuedMessages + const [next, ...rest] = queuedMessages setQueuedMessages(rest) - void sendMessage(nextMessage) + void sendMessage(next.message, undefined, next.additionalContext) }, [isSending, queuedMessages, sendMessage]) const stopGeneration = useCallback(async () => {