ARCHITECTURE.md: - Multi-Agent System: 'Review + Finalizer' → 'Preparer + Review + Finalizer' - Neue Sektion: Vorbereiter-Agent (Preparer) mit Flow, SSE-Events, History-Logik - Neue Sektion: Interaktive Rückfragen (ask_user_choice) mit Tool-Definition, Backend/Frontend-Flow - Neue Sektion: Plan-Modus mit Tool-Filterung, System-Prompt-Anpassungen - System-Prompt-Aufbau: 12 → 14+ Blöcke (Anweisungen, Rückfragen, Plan-Modus, Preparer) - Tool-System: ask_user_choice + Plan-Modus Read-only Filter dokumentiert - Agent-System: AllowUserChoice + TaskInstruction Felder - Datenmodell: preparer_agent_id, plan_mode, Tag, neue StopReasons - DB-Persistierung: Tag-Markierung für Sub-Agent-Messages ARCHITECTURE_QUICK.md: - Sessions/Chains/Messages Tabellen aktualisiert - Chat-Pipeline: Preparer-Phase + ask_user_choice ergänzt - Tool-System: 12 → 13 Tools - System-Prompt: 12 → 14+ Blöcke - Multi-Agent: Preparer + Tag-System README.md: - Features: Vorbereiter-Agent, Interaktive Rückfragen, Plan-Modus - 12 → 13 Tools
288 lines
14 KiB
Markdown
288 lines
14 KiB
Markdown
# ARCHITECTURE_QUICK.md – Schnellreferenz
|
||
|
||
> Kurzfassung der [ARCHITECTURE.md](ARCHITECTURE.md) für schnelles Nachschlagen beim Entwickeln.
|
||
|
||
---
|
||
|
||
## Tech-Stack
|
||
|
||
**.NET 10** Minimal API · **SQLite** + Dapper · **Anthropic Claude API** (SSE Streaming) · **Vanilla JS** SPA · **KaTeX** (Math) · **Kestrel** auf Port 19000
|
||
|
||
---
|
||
|
||
## Verzeichnisstruktur (nur Schlüssel-Dateien)
|
||
|
||
```
|
||
gott/
|
||
├── Program.cs # Startup, DI, Middleware, Routing
|
||
├── appsettings.json # Tokens, API-Keys, Limits
|
||
├── Models/ # Records (reine Daten)
|
||
├── Services/ # Business-Logic (alle Singletons + WorkspaceHelper)
|
||
├── Endpoints/ # HTTP API (Minimal API MapXxx-Pattern)
|
||
├── Middleware/ # AuthMiddleware
|
||
├── Templates/ # Vorlagen für neue Agents (IDENTITY, SOUL, USER)
|
||
├── wwwroot/ # ⚠️ HIER Frontend editieren!
|
||
│ ├── js/app.js # App-Init
|
||
│ ├── js/router.js # Hash-basiertes SPA-Routing
|
||
│ ├── js/api.js # fetch()-Wrapper
|
||
│ ├── js/chat.js # SSE-Stream, Markdown-Rendering
|
||
│ ├── js/ui.js # UI-Helpers, buildAgentCard(), buildSessionCard(), Review-Rendering
|
||
│ ├── js/pages/ # Seiten-Komponenten
|
||
│ └── css/ # Styles (theme.css = CSS Variables)
|
||
├── WindowsApp/ # WPF + WebView2 Desktop Client
|
||
└── publish/ # ⛔ NICHT editieren!
|
||
└── data/
|
||
├── gott.db # SQLite DB
|
||
├── agents/{id}/ # Memory-Dateien pro Agent
|
||
├── skills/{slug}/ # Skill-Dateien
|
||
└── images/ # Krea-generierte Bilder
|
||
```
|
||
|
||
---
|
||
|
||
## Datenmodell (Kurzform)
|
||
|
||
```
|
||
User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* Attachment
|
||
Agent *──* Skill (via agent_skills)
|
||
Session 1──* Cronjob
|
||
Session 1──* Archive
|
||
User 1──* SharedMessage ──1 Message
|
||
```
|
||
|
||
| Tabelle | Zweck |
|
||
|---------|-------|
|
||
| `users` | Login, Persona, Settings (JSON), DefaultPath |
|
||
| `tokens` | Auth-Tokens → User |
|
||
| `agents` | AI-Agenten (Model, Tools, Config, AvatarScale, AvatarOffsetX/Y) |
|
||
| `sessions` | Chat-Sessions (Workspace, Context, Telegram, AvatarScale, AvatarOffsetX/Y, AllowedChatIds, PreparerAgentId, ReviewAgentId, MaxReviewIterations, FinalizerAgentId) |
|
||
| `chains` | Ein Request-Response-Zyklus (Tokens, Timing, Iterations, PlanMode) |
|
||
| `messages` | Einzelne Nachrichten (text / tool_use / tool_result / error / web_search_result), Tag für Sub-Agent-Markierung |
|
||
| `attachments` | Base64-Anhänge (Bilder, Dokumente) |
|
||
| `archives` | Archivierte Chain-Gruppen |
|
||
| `cronjobs` | Geplante Tasks (Cron-Expression + Prompt) |
|
||
| `agent_skills` | N:M Agent ↔ Skill |
|
||
| `shared_messages` | Geteilte Nachrichten (öffentliche Links via Share-Token) |
|
||
| `telegram_links` | Telegram Chat-ID ↔ Session |
|
||
|
||
---
|
||
|
||
## API-Endpunkte (Übersicht)
|
||
|
||
| Gruppe | Route | Wichtigstes |
|
||
|--------|-------|-------------|
|
||
| Auth | `/api/auth/` | `POST login`, `POST logout`, `GET me`, `GET autologin` |
|
||
| Chat | `/api/chat` | `POST` → SSE Stream, `POST stop` |
|
||
| History | `/api/history` | GET history, poll, archive, marks, delete |
|
||
| Sessions | `/api/sessions/` | CRUD + system-prompt, exec, git-status |
|
||
| Agents | `/api/agents/` | CRUD |
|
||
| Admin | `/api/admin/` | User CRUD, impersonate, login-link (Admin-only) |
|
||
| Workspace | `/api/workspace/` | tree, file read/write, mkdir, rmdir, browse, agent-files |
|
||
| Telegram | `/api/telegram/` | webhook (unauth), config, registration |
|
||
| Cronjobs | `/api/cronjobs/` | CRUD + toggle, manual run |
|
||
| Krea | `/api/images/` | generate, list, file-serve, thumb, status (file/* ohne Auth) |
|
||
| Skills | `/api/skills` | list, agent-mapping, output-files |
|
||
| Profile | `/api/profile` | GET, PUT, password |
|
||
| Settings | `/api/settings` | GET, PUT (JSON blob) |
|
||
| Backup | `/api/backup` | POST → tar.gz download (Admin) |
|
||
| Shared | `/api/shared/`, `/api/messages/{id}/share` | Share erstellen, öffentlich abrufen, löschen |
|
||
| Info | `/api/info` | GET → Build-Zeitstempel |
|
||
| ServerSettings | `/api/admin/server-settings` | `GET`, `PUT` (Admin-only, liest/schreibt `appsettings.Production.json`) |
|
||
|
||
---
|
||
|
||
## Services (alle Singletons)
|
||
|
||
| Service | Was es tut |
|
||
|---------|-----------|
|
||
| **DatabaseService** | Alles DB: Schema, Migrationen, CRUD |
|
||
| **AuthService** | Token-Auth, Passwort-Hashing (SHA256) |
|
||
| **ChatService** | Chat-Kontext aufbauen, History aus DB laden |
|
||
| **AnthropicService** | Claude API: SSE Streaming + Non-Streaming |
|
||
| **ToolService** | Tool-Definitionen + Ausführung (12 Tools) |
|
||
| **WorkspaceHelper** | Workspace-Pfad-Auflösung (relativ → absolut), Path-Traversal-Schutz (static) |
|
||
| **SystemPromptBuilder** | System-Prompt aus modularen Blöcken zusammenbauen (static) |
|
||
| **MemoryService** | Agent-Gedächtnis auf Dateisystem |
|
||
| **SkillService** | Skill-Discovery aus Dateisystem |
|
||
| **TelegramService** | Telegram Bot API |
|
||
| **CronjobService** | BackgroundService, minütlicher Cron-Check |
|
||
| **KreaService** | Krea API Bildgenerierung + Job-Polling |
|
||
| **ImageService** | Bild-Resize (ImageSharp, max 512px) |
|
||
| **StreamingTracker** | Tracking aktiver Streams + CancellationTokenSource pro Session für Stop |
|
||
|
||
---
|
||
|
||
## Chat-Pipeline (Flow)
|
||
|
||
```
|
||
User-Input → POST /api/chat (SSE)
|
||
→ ChatService.BuildContext()
|
||
→ History aus DB laden (letzte N Chains)
|
||
→ SystemPromptBuilder: 14 Blöcke zusammensetzen (+ Plan-Modus/Preparer-Blöcke)
|
||
→ Tool-Definitionen vom ToolService holen (im Plan-Modus: nur Read-only)
|
||
→ Preparer-Phase (optional, wenn PreparerAgentId gesetzt):
|
||
→ RunPreparer() → RunAgentChat(agentType: "preparer")
|
||
→ Antwort ohne [QUESTION] → automatisch weiterleiten (Default = Forward)
|
||
→ [QUESTION] → Rückfrage an User, Flow stoppt
|
||
→ AnthropicService.StreamChat()
|
||
→ Claude API Call (SSE)
|
||
→ Token-für-Token an Client streamen
|
||
→ Bei tool_use → ToolService.Execute() → Ergebnis zurück → neuer API Call
|
||
→ Bei ask_user_choice → SSE user_choice Event → Flow stoppt (awaiting_user_choice)
|
||
→ Loop bis end_turn oder max_iterations (100)
|
||
→ Bei end_turn + ReviewAgent → Review-Phase:
|
||
→ Review-Agent prüft (eigene Tools, max 25 Iterationen)
|
||
→ [APPROVED] → Fertig | Feedback → Worker korrigiert → erneuter Review
|
||
→ Bei FinalizerAgent → Finalizer-Phase:
|
||
→ Finalizer-Agent arbeitet (eigene Tools, z.B. git commit)
|
||
→ Einmalig, kein Feedback-Loop
|
||
→ Stop-Button: POST /api/chat/stop → StreamingTracker.Cancel()
|
||
→ CancellationToken durchgereicht bis ToolService → Prozess-Kill
|
||
→ client_disconnected
|
||
→ Chain + Messages in DB speichern
|
||
```
|
||
|
||
**History-Optimierung:** Ältere Chains nur Text-Messages (keine Tool-Calls). Letzte Chain vollständig. Tool-Results auf 20.000 Zeichen gekürzt. Attachments nur für letzte User-Message.
|
||
|
||
**Rendering:** Markdown via marked.js + LaTeX via KaTeX (`$$...$$` Block, `$...$` Inline). Timestamps im Format `dd.MM.yyyy HH:mm:ss` on hover.
|
||
|
||
---
|
||
|
||
## Tool-System (13 Tools)
|
||
|
||
| Tool | Funktion |
|
||
|------|----------|
|
||
| `read_file` | Datei lesen |
|
||
| `write_file` | Datei erstellen/überschreiben |
|
||
| `edit_file` | Exakten Textabschnitt ersetzen |
|
||
| `list_files` | Verzeichnisinhalt auflisten |
|
||
| `delete_file` | Datei/leeres Verzeichnis löschen |
|
||
| `execute` | Shell-Befehl ausführen (bash, 180s Timeout) |
|
||
| `glob` | Dateien per Glob-Pattern finden |
|
||
| `grep` | Dateien per Regex/Text durchsuchen |
|
||
| `todo_write` | Aufgabenliste schreiben (wird im Prompt angezeigt) |
|
||
| `memory_read` | Memory-Datei lesen |
|
||
| `memory_write` | Memory-Datei schreiben/appenden |
|
||
| `memory_list` | Memory-Dateien auflisten |
|
||
| `ask_user_choice` | Interaktive Rückfrage mit 2-5 Auswahlmöglichkeiten (wenn AllowUserChoice aktiv) |
|
||
|
||
**Sicherheit:** Alle Pfade werden auf das Workspace-Verzeichnis beschränkt (`..` wird blockiert). Tools sind pro Agent konfigurierbar (Feld `tools` als komma-separierte Liste).
|
||
|
||
**Tool-Choice:** Standard `auto`. Wird zu `none` bei `/no-tools`. Einzelne Tools forcierbar via `/tool:toolname`.
|
||
|
||
---
|
||
|
||
## System-Prompt (14+ Blöcke, in Reihenfolge)
|
||
|
||
1. **Identity** – `IDENTITY.md` des Agents
|
||
2. **Soul** – `SOUL.md` des Agents
|
||
3. **Anweisungen** – `TaskInstruction` des Agents (optional, wenn gesetzt)
|
||
4. **User** – `USER.md` (globale User-Infos) + Persona
|
||
5. **Rules** – Verhaltensregeln (Tool-Nutzung, Workspace)
|
||
6. **Workspace** – Pfad-Info, Tool-Liste
|
||
7. **Rückfragen** – Hinweis zu `ask_user_choice` (wenn AllowUserChoice aktiv)
|
||
8. **Context** – Session-Kontext (custom system prompt)
|
||
9. **Skills** – Zugeordnete Skill-Prompts
|
||
10. **Memory** – Aktueller MEMORY.md-Inhalt + Regeln
|
||
11. **Git** – Commit-Verhalten (wenn AutoCommit konfiguriert)
|
||
12. **Verhaltensregeln** – "IMMER Tools aufrufen" (wenn Workspace + any)
|
||
13. **Erinnerung** – Höchste Priorität: Tool-Aufrufe! (wenn Workspace + any)
|
||
14. **Markierte Nachrichten** – Vom User als wichtig markiert
|
||
- **[Plan-Modus]** – Überspringt 5, 11, 12, 13; Read-only Tools; "Nur analysieren"
|
||
- **[Preparer-Block]** – Instruktionen für Vorbereiter-Agents
|
||
|
||
---
|
||
|
||
## Frontend-Routing
|
||
|
||
| Hash-Route | Page-Datei | Beschreibung |
|
||
|------------|-----------|--------------|
|
||
| `#/` | `dashboard.js` | Session-Übersicht |
|
||
| `#/chat/{id}` | `chat-page.js` | Chat |
|
||
| `#/session/{id}` | `session-page.js` | Session-Settings |
|
||
| `#/agent/{id}` | `agent-page.js` | Agent-Editor |
|
||
| `#/cronjobs` | `cronjob-page.js` | Cronjobs |
|
||
| `#/profile` | `profile-page.js` | Profil |
|
||
| `#/settings` | `settings-page.js` | Einstellungen |
|
||
| `#/admin` | `admin-page.js` | Benutzerverwaltung (Admin) |
|
||
| `#/server-settings` | `server-settings-page.js` | Servereinstellungen (Admin) |
|
||
| `#/login` | `login-page.js` | Login |
|
||
| `#/shared/{token}` | `shared-page.js` | Geteilte Nachricht (öffentlich, kein Auth) |
|
||
|
||
---
|
||
|
||
## Auth-Flow
|
||
|
||
1. `POST /api/auth/login` → Token generiert, als `gott_token` HttpOnly Cookie gesetzt
|
||
2. Jeder `/api/`-Request → `AuthMiddleware` prüft Cookie → setzt `UserId` + `IsAdmin`
|
||
3. Ausnahmen: Login, Autologin, Telegram-Webhook, `GET /api/shared/{token}`, `GET /api/images/file/*` brauchen kein Auth
|
||
4. **Krea API-Key**: `/api/images/`-Routen akzeptieren `X-Api-Key`-Header (Config: `KreaApiKey`) für Automation ohne User-Kontext
|
||
5. **Impersonate**: Admin kann via `POST /api/admin/users/{id}/impersonate` als anderer User einloggen
|
||
6. **Login-Link**: Admin generiert via `POST /api/admin/users/{id}/login-link` einen Autologin-Link (Token-basiert, `GET /api/auth/autologin?token=xxx`)
|
||
7. **DefaultPath**: Pro User ein Basis-Ordner (nur vom Admin setzbar), Session-Workspaces sind relativ dazu
|
||
|
||
---
|
||
|
||
## Konfiguration (appsettings.json)
|
||
|
||
```json
|
||
{
|
||
"Port": 19000, // Server-Port (erfordert Neustart)
|
||
"AnthropicToken": "", // Anthropic API Key (REQUIRED)
|
||
"MaxIterations": 100, // Max Tool-Loop Iterationen pro Chat
|
||
"PayloadLogging": false, // API-Payloads loggen (Debug)
|
||
"PayloadLoggingGzip": false, // Payload-Logs als .gz komprimieren
|
||
"KreaToken": "", // Krea API Token (optional)
|
||
"KreaApiKey": "" // API-Key für Krea-Endpoints ohne User-Auth (optional)
|
||
}
|
||
```
|
||
|
||
Verwaltung über **Admin-UI** (`#/server-settings`): Liest `appsettings.Production.json` (Fallback: `appsettings.json` → Default). Schreibt immer in `appsettings.Production.json`. Die Datei wird **nicht** beim Publish mitkopiert.
|
||
|
||
---
|
||
|
||
## Deployment
|
||
|
||
```bash
|
||
./deploy.sh # dotnet publish → systemctl restart gott
|
||
```
|
||
|
||
Läuft als `systemd`-Service, Kestrel auf konfigurierbarem Port (Default 19000), typisch hinter Nginx/Caddy Reverse Proxy.
|
||
|
||
---
|
||
|
||
## Multi-Agent System (Preparer + Review + Finalizer)
|
||
|
||
Eine Session kann bis zu **vier Agents** haben: Worker (Pflicht), Preparer (optional, `preparer_agent_id`), Review (optional, `review_agent_id`, `max_review_iterations`), Finalizer (optional, `finalizer_agent_id`).
|
||
|
||
**Flow:** Preparer analysiert User-Anfrage (→ Vorarbeit leisten oder `[QUESTION]` Rückfrage) → Worker-Agent arbeitet → Review-Agent prüft (`[APPROVED]` / Feedback-Loop) → Finalizer-Agent arbeitet (einmalig) → Fertig.
|
||
|
||
**Preparer:** Default = Forward (jede Antwort wird automatisch weitergeleitet, `[QUESTION]` stoppt). Bekommt eigene History mit `includeTag: "preparer"`. Aufbereiteter Prompt wird als `[Vorbereitet von AgentName]:` User-Message gespeichert.
|
||
|
||
**Backend:** `ChatService` baut `PreparerContext` + `ReviewContext` + `FinalizerContext`. `RunPreparer()` im ChatEndpoint (vor StreamChat). `RunReview()` + `RunFinalizer()` in AnthropicService. Alle nutzen `RunAgentChat()` (mit `Tag`-Markierung, Sub-Agent-Messages aus API-History gefiltert).
|
||
|
||
**SSE-Events:**
|
||
- Preparer: `preparer_start`, `preparer_text`, `preparer_tool_use`, `preparer_done`
|
||
- Review: `review_start`, `review_text`, `review_tool_use`, `review_feedback`, `review_approved`
|
||
- Finalizer: `finalizer_start`, `finalizer_text`, `finalizer_tool_use`, `finalizer_done`
|
||
|
||
**Frontend-Rendering:**
|
||
- Streaming: `chat.js` rendert Preparer-/Review-/Finalizer-Events als eigene Bubbles
|
||
- History: `renderMarkdown` parst `[Preparer: AgentName]`, `[Vorbereitet von AgentName]`, `[Review: AgentName]`, `[Finalizer: AgentName]`, filtert `[APPROVED]`, `[FORWARD]`, `[QUESTION]`
|
||
- Bubble-Klassen: `.preparer-bubble` (Info-Farbe), `.review-bubble` (sekundäre Farbe), `.finalizer-bubble` (grüne Farbe)
|
||
|
||
**Web-Search Sources:**
|
||
- `web_search_result`-Messages in DB gespeichert (Sources als JSON-Array, leere werden übersprungen)
|
||
- History + Shared-Page: Tool-Box mit klickbaren Source-Links (Domain + Title)
|
||
- Streaming: `pauseStreamBubble()` hält Bubble offen zwischen Web-Searches (keine Doppel-Bubbles)
|
||
|
||
---
|
||
|
||
## Wichtige Regeln beim Entwickeln
|
||
|
||
- ⚠️ **Quelldateien in `wwwroot/`** editieren, NICHT in `publish/wwwroot/`
|
||
- ⛔ **`publish/data/gott.db`** niemals manuell modifizieren/löschen
|
||
- ⛔ **`publish/`** generell nicht anfassen
|
||
- 🔧 **.NET 10** ohne Nullable, ohne Implicit Usings
|
||
- 📦 DB-Migrationen sind idempotent (IF NOT EXISTS Pattern in `DatabaseService`)
|