diff --git a/backend/workflows/converter.py b/backend/workflows/converter.py
index fbe1843d..18e40539 100644
--- a/backend/workflows/converter.py
+++ b/backend/workflows/converter.py
@@ -231,7 +231,13 @@ class WorkflowConverter:
tool_data = tool_node.get('data', {})
tool_name = tool_data.get('nodeId', tool_data.get('label', 'Unknown Tool'))
tool_desc = tool_data.get('description', 'No description available')
- prompt_parts.append(f"- **{tool_name}**: {tool_desc}")
+ tool_instructions = tool_data.get('instructions', '')
+
+ # Build tool description with instructions if provided
+ tool_description = f"- **{tool_name}**: {tool_desc}"
+ if tool_instructions:
+ tool_description += f" - Instructions: {tool_instructions}"
+ prompt_parts.append(tool_description)
# Collect tool ID for XML examples
tool_id = tool_data.get('nodeId')
@@ -327,6 +333,7 @@ class WorkflowConverter:
data = node.get('data', {})
name = data.get('label', 'Tool')
tool_id = data.get('nodeId', 'unknown_tool')
+ instructions = data.get('instructions', '')
input_connections = self._find_node_inputs(node.get('id'), edges)
output_connections = self._find_node_outputs(node.get('id'), edges)
@@ -337,6 +344,10 @@ class WorkflowConverter:
f"**Purpose**: Provides {name.lower()} functionality to the workflow",
]
+ # Add instructions if provided
+ if instructions:
+ description.append(f"**Instructions**: {instructions}")
+
if input_connections:
description.append(f"**Connected to agents**: {', '.join(input_connections)}")
diff --git a/frontend/src/app/(dashboard)/workflows/page.tsx b/frontend/src/app/(dashboard)/workflows/page.tsx
index c65912c1..ce70aced 100644
--- a/frontend/src/app/(dashboard)/workflows/page.tsx
+++ b/frontend/src/app/(dashboard)/workflows/page.tsx
@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
-import { Plus, Play, Edit, Trash2, Clock, CheckCircle, XCircle, AlertCircle, Check, X } from "lucide-react";
+import { Plus, Play, Edit, Trash2, Clock, CheckCircle, XCircle, AlertCircle, Check, X, Workflow as WorkflowIcon } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
@@ -234,6 +234,23 @@ export default function WorkflowsPage() {
}
};
+ const getWorkflowColor = (status: string) => {
+ switch (status) {
+ case "active":
+ return "#10b981"; // green-500
+ case "draft":
+ return "#f59e0b"; // amber-500
+ case "paused":
+ return "#6b7280"; // gray-500
+ case "disabled":
+ return "#ef4444"; // red-500
+ case "archived":
+ return "#9ca3af"; // gray-400
+ default:
+ return "#8b5cf6"; // violet-500
+ }
+ };
+
if (loading) {
return (
@@ -322,91 +339,96 @@ export default function WorkflowsPage() {
) : (
{workflows.map((workflow) => (
-
-
-
-
- {editingWorkflowId === workflow.id ? (
-
-
setEditingName(e.target.value)}
- className="text-lg font-semibold h-8"
- onKeyDown={(e) => {
- if (e.key === 'Enter') {
- handleSaveEditName(workflow.id);
- } else if (e.key === 'Escape') {
- handleCancelEditName();
- }
- }}
- autoFocus
- />
-
-
-
-
-
- ) : (
-
handleStartEditName(workflow)}
- >
- {workflow.definition.name || workflow.name}
-
- )}
-
{workflow.definition.description || workflow.description}
-
- {getStatusBadge(workflow.status)}
+
+ {/* Colorful Header */}
+
+
+
-
-
-
+
+ {getStatusIcon(workflow.status)}
+
+
+
+ {/* Content */}
+
+
+ {/* Title and Status */}
+
+
+ {editingWorkflowId === workflow.id ? (
+
+
setEditingName(e.target.value)}
+ className="text-lg font-semibold h-8"
+ onKeyDown={(e) => {
+ if (e.key === 'Enter') {
+ handleSaveEditName(workflow.id);
+ } else if (e.key === 'Escape') {
+ handleCancelEditName();
+ }
+ }}
+ autoFocus
+ />
+
+
+
+
+
+ ) : (
+
handleStartEditName(workflow)}
+ >
+ {workflow.definition.name || workflow.name}
+
+ )}
+
+ {getStatusBadge(workflow.status)}
+
+
+ {workflow.definition.description || workflow.description || 'No description provided'}
+
-
-
-
+
+
))}
)}
diff --git a/frontend/src/components/workflows/NodePalette.tsx b/frontend/src/components/workflows/NodePalette.tsx
index 1c625f4b..7d3b85fb 100644
--- a/frontend/src/components/workflows/NodePalette.tsx
+++ b/frontend/src/components/workflows/NodePalette.tsx
@@ -213,15 +213,15 @@ export default function NodePalette() {
-
+
Input
-
+
Agents
-
+
Tools
@@ -257,8 +257,8 @@ export default function NodePalette() {
variables: {}
}}
>
-
-
+
+
@@ -268,12 +268,12 @@ export default function NodePalette() {
{node.name}
Required
-
+
{node.description}
-
+
);
@@ -310,9 +310,9 @@ export default function NodePalette() {
config: {},
}}
>
-
-
-
+
+
+
@@ -320,12 +320,12 @@ export default function NodePalette() {
{node.name}
-
+
{node.description}
-
+
);
@@ -361,10 +361,11 @@ export default function NodePalette() {
label: node.name,
nodeId: node.id,
config: {},
+ instructions: "",
}}
>
-
-
+
+
@@ -378,7 +379,7 @@ export default function NodePalette() {
-
+
);
diff --git a/frontend/src/components/workflows/WorkflowBuilder.tsx b/frontend/src/components/workflows/WorkflowBuilder.tsx
index bc19fb6f..fe9ef851 100644
--- a/frontend/src/components/workflows/WorkflowBuilder.tsx
+++ b/frontend/src/components/workflows/WorkflowBuilder.tsx
@@ -84,6 +84,7 @@ const initialNodes: Node[] = [
data: {
label: 'Web Search',
nodeId: 'web_search_tool',
+ instructions: '',
outputConnections: [
{
id: 'agent-1',
diff --git a/frontend/src/components/workflows/nodes/ToolConnectionNode.tsx b/frontend/src/components/workflows/nodes/ToolConnectionNode.tsx
index 0e303000..09c2a4af 100644
--- a/frontend/src/components/workflows/nodes/ToolConnectionNode.tsx
+++ b/frontend/src/components/workflows/nodes/ToolConnectionNode.tsx
@@ -1,9 +1,14 @@
"use client";
-import { memo } from "react";
+import { memo, useState } from "react";
import { Handle, Position, NodeProps } from "@xyflow/react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
+import { Button } from "@/components/ui/button";
+import { Textarea } from "@/components/ui/textarea";
+import { Label } from "@/components/ui/label";
+import { Separator } from "@/components/ui/separator";
+import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
import {
Database,
FileText,
@@ -14,18 +19,24 @@ import {
Cloud,
Send,
Settings,
- Wrench
+ Wrench,
+ ChevronDown,
+ ChevronUp
} from "lucide-react";
+import { useWorkflow } from "../WorkflowContext";
interface ToolConnectionNodeData {
label: string;
nodeId?: string;
toolType?: string;
config?: any;
+ instructions?: string;
}
-const ToolConnectionNode = memo(({ data, selected }: NodeProps) => {
+const ToolConnectionNode = memo(({ data, selected, id }: NodeProps) => {
const nodeData = data as unknown as ToolConnectionNodeData;
+ const [isConfigOpen, setIsConfigOpen] = useState(false);
+ const { updateNodeData } = useWorkflow();
const getToolConfig = () => {
const toolId = nodeData.nodeId || nodeData.toolType;
@@ -134,6 +145,49 @@ const ToolConnectionNode = memo(({ data, selected }: NodeProps) => {
Ready
+
+ {/* Show instructions preview if available */}
+ {nodeData.instructions && !isConfigOpen && (
+
+ Instructions: {nodeData.instructions.length > 50
+ ? `${nodeData.instructions.substring(0, 50)}...`
+ : nodeData.instructions}
+
+ )}
+
+
+
+ {/* Configuration Toggle */}
+
+
+
+
+
+
+ {/* Instructions Configuration */}
+
+
+
+
+