Der Compliance Advisor gehoert ins Compliance SDK (macmini:3007/sdk/agents), nicht ins Lehrer-Admin. Die verbleibenden 5 Agenten (TutorAgent, GraderAgent, QualityJudge, AlertAgent, Orchestrator) bleiben erhalten. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
378 lines
14 KiB
TypeScript
378 lines
14 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import Link from 'next/link'
|
|
import { Bot, Activity, Brain, Settings, FileText, BarChart3, Clock, AlertTriangle, CheckCircle, Pause, XCircle, ChevronRight, Cpu, MessageSquare, Database, RefreshCw } from 'lucide-react'
|
|
|
|
// Agent types
|
|
interface AgentConfig {
|
|
id: string
|
|
name: string
|
|
description: string
|
|
soulFile: string
|
|
color: string
|
|
icon: 'bot' | 'brain' | 'message' | 'alert' | 'settings'
|
|
status: 'running' | 'paused' | 'stopped' | 'error'
|
|
activeSessions: number
|
|
totalProcessed: number
|
|
avgResponseTime: number
|
|
lastActivity: string
|
|
}
|
|
|
|
interface AgentStats {
|
|
totalSessions: number
|
|
activeSessions: number
|
|
totalMessages: number
|
|
avgLatency: number
|
|
errorRate: number
|
|
memoryUsage: number
|
|
}
|
|
|
|
// Mock data - In production, fetch from API
|
|
const mockAgents: AgentConfig[] = [
|
|
{
|
|
id: 'tutor-agent',
|
|
name: 'TutorAgent',
|
|
description: 'Lernbegleitung und Fragen beantworten',
|
|
soulFile: 'tutor-agent.soul.md',
|
|
color: '#3b82f6',
|
|
icon: 'brain',
|
|
status: 'running',
|
|
activeSessions: 12,
|
|
totalProcessed: 1847,
|
|
avgResponseTime: 234,
|
|
lastActivity: '2 min ago'
|
|
},
|
|
{
|
|
id: 'grader-agent',
|
|
name: 'GraderAgent',
|
|
description: 'Klausur-Korrektur und Bewertung',
|
|
soulFile: 'grader-agent.soul.md',
|
|
color: '#10b981',
|
|
icon: 'bot',
|
|
status: 'running',
|
|
activeSessions: 3,
|
|
totalProcessed: 456,
|
|
avgResponseTime: 1205,
|
|
lastActivity: '5 min ago'
|
|
},
|
|
{
|
|
id: 'quality-judge',
|
|
name: 'QualityJudge',
|
|
description: 'BQAS Qualitaetspruefung',
|
|
soulFile: 'quality-judge.soul.md',
|
|
color: '#f59e0b',
|
|
icon: 'settings',
|
|
status: 'running',
|
|
activeSessions: 8,
|
|
totalProcessed: 3291,
|
|
avgResponseTime: 89,
|
|
lastActivity: '1 min ago'
|
|
},
|
|
{
|
|
id: 'alert-agent',
|
|
name: 'AlertAgent',
|
|
description: 'Monitoring und Benachrichtigungen',
|
|
soulFile: 'alert-agent.soul.md',
|
|
color: '#ef4444',
|
|
icon: 'alert',
|
|
status: 'running',
|
|
activeSessions: 1,
|
|
totalProcessed: 892,
|
|
avgResponseTime: 45,
|
|
lastActivity: '30 sec ago'
|
|
},
|
|
{
|
|
id: 'orchestrator',
|
|
name: 'Orchestrator',
|
|
description: 'Task-Koordination und Routing',
|
|
soulFile: 'orchestrator.soul.md',
|
|
color: '#8b5cf6',
|
|
icon: 'message',
|
|
status: 'running',
|
|
activeSessions: 24,
|
|
totalProcessed: 8934,
|
|
avgResponseTime: 12,
|
|
lastActivity: 'just now'
|
|
}
|
|
]
|
|
|
|
const mockStats: AgentStats = {
|
|
totalSessions: 156,
|
|
activeSessions: 48,
|
|
totalMessages: 15420,
|
|
avgLatency: 156,
|
|
errorRate: 0.8,
|
|
memoryUsage: 67
|
|
}
|
|
|
|
function getIconComponent(icon: string, className: string) {
|
|
switch(icon) {
|
|
case 'bot': return <Bot className={className} />
|
|
case 'brain': return <Brain className={className} />
|
|
case 'message': return <MessageSquare className={className} />
|
|
case 'alert': return <AlertTriangle className={className} />
|
|
case 'settings': return <Settings className={className} />
|
|
default: return <Bot className={className} />
|
|
}
|
|
}
|
|
|
|
function getStatusIcon(status: string) {
|
|
switch(status) {
|
|
case 'running': return <CheckCircle className="w-4 h-4 text-green-500" />
|
|
case 'paused': return <Pause className="w-4 h-4 text-yellow-500" />
|
|
case 'stopped': return <XCircle className="w-4 h-4 text-gray-500" />
|
|
case 'error': return <AlertTriangle className="w-4 h-4 text-red-500" />
|
|
default: return null
|
|
}
|
|
}
|
|
|
|
function getStatusColor(status: string) {
|
|
switch(status) {
|
|
case 'running': return 'bg-green-500/10 text-green-600 border-green-500/20'
|
|
case 'paused': return 'bg-yellow-500/10 text-yellow-600 border-yellow-500/20'
|
|
case 'stopped': return 'bg-gray-500/10 text-gray-600 border-gray-500/20'
|
|
case 'error': return 'bg-red-500/10 text-red-600 border-red-500/20'
|
|
default: return 'bg-gray-500/10 text-gray-600 border-gray-500/20'
|
|
}
|
|
}
|
|
|
|
export default function AgentManagementPage() {
|
|
const [agents, setAgents] = useState<AgentConfig[]>(mockAgents)
|
|
const [stats, setStats] = useState<AgentStats>(mockStats)
|
|
const [loading, setLoading] = useState(false)
|
|
const [lastRefresh, setLastRefresh] = useState(new Date())
|
|
|
|
const refreshData = async () => {
|
|
setLoading(true)
|
|
// In production, fetch from API
|
|
// const response = await fetch('/api/admin/agents/status')
|
|
await new Promise(resolve => setTimeout(resolve, 500))
|
|
setLastRefresh(new Date())
|
|
setLoading(false)
|
|
}
|
|
|
|
useEffect(() => {
|
|
// Auto-refresh every 30 seconds
|
|
const interval = setInterval(refreshData, 30000)
|
|
return () => clearInterval(interval)
|
|
}, [])
|
|
|
|
return (
|
|
<div className="p-6 max-w-7xl mx-auto">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between mb-8">
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-gray-900 flex items-center gap-3">
|
|
<div className="p-2 bg-teal-100 rounded-lg">
|
|
<Bot className="w-6 h-6 text-teal-600" />
|
|
</div>
|
|
Agent Management
|
|
</h1>
|
|
<p className="text-gray-500 mt-1">
|
|
Multi-Agent System verwalten, SOUL-Files bearbeiten, Statistiken analysieren
|
|
</p>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-sm text-gray-500">
|
|
Letzte Aktualisierung: {lastRefresh.toLocaleTimeString('de-DE')}
|
|
</span>
|
|
<button
|
|
onClick={refreshData}
|
|
disabled={loading}
|
|
className="flex items-center gap-2 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 transition-colors disabled:opacity-50"
|
|
>
|
|
<RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
|
|
Aktualisieren
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Quick Links */}
|
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
|
|
<Link
|
|
href="/ai/agents/architecture"
|
|
className="flex items-center gap-3 p-4 bg-white border border-gray-200 rounded-xl hover:border-teal-300 hover:shadow-md transition-all group"
|
|
>
|
|
<div className="p-2 bg-purple-100 rounded-lg group-hover:bg-purple-200 transition-colors">
|
|
<FileText className="w-5 h-5 text-purple-600" />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-gray-900">Architektur</div>
|
|
<div className="text-sm text-gray-500">Dokumentation & Diagramme</div>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-gray-400 ml-auto" />
|
|
</Link>
|
|
|
|
<Link
|
|
href="/ai/agents/sessions"
|
|
className="flex items-center gap-3 p-4 bg-white border border-gray-200 rounded-xl hover:border-teal-300 hover:shadow-md transition-all group"
|
|
>
|
|
<div className="p-2 bg-blue-100 rounded-lg group-hover:bg-blue-200 transition-colors">
|
|
<Activity className="w-5 h-5 text-blue-600" />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-gray-900">Sessions</div>
|
|
<div className="text-sm text-gray-500">{stats.activeSessions} aktiv</div>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-gray-400 ml-auto" />
|
|
</Link>
|
|
|
|
<Link
|
|
href="/ai/agents/statistics"
|
|
className="flex items-center gap-3 p-4 bg-white border border-gray-200 rounded-xl hover:border-teal-300 hover:shadow-md transition-all group"
|
|
>
|
|
<div className="p-2 bg-green-100 rounded-lg group-hover:bg-green-200 transition-colors">
|
|
<BarChart3 className="w-5 h-5 text-green-600" />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-gray-900">Statistiken</div>
|
|
<div className="text-sm text-gray-500">Performance & Trends</div>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-gray-400 ml-auto" />
|
|
</Link>
|
|
|
|
<Link
|
|
href="/ai/test-quality"
|
|
className="flex items-center gap-3 p-4 bg-white border border-gray-200 rounded-xl hover:border-teal-300 hover:shadow-md transition-all group"
|
|
>
|
|
<div className="p-2 bg-amber-100 rounded-lg group-hover:bg-amber-200 transition-colors">
|
|
<Cpu className="w-5 h-5 text-amber-600" />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-gray-900">BQAS</div>
|
|
<div className="text-sm text-gray-500">Qualitaetssicherung</div>
|
|
</div>
|
|
<ChevronRight className="w-5 h-5 text-gray-400 ml-auto" />
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Stats Overview */}
|
|
<div className="grid grid-cols-2 md:grid-cols-6 gap-4 mb-8">
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Gesamt Sessions</div>
|
|
<div className="text-2xl font-bold text-gray-900">{stats.totalSessions.toLocaleString()}</div>
|
|
</div>
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Aktive Sessions</div>
|
|
<div className="text-2xl font-bold text-green-600">{stats.activeSessions}</div>
|
|
</div>
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Nachrichten (24h)</div>
|
|
<div className="text-2xl font-bold text-gray-900">{stats.totalMessages.toLocaleString()}</div>
|
|
</div>
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Avg. Latenz</div>
|
|
<div className="text-2xl font-bold text-gray-900">{stats.avgLatency}ms</div>
|
|
</div>
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Fehlerrate</div>
|
|
<div className="text-2xl font-bold text-amber-600">{stats.errorRate}%</div>
|
|
</div>
|
|
<div className="bg-white border border-gray-200 rounded-xl p-4">
|
|
<div className="text-sm text-gray-500 mb-1">Memory Usage</div>
|
|
<div className="text-2xl font-bold text-gray-900">{stats.memoryUsage}%</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Agents Grid */}
|
|
<div className="mb-6">
|
|
<h2 className="text-lg font-semibold text-gray-900 mb-4">Agents</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
{agents.map((agent) => (
|
|
<Link
|
|
key={agent.id}
|
|
href={`/ai/agents/${agent.id}`}
|
|
className="bg-white border border-gray-200 rounded-xl p-5 hover:border-teal-300 hover:shadow-lg transition-all group"
|
|
>
|
|
{/* Header */}
|
|
<div className="flex items-start justify-between mb-4">
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className="p-2.5 rounded-lg"
|
|
style={{ backgroundColor: `${agent.color}20` }}
|
|
>
|
|
{getIconComponent(agent.icon, `w-5 h-5`)}
|
|
<style jsx>{`
|
|
svg { color: ${agent.color}; }
|
|
`}</style>
|
|
</div>
|
|
<div>
|
|
<h3 className="font-semibold text-gray-900 group-hover:text-teal-600 transition-colors">
|
|
{agent.name}
|
|
</h3>
|
|
<p className="text-sm text-gray-500">{agent.description}</p>
|
|
</div>
|
|
</div>
|
|
<div className={`flex items-center gap-1.5 px-2 py-1 rounded-full text-xs font-medium border ${getStatusColor(agent.status)}`}>
|
|
{getStatusIcon(agent.status)}
|
|
{agent.status}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Stats */}
|
|
<div className="grid grid-cols-3 gap-3 mb-4">
|
|
<div className="text-center p-2 bg-gray-50 rounded-lg">
|
|
<div className="text-lg font-semibold text-gray-900">{agent.activeSessions}</div>
|
|
<div className="text-xs text-gray-500">Sessions</div>
|
|
</div>
|
|
<div className="text-center p-2 bg-gray-50 rounded-lg">
|
|
<div className="text-lg font-semibold text-gray-900">{agent.totalProcessed}</div>
|
|
<div className="text-xs text-gray-500">Verarbeitet</div>
|
|
</div>
|
|
<div className="text-center p-2 bg-gray-50 rounded-lg">
|
|
<div className="text-lg font-semibold text-gray-900">{agent.avgResponseTime}ms</div>
|
|
<div className="text-xs text-gray-500">Avg. Zeit</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex items-center justify-between pt-3 border-t border-gray-100">
|
|
<div className="flex items-center gap-2 text-sm text-gray-500">
|
|
<FileText className="w-4 h-4" />
|
|
{agent.soulFile}
|
|
</div>
|
|
<div className="flex items-center gap-1 text-sm text-gray-400">
|
|
<Clock className="w-3.5 h-3.5" />
|
|
{agent.lastActivity}
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Info Box */}
|
|
<div className="bg-teal-50 border border-teal-200 rounded-xl p-5">
|
|
<div className="flex gap-4">
|
|
<div className="p-2 bg-teal-100 rounded-lg h-fit">
|
|
<Brain className="w-5 h-5 text-teal-600" />
|
|
</div>
|
|
<div>
|
|
<h3 className="font-semibold text-teal-900 mb-2">Multi-Agent Architektur</h3>
|
|
<p className="text-sm text-teal-700 mb-3">
|
|
Das Breakpilot Multi-Agent-System basiert auf dem Mission Control Konzept. Jeder Agent hat eine
|
|
definierte Persoenlichkeit (SOUL-File), die sein Verhalten steuert. Die Agents kommunizieren
|
|
ueber einen Message Bus und nutzen ein gemeinsames Gedaechtnis (Shared Brain).
|
|
</p>
|
|
<div className="flex gap-3">
|
|
<Link
|
|
href="/ai/agents/architecture"
|
|
className="text-sm font-medium text-teal-600 hover:text-teal-800"
|
|
>
|
|
Architektur ansehen →
|
|
</Link>
|
|
<Link
|
|
href="/ai/agents/architecture#soul-files"
|
|
className="text-sm font-medium text-teal-600 hover:text-teal-800"
|
|
>
|
|
SOUL-Files verstehen →
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|