feat: Agent Management Modul — SOUL-Editor, Dashboard, Architektur-Doku
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 38s
CI / test-python-document-crawler (push) Successful in 24s
CI / test-python-dsms-gateway (push) Successful in 19s

- SOUL-Dateien: System-Prompts aus Chat-Routen extrahiert nach agent-core/soul/*.soul.md
- soul-reader.ts: Lese-/Schreib-API mit 30s TTL-Cache und Backup-Versionierung
- agent-registry.ts: Statische Konfiguration der 2 Compliance-Agenten
- 5 API-Routen: /api/sdk/agents (Liste, Detail, SOUL GET/PUT, Sessions, Statistiken)
- 5 Frontend-Seiten: Dashboard, Detail mit SOUL-Editor, Architektur, Sessions, Statistiken
- Sidebar: "Agenten" Link nach Architektur eingefügt
- Wire-Up: compliance-advisor + drafting-engine lesen SOUL-Datei mit Fallback
- Dockerfile: agent-core wird in Production-Image kopiert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-04 16:53:36 +01:00
parent dd404da6cd
commit 560bdfb7fd
19 changed files with 1363 additions and 99 deletions

View File

@@ -0,0 +1,37 @@
/**
* GET /api/sdk/agents/[agentId] — Agent-Detail mit SOUL-Content
*/
import { NextRequest, NextResponse } from 'next/server'
import { getAgentById } from '@/lib/sdk/agents/agent-registry'
import { readSoulFile, getSoulFileStats, soulFileExists } from '@/lib/sdk/agents/soul-reader'
export async function GET(
_request: NextRequest,
{ params }: { params: Promise<{ agentId: string }> }
) {
try {
const { agentId } = await params
const agent = getAgentById(agentId)
if (!agent) {
return NextResponse.json({ error: 'Agent not found' }, { status: 404 })
}
const exists = await soulFileExists(agentId)
const soulContent = await readSoulFile(agentId)
const fileStats = await getSoulFileStats(agentId)
return NextResponse.json({
...agent,
status: exists ? agent.status : 'error',
soulContent: soulContent || '',
createdAt: fileStats?.createdAt || null,
updatedAt: fileStats?.updatedAt || null,
fileSize: fileStats?.size || 0,
})
} catch (error) {
console.error('Error fetching agent detail:', error)
return NextResponse.json({ error: 'Failed to fetch agent' }, { status: 500 })
}
}

View File

@@ -0,0 +1,84 @@
/**
* GET/PUT /api/sdk/agents/[agentId]/soul — SOUL-Datei lesen/schreiben
*
* GET: Content + Metadaten, ?history=true fuer Backup-Versionen
* PUT: Backup erstellen -> neuen Content schreiben -> Cache invalidieren
*/
import { NextRequest, NextResponse } from 'next/server'
import { getAgentById } from '@/lib/sdk/agents/agent-registry'
import {
readSoulFile,
writeSoulFile,
listSoulBackups,
getSoulFileStats,
} from '@/lib/sdk/agents/soul-reader'
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ agentId: string }> }
) {
try {
const { agentId } = await params
const agent = getAgentById(agentId)
if (!agent) {
return NextResponse.json({ error: 'Agent not found' }, { status: 404 })
}
const showHistory = request.nextUrl.searchParams.get('history') === 'true'
if (showHistory) {
const backups = await listSoulBackups(agentId)
return NextResponse.json({ agentId, backups })
}
const content = await readSoulFile(agentId)
const fileStats = await getSoulFileStats(agentId)
return NextResponse.json({
agentId,
content: content || '',
updatedAt: fileStats?.updatedAt || null,
size: fileStats?.size || 0,
})
} catch (error) {
console.error('Error reading SOUL file:', error)
return NextResponse.json({ error: 'Failed to read SOUL file' }, { status: 500 })
}
}
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ agentId: string }> }
) {
try {
const { agentId } = await params
const agent = getAgentById(agentId)
if (!agent) {
return NextResponse.json({ error: 'Agent not found' }, { status: 404 })
}
const body = await request.json()
const { content } = body
if (typeof content !== 'string' || content.trim().length === 0) {
return NextResponse.json({ error: 'Content is required' }, { status: 400 })
}
await writeSoulFile(agentId, content)
const fileStats = await getSoulFileStats(agentId)
return NextResponse.json({
agentId,
updatedAt: fileStats?.updatedAt || new Date().toISOString(),
size: fileStats?.size || content.length,
message: 'SOUL file updated successfully',
})
} catch (error) {
console.error('Error writing SOUL file:', error)
return NextResponse.json({ error: 'Failed to write SOUL file' }, { status: 500 })
}
}

View File

@@ -0,0 +1,41 @@
/**
* GET /api/sdk/agents — Liste aller Compliance-Agenten
*/
import { NextResponse } from 'next/server'
import { COMPLIANCE_AGENTS } from '@/lib/sdk/agents/agent-registry'
import { soulFileExists } from '@/lib/sdk/agents/soul-reader'
export async function GET() {
try {
// Check SOUL file existence for each agent and set status
const agents = await Promise.all(
COMPLIANCE_AGENTS.map(async (agent) => {
const exists = await soulFileExists(agent.id)
return {
...agent,
status: exists ? agent.status : 'error' as const,
}
})
)
const activeCount = agents.filter(a => a.status === 'active').length
const errorCount = agents.filter(a => a.status === 'error').length
return NextResponse.json({
agents,
stats: {
total: agents.length,
active: activeCount,
inactive: agents.length - activeCount - errorCount,
error: errorCount,
totalSessions: 0,
avgResponseTime: '—',
},
timestamp: new Date().toISOString(),
})
} catch (error) {
console.error('Error fetching agents:', error)
return NextResponse.json({ error: 'Failed to fetch agents' }, { status: 500 })
}
}

View File

@@ -0,0 +1,13 @@
/**
* GET /api/sdk/agents/sessions — Agent-Sessions (Placeholder)
*/
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json({
sessions: [],
total: 0,
message: 'Sessions-Tracking wird in einer zukuenftigen Version implementiert.',
})
}

View File

@@ -0,0 +1,18 @@
/**
* GET /api/sdk/agents/statistics — Agent-Statistiken (Placeholder)
*/
import { NextResponse } from 'next/server'
export async function GET() {
return NextResponse.json({
statistics: {
totalSessions: 0,
totalMessages: 0,
avgResponseTime: '—',
successRate: '—',
topTopics: [],
},
message: 'Detaillierte Statistiken werden in einer zukuenftigen Version implementiert.',
})
}