Files
breakpilot-lehrer/admin-lehrer/app/api/admin/agents/[agentId]/soul/route.ts
Benjamin Boenisch 5a31f52310 Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:26 +01:00

188 lines
5.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import * as fs from 'fs/promises'
import * as path from 'path'
/**
* Agent SOUL File API
*
* GET - Get SOUL file content
* PUT - Update SOUL file content
* GET /history - Get version history
*/
const AGENT_CORE_PATH = process.env.AGENT_CORE_PATH || '/app/agent-core'
const SOUL_PATH = path.join(AGENT_CORE_PATH, 'soul')
interface SoulVersion {
version: string
timestamp: string
content: string
author: string
changes: string
}
// Read SOUL file content
async function readSoulFile(agentId: string): Promise<string | null> {
const soulFile = `${agentId}.soul.md`
const soulFilePath = path.join(SOUL_PATH, soulFile)
try {
const content = await fs.readFile(soulFilePath, 'utf-8')
return content
} catch {
return null
}
}
// Get version history from backup directory
async function getVersionHistory(agentId: string): Promise<SoulVersion[]> {
const backupDir = path.join(SOUL_PATH, '.backups')
const versions: SoulVersion[] = []
try {
const files = await fs.readdir(backupDir)
const agentBackups = files.filter(f => f.startsWith(`${agentId}-`) && f.endsWith('.soul.md'))
for (const file of agentBackups.slice(-10)) { // Last 10 versions
const filePath = path.join(backupDir, file)
const stats = await fs.stat(filePath)
const content = await fs.readFile(filePath, 'utf-8')
// Extract timestamp from filename
const match = file.match(/-(\d+)\.soul\.md$/)
const timestamp = match ? new Date(parseInt(match[1])).toISOString() : stats.mtime.toISOString()
versions.push({
version: file.replace('.soul.md', ''),
timestamp,
content,
author: 'Admin',
changes: 'Manual update'
})
}
// Sort by timestamp descending
versions.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())
} catch {
// No backup directory or can't read
}
return versions
}
// GET - Get SOUL file content
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ agentId: string }> }
) {
try {
const { agentId } = await params
const url = new URL(request.url)
const includeHistory = url.searchParams.get('history') === 'true'
const content = await readSoulFile(agentId)
if (!content) {
return NextResponse.json(
{ error: 'SOUL file not found' },
{ status: 404 }
)
}
const soulFile = `${agentId}.soul.md`
const soulFilePath = path.join(SOUL_PATH, soulFile)
const stats = await fs.stat(soulFilePath)
const response: {
agentId: string
soulFile: string
content: string
updatedAt: string
size: number
history?: SoulVersion[]
} = {
agentId,
soulFile,
content,
updatedAt: stats.mtime.toISOString(),
size: stats.size
}
if (includeHistory) {
response.history = await getVersionHistory(agentId)
}
return NextResponse.json(response)
} catch (error) {
console.error('Error fetching SOUL file:', error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to fetch SOUL file' },
{ status: 500 }
)
}
}
// PUT - Update SOUL file content
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ agentId: string }> }
) {
try {
const { agentId } = await params
const body = await request.json()
const { content, author, changeDescription } = body
if (!content) {
return NextResponse.json(
{ error: 'content is required' },
{ status: 400 }
)
}
const soulFile = `${agentId}.soul.md`
const soulFilePath = path.join(SOUL_PATH, soulFile)
// Check if file exists
try {
await fs.access(soulFilePath)
} catch {
return NextResponse.json(
{ error: 'SOUL file not found' },
{ status: 404 }
)
}
// Create backup before updating
const backupDir = path.join(SOUL_PATH, '.backups')
const backupPath = path.join(backupDir, `${agentId}-${Date.now()}.soul.md`)
try {
await fs.mkdir(backupDir, { recursive: true })
const currentContent = await fs.readFile(soulFilePath, 'utf-8')
await fs.writeFile(backupPath, currentContent, 'utf-8')
} catch (backupError) {
console.warn('Failed to create backup:', backupError)
}
// Write new content
await fs.writeFile(soulFilePath, content, 'utf-8')
const stats = await fs.stat(soulFilePath)
return NextResponse.json({
success: true,
message: `SOUL file for ${agentId} updated successfully`,
agentId,
soulFile,
updatedAt: stats.mtime.toISOString(),
size: stats.size,
author: author || 'Admin',
changeDescription: changeDescription || 'Manual update'
})
} catch (error) {
console.error('Error updating SOUL file:', error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to update SOUL file' },
{ status: 500 }
)
}
}