diff --git a/ROADMAP.md b/ROADMAP.md index 2078abb..fef86eb 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -35,6 +35,7 @@ Stand: 14.04.2026 | **Context-Management (Phase 9)** | ✅ | eb91e54 | | **Sprach-Interface (Phase 10)** | ✅ | 14.04.2026 | | **Multi-Agent-Modi (Phase 11 — Basis)** | ✅ | 14.04.2026 | +| **Multi-Agent-Ausbau (Phase 11 — Vollendung)** | ✅ | 14.04.2026 | --- @@ -348,7 +349,7 @@ Benötigt `OPENAI_API_KEY` Umgebungsvariable für Whisper + TTS. --- -## Phase 11: Multi-Agent-Architektur (Context-Einsparung) 🚧 TEIL-ERLEDIGT +## Phase 11: Multi-Agent-Architektur (Context-Einsparung) ✅ ERLEDIGT > **Basis-Implementierung:** 14.04.2026 (Tool-Filterung + Persistenz + UI-Badge) @@ -369,7 +370,30 @@ Benötigt `OPENAI_API_KEY` Umgebungsvariable für Whisper + TTS. - ✅ **Frontend: mode-changed Listener** (`events.ts`) - Badge aktualisiert sich bei Modus-Wechsel live -### Noch offen (Ausbau) +### Ausbau-Implementierung (14.04.2026) + +- ✅ **AUTO-Modus Keyword-Heuristik** (`chooseAutoMode()` in Bridge) + - < 80 Zeichen → solo + - "implementiere/refactor/baue…" → experten + - "lies/suche/finde/analysiere…" + > 120 Zeichen → handlanger + - > 300 Zeichen ohne klare Keywords → handlanger (safer default) + - Sendet `auto-mode-chosen` Event ans Frontend +- ✅ **Custom Sub-Agent-Definitionen via SDK `agents` Option** + - **Handlanger**: Sub-Agent "worker" auf **Haiku** — nur Ausführung, max 500 Tokens Rückmeldung + - **Experten**: 4 autonome Agents + - `research` — Code/Docs durchsuchen (Read, Grep, Glob, Bash) + - `implement` — Code schreiben nach Best-Practices (volle Tools) + - `test` — Testfälle wählen und ausführen (volle Tools) + - `review` — Code prüfen auf Qualität/Sicherheit (read-only) + - Experten erben Modell (`model: 'inherit'`), Handlanger nutzt explizit Haiku +- ✅ **AgentView: Delegations-Badge** + - Bei Sub-Agent-Knoten wird der aktuelle Delegations-Modus farbcodiert angezeigt + - 👷 Handlanger (orange), 🎓 Experten (lila), 🤖 Auto (cyan) +- ✅ **Orchestrator-Prompts angepasst** + - Verweisen explizit auf `subagent_type` der verfügbaren Custom Agents + - Anweisung: Formuliere WAS (Experten) oder EXAKT WIE (Handlanger) + +### Alle Phase 11 Features implementiert! ### Die drei Agent-Modi (einstellbar!) diff --git a/scripts/claude-bridge.js b/scripts/claude-bridge.js index e62da52..8dc06ae 100644 --- a/scripts/claude-bridge.js +++ b/scripts/claude-bridge.js @@ -33,43 +33,46 @@ Du bist der HAUPT-AGENT und arbeitest im HANDLANGER-MODUS. WICHTIG: Du denkst und planst, aber Sub-Agents führen aus! -Wenn du eine Aufgabe bekommst: -1. ANALYSIERE was nötig ist -2. DELEGIERE an passende Sub-Agents mit EXAKTEN Anweisungen -3. Sub-Agents führen GENAU aus, was du sagst — sie denken NICHT selbst -4. Du erhältst ZUSAMMENFASSUNGEN zurück (keine Rohdaten) -5. Du entscheidest den nächsten Schritt +Dir steht das Task-Tool zur Verfügung mit dem Sub-Agent-Typ "worker". +Der Worker läuft auf Haiku (günstig) und führt genau aus was du sagst. + +Arbeitsweise: +1. ANALYSIERE die Aufgabe +2. Zerlege in EXAKTE Ausführungsschritte +3. Delegiere jeden Schritt per Task(subagent_type: "worker", prompt: "...") +4. Formuliere den Task-Prompt als exakte Anweisung, nicht als Frage +5. Sammle die Zusammenfassungen, entscheide den nächsten Schritt Beispiel-Delegationen: -- "Lies Datei X, gib mir Zeilen 10-50 zurück" -- "Suche nach 'handleError' in src/, liste die Dateien" -- "Führe 'npm test' aus, berichte nur ob passed/failed" +- Task(subagent_type:"worker", prompt:"Lies src/lib.rs, gib mir Zeilen 10-50 zurück") +- Task(subagent_type:"worker", prompt:"Suche 'handleError' in src/ via Grep, liste die Dateien") +- Task(subagent_type:"worker", prompt:"Führe 'npm test' aus, berichte nur passed/failed + Fehlerzeile") -Halte deinen Context klein — lass Sub-Agents die Details bearbeiten! +Halte deinen Context klein — lass den Worker die Rohdaten bearbeiten! `, experten: ` Du bist der HAUPT-AGENT und arbeitest im EXPERTEN-MODUS. -WICHTIG: Du koordinierst autonome Experten-Agents! +WICHTIG: Du koordinierst vier autonome Experten-Agents! -Deine Experten: -- **Research**: Durchsucht Code, findet Informationen, PLANT SELBST wie er sucht -- **Implement**: Schreibt Code, ENTSCHEIDET SELBST wie er es macht (Best Practices) -- **Test**: Schreibt und führt Tests aus, WÄHLT SELBST passende Testfälle -- **Review**: Prüft Code, FINDET SELBST Probleme +Task-Tool Sub-Agent-Typen (autonome Experten): +- **research**: Durchsucht Code/Docs, findet Infos. Wähle diesen für "Finde heraus…", "Wo ist…" +- **implement**: Schreibt Code nach Best-Practices. Wähle diesen für "Implementiere…", "Baue…" +- **test**: Schreibt und führt Tests. Wähle diesen für "Teste…" +- **review**: Prüft Code auf Qualität/Sicherheit. Wähle diesen für "Prüfe…" -Wenn du eine Aufgabe bekommst: -1. TEILE sie in Experten-Bereiche auf -2. DELEGIERE an den passenden Experten mit dem WAS, nicht dem WIE -3. Der Experte arbeitet AUTONOM und liefert eine Zusammenfassung -4. Du INTEGRIERST die Ergebnisse +Arbeitsweise: +1. ZERLEGE die Aufgabe in Experten-Bereiche +2. DELEGIERE via Task(subagent_type: "research"|"implement"|"test"|"review", prompt: "...") +3. Formuliere das WAS, nicht das WIE — die Experten planen selbst +4. Integriere die Zusammenfassungen, orchestriere weitere Schritte Beispiel-Delegationen: -- Research: "Finde heraus wie Authentication in diesem Projekt implementiert ist" -- Implement: "Füge OAuth2-Support hinzu" (ohne exakte Code-Vorgabe) -- Test: "Teste die neue Auth-Funktionalität" -- Review: "Prüfe die OAuth-Implementierung auf Sicherheitsprobleme" +- Task(subagent_type:"research", prompt:"Finde heraus wie Authentication implementiert ist") +- Task(subagent_type:"implement", prompt:"Füge OAuth2-Support hinzu mit Token-Refresh") +- Task(subagent_type:"test", prompt:"Teste die neue Auth-Funktionalität") +- Task(subagent_type:"review", prompt:"Prüfe die OAuth-Implementierung auf Sicherheitsprobleme") `, auto: ` @@ -84,6 +87,82 @@ Teile deine Wahl am Anfang mit: "[Modus: X] Begründung" `, }; +// ============ Custom Sub-Agent Definitionen ============ +// Werden je nach Modus an query() übergeben + +const HANDLANGER_AGENTS = { + worker: { + description: 'Führt exakte Anweisungen des Haupt-Agents aus (lesen, suchen, triviale Edits). Denkt NICHT selbst, berichtet komprimiert zurück.', + // Günstiges Modell — Handlanger muss nicht planen + model: 'haiku', + tools: ['Read', 'Grep', 'Glob', 'Bash', 'Edit', 'Write'], + prompt: `Du bist ein HANDLANGER-Agent. + +WICHTIG: +1. Führe GENAU aus was der Haupt-Agent verlangt — denke NICHT selbst +2. Plane keine eigene Herangehensweise +3. Berichte KOMPRIMIERT zurück (max. 500 Tokens): + - Bei Read: Relevante Zeilen/Passagen, keine Volltext-Dumps + - Bei Grep: Liste der Treffer mit Zeilennummern + - Bei Bash: Exit-Code + wichtigste Ausgabe-Zeilen + - Bei Edit/Write: Bestätigung was geändert wurde +4. Keine Erklärungen, keine Vorschläge — nur das verlangte Ergebnis`, + }, +}; + +const EXPERTEN_AGENTS = { + research: { + description: 'Durchsucht Code und Dokumentation autonom. Findet selbst heraus was relevant ist.', + model: 'inherit', + tools: ['Read', 'Grep', 'Glob', 'Bash'], + prompt: `Du bist ein RESEARCH-Experte. + +Du bekommst eine Frage — plane selbst wie du sie beantwortest: +- Wähle selbst welche Dateien/Patterns zu suchen sind +- Priorisiere wichtige Infos +- Berichte strukturiert: Was gefunden, wo (Pfade/Zeilen), warum relevant +- Max 1000 Tokens Zusammenfassung`, + }, + implement: { + description: 'Schreibt Code-Änderungen nach Best-Practices. Entscheidet selbst über Architektur und Details.', + model: 'inherit', + tools: ['Read', 'Grep', 'Glob', 'Edit', 'Write', 'Bash'], + prompt: `Du bist ein IMPLEMENT-Experte. + +Du bekommst das WAS — entscheide selbst das WIE: +- Lies relevanten Code zum Verständnis +- Implementiere nach Best-Practices (Codierrichtlinien des Projekts beachten) +- Berichte: welche Dateien geändert, was war der Kern, was beibehalten +- Max 800 Tokens Zusammenfassung`, + }, + test: { + description: 'Schreibt und führt Tests aus. Wählt selbst sinnvolle Testfälle.', + model: 'inherit', + tools: ['Read', 'Grep', 'Glob', 'Edit', 'Write', 'Bash'], + prompt: `Du bist ein TEST-Experte. + +Du bekommst ein Feature — wähle selbst passende Testfälle: +- Happy Path + sinnvolle Edge Cases +- Nutze vorhandene Test-Infrastruktur +- Berichte: Tests geschrieben (Anzahl), was ist abgedeckt, passed/failed +- Max 500 Tokens Zusammenfassung`, + }, + review: { + description: 'Prüft Code auf Qualität, Sicherheit und Stil. Findet selbst Probleme.', + model: 'inherit', + tools: ['Read', 'Grep', 'Glob', 'Bash'], + prompt: `Du bist ein REVIEW-Experte. + +Du bekommst Code zum Prüfen — finde selbst Probleme: +- Sicherheit (Injections, Secrets, Auth) +- Performance (N+1, unnötige Loops) +- Fehlerbehandlung (Boundary-Cases) +- Stil (Konsistenz mit Projekt) +- Berichte strukturiert nach Schwere (kritisch/warnung/info) +- Max 800 Tokens`, + }, +}; + // Subagent-Tracking // Map: toolUseId → { agentId, parentId, type, task, depth } const activeSubagents = new Map(); @@ -147,6 +226,38 @@ function sendMonitorEvent(type, summary, details = {}, options = {}) { }); } +// AUTO-Modus: Heuristik wählt passenden Modus basierend auf Aufgabe +// Rückgabe: 'solo' | 'handlanger' | 'experten' +function chooseAutoMode(message) { + const text = (message || '').toLowerCase(); + const charCount = text.length; + + // Keywords die klar auf Experten-Aufgaben hinweisen (komplexe, parallelisierbare Arbeit) + const expertKeywords = [ + 'implementiere', 'implementier ', 'refactor', 'architektur', 'entwickle', + 'erstelle feature', 'feature ', 'design', 'baue ', 'optimiere', + 'migration', 'umbau', 'umstruktur', + ]; + + // Keywords die auf Handlanger-Aufgaben hinweisen (viel koordinieren/sammeln) + const handlangerKeywords = [ + 'lies ', 'suche ', 'finde ', 'zeig mir ', 'untersuche', + 'analysiere', 'durchsuche', 'alle dateien', 'sammle', + 'liste alle', 'vergleiche', + ]; + + // Klar triviale Aufgaben → solo + if (charCount < 80) return 'solo'; + + if (expertKeywords.some(kw => text.includes(kw))) return 'experten'; + if (handlangerKeywords.some(kw => text.includes(kw)) && charCount > 120) return 'handlanger'; + + // Längere Nachrichten ohne klare Keywords → handlanger (safer default) + if (charCount > 300) return 'handlanger'; + + return 'solo'; +} + // Tool-Input für Logging kürzen (sensitive Daten maskieren) function summarizeToolInput(tool, input) { if (!input) return ''; @@ -221,13 +332,24 @@ async function sendMessage(message, requestId, model = null, contextOverride = n resumeSessionId: resumeSessionId || null, }); - sendResponse(requestId, { agentId: currentAgentId, status: 'gestartet', model: useModel, resuming: isResuming, mode: agentMode }); + // AUTO-Modus: Effektiven Modus aus der Nachricht ableiten + let effectiveMode = agentMode; + if (agentMode === 'auto') { + effectiveMode = chooseAutoMode(message); + sendEvent('auto-mode-chosen', { chosen: effectiveMode, messageLength: message.length }); + sendMonitorEvent('agent', `Auto-Modus gewählt: ${effectiveMode}`, { + chosen: effectiveMode, + messageLength: message.length, + }); + } - // Orchestrator-Prompt für nicht-Solo Modi + sendResponse(requestId, { agentId: currentAgentId, status: 'gestartet', model: useModel, resuming: isResuming, mode: agentMode, effectiveMode }); + + // Orchestrator-Prompt für nicht-Solo Modi (nutzt effektiven Modus) let orchestratorPrompt = ''; - if (agentMode !== 'solo' && ORCHESTRATOR_PROMPTS[agentMode]) { - orchestratorPrompt = ORCHESTRATOR_PROMPTS[agentMode]; - sendMonitorEvent('agent', `Orchestrator-Modus: ${agentMode}`, { mode: agentMode }); + if (effectiveMode !== 'solo' && ORCHESTRATOR_PROMPTS[effectiveMode]) { + orchestratorPrompt = ORCHESTRATOR_PROMPTS[effectiveMode]; + sendMonitorEvent('agent', `Orchestrator-Modus: ${effectiveMode}`, { mode: effectiveMode }); } // Nachricht mit Context und Orchestrator kombinieren @@ -256,23 +378,29 @@ async function sendMessage(message, requestId, model = null, contextOverride = n queryOptions.sessionId = resumeSessionId; } - // Tool-Filterung je nach Agent-Modus — erzwingt Delegation + // Tool-Filterung + Custom Sub-Agents je nach effektivem Modus // Handlanger: Main darf NUR delegieren (Task) und planen (TodoWrite) + // Sub-Agents laufen auf Haiku (siehe HANDLANGER_AGENTS) // Experten: Main darf zusätzlich lesen/suchen, aber nicht schreiben - if (agentMode === 'handlanger') { + // Sub-Agents sind autonome Research/Implement/Test/Review + if (effectiveMode === 'handlanger') { queryOptions.allowedTools = ['Task', 'TodoWrite']; - sendMonitorEvent('agent', 'Handlanger-Modus: Main darf nur Task+TodoWrite', { - mode: agentMode, + queryOptions.agents = HANDLANGER_AGENTS; + sendMonitorEvent('agent', 'Handlanger-Modus: Main → Task+TodoWrite, Worker auf Haiku', { + mode: effectiveMode, allowedTools: queryOptions.allowedTools, + agents: Object.keys(HANDLANGER_AGENTS), }); - } else if (agentMode === 'experten') { + } else if (effectiveMode === 'experten') { queryOptions.allowedTools = ['Task', 'TodoWrite', 'Read', 'Grep', 'Glob']; - sendMonitorEvent('agent', 'Experten-Modus: Main darf lesen+delegieren', { - mode: agentMode, + queryOptions.agents = EXPERTEN_AGENTS; + sendMonitorEvent('agent', 'Experten-Modus: 4 autonome Experten verfügbar', { + mode: effectiveMode, allowedTools: queryOptions.allowedTools, + agents: Object.keys(EXPERTEN_AGENTS), }); } - // solo + auto: keine Einschränkung + // solo: keine Einschränkung const conversation = query({ prompt: fullPrompt, diff --git a/src/lib/components/AgentView.svelte b/src/lib/components/AgentView.svelte index 28c5c91..27b29ba 100644 --- a/src/lib/components/AgentView.svelte +++ b/src/lib/components/AgentView.svelte @@ -1,7 +1,14 @@