From 609f1fa649fcbbbdc92a3f362fbd8d5a62d65d98 Mon Sep 17 00:00:00 2001 From: Avirup Sinha Date: Tue, 2 Sep 2025 20:05:54 +0530 Subject: [PATCH 1/2] feat:Workflow Builder UI Integration in Xyne Dashboard --- frontend/package.json | 6 +- frontend/src/assets/arrow-left.svg | 3 + frontend/src/assets/bot-logo.svg | 10 + frontend/src/assets/check-circle.svg | 3 + frontend/src/assets/file-up.svg | 3 + frontend/src/assets/grid-dashboard-01.svg | 6 + frontend/src/assets/import-dsl.svg | 3 + frontend/src/assets/play.svg | 3 + frontend/src/assets/plus.svg | 3 + frontend/src/assets/sitemap.svg | 6 + frontend/src/assets/vector.svg | 3 + frontend/src/components/Sidebar.tsx | 21 + .../components/workflow/AIAgentConfigUI.tsx | 404 ++++ .../src/components/workflow/ActionBar.tsx | 57 + frontend/src/components/workflow/Default.ts | 15 + .../src/components/workflow/EmailConfigUI.tsx | 215 ++ frontend/src/components/workflow/Types.ts | 248 +++ .../components/workflow/WhatHappensNextUI.tsx | 154 ++ .../components/workflow/WorkflowBuilder.tsx | 1731 +++++++++++++++++ .../src/components/workflow/WorkflowCard.tsx | 80 + .../workflow/WorkflowExecutionModal.tsx | 408 ++++ .../src/components/workflow/WorkflowIcons.tsx | 173 ++ .../components/workflow/WorkflowProvider.tsx | 92 + .../src/components/workflow/WorkflowUtils.ts | 226 +++ .../components/workflow/api/ApiHandlers.ts | 97 + frontend/src/routeTree.gen.ts | 27 + .../src/routes/_authenticated/workflow.tsx | 343 ++++ 27 files changed, 4338 insertions(+), 2 deletions(-) create mode 100644 frontend/src/assets/arrow-left.svg create mode 100644 frontend/src/assets/bot-logo.svg create mode 100644 frontend/src/assets/check-circle.svg create mode 100644 frontend/src/assets/file-up.svg create mode 100644 frontend/src/assets/grid-dashboard-01.svg create mode 100644 frontend/src/assets/import-dsl.svg create mode 100644 frontend/src/assets/play.svg create mode 100644 frontend/src/assets/plus.svg create mode 100644 frontend/src/assets/sitemap.svg create mode 100644 frontend/src/assets/vector.svg create mode 100644 frontend/src/components/workflow/AIAgentConfigUI.tsx create mode 100644 frontend/src/components/workflow/ActionBar.tsx create mode 100644 frontend/src/components/workflow/Default.ts create mode 100644 frontend/src/components/workflow/EmailConfigUI.tsx create mode 100644 frontend/src/components/workflow/Types.ts create mode 100644 frontend/src/components/workflow/WhatHappensNextUI.tsx create mode 100644 frontend/src/components/workflow/WorkflowBuilder.tsx create mode 100644 frontend/src/components/workflow/WorkflowCard.tsx create mode 100644 frontend/src/components/workflow/WorkflowExecutionModal.tsx create mode 100644 frontend/src/components/workflow/WorkflowIcons.tsx create mode 100644 frontend/src/components/workflow/WorkflowProvider.tsx create mode 100644 frontend/src/components/workflow/WorkflowUtils.ts create mode 100644 frontend/src/components/workflow/api/ApiHandlers.ts create mode 100644 frontend/src/routes/_authenticated/workflow.tsx diff --git a/frontend/package.json b/frontend/package.json index 7c6431628..336dbac81 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,11 +29,12 @@ "@tanstack/react-router": "^1.102.0", "@tanstack/react-virtual": "^3.13.12", "@uiw/react-markdown-preview": "^5.1.3", + "@xyflow/react": "^12.8.4", "caniuse-lite": "^1.0.30001696", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "docx-preview": "^0.3.5", "date-fns": "^4.1.0", + "docx-preview": "^0.3.5", "dompurify": "^3.2.6", "hono": "^4.6.15", "jszip": "^3.10.1", @@ -44,6 +45,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-icons": "^5.5.0", + "react-is": "^19.1.1", "react-json-view": "^1.21.3", "react-zoom-pan-pinch": "^3.7.0", "recharts": "^3.1.0", @@ -78,4 +80,4 @@ "vite-plugin-svgr": "^4.3.0", "vitest": "^3.1.4" } -} \ No newline at end of file +} diff --git a/frontend/src/assets/arrow-left.svg b/frontend/src/assets/arrow-left.svg new file mode 100644 index 000000000..8b5782706 --- /dev/null +++ b/frontend/src/assets/arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/bot-logo.svg b/frontend/src/assets/bot-logo.svg new file mode 100644 index 000000000..19d84890b --- /dev/null +++ b/frontend/src/assets/bot-logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/frontend/src/assets/check-circle.svg b/frontend/src/assets/check-circle.svg new file mode 100644 index 000000000..7863c62c2 --- /dev/null +++ b/frontend/src/assets/check-circle.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/file-up.svg b/frontend/src/assets/file-up.svg new file mode 100644 index 000000000..166424d08 --- /dev/null +++ b/frontend/src/assets/file-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/grid-dashboard-01.svg b/frontend/src/assets/grid-dashboard-01.svg new file mode 100644 index 000000000..4cca66cd9 --- /dev/null +++ b/frontend/src/assets/grid-dashboard-01.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/assets/import-dsl.svg b/frontend/src/assets/import-dsl.svg new file mode 100644 index 000000000..9415c302e --- /dev/null +++ b/frontend/src/assets/import-dsl.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/play.svg b/frontend/src/assets/play.svg new file mode 100644 index 000000000..58ea537f2 --- /dev/null +++ b/frontend/src/assets/play.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/plus.svg b/frontend/src/assets/plus.svg new file mode 100644 index 000000000..336b11f62 --- /dev/null +++ b/frontend/src/assets/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/sitemap.svg b/frontend/src/assets/sitemap.svg new file mode 100644 index 000000000..d8bcc11b3 --- /dev/null +++ b/frontend/src/assets/sitemap.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/frontend/src/assets/vector.svg b/frontend/src/assets/vector.svg new file mode 100644 index 000000000..9c7e84fd7 --- /dev/null +++ b/frontend/src/assets/vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 723cbe12b..6d228086d 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -12,6 +12,7 @@ import { Key, BarChart3, BookOpen, + Workflow, } from "lucide-react" import { useState, useEffect } from "react" import HistoryModal from "@/components/HistoryModal" @@ -170,6 +171,26 @@ export const Sidebar = ({ + + + + + + + + + {/* TODO: Add appropriate Link destination and Tooltip info for the Bot icon */} {isAgentMode && ( void; + onSave?: (agentConfig: AIAgentConfig) => void; +} + +export interface AIAgentConfig { + name: string; + description: string; + model: string; + inputPrompt: string; + systemPrompt: string; + knowledgeBase: string; +} + +const AIAgentConfigUI: React.FC = ({ isVisible, onBack, onSave }) => { + const [agentConfig, setAgentConfig] = useState({ + name: 'Document Summariser', + description: '', + model: 'gpt-oss-120b', + inputPrompt: '$json.input', + systemPrompt: '', + knowledgeBase: '' + }); + + const [isModelDropdownOpen, setIsModelDropdownOpen] = useState(false); + const [isKnowledgeDropdownOpen, setIsKnowledgeDropdownOpen] = useState(false); + const [isEnhancingPrompt, setIsEnhancingPrompt] = useState(false); + + const models = [ + 'gpt-oss-120b', + 'gpt-4', + 'gpt-3.5-turbo', + 'claude-3-sonnet', + 'claude-3-haiku' + ]; + + const enhanceSystemPrompt = async () => { + if (!agentConfig.systemPrompt.trim()) { + alert('Please enter a system prompt first'); + return; + } + + setIsEnhancingPrompt(true); + + try { + // Use Xyne's existing prompt generation endpoint with Bedrock + const requirements = `Enhance this AI agent system prompt to be more professional, clear, and effective. Make it more structured and comprehensive while preserving the original intent. + +Original prompt: "${agentConfig.systemPrompt}" + +Please provide an enhanced version that: +1. Is clear and specific about the AI agent's role +2. Includes proper behavioral guidelines +3. Has clear instructions for output format +4. Maintains the original purpose but makes it more professional + +Return only the enhanced system prompt without any additional explanation.`; + + // Create EventSource for streaming response from Xyne's Bedrock implementation + const url = `/agent/generate-prompt?requirements=${encodeURIComponent(requirements)}&modelId=${encodeURIComponent(agentConfig.model)}`; + const eventSource = new EventSource(url); + + let enhancedPrompt = ''; + let timeoutId: NodeJS.Timeout; + + // Set a timeout to prevent hanging + timeoutId = setTimeout(() => { + eventSource.close(); + setIsEnhancingPrompt(false); + throw new Error('Request timeout'); + }, 30000); // 30 second timeout + + eventSource.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + + if (event.type === 'ResponseUpdate' || data.type === 'update') { + enhancedPrompt += data.text || data.content || ''; + } else if (event.type === 'End' || data.type === 'end') { + clearTimeout(timeoutId); + eventSource.close(); + + const finalPrompt = data.fullPrompt || enhancedPrompt.trim(); + if (finalPrompt) { + setAgentConfig(prev => ({ + ...prev, + systemPrompt: finalPrompt + })); + } + setIsEnhancingPrompt(false); + } + } catch (parseError) { + // Handle non-JSON responses (raw text chunks) + if (typeof event.data === 'string') { + enhancedPrompt += event.data; + } + } + }; + + eventSource.onerror = (error) => { + console.error('EventSource error:', error); + clearTimeout(timeoutId); + eventSource.close(); + setIsEnhancingPrompt(false); + + // Fallback enhancement + const fallbackEnhancement = `You are a professional ${agentConfig.name.toLowerCase()} AI agent specialized in ${agentConfig.description || 'data processing'}. + +CORE RESPONSIBILITIES: +${agentConfig.systemPrompt} + +BEHAVIORAL GUIDELINES: +- Maintain a professional and helpful tone at all times +- Provide accurate, relevant, and well-structured responses +- Follow clear output formatting standards +- Ensure all responses are actionable and clear +- Process input thoroughly before responding + +OUTPUT REQUIREMENTS: +- Structure responses with clear headings when appropriate +- Use bullet points or numbered lists for complex information +- Maintain consistency in tone and style +- Always double-check accuracy before providing final output + +Always strive for excellence and helpfulness in your responses while adhering to these guidelines.`; + + setAgentConfig(prev => ({ + ...prev, + systemPrompt: fallbackEnhancement + })); + }; + + } catch (error) { + console.error('Error enhancing prompt:', error); + setIsEnhancingPrompt(false); + + // Fallback enhancement for any other errors + const fallbackEnhancement = `You are a professional ${agentConfig.name.toLowerCase()} AI agent. ${agentConfig.systemPrompt} + +Key responsibilities: +- Analyze and process the provided input thoroughly +- Maintain a professional and helpful tone +- Provide accurate and relevant responses +- Follow structured output formatting +- Ensure all responses are clear and actionable + +Always strive for accuracy and helpfulness in your responses.`; + + setAgentConfig(prev => ({ + ...prev, + systemPrompt: fallbackEnhancement + })); + + alert('Enhancement failed. A basic improvement has been applied.'); + } + }; + + const handleSave = () => { + onSave?.(agentConfig); + }; + + return ( +
+ {/* Header */} +
+ + +

+ AI Agent +

+ + +
+ + {/* Content */} +
+
+ {/* Agent Name */} +
+ + setAgentConfig(prev => ({ ...prev, name: e.target.value }))} + placeholder="Enter agent name" + className="w-full" + /> +
+ + {/* Agent Description */} +
+ +