Files
breakpilot-core/pitch-deck/components/slides/AIPipelineSlide.tsx
Benjamin Boenisch b7d21daa24
All checks were successful
CI / test-bqas (push) Successful in 32s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 46s
CI / test-python-voice (push) Successful in 38s
feat: Add DevSecOps tools, Woodpecker proxy, Vault persistent storage, pitch-deck annex slides
- Install Gitleaks, Trivy, Grype, Syft, Semgrep, Bandit in backend-core Dockerfile
- Add Woodpecker SQLite proxy API (fallback without API token)
- Mount woodpecker_data volume read-only to backend-core
- Add backend proxy fallback in admin-core Woodpecker route
- Add Vault file-based persistent storage (config.hcl, init-vault.sh)
- Auto-init, unseal and root-token persistence for Vault
- Add 6 pitch-deck annex slides (Assumptions, Architecture, GTM, Regulatory, Engineering, AI Pipeline)
- Dynamic margin/amortization KPIs in BusinessModelSlide
- Market sources modal with citations in MarketSlide
- Redesign nginx landing page to 3-column layout (Lehrer/Compliance/Core)
- Extend MkDocs nav with Services and SDK documentation sections
- Add SDK Protection architecture doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:42:43 +01:00

330 lines
17 KiB
TypeScript

'use client'
import { useState } from 'react'
import { Language } from '@/lib/types'
import { t } from '@/lib/i18n'
import GradientText from '../ui/GradientText'
import FadeInView from '../ui/FadeInView'
import GlassCard from '../ui/GlassCard'
import {
Brain,
Search,
Database,
FileText,
Bot,
Zap,
Layers,
ArrowRight,
Activity,
Shield,
Cpu,
MessageSquare,
Eye,
Gauge,
Network,
Sparkles,
} from 'lucide-react'
interface AIPipelineSlideProps {
lang: Language
}
type PipelineTab = 'rag' | 'agents' | 'quality'
export default function AIPipelineSlide({ lang }: AIPipelineSlideProps) {
const i = t(lang)
const de = lang === 'de'
const [activeTab, setActiveTab] = useState<PipelineTab>('rag')
const heroStats = [
{ value: '19', label: de ? 'Indexierte Verordnungen' : 'Indexed Regulations', sub: 'DSGVO · AI Act · NIS2 · CRA · ePrivacy · ...', color: 'text-indigo-400' },
{ value: '7', label: de ? 'Autonome Agenten' : 'Autonomous Agents', sub: de ? 'SOUL-basiert · Orchestriert' : 'SOUL-based · Orchestrated', color: 'text-purple-400' },
{ value: '5', label: de ? 'KI-Modelle lokal' : 'Local AI Models', sub: 'Llama 3.2 · Qwen 2.5 · BGE-M3 · TrOCR · CrossEncoder', color: 'text-emerald-400' },
{ value: '97', label: de ? 'Golden-Suite Tests' : 'Golden Suite Tests', sub: de ? 'Automatische Qualitaetssicherung' : 'Automatic Quality Assurance', color: 'text-amber-400' },
]
const tabs: { id: PipelineTab; label: string; icon: typeof Brain }[] = [
{ id: 'rag', label: de ? 'RAG-Pipeline' : 'RAG Pipeline', icon: Search },
{ id: 'agents', label: de ? 'Multi-Agent-System' : 'Multi-Agent System', icon: Bot },
{ id: 'quality', label: de ? 'Qualitaetssicherung' : 'Quality Assurance', icon: Gauge },
]
// RAG Pipeline content
const ragPipelineSteps = [
{
icon: FileText,
color: 'text-blue-400',
bg: 'bg-blue-500/10 border-blue-500/20',
title: de ? '1. Ingestion' : '1. Ingestion',
items: de
? ['PDF-Upload, URL-Crawling, API-Import', 'Automatische Spracherkennung (DE/EN)', 'Semantisches Chunking (rekursiv, 512 Tokens)', 'Metadaten-Extraktion (Verordnung, Artikel, Absatz)']
: ['PDF upload, URL crawling, API import', 'Automatic language detection (DE/EN)', 'Semantic chunking (recursive, 512 tokens)', 'Metadata extraction (regulation, article, paragraph)'],
},
{
icon: Cpu,
color: 'text-purple-400',
bg: 'bg-purple-500/10 border-purple-500/20',
title: de ? '2. Embedding' : '2. Embedding',
items: de
? ['BGE-M3 Multilingual Embeddings (lokal)', 'CrossEncoder Re-Ranking (lokal)', 'HyDE: Hypothetical Document Embeddings', 'Lazy Model Loading (Speicher-optimiert)']
: ['BGE-M3 multilingual embeddings (local)', 'CrossEncoder re-ranking (local)', 'HyDE: Hypothetical Document Embeddings', 'Lazy model loading (memory-optimized)'],
},
{
icon: Database,
color: 'text-emerald-400',
bg: 'bg-emerald-500/10 border-emerald-500/20',
title: de ? '3. Vektorspeicher' : '3. Vector Store',
items: de
? ['Qdrant Vector DB (Self-hosted)', '5 Collections: Legal Corpus, DSFA, Compliance, Dokumente, Agenten-Wissen', 'MinIO Object Storage fuer Quelldokumente', 'Automatische Re-Indexierung bei Updates']
: ['Qdrant Vector DB (self-hosted)', '5 Collections: Legal Corpus, DSFA, Compliance, Documents, Agent Knowledge', 'MinIO object storage for source documents', 'Automatic re-indexing on updates'],
},
{
icon: Search,
color: 'text-indigo-400',
bg: 'bg-indigo-500/10 border-indigo-500/20',
title: de ? '4. Hybrid Search' : '4. Hybrid Search',
items: de
? ['Dense Retrieval (70%) + BM25 Keyword (30%)', 'Deutsche Komposita-Zerlegung', 'Cross-Encoder Re-Ranking der Top-K Ergebnisse', 'Quellen-Attribution mit Artikel-Referenz']
: ['Dense retrieval (70%) + BM25 keyword (30%)', 'German compound word decomposition', 'Cross-encoder re-ranking of top-K results', 'Source attribution with article reference'],
},
]
// Multi-Agent System content
const agents = [
{ name: de ? 'Compliance-Berater' : 'Compliance Advisor', soul: 'compliance-advisor.soul.md', desc: de ? 'Beantwortet Compliance-Fragen mit RAG-Kontext' : 'Answers compliance questions with RAG context', color: 'text-indigo-400' },
{ name: de ? 'Audit-Agent' : 'Audit Agent', soul: 'quality-judge.soul.md', desc: de ? 'Prueft Dokumente gegen regulatorische Anforderungen' : 'Checks documents against regulatory requirements', color: 'text-emerald-400' },
{ name: de ? 'Dokument-Agent' : 'Drafting Agent', soul: 'drafting-agent.soul.md', desc: de ? 'Erstellt Compliance-Dokumente und Policies' : 'Creates compliance documents and policies', color: 'text-purple-400' },
{ name: 'Orchestrator', soul: 'orchestrator.soul.md', desc: de ? 'Task-Routing und Koordination aller Agenten' : 'Task routing and coordination of all agents', color: 'text-amber-400' },
{ name: de ? 'Alert-Agent' : 'Alert Agent', soul: 'alert-agent.soul.md', desc: de ? 'Monitoring, Fristen und Benachrichtigungen' : 'Monitoring, deadlines and notifications', color: 'text-red-400' },
{ name: de ? 'Tutor-Agent' : 'Tutor Agent', soul: 'tutor-agent.soul.md', desc: de ? 'Interaktive Compliance-Schulungen' : 'Interactive compliance training', color: 'text-blue-400' },
]
const agentInfra = [
{ icon: MessageSquare, label: 'SOUL Files', desc: de ? 'Deklarative Agenten-Persoenlichkeit in Markdown' : 'Declarative agent personality in Markdown' },
{ icon: Brain, label: 'Shared Brain', desc: de ? 'Gemeinsamer Wissensspeicher + Langzeitgedaechtnis' : 'Shared knowledge store + long-term memory' },
{ icon: Network, label: 'Message Bus', desc: de ? 'Valkey/Redis · Pub/Sub · Task Queue' : 'Valkey/Redis · Pub/Sub · Task Queue' },
{ icon: Activity, label: 'Session Manager', desc: de ? 'Heartbeat · Checkpoints · Recovery' : 'Heartbeat · Checkpoints · Recovery' },
]
// Quality Assurance content
const qaFeatures = [
{
icon: Shield,
color: 'text-emerald-400',
title: de ? 'BQAS — Quality Assurance System' : 'BQAS — Quality Assurance System',
items: de
? ['97 Golden-Suite-Referenztests fuer Regressionserkennung', 'Synthetische Testgenerierung per LLM', 'RAG-Retrieval-Accuracy und Correction-Tests', 'Precision, Recall, F1 Tracking ueber alle Releases']
: ['97 golden suite reference tests for regression detection', 'Synthetic test generation via LLM', 'RAG retrieval accuracy and correction tests', 'Precision, recall, F1 tracking across all releases'],
},
{
icon: Eye,
color: 'text-indigo-400',
title: de ? 'LLM Evaluation & Vergleich' : 'LLM Evaluation & Comparison',
items: de
? ['Side-by-Side-Vergleich: Ollama lokal vs. OpenAI vs. Claude', 'Latenz-, Token- und Qualitaets-Metriken pro Provider', 'Automatischer Fallback bei Provider-Ausfall', 'Self-RAG: Selbstreflektierende Antwortvalidierung']
: ['Side-by-side comparison: Ollama local vs. OpenAI vs. Claude', 'Latency, token and quality metrics per provider', 'Automatic fallback on provider failure', 'Self-RAG: Self-reflective answer validation'],
},
{
icon: Sparkles,
color: 'text-purple-400',
title: de ? 'Document Intelligence' : 'Document Intelligence',
items: de
? ['TrOCR Handschrifterkennung mit LoRA Fine-Tuning', 'Multi-OCR-Pipeline: 5 Methoden parallel (Vision LLM, Tesseract, OpenCV, ...)', 'Labeling-Interface fuer Trainingsdaten-Erstellung (DSGVO-konform, lokal)', 'OpenCV Document Reconstruction (Deskew, Dewarp, Binarisierung)']
: ['TrOCR handwriting recognition with LoRA fine-tuning', 'Multi-OCR pipeline: 5 methods in parallel (Vision LLM, Tesseract, OpenCV, ...)', 'Labeling interface for training data creation (GDPR-compliant, local)', 'OpenCV document reconstruction (deskew, dewarp, binarization)'],
},
{
icon: Zap,
color: 'text-amber-400',
title: de ? 'GPU & Training' : 'GPU & Training',
items: de
? ['Lokales Training auf Apple Silicon (M4 Max, 64 GB unified)', 'vast.ai Integration fuer Cloud-GPU bei Bedarf', 'LoRA/QLoRA Fine-Tuning mit konfigurierbaren Hyperparametern', 'SSE-Streaming fuer Echtzeit-Trainingsmetriken (Loss, Accuracy, F1)']
: ['Local training on Apple Silicon (M4 Max, 64 GB unified)', 'vast.ai integration for cloud GPU on demand', 'LoRA/QLoRA fine-tuning with configurable hyperparameters', 'SSE streaming for real-time training metrics (loss, accuracy, F1)'],
},
]
return (
<div>
<FadeInView className="text-center mb-5">
<p className="text-xs font-mono text-indigo-400/60 uppercase tracking-widest mb-2">
{de ? 'Anhang' : 'Appendix'}
</p>
<h2 className="text-4xl md:text-5xl font-bold mb-2">
<GradientText>{i.annex.aipipeline.title}</GradientText>
</h2>
<p className="text-lg text-white/50 max-w-2xl mx-auto">{i.annex.aipipeline.subtitle}</p>
</FadeInView>
{/* Hero Stats */}
<FadeInView delay={0.1}>
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 mb-4">
{heroStats.map((stat, idx) => (
<div key={idx} className="border border-white/[0.08] rounded-xl p-2.5 bg-white/[0.03] text-center">
<p className={`text-2xl font-black tracking-tight ${stat.color}`}>{stat.value}</p>
<p className="text-[11px] font-semibold text-white/70">{stat.label}</p>
<p className="text-[9px] text-white/30 mt-0.5 leading-tight">{stat.sub}</p>
</div>
))}
</div>
</FadeInView>
{/* Tab Navigation */}
<FadeInView delay={0.15}>
<div className="flex items-center justify-center gap-2 mb-4">
{tabs.map((tab) => {
const Icon = tab.icon
return (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={`flex items-center gap-2 px-4 py-2 rounded-xl text-sm transition-all
${activeTab === tab.id
? 'bg-indigo-500/20 text-indigo-300 border border-indigo-500/30'
: 'bg-white/[0.04] text-white/40 border border-transparent hover:text-white/60 hover:bg-white/[0.06]'
}`}
>
<Icon className="w-4 h-4" />
{tab.label}
</button>
)
})}
</div>
</FadeInView>
{/* Tab Content */}
<FadeInView delay={0.2} key={activeTab}>
{activeTab === 'rag' && (
<div>
{/* Pipeline Flow Visualization */}
<div className="flex items-center justify-center gap-1 mb-4 flex-wrap">
{[
{ icon: FileText, label: de ? 'Dokumente' : 'Documents' },
{ icon: Layers, label: 'Chunking' },
{ icon: Cpu, label: 'BGE-M3' },
{ icon: Database, label: 'Qdrant' },
{ icon: Search, label: 'Hybrid Search' },
{ icon: Brain, label: 'LLM' },
].map((step, idx, arr) => (
<div key={idx} className="flex items-center gap-1">
<div className="flex items-center gap-1 px-2 py-1 rounded-lg bg-white/[0.05] border border-white/[0.08]">
<step.icon className="w-3 h-3 text-indigo-400" />
<span className="text-[10px] text-white/50">{step.label}</span>
</div>
{idx < arr.length - 1 && <ArrowRight className="w-3 h-3 text-white/20" />}
</div>
))}
</div>
{/* Pipeline Steps */}
<div className="grid md:grid-cols-2 gap-3">
{ragPipelineSteps.map((step, idx) => {
const Icon = step.icon
return (
<div key={idx} className={`border rounded-xl p-3 ${step.bg}`}>
<div className="flex items-center gap-2 mb-2">
<Icon className={`w-4 h-4 ${step.color}`} />
<h3 className="text-xs font-bold text-white">{step.title}</h3>
</div>
<ul className="space-y-1">
{step.items.map((item, iidx) => (
<li key={iidx} className="flex items-start gap-1.5 text-[11px] text-white/50">
<span className={`w-1 h-1 rounded-full mt-1.5 ${step.color} bg-current shrink-0`} />
{item}
</li>
))}
</ul>
</div>
)
})}
</div>
</div>
)}
{activeTab === 'agents' && (
<div className="grid md:grid-cols-12 gap-4">
{/* Agent List */}
<div className="md:col-span-7">
<GlassCard hover={false} className="p-4">
<div className="flex items-center gap-2 mb-3">
<Bot className="w-4 h-4 text-white/40" />
<p className="text-xs font-semibold text-white/40 uppercase tracking-wider">
{de ? 'Agenten-Fleet' : 'Agent Fleet'}
</p>
</div>
<div className="grid grid-cols-2 gap-2">
{agents.map((agent, idx) => (
<div key={idx} className="p-2 rounded-lg bg-white/[0.03] border border-white/5">
<div className="flex items-center gap-1.5 mb-1">
<div className={`w-1.5 h-1.5 rounded-full ${agent.color} bg-current`} />
<p className="text-xs font-bold text-white/80">{agent.name}</p>
</div>
<p className="text-[10px] text-white/40 leading-tight">{agent.desc}</p>
<p className="text-[9px] font-mono text-white/20 mt-1">{agent.soul}</p>
</div>
))}
</div>
</GlassCard>
</div>
{/* Agent Infrastructure */}
<div className="md:col-span-5">
<GlassCard hover={false} className="p-4 h-full">
<div className="flex items-center gap-2 mb-3">
<Network className="w-4 h-4 text-white/40" />
<p className="text-xs font-semibold text-white/40 uppercase tracking-wider">
{de ? 'Infrastruktur' : 'Infrastructure'}
</p>
</div>
<div className="space-y-2.5">
{agentInfra.map((inf, idx) => {
const Icon = inf.icon
return (
<div key={idx} className="flex items-start gap-2.5">
<div className="w-7 h-7 rounded-lg bg-purple-500/10 border border-purple-500/20 flex items-center justify-center shrink-0">
<Icon className="w-3.5 h-3.5 text-purple-400" />
</div>
<div>
<p className="text-xs font-semibold text-white/70">{inf.label}</p>
<p className="text-[10px] text-white/40">{inf.desc}</p>
</div>
</div>
)
})}
</div>
<div className="mt-3 pt-3 border-t border-white/5">
<p className="text-[10px] text-white/20">
{de
? 'Alle Agenten laufen lokal · Kein API-Schluessel erforderlich · DSGVO-konform'
: 'All agents run locally · No API key required · GDPR-compliant'}
</p>
</div>
</GlassCard>
</div>
</div>
)}
{activeTab === 'quality' && (
<div className="grid md:grid-cols-2 gap-3">
{qaFeatures.map((feat, idx) => {
const Icon = feat.icon
return (
<GlassCard key={idx} hover={false} className="p-3">
<div className="flex items-center gap-2 mb-2">
<Icon className={`w-4 h-4 ${feat.color}`} />
<h3 className="text-xs font-bold text-white">{feat.title}</h3>
</div>
<ul className="space-y-1">
{feat.items.map((item, iidx) => (
<li key={iidx} className="flex items-start gap-1.5 text-[11px] text-white/50">
<span className={`w-1 h-1 rounded-full mt-1.5 ${feat.color} bg-current shrink-0`} />
{item}
</li>
))}
</ul>
</GlassCard>
)
})}
</div>
)}
</FadeInView>
</div>
)
}