import React, { useState, useCallback } from 'react';
import {
ReactFlow,
Controls,
Background,
applyNodeChanges,
applyEdgeChanges,
addEdge,
Node,
Edge,
OnNodesChange,
OnEdgesChange,
OnConnect,
NodeTypes,
Handle,
Position,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import { Bot, Play, Save, Plus, Settings } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';
import { API_URL } from '@/config/api';
// Custom Node Component
const AgentNode = ({ data }: { data: { label: string; role?: string } }) => {
return (
{data.label}
{data.role || 'General Agent'}
);
};
const nodeTypes: NodeTypes = {
agent: AgentNode,
};
const initialNodes: Node[] = [
{
id: '1',
type: 'agent',
data: { label: 'Orchestrator', role: 'Supervisor' },
position: { x: 250, y: 5 },
},
];
const initialEdges: Edge[] = [];
export default function AgentFlowWidget() {
const [nodes, setNodes] = useState(initialNodes);
const [edges, setEdges] = useState(initialEdges);
const [isRunning, setIsRunning] = useState(false);
const onNodesChange: OnNodesChange = useCallback(
(changes) => setNodes((nds) => applyNodeChanges(changes, nds)),
[],
);
const onEdgesChange: OnEdgesChange = useCallback(
(changes) => setEdges((eds) => applyEdgeChanges(changes, eds)),
[],
);
const onConnect: OnConnect = useCallback(
(params) => setEdges((eds) => addEdge(params, eds)),
[],
);
const addAgent = () => {
const id = `agent-${nodes.length + 1}`;
const newNode: Node = {
id,
type: 'agent',
data: { label: `Agent ${nodes.length + 1}`, role: 'Worker' },
position: { x: Math.random() * 400, y: Math.random() * 400 },
};
setNodes((nds) => [...nds, newNode]);
};
const runFlow = async () => {
setIsRunning(true);
try {
// Prepare payload for backend
const workflowPayload = {
workflow: {
nodes: nodes.map(n => ({ id: n.id, type: n.type, data: n.data })),
edges: edges.map(e => ({ source: e.source, target: e.target }))
}
};
// Call the backend handler (this matches the structure found in toolHandlers.ts)
// Note: In a real app, this would be a proper API call or WebSocket event
console.log('Running workflow:', workflowPayload);
// Simulation
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
console.error('Flow execution failed:', error);
} finally {
setIsRunning(false);
}
};
return (
{/* Header */}
Agent Flow Builder
{isRunning ? "EXECUTING" : "DESIGN MODE"}
{/* Canvas */}
);
}