Files
aitbc/apps/marketplace/src/components/TaskDecomposition.tsx
AITBC System b033923756 chore: normalize file permissions across repository
- Remove executable permissions from configuration files (.editorconfig, .env.example, .gitignore)
- Remove executable permissions from documentation files (README.md, LICENSE, SECURITY.md)
- Remove executable permissions from web assets (HTML, CSS, JS files)
- Remove executable permissions from data files (JSON, SQL, YAML, requirements.txt)
- Remove executable permissions from source code files across all apps
- Add executable permissions to Python
2026-03-08 11:26:18 +01:00

1081 lines
42 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './ui/card';
import { Button } from './ui/button';
import { Badge } from './ui/badge';
import { Input } from './ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
import { Alert, AlertDescription, AlertTitle } from './ui/alert';
import { Progress } from './ui/progress';
import { Separator } from './ui/separator';
import {
Layers,
Play,
Pause,
Square,
Settings,
Clock,
TrendingUp,
Activity,
CheckCircle,
AlertTriangle,
XCircle,
RefreshCw,
Eye,
Cpu,
Zap,
Target,
BarChart3,
Timer,
DollarSign,
Shield,
Network,
GitBranch,
Box,
ArrowRight,
ArrowDown,
MoreHorizontal
} from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { useWallet } from '@/hooks/use-wallet';
interface SubTask {
subTaskId: string;
parentTaskId: string;
name: string;
description: string;
status: 'pending' | 'assigned' | 'in_progress' | 'completed' | 'failed' | 'cancelled';
assignedAgent?: string;
dependencies: string[];
outputs: string[];
inputs: string[];
createdAt: string;
startedAt?: string;
completedAt?: string;
errorMessage?: string;
retryCount: number;
maxRetries: number;
requirements: {
taskType: string;
estimatedDuration: number;
gpuTier: string;
memoryRequirement: number;
computeIntensity: number;
dataSize: number;
priority: number;
maxCost?: number;
};
}
interface TaskDecomposition {
originalTaskId: string;
subTasks: SubTask[];
dependencyGraph: Record<string, string[]>;
executionPlan: string[][];
estimatedTotalDuration: number;
estimatedTotalCost: number;
confidenceScore: number;
decompositionStrategy: string;
createdAt: string;
}
interface TaskAggregation {
aggregationId: string;
parentTaskId: string;
aggregationType: string;
inputSubTasks: string[];
outputFormat: string;
aggregationFunction: string;
createdAt: string;
}
const TaskDecomposition: React.FC = () => {
const { toast } = useToast();
const { isConnected, address } = useWallet();
const [decompositions, setDecompositions] = useState<TaskDecomposition[]>([]);
const [selectedDecomposition, setSelectedDecomposition] = useState<TaskDecomposition | null>(null);
const [aggregations, setAggregations] = useState<TaskAggregation[]>([]);
const [activeTab, setActiveTab] = useState('overview');
const [loading, setLoading] = useState(true);
const [decomposing, setDecomposing] = useState(false);
// Form states
const [taskDescription, setTaskDescription] = useState('');
const [taskType, setTaskType] = useState('mixed_modal');
const [estimatedDuration, setEstimatedDuration] = useState('2');
const [gpuTier, setGpuTier] = useState('mid_range_gpu');
const [memoryRequirement, setMemoryRequirement] = useState('8');
const [dataSize, setDataSize] = useState('1000');
const [priority, setPriority] = useState('5');
const [maxCost, setMaxCost] = useState('0.5');
const [strategy, setStrategy] = useState('adaptive');
const [maxSubtasks, setMaxSubtasks] = useState('10');
// Mock data for demonstration
const mockDecompositions: TaskDecomposition[] = [
{
originalTaskId: 'task_001',
subTasks: [
{
subTaskId: 'subtask_001',
parentTaskId: 'task_001',
name: 'Data Preprocessing',
description: 'Clean and preprocess input data',
status: 'completed',
assignedAgent: 'agent_001',
dependencies: [],
outputs: ['cleaned_data'],
inputs: ['raw_data'],
createdAt: '2024-01-26T14:00:00Z',
startedAt: '2024-01-26T14:00:00Z',
completedAt: '2024-01-26T14:30:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'data_analysis',
estimatedDuration: 0.5,
gpuTier: 'mid_range_gpu',
memoryRequirement: 4,
computeIntensity: 0.3,
dataSize: 500,
priority: 5,
maxCost: 0.05
}
},
{
subTaskId: 'subtask_002',
parentTaskId: 'task_001',
name: 'Feature Extraction',
description: 'Extract features from processed data',
status: 'in_progress',
assignedAgent: 'agent_002',
dependencies: ['subtask_001'],
outputs: ['features'],
inputs: ['cleaned_data'],
createdAt: '2024-01-26T14:30:00Z',
startedAt: '2024-01-26T14:35:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'model_inference',
estimatedDuration: 1.5,
gpuTier: 'high_end_gpu',
memoryRequirement: 8,
computeIntensity: 0.8,
dataSize: 300,
priority: 7,
maxCost: 0.15
}
},
{
subTaskId: 'subtask_003',
parentTaskId: 'task_001',
name: 'Result Aggregation',
description: 'Aggregate and format results',
status: 'pending',
dependencies: ['subtask_002'],
outputs: ['final_results'],
inputs: ['features'],
createdAt: '2024-01-26T14:30:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'data_analysis',
estimatedDuration: 0.3,
gpuTier: 'cpu_only',
memoryRequirement: 2,
computeIntensity: 0.2,
dataSize: 100,
priority: 3,
maxCost: 0.02
}
}
],
dependencyGraph: {
'subtask_001': [],
'subtask_002': ['subtask_001'],
'subtask_003': ['subtask_002']
},
executionPlan: [
['subtask_001'],
['subtask_002'],
['subtask_003']
],
estimatedTotalDuration: 2.3,
estimatedTotalCost: 0.22,
confidenceScore: 0.88,
decompositionStrategy: 'sequential',
createdAt: '2024-01-26T13:45:00Z'
},
{
originalTaskId: 'task_002',
subTasks: [
{
subTaskId: 'subtask_004',
parentTaskId: 'task_002',
name: 'Image Processing',
description: 'Process input images',
status: 'completed',
assignedAgent: 'agent_003',
dependencies: [],
outputs: ['processed_images'],
inputs: ['raw_images'],
createdAt: '2024-01-26T12:00:00Z',
startedAt: '2024-01-26T12:05:00Z',
completedAt: '2024-01-26T13:05:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'image_processing',
estimatedDuration: 1.0,
gpuTier: 'high_end_gpu',
memoryRequirement: 6,
computeIntensity: 0.7,
dataSize: 800,
priority: 8,
maxCost: 0.10
}
},
{
subTaskId: 'subtask_005',
parentTaskId: 'task_002',
name: 'Text Analysis',
description: 'Analyze text content',
status: 'completed',
assignedAgent: 'agent_001',
dependencies: [],
outputs: ['text_features'],
inputs: ['raw_text'],
createdAt: '2024-01-26T12:00:00Z',
startedAt: '2024-01-26T12:00:00Z',
completedAt: '2024-01-26T12:45:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'text_processing',
estimatedDuration: 0.75,
gpuTier: 'mid_range_gpu',
memoryRequirement: 4,
computeIntensity: 0.4,
dataSize: 200,
priority: 6,
maxCost: 0.04
}
},
{
subTaskId: 'subtask_006',
parentTaskId: 'task_002',
name: 'Multi-Modal Fusion',
description: 'Combine image and text features',
status: 'in_progress',
assignedAgent: 'agent_004',
dependencies: ['subtask_004', 'subtask_005'],
outputs: ['fused_features'],
inputs: ['processed_images', 'text_features'],
createdAt: '2024-01-26T13:05:00Z',
startedAt: '2024-01-26T13:10:00Z',
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: 'mixed_modal',
estimatedDuration: 1.5,
gpuTier: 'premium_gpu',
memoryRequirement: 12,
computeIntensity: 0.9,
dataSize: 1000,
priority: 9,
maxCost: 0.20
}
}
],
dependencyGraph: {
'subtask_004': [],
'subtask_005': [],
'subtask_006': ['subtask_004', 'subtask_005']
},
executionPlan: [
['subtask_004', 'subtask_005'],
['subtask_006']
],
estimatedTotalDuration: 2.5,
estimatedTotalCost: 0.34,
confidenceScore: 0.92,
decompositionStrategy: 'parallel',
createdAt: '2024-01-26T11:50:00Z'
}
];
const mockAggregations: TaskAggregation[] = [
{
aggregationId: 'agg_001',
parentTaskId: 'task_001',
aggregationType: 'concat',
inputSubTasks: ['subtask_001', 'subtask_002', 'subtask_003'],
outputFormat: 'json',
aggregationFunction: 'concatenate_results_json',
createdAt: '2024-01-26T13:45:00Z'
},
{
aggregationId: 'agg_002',
parentTaskId: 'task_002',
aggregationType: 'merge',
inputSubTasks: ['subtask_004', 'subtask_005', 'subtask_006'],
outputFormat: 'array',
aggregationFunction: 'merge_results_array',
createdAt: '2024-01-26T11:50:00Z'
}
];
useEffect(() => {
// Load mock data
setTimeout(() => {
setDecompositions(mockDecompositions);
setAggregations(mockAggregations);
if (mockDecompositions.length > 0) {
setSelectedDecomposition(mockDecompositions[0]);
}
setLoading(false);
}, 1000);
}, []);
const handleDecomposeTask = async () => {
if (!isConnected) {
toast({
title: "Wallet Not Connected",
description: "Please connect your wallet to decompose tasks",
variant: "destructive"
});
return;
}
if (!taskDescription || !taskType || !estimatedDuration) {
toast({
title: "Missing Information",
description: "Please fill in all required task details",
variant: "destructive"
});
return;
}
try {
setDecomposing(true);
toast({
title: "Decomposing Task",
description: "Analyzing task and creating sub-tasks...",
variant: "default"
});
// Simulate decomposition
await new Promise(resolve => setTimeout(resolve, 3000));
// Create new decomposition
const newDecomposition: TaskDecomposition = {
originalTaskId: `task_${Date.now()}`,
subTasks: [
{
subTaskId: `subtask_${Date.now()}_1`,
parentTaskId: `task_${Date.now()}`,
name: 'Initial Processing',
description: 'Process initial task requirements',
status: 'pending',
dependencies: [],
outputs: ['processed_data'],
inputs: ['raw_input'],
createdAt: new Date().toISOString(),
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: taskType,
estimatedDuration: parseFloat(estimatedDuration) * 0.3,
gpuTier: gpuTier,
memoryRequirement: parseInt(memoryRequirement) * 0.5,
computeIntensity: 0.5,
dataSize: parseInt(dataSize) * 0.3,
priority: parseInt(priority),
maxCost: parseFloat(maxCost) * 0.3
}
},
{
subTaskId: `subtask_${Date.now()}_2`,
parentTaskId: `task_${Date.now()}`,
name: 'Main Computation',
description: 'Execute main task computation',
status: 'pending',
dependencies: [`subtask_${Date.now()}_1`],
outputs: ['computed_results'],
inputs: ['processed_data'],
createdAt: new Date().toISOString(),
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: taskType,
estimatedDuration: parseFloat(estimatedDuration) * 0.6,
gpuTier: gpuTier,
memoryRequirement: parseInt(memoryRequirement),
computeIntensity: 0.8,
dataSize: parseInt(dataSize) * 0.6,
priority: parseInt(priority),
maxCost: parseFloat(maxCost) * 0.6
}
},
{
subTaskId: `subtask_${Date.now()}_3`,
parentTaskId: `task_${Date.now()}`,
name: 'Result Processing',
description: 'Process and format results',
status: 'pending',
dependencies: [`subtask_${Date.now()}_2`],
outputs: ['final_results'],
inputs: ['computed_results'],
createdAt: new Date().toISOString(),
retryCount: 0,
maxRetries: 3,
requirements: {
taskType: taskType,
estimatedDuration: parseFloat(estimatedDuration) * 0.1,
gpuTier: 'cpu_only',
memoryRequirement: parseInt(memoryRequirement) * 0.3,
computeIntensity: 0.2,
dataSize: parseInt(dataSize) * 0.1,
priority: parseInt(priority),
maxCost: parseFloat(maxCost) * 0.1
}
}
],
dependencyGraph: {
[`subtask_${Date.now()}_1`]: [],
[`subtask_${Date.now()}_2`]: [`subtask_${Date.now()}_1`],
[`subtask_${Date.now()}_3`]: [`subtask_${Date.now()}_2`]
},
executionPlan: [
[`subtask_${Date.now()}_1`],
[`subtask_${Date.now()}_2`],
[`subtask_${Date.now()}_3`]
],
estimatedTotalDuration: parseFloat(estimatedDuration),
estimatedTotalCost: parseFloat(maxCost),
confidenceScore: 0.85,
decompositionStrategy: strategy,
createdAt: new Date().toISOString()
};
setDecompositions([newDecomposition, ...decompositions]);
setSelectedDecomposition(newDecomposition);
setActiveTab('decompositions');
// Reset form
setTaskDescription('');
setTaskType('mixed_modal');
setEstimatedDuration('2');
setGpuTier('mid_range_gpu');
setMemoryRequirement('8');
setDataSize('1000');
setPriority('5');
setMaxCost('0.5');
setStrategy('adaptive');
setMaxSubtasks('10');
toast({
title: "Task Decomposed",
description: `Task decomposed into ${newDecomposition.subTasks.length} sub-tasks`,
variant: "default"
});
} catch (error) {
toast({
title: "Decomposition Failed",
description: "There was an error decomposing the task",
variant: "destructive"
});
} finally {
setDecomposing(false);
}
};
const getStatusColor = (status: string) => {
switch (status) {
case 'completed': return 'bg-green-500';
case 'in_progress': return 'bg-blue-500';
case 'pending': return 'bg-yellow-500';
case 'failed': return 'bg-red-500';
case 'cancelled': return 'bg-gray-500';
default: return 'bg-gray-400';
}
};
const getOverallProgress = (decomposition: TaskDecomposition) => {
const completedCount = decomposition.subTasks.filter(st => st.status === 'completed').length;
return (completedCount / decomposition.subTasks.length) * 100;
};
const renderExecutionPlan = (plan: string[][]) => {
return (
<div className="space-y-4">
{plan.map((stage, stageIndex) => (
<div key={stageIndex} className="flex items-center space-x-4">
<div className="flex flex-col items-center">
<div className="w-8 h-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center text-sm font-medium">
{stageIndex + 1}
</div>
{stageIndex < plan.length - 1 && (
<ArrowDown className="w-4 h-4 text-muted-foreground" />
)}
</div>
<div className="flex-1">
<div className="flex flex-wrap gap-2">
{stage.map((subTaskId) => {
const subTask = selectedDecomposition?.subTasks.find(st => st.subTaskId === subTaskId);
return (
<Badge key={subTaskId} variant="outline" className="flex items-center space-x-1">
<div className={`w-2 h-2 rounded-full ${getStatusColor(subTask?.status || 'pending')}`}></div>
<span>{subTask?.name || subTaskId}</span>
</Badge>
);
})}
</div>
<p className="text-xs text-muted-foreground mt-1">
{stage.length > 1 ? 'Parallel execution' : 'Sequential execution'}
</p>
</div>
</div>
))}
</div>
);
};
if (loading) {
return (
<div className="container mx-auto p-6 space-y-6">
<div className="text-center py-8">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto"></div>
<p className="mt-2 text-muted-foreground">Loading task decomposition system...</p>
</div>
</div>
);
}
return (
<div className="container mx-auto p-6 space-y-6">
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold">Task Decomposition</h1>
<p className="text-muted-foreground mt-2">
Intelligent task splitting and sub-task management system
</p>
</div>
<div className="flex items-center space-x-2">
<Badge variant="outline" className="flex items-center space-x-1">
<Layers className="w-4 h-4" />
<span>{decompositions.length} Decompositions</span>
</Badge>
<Badge variant="outline" className="flex items-center space-x-1">
<GitBranch className="w-4 h-4" />
<span>{aggregations.length} Aggregations</span>
</Badge>
</div>
</div>
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList className="grid w-full grid-cols-4">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="decompositions">Decompositions</TabsTrigger>
<TabsTrigger value="decompose">Decompose Task</TabsTrigger>
<TabsTrigger value="aggregations">Aggregations</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-6">
{/* System Statistics */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<Card>
<CardContent className="pt-6">
<div className="flex items-center space-x-2">
<Layers className="w-4 h-4 text-muted-foreground" />
<span className="text-sm font-medium">Total Decompositions</span>
</div>
<div className="text-2xl font-bold">{decompositions.length}</div>
</CardContent>
</Card>
<Card>
<CardContent className="pt-6">
<div className="flex items-center space-x-2">
<Box className="w-4 h-4 text-muted-foreground" />
<span className="text-sm font-medium">Total Sub-tasks</span>
</div>
<div className="text-2xl font-bold">
{decompositions.reduce((sum, d) => sum + d.subTasks.length, 0)}
</div>
</CardContent>
</Card>
<Card>
<CardContent className="pt-6">
<div className="flex items-center space-x-2">
<Timer className="w-4 h-4 text-muted-foreground" />
<span className="text-sm font-medium">Avg Duration</span>
</div>
<div className="text-2xl font-bold">
{(decompositions.reduce((sum, d) => sum + d.estimatedTotalDuration, 0) / decompositions.length || 0).toFixed(1)}h
</div>
</CardContent>
</Card>
<Card>
<CardContent className="pt-6">
<div className="flex items-center space-x-2">
<DollarSign className="w-4 h-4 text-muted-foreground" />
<span className="text-sm font-medium">Avg Cost</span>
</div>
<div className="text-2xl font-bold">
{(decompositions.reduce((sum, d) => sum + d.estimatedTotalCost, 0) / decompositions.length || 0).toFixed(3)} AITBC
</div>
</CardContent>
</Card>
</div>
{/* Recent Decompositions */}
<Card>
<CardHeader>
<CardTitle>Recent Task Decompositions</CardTitle>
<CardDescription>
Latest task decomposition activities
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{decompositions.slice(0, 3).map((decomposition) => (
<div key={decomposition.originalTaskId} className="flex items-center justify-between p-4 border rounded-lg">
<div className="flex items-center space-x-4">
<div className="flex flex-col items-center">
<div className="w-8 h-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center text-sm font-medium">
{decomposition.subTasks.length}
</div>
<p className="text-xs text-muted-foreground mt-1">sub-tasks</p>
</div>
<div>
<p className="font-medium">{decomposition.originalTaskId}</p>
<p className="text-sm text-muted-foreground">
{decomposition.decompositionStrategy} {decomposition.estimatedTotalDuration.toFixed(1)}h {decomposition.estimatedTotalCost.toFixed(3)} AITBC
</p>
</div>
</div>
<div className="text-right">
<div className="flex items-center space-x-2">
<Progress value={getOverallProgress(decomposition)} className="w-16 h-2" />
<span className="text-sm font-medium">{getOverallProgress(decomposition).toFixed(0)}%</span>
</div>
<p className="text-xs text-muted-foreground mt-1">
{new Date(decomposition.createdAt).toLocaleDateString()}
</p>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="decompositions" className="space-y-6">
{/* Decomposition Selection */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Decompositions List */}
<Card>
<CardHeader>
<CardTitle>Task Decompositions</CardTitle>
<CardDescription>
Available task decompositions
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{decompositions.map((decomposition) => (
<div
key={decomposition.originalTaskId}
className={`p-4 border rounded-lg cursor-pointer transition-colors ${
selectedDecomposition?.originalTaskId === decomposition.originalTaskId
? 'border-primary bg-primary/5'
: 'border-border hover:bg-muted/50'
}`}
onClick={() => setSelectedDecomposition(decomposition)}
>
<div className="flex items-center justify-between mb-2">
<h4 className="font-semibold">{decomposition.originalTaskId}</h4>
<div className="flex items-center space-x-2">
<Badge variant="outline" className="text-xs">
{decomposition.decompositionStrategy}
</Badge>
<Badge variant="outline" className="text-xs">
{(decomposition.confidenceScore * 100).toFixed(0)}% confidence
</Badge>
</div>
</div>
<div className="space-y-1 text-sm">
<div className="flex justify-between">
<span className="text-muted-foreground">Sub-tasks:</span>
<span className="font-medium">{decomposition.subTasks.length}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Duration:</span>
<span className="font-medium">{decomposition.estimatedTotalDuration.toFixed(1)}h</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Cost:</span>
<span className="font-medium">{decomposition.estimatedTotalCost.toFixed(3)} AITBC</span>
</div>
</div>
<div className="mt-2">
<div className="flex items-center space-x-2">
<Progress value={getOverallProgress(decomposition)} className="flex-1 h-2" />
<span className="text-xs font-medium">{getOverallProgress(decomposition).toFixed(0)}%</span>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
{/* Decomposition Details */}
{selectedDecomposition && (
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<GitBranch className="w-5 h-5" />
<span>{selectedDecomposition.originalTaskId}</span>
</CardTitle>
<CardDescription>
Detailed task decomposition information
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{/* Overview */}
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-muted-foreground">Strategy</p>
<p className="text-lg font-bold capitalize">{selectedDecomposition.decompositionStrategy}</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Confidence</p>
<p className="text-lg font-bold">{(selectedDecomposition.confidenceScore * 100).toFixed(1)}%</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Total Duration</p>
<p className="text-lg font-bold">{selectedDecomposition.estimatedTotalDuration.toFixed(1)}h</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Total Cost</p>
<p className="text-lg font-bold">{selectedDecomposition.estimatedTotalCost.toFixed(3)} AITBC</p>
</div>
</div>
{/* Execution Plan */}
<div>
<h4 className="font-semibold mb-3">Execution Plan</h4>
{renderExecutionPlan(selectedDecomposition.executionPlan)}
</div>
{/* Sub-tasks */}
<div>
<h4 className="font-semibold mb-3">Sub-tasks</h4>
<div className="space-y-3">
{selectedDecomposition.subTasks.map((subTask) => (
<div key={subTask.subTaskId} className="p-3 border rounded-lg">
<div className="flex items-center justify-between mb-2">
<h5 className="font-medium">{subTask.name}</h5>
<div className={`w-2 h-2 rounded-full ${getStatusColor(subTask.status)}`}></div>
</div>
<p className="text-sm text-muted-foreground mb-2">{subTask.description}</p>
<div className="grid grid-cols-2 gap-2 text-xs">
<div>
<span className="text-muted-foreground">Type:</span>
<p className="font-medium">{subTask.requirements.taskType}</p>
</div>
<div>
<span className="text-muted-foreground">Duration:</span>
<p className="font-medium">{subTask.requirements.estimatedDuration}h</p>
</div>
<div>
<span className="text-muted-foreground">GPU:</span>
<p className="font-medium capitalize">{subTask.requirements.gpuTier.replace('_', ' ')}</p>
</div>
<div>
<span className="text-muted-foreground">Memory:</span>
<p className="font-medium">{subTask.requirements.memoryRequirement}GB</p>
</div>
</div>
{subTask.assignedAgent && (
<div className="mt-2">
<span className="text-xs text-muted-foreground">Assigned to:</span>
<p className="text-sm font-medium">{subTask.assignedAgent}</p>
</div>
)}
</div>
))}
</div>
</div>
</CardContent>
</Card>
)}
</div>
</TabsContent>
<TabsContent value="decompose" className="space-y-6">
{/* Task Decomposition Form */}
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<GitBranch className="w-5 h-5" />
<span>Decompose New Task</span>
</CardTitle>
<CardDescription>
Create a new task decomposition with intelligent sub-task splitting
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<label className="text-sm font-medium">Task Description</label>
<textarea
className="w-full p-2 border rounded-lg"
rows={3}
placeholder="Describe the task to be decomposed..."
value={taskDescription}
onChange={(e) => setTaskDescription(e.target.value)}
/>
</div>
<div className="space-y-4">
<div className="space-y-2">
<label className="text-sm font-medium">Task Type</label>
<Select value={taskType} onValueChange={setTaskType}>
<SelectTrigger>
<SelectValue placeholder="Select task type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="text_processing">Text Processing</SelectItem>
<SelectItem value="image_processing">Image Processing</SelectItem>
<SelectItem value="audio_processing">Audio Processing</SelectItem>
<SelectItem value="video_processing">Video Processing</SelectItem>
<SelectItem value="data_analysis">Data Analysis</SelectItem>
<SelectItem value="model_inference">Model Inference</SelectItem>
<SelectItem value="model_training">Model Training</SelectItem>
<SelectItem value="compute_intensive">Compute Intensive</SelectItem>
<SelectItem value="io_bound">IO Bound</SelectItem>
<SelectItem value="mixed_modal">Mixed Modal</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Decomposition Strategy</label>
<Select value={strategy} onValueChange={setStrategy}>
<SelectTrigger>
<SelectValue placeholder="Select strategy" />
</SelectTrigger>
<SelectContent>
<SelectItem value="sequential">Sequential</SelectItem>
<SelectItem value="parallel">Parallel</SelectItem>
<SelectItem value="hierarchical">Hierarchical</SelectItem>
<SelectItem value="pipeline">Pipeline</SelectItem>
<SelectItem value="adaptive">Adaptive</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Estimated Duration (hours)</label>
<Input
type="number"
placeholder="Enter estimated duration"
value={estimatedDuration}
onChange={(e) => setEstimatedDuration(e.target.value)}
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">GPU Tier</label>
<Select value={gpuTier} onValueChange={setGpuTier}>
<SelectTrigger>
<SelectValue placeholder="Select GPU tier" />
</SelectTrigger>
<SelectContent>
<SelectItem value="cpu_only">CPU Only</SelectItem>
<SelectItem value="low_end_gpu">Low-end GPU</SelectItem>
<SelectItem value="mid_range_gpu">Mid-range GPU</SelectItem>
<SelectItem value="high_end_gpu">High-end GPU</SelectItem>
<SelectItem value="premium_gpu">Premium GPU</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Memory Requirement (GB)</label>
<Input
type="number"
placeholder="Enter memory requirement"
value={memoryRequirement}
onChange={(e) => setMemoryRequirement(e.target.value)}
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Data Size (MB)</label>
<Input
type="number"
placeholder="Enter data size"
value={dataSize}
onChange={(e) => setDataSize(e.target.value)}
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Priority (1-10)</label>
<Input
type="number"
min="1"
max="10"
placeholder="Enter priority"
value={priority}
onChange={(e) => setPriority(e.target.value)}
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Maximum Cost (AITBC)</label>
<Input
type="number"
placeholder="Enter maximum cost"
value={maxCost}
onChange={(e) => setMaxCost(e.target.value)}
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Maximum Sub-tasks</label>
<Input
type="number"
placeholder="Enter maximum sub-tasks"
value={maxSubtasks}
onChange={(e) => setMaxSubtasks(e.target.value)}
/>
</div>
</div>
<Button
onClick={handleDecomposeTask}
className="w-full"
disabled={decomposing}
>
{decomposing ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
Decomposing...
</>
) : (
<>
<GitBranch className="w-4 h-4 mr-2" />
Decompose Task
</>
)}
</Button>
</CardContent>
</Card>
{/* Strategy Information */}
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<Settings className="w-5 h-5" />
<span>Decomposition Strategies</span>
</CardTitle>
<CardDescription>
Available task decomposition strategies
</CardDescription>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div className="p-4 border rounded-lg">
<h4 className="font-semibold mb-2">Sequential</h4>
<p className="text-sm text-muted-foreground">
Tasks are executed one after another in a linear sequence
</p>
</div>
<div className="p-4 border rounded-lg">
<h4 className="font-semibold mb-2">Parallel</h4>
<p className="text-sm text-muted-foreground">
Tasks are executed simultaneously when possible
</p>
</div>
<div className="p-4 border rounded-lg">
<h4 className="font-semibold mb-2">Hierarchical</h4>
<p className="text-sm text-muted-foreground">
Tasks are organized in a hierarchical structure
</p>
</div>
<div className="p-4 border rounded-lg">
<h4 className="font-semibold mb-2">Pipeline</h4>
<p className="text-sm text-muted-foreground">
Tasks flow through predefined processing stages
</p>
</div>
<div className="p-4 border rounded-lg">
<h4 className="font-semibold mb-2">Adaptive</h4>
<p className="text-sm text-muted-foreground">
Strategy is selected based on task characteristics
</p>
</div>
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="aggregations" className="space-y-6">
{/* Aggregation List */}
<Card>
<CardHeader>
<CardTitle className="flex items-center space-x-2">
<Layers className="w-5 h-5" />
<span>Task Aggregations</span>
</CardTitle>
<CardDescription>
Result aggregation configurations for completed sub-tasks
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-4">
{aggregations.map((aggregation) => (
<div key={aggregation.aggregationId} className="p-4 border rounded-lg">
<div className="flex items-center justify-between mb-2">
<h4 className="font-semibold">{aggregation.aggregationId}</h4>
<Badge variant="outline">{aggregation.aggregationType}</Badge>
</div>
<div className="space-y-2 text-sm">
<div>
<span className="text-muted-foreground">Parent Task:</span>
<p className="font-medium">{aggregation.parentTaskId}</p>
</div>
<div>
<span className="text-muted-foreground">Input Sub-tasks:</span>
<p className="font-medium">{aggregation.inputSubTasks.join(', ')}</p>
</div>
<div>
<span className="text-muted-foreground">Output Format:</span>
<p className="font-medium">{aggregation.outputFormat}</p>
</div>
<div>
<span className="text-muted-foreground">Function:</span>
<p className="font-medium">{aggregation.aggregationFunction}</p>
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
);
};
export default TaskDecomposition;