Files
gott/ARCHITECTURE.md
T
Meleki 1693ace243 docs: Shared Messages Feature in ARCHITECTURE.md, ARCHITECTURE_QUICK.md und TODO.md ergänzt
- ARCHITECTURE.md: Neues Kapitel 17 (Nachrichten teilen), ER-Diagramm,
  Tabelle shared_messages, SharedEndpoint, Auth-Ausnahme, Frontend-Route,
  Dateibaum aktualisiert, Endpoint-Anzahl 14→15
- ARCHITECTURE_QUICK.md: Tabelle, Endpoint, Route, Auth-Ausnahme ergänzt
- TODO.md: Share-Feature als erledigt markiert, neuen Punkt für
  Share-Verwaltung hinzugefügt
2026-03-04 23:38:13 +01:00

921 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ARCHITECTURE.md – Gott
**Gott** ist eine selbst-gehostete AI-Chat-Plattform, gebaut auf **.NET 10** und der **Anthropic Claude API**. Sie bietet Multi-User-Support, persistente Agent-Memory, Datei-/Shell-Tools, Telegram-Integration, Cronjobs und eine Krea-Bildgenerierung – alles über ein Vanilla-JavaScript-Frontend gesteuert.
---
## Inhaltsverzeichnis
1. [Überblick](#überblick)
2. [Tech-Stack](#tech-stack)
3. [Projektstruktur](#projektstruktur)
4. [Datenmodell](#datenmodell)
5. [Backend-Architektur](#backend-architektur)
- [Program.cs – Startup](#programcs--startup)
- [Services](#services)
- [Endpoints (API)](#endpoints-api)
- [Middleware](#middleware)
- [Models](#models)
- [Templates](#templates)
6. [Frontend-Architektur](#frontend-architektur)
7. [Chat-Pipeline](#chat-pipeline)
8. [Tool-System](#tool-system)
9. [Agent-System](#agent-system)
10. [System-Prompt-Aufbau](#system-prompt-aufbau)
11. [Memory-System](#memory-system)
12. [Skill-System](#skill-system)
13. [Telegram-Integration](#telegram-integration)
14. [Cronjob-System](#cronjob-system)
15. [Krea-Bildgenerierung](#krea-bildgenerierung)
16. [Auth & Multi-User](#auth--multi-user)
17. [Nachrichten teilen (Shared Messages)](#nachrichten-teilen-shared-messages)
18. [Workspace & File-Explorer](#workspace--file-explorer)
19. [Windows Desktop App](#windows-desktop-app)
20. [Deployment](#deployment)
21. [Konfiguration](#konfiguration)
22. [Datenbank-Migrationen](#datenbank-migrationen)
---
## Überblick
```
┌─────────────────────────────────────────────────────────────┐
│ Browser / WebView2 │
│ Vanilla JS SPA (wwwroot/) │
├─────────────────────────────────────────────────────────────┤
│ ASP.NET 10 Minimal API │
│ http://0.0.0.0:19000 │
├──────┬──────┬──────┬──────┬──────┬──────┬──────┬───────────┤
│ Auth │ Chat │ Hist │ Sess │Agent │ Tele │ Cron │ Krea │
│ │ SSE │ │ │ │ gram │ jobs │ Images │
├──────┴──────┴──────┴──────┴──────┴──────┴──────┴───────────┤
│ Services Layer │
│ AnthropicService · ChatService · ToolService │
│ DatabaseService · MemoryService · SkillService │
│ TelegramService · CronjobService · KreaService │
├─────────────────────────────────────────────────────────────┤
│ SQLite (data/gott.db) via Dapper │
│ Filesystem (data/agents/, data/skills/) │
├─────────────────────────────────────────────────────────────┤
│ Anthropic Claude API (claude-sonnet/opus/haiku) │
│ Krea API (Bildgenerierung) │
│ Telegram Bot API │
└─────────────────────────────────────────────────────────────┘
```
---
## Tech-Stack
| Schicht | Technologie |
|---------------|-----------------------------------------------------------|
| **Runtime** | .NET 10 (ohne Nullable, ohne Implicit Usings) |
| **Web** | ASP.NET Minimal API, Kestrel |
| **Datenbank** | SQLite via Microsoft.Data.Sqlite + Dapper |
| **AI** | Anthropic Claude API (Streaming SSE + Non-Streaming) |
| **Images** | SixLabors.ImageSharp (Resize, Thumbnails) |
| **Cron** | Cronos (Cron-Expression-Parsing) |
| **Frontend** | Vanilla JavaScript SPA (kein Framework) |
| **Markdown** | marked.js (Client-side Rendering) |
| **Editor** | CodeMirror 5 + EasyMDE |
| **Icons** | Font Awesome |
| **Fonts** | Inter, JetBrains Mono (self-hosted) |
| **Desktop** | WPF + WebView2 (.NET 10, Windows-only) |
---
## Projektstruktur
```
gott/
├── Program.cs # Startup, DI, Middleware, Routing
├── gott.csproj # Projekt-Definition (.NET 10)
├── appsettings.json # Konfiguration (Tokens, Limits)
├── deploy.sh # Deployment-Script (systemctl)
│
├── Models/ # Daten-Modelle (Records)
│ ├── UserRecord.cs
│ ├── AgentRecord.cs
│ ├── SessionRecord.cs
│ ├── ChainRecord.cs
│ ├── MessageRecord.cs # + AttachmentRecord
│ ├── ArchiveRecord.cs
│ ├── CronjobRecord.cs
│ ├── KreaImageRecord.cs
│ ├── SharedMessageRecord.cs # Geteilte Nachrichten (Share-Token)
│ ├── ChatModels.cs # ChatMessage, ChatRequest, AttachmentInfo/Block
│ └── ChatContext.cs # Runtime-Kontext für einen Chat
│
├── Services/ # Business-Logic
│ ├── DatabaseService.cs # SQLite CRUD, Schema, Migrationen
│ ├── AuthService.cs # Token-basierte Authentifizierung
│ ├── ChatService.cs # Kontext-Aufbau, History-Builder
│ ├── AnthropicService.cs # Claude API (Streaming + Non-Streaming)
│ ├── ToolService.cs # Tool-Definitionen + Ausführung
│ ├── SystemPromptBuilder.cs # Modularer System-Prompt aus Blöcken
│ ├── MemoryService.cs # Agent-Gedächtnis (Dateisystem)
│ ├── SkillService.cs # Skill-Verwaltung (Dateisystem)
│ ├── TelegramService.cs # Telegram Bot API Integration
│ ├── CronjobService.cs # BackgroundService für Cron-Tasks
│ ├── KreaService.cs # Krea Image Generation API
│ ├── ImageService.cs # Bild-Resize (Avatar, Session-Image)
│ └── StreamingTracker.cs # Concurrent Tracking aktiver Streams
│
├── Endpoints/ # HTTP API (Minimal API)
│ ├── AuthEndpoint.cs # Login, Logout, Me
│ ├── ChatEndpoint.cs # POST /api/chat (SSE Streaming)
│ ├── HistoryEndpoint.cs # History, Archive, Attachments, Marks
│ ├── SessionEndpoint.cs # CRUD + SystemPrompt, Exec, Git-Status
│ ├── AgentEndpoint.cs # CRUD
│ ├── WorkspaceEndpoint.cs # File-Tree, File-Read/Write, Browse, Agent-Files
│ ├── TelegramEndpoint.cs # Webhook, Config, Registration
│ ├── CronjobEndpoint.cs # CRUD + Toggle, Manual Run
│ ├── KreaEndpoint.cs # Generate, List, File-Serve
│ ├── SkillEndpoint.cs # List, Agent-Skill-Mapping, Output-Files
│ ├── SharedEndpoint.cs # Nachrichten teilen (öffentliche Links)
│ ├── ProfileEndpoint.cs # Profil, Persona, Passwort
│ ├── SettingsEndpoint.cs # User-Settings (JSON blob)
│ ├── BackupEndpoint.cs # Backup als tar.gz Download
│ └── InfoEndpoint.cs # Build-Zeitstempel
│
├── Middleware/
│ └── AuthMiddleware.cs # Cookie-basierte Token-Validierung
│
├── Extensions/
│ └── HttpContextExtensions.cs # GetUserId(), IsAdmin()
│
├── Templates/ # Standard-Templates für neue Agents
│ ├── IDENTITY.md # Wer bin ich? (Name, Sprache)
│ ├── SOUL.md # Persönlichkeit, Verhalten
│ └── USER.md # Infos über den User
│
├── wwwroot/ # Frontend (Vanilla JS SPA)
│ ├── index.html # Single HTML Entry Point
│ ├── css/ # Stylesheets
│ │ ├── theme.css # CSS Custom Properties (Dark Theme)
│ │ ├── base.css # Reset, Grundlayout
│ │ ├── main.css # Sidebar, Layout-Struktur
│ │ ├── chat.css # Chat-Nachrichten, Bubbles
│ │ ├── dashboard.css # Dashboard-Grid
│ │ ├── form.css # Formulare, Inputs
│ │ ├── markdown.css # Markdown-Rendering-Styles
│ │ ├── file-explorer.css # File-Explorer Panel
│ │ ├── login.css # Login-Seite
│ │ ├── mobile.css # Responsive Anpassungen
│ │ ├── tooltip.css # Tooltip-Styles
│ │ ├── fonts.css # @font-face Definitionen
│ │ ├── placeholder.css # Placeholder/Loading States
│ │ ├── codemirror.min.css # CodeMirror Editor
│ │ └── easymde.min.css # EasyMDE Editor
│ ├── js/
│ │ ├── app.js # App-Initialisierung, Auth-Check
│ │ ├── router.js # Client-side SPA Router
│ │ ├── api.js # API-Client (fetch wrapper)
│ │ ├── ui.js # UI-Utilities (Modal, Toast, etc.)
│ │ ├── chat.js # Chat-Logic, SSE-Streaming
│ │ ├── history.js # History-Rendering, Pagination
│ │ ├── session.js # Session-Verwaltung
│ │ ├── file-explorer.js # File-Explorer Komponente
│ │ ├── commands-ui.js # Custom-Commands UI
│ │ ├── emoji.js # Emoji-Picker
│ │ ├── emoji.userdata.js # Häufig genutzte Emojis
│ │ ├── tooltip.js # Tooltip-System
│ │ ├── title.js # Tab-Titel-Management
│ │ ├── pages/ # Seiten-Komponenten
│ │ │ ├── chat-page.js # Haupt-Chat-Ansicht
│ │ │ ├── dashboard.js # Dashboard / Home
│ │ │ ├── session-page.js # Session-Einstellungen
│ │ │ ├── agent-page.js # Agent-Editor
│ │ │ ├── cronjob-page.js # Cronjob-Verwaltung
│ │ │ ├── profile-page.js # Profil-Bearbeitung
│ │ │ ├── settings-page.js # App-Einstellungen
│ │ │ ├── login-page.js # Login-Formular
│ │ │ └── shared-page.js # Öffentliche geteilte Nachricht
│ │ └── lib/ # Vendor-Libraries
│ │ ├── marked.min.js # Markdown Parser
│ │ ├── codemirror.min.js # Code Editor
│ │ ├── codemirror.cjs # CM CommonJS Wrapper
│ │ ├── easymde.min.js # Markdown Editor
│ │ └── cm-mode-*.min.js # CodeMirror Syntax-Modes
│ ├── fonts/ # Self-hosted Fonts (Inter, JetBrains Mono)
│ └── lib/font-awesome/ # Font Awesome Icons
│
├── WindowsApp/ # Windows Desktop Client (WPF)
│ ├── Gott.csproj # .NET 10 Windows, WebView2
│ ├── App.xaml / App.xaml.cs # WPF Application
│ ├── MainWindow.xaml/cs # WebView2 Host Window
│ └── appsettings.json # Server-URL Konfiguration
│
└── publish/ # Build-Output (NICHT editieren!)
└── data/
├── gott.db # SQLite Datenbank
├── agents/ # Agent Memory-Dateien
│ └── {agentId}/
│ ├── IDENTITY.md
│ ├── SOUL.md
│ ├── MEMORY.md
│ └── memory/ # Tages-Logs etc.
├── skills/ # Skill-Verzeichnisse
│ └── {slug}/
│ ├── SKILL.md
│ ├── PROMPT.md
│ └── output/
├── images/ # Krea-generierte Bilder
├── logs/ # Payload-Logs (optional)
└── backup/ # Backup-Archive
```
---
## Datenmodell
### Entity-Relationship
```
User (1) ─── (*) Agent
User (1) ─── (*) Session
Agent (1) ─── (*) Session (Session hat optional einen Agent)
Agent (*) ─── (*) Skill (via agent_skills Tabelle)
Session (1) ─── (*) Chain (ein Chat-Request = eine Chain)
Session (1) ─── (*) Archive (archivierte Chains)
Chain (1) ─── (*) Message
Message (1) ─── (*) Attachment
Session (1) ─── (*) Cronjob
User (1) ─── (*) Cronjob
User (1) ─── (*) SharedMessage
Message (1) ─── (*) SharedMessage
```
### Tabellen
| Tabelle | Beschreibung |
|-------------------|-----------------------------------------------------|
| `users` | Benutzer (username, password_hash, persona, settings) |
| `tokens` | Auth-Tokens (token → user_id) |
| `agents` | AI-Agenten (model, soul, identity, memory, tools) |
| `sessions` | Chat-Sessions (workspace, context, telegram-config) |
| `chains` | Request-Chains (model, tokens, iterations, timing) |
| `messages` | Einzelne Nachrichten (text, tool_use, tool_result) |
| `attachments` | Datei-Anhänge (base64, image/document) |
| `archives` | Archivierte Chain-Gruppen |
| `agent_skills` | Agent ↔ Skill Zuordnung |
| `cronjobs` | Geplante Tasks (cron expression, prompt) |
| `shared_messages` | Geteilte Nachrichten (Share-Token, Ablaufdatum) |
| `telegram_links` | Telegram Chat ↔ Session Verknüpfung |
### Zentrale Records
**ChainRecord** – Repräsentiert einen kompletten Request-Response-Zyklus:
- `ChainId` – Eindeutige ID
- `SessionId` – Zugehörige Session
- `Model` – Verwendetes Claude-Modell (z.B. `claude-sonnet-4-6`)
- `SystemPrompt` – Der vollständige System-Prompt (gespeichert für Nachvollziehbarkeit)
- `InputTokens`, `OutputTokens`, `CacheCreationTokens`, `CacheReadTokens` – Token-Verbrauch
- `Iterations` – Anzahl der Tool-Loop-Durchläufe
- `StopReason` – `end_turn`, `tool_use`, `max_iterations`, `error`, `client_disconnected`
- `DurationMs` – Gesamtdauer der Chain
**MessageRecord** – Eine einzelne Nachricht innerhalb einer Chain:
- `Role` – `user`, `assistant`, `system`
- `Type` – `text`, `tool_use`, `tool_result`, `error`
- `Content` – Textinhalt oder JSON (bei tool_use: Input-JSON)
- `ToolName`, `ToolCallId` – Bei Tool-Aufrufen
- `IsMarked` – Als wichtig markierte Nachricht (wird in System-Prompt aufgenommen)
- `DeletedOn` – Soft-Delete Zeitstempel
---
## Backend-Architektur
### Program.cs – Startup
Die `Program.cs` ist der zentrale Einstiegspunkt und konfiguriert:
1. **Service-Registrierung** – Alle Services als Singletons im DI-Container
2. **Datenbank-Initialisierung** – `DatabaseService` erstellt Schema + Migrationen
3. **Default-User** – Wird automatisch angelegt falls keine User existieren
4. **Middleware** – Static Files → `AuthMiddleware` → Endpoints
5. **Endpoint-Mapping** – Alle 15 Endpoint-Gruppen registriert
6. **Server** – Kestrel auf `http://0.0.0.0:19000`
Initialisierungsreihenfolge:
```
AuthService → DatabaseService → EnsureDefaultUser
→ ImageService, StreamingTracker, MemoryService, SkillService
→ ToolService → ChatService
→ AnthropicService → TelegramService → KreaService
→ CronjobService (BackgroundService)
```
### Services
| Service | Typ | Aufgabe |
|------------------------|--------------|------------------------------------------------------------------|
| `DatabaseService` | Singleton | SQLite CRUD, Schema-Init, Migrationen, alle DB-Operationen |
| `AuthService` | Singleton | Token-Erzeugung/-Validierung, Passwort-Hashing (SHA256) |
| `ChatService` | Singleton | Chat-Kontext aufbauen, History aus DB rekonstruieren |
| `AnthropicService` | Singleton | Claude API Kommunikation (Streaming SSE + Non-Streaming) |
| `ToolService` | Singleton | Tool-Definitionen bereitstellen, Tool-Aufrufe ausführen |
| `SystemPromptBuilder` | Static | Modularer System-Prompt aus konfigurierbaren Blöcken |
| `MemoryService` | Singleton | Agent-Gedächtnis auf Dateisystem (MEMORY.md, IDENTITY.md etc.) |
| `SkillService` | Singleton | Skill-Discovery und -Management aus Dateisystem |
| `TelegramService` | Singleton | Telegram Bot API, Webhook-Handling, Nachrichten senden |
| `CronjobService` | Background | Minütlicher Check auf fällige Cronjobs, Ausführung via Claude |
| `KreaService` | Singleton | Krea API für Bildgenerierung, Job-Polling, Image-Download |
| `ImageService` | Singleton | Bild-Resize (max 512px) für Avatare und Session-Bilder |
| `StreamingTracker` | Singleton | ConcurrentDictionary – trackt welche Sessions gerade streamen |
### Endpoints (API)
Alle Endpoints folgen dem **Minimal API**-Pattern mit Extension Methods (`MapXxxEndpoints`).
| Gruppe | Basis-Route | Methoden |
|---------------|----------------------------|---------------------------------------------|
| **Auth** | `/api/auth/` | `POST login`, `POST logout`, `GET me` |
| **Chat** | `/api/chat` | `POST` (SSE Streaming) |
| **History** | `/api/history` | `GET history`, `GET poll`, `POST archive`, `GET archives`, `GET archive/{id}`, `GET attachments/{id}`, `PUT messages/{id}/mark`, `PUT messages/{id}/delete`, `GET chains/{id}` |
| **Sessions** | `/api/sessions/` | CRUD + `GET system-prompt`, `GET system-prompt-blocks`, `GET streaming`, `POST exec`, `GET git-status` |
| **Agents** | `/api/agents/` | CRUD |
| **Workspace** | `/api/workspace/` | `GET tree`, `GET/PUT file`, `GET browse`, `GET agent/tree`, `GET/PUT agent/file`, `GET raw` |
| **Telegram** | `/api/telegram/` | `POST webhook/{sessionId}` (unauthenticated), Session-Config CRUD, Webhook-Management |
| **Cronjobs** | `/api/cronjobs/` | CRUD + `POST toggle`, `POST run` |
| **Krea** | `/api/images/` | `POST generate`, `GET list`, `GET file/{name}`, `GET status` |
| **Skills** | `/api/skills` | `GET list`, `GET/PUT agent skills`, Output-Files + Thumbnails |
| **Profile** | `/api/profile` | `GET`, `PUT`, `PUT password` |
| **Settings** | `/api/settings` | `GET`, `PUT` |
| **Backup** | `/api/backup` | `POST` (Admin only, tar.gz Download) |
| **Shared** | `/api/shared/`, `/api/messages/{id}/share` | Share erstellen, öffentlich abrufen, auflisten, löschen |
| **Info** | `/api/info` | `GET` (Build-Zeitstempel) |
### Middleware
**AuthMiddleware** prüft jede `/api/`-Anfrage auf ein gültiges `gott_token`-Cookie.
Ausnahmen (kein Auth nötig):
- Statische Dateien (nicht `/api/`)
- `POST /api/auth/login`
- `POST /api/telegram/webhook/{sessionId}` (authentifiziert via Secret-Header)
- `GET /api/shared/{token}` (öffentlicher Zugriff auf geteilte Nachrichten)
Bei Erfolg werden `UserId` und `IsAdmin` in `HttpContext.Items` gesetzt.
### Models
Die Models in `Models/` sind reine Daten-Records ohne Business-Logic (Ausnahme: `ChatMessage` hat Helper-Methoden für Content-Extraktion und `UserRecord` hat `GetEffectivePersona()`).
**ChatContext** ist ein Runtime-Objekt das den vollständigen Kontext eines Chat-Requests hält:
- Chain-ID, Session-ID, Model-ID
- Aufgelöster System-Prompt (Text + strukturierte Blöcke)
- Workspace-Pfad, Tool-Choice
- Referenzen auf Agent und Session Records
### Templates
`Templates/` enthält Vorlagen die beim Erstellen eines neuen Agents in dessen Memory-Verzeichnis kopiert werden:
- **IDENTITY.md** – Name und Grundinfos (Platzhalter `{NAME}` wird ersetzt)
- **SOUL.md** – Persönlichkeit und Verhaltensgrundsätze
- **USER.md** – Informationen über den User (global, nicht agent-spezifisch)
---
## Frontend-Architektur
Das Frontend ist eine **Single-Page Application** ohne Build-Step, komplett in Vanilla JavaScript.
### Routing
`router.js` implementiert ein Hash-basiertes Client-Side-Routing:
| Route | Page | Beschreibung |
|--------------------------|---------------------|---------------------------|
| `#/` | `dashboard.js` | Session-Übersicht |
| `#/chat/{sessionId}` | `chat-page.js` | Chat-Ansicht |
| `#/session/{sessionId}` | `session-page.js` | Session-Einstellungen |
| `#/agent/{agentId}` | `agent-page.js` | Agent-Editor |
| `#/cronjobs` | `cronjob-page.js` | Cronjob-Verwaltung |
| `#/profile` | `profile-page.js` | Profil |
| `#/settings` | `settings-page.js` | App-Einstellungen |
| `#/login` | `login-page.js` | Login |
| `#/shared/{token}` | `shared-page.js` | Öffentliche geteilte Nachricht (kein Auth) |
### Kern-Module
- **app.js** – Initialisierung, Auth-Check, globale Event-Handler
- **api.js** – Zentraler API-Client mit `fetch()`-Wrapper, Auth-Redirect bei 401
- **ui.js** – UI-Utilities (Modals, Toasts, Confirmations, etc.)
- **chat.js** – SSE-Stream-Handling, Markdown-Rendering, Tool-Output-Darstellung
- **history.js** – Chat-History laden, paginieren, rendern
- **session.js** – Session-State-Management
- **file-explorer.js** – Workspace File-Explorer Panel
- **commands-ui.js** – Custom-Commands UI-Komponente
- **emoji.js** – Emoji-Picker mit Kategorien und Suche
- **tooltip.js** – Tooltip-System für Hover-Infos
- **title.js** – Dynamisches Tab-Titel-Management
### Styling
CSS ist in modulare Dateien aufgeteilt mit CSS Custom Properties für Theming:
- `theme.css` – Alle Farben, Abstände, Schriften als CSS Variables
- `base.css` – Reset und Grundlayout
- `main.css` – Sidebar, Content-Area, Responsive Layout
- `chat.css` – Chat-Bubbles, Streaming-Animation, Tool-Outputs
- `markdown.css` – Rendering von Markdown in Nachrichten
- `mobile.css` – Responsive Breakpoints und Anpassungen
---
## Chat-Pipeline
Der Chat-Flow von User-Input bis zur gerenderten Antwort:
```
1. User tippt Nachricht + optionale Attachments (Bilder/Dokumente)
↓
2. Frontend: POST /api/chat { content, sessionId }
↓
3. ChatEndpoint:
a) User-Message + Attachments in DB speichern
b) ChatService.PrepareContext() → Agent, Model, System-Prompt, Chain
c) ChatService.BuildHistoryFromDb() → vollständige Message-History
d) AnthropicService.StreamChat() starten
↓
4. AnthropicService (Agentic Loop):
┌─────────────────────────────────────────┐
│ while (iterations < maxIterations) │
│ → Claude API Request (SSE) │
│ → Stream-Processing: │
│ • Text-Tokens → SSE an Frontend │
│ • Tool-Use → ToolService.Execute() │
│ • Tool-Results → nächste Iteration │
│ → Messages in DB persistieren │
│ → Stop wenn: end_turn / max_iterations│
└─────────────────────────────────────────┘
↓
5. Frontend: SSE Events empfangen und rendern
• "text" → Markdown parsen, Token für Token anzeigen
• "tool_*" → Tool-Aufrufe collapsible darstellen
• "done" → Token-Stats, Dauer, Model anzeigen
```
### Streaming vs Non-Streaming
- **Web-Chat**: Streaming via SSE (`text/event-stream`). Tokens werden in Echtzeit gerendert.
- **Telegram**: Non-Streaming via `ChatNonStreaming()`. Vollständige Antwort wird abgewartet und als Telegram-Nachricht gesendet.
- **Cronjobs**: Non-Streaming, wie Telegram.
### History-Optimierung
Die History-Rekonstruktion in `BuildHistoryFromDb()` ist optimiert:
- **Ältere Chains**: Nur `text`-Messages (user + assistant), keine Tool-Calls
- **Letzte Chain**: Vollständig mit allen Tool-Use/Tool-Result Blöcken
- **Attachments**: Nur für die letzte User-Message geladen (spart enorme Token)
- **Tool-Results**: In der History auf 20.000 Zeichen gekürzt (vollständig in DB)
---
## Tool-System
Der Agent hat Zugriff auf folgende Tools, abhängig von Konfiguration:
### Datei-Tools (wenn Workspace konfiguriert)
| Tool | Beschreibung |
|---------------|--------------------------------------------------|
| `read_file` | Datei lesen (relativer Pfad zum Workspace) |
| `write_file` | Datei erstellen/überschreiben |
| `edit_file` | Exakten Textabschnitt in Datei ersetzen |
| `list_files` | Verzeichnis-Listing |
| `delete_file` | Datei oder leeres Verzeichnis löschen |
| `execute` | Shell-Befehl ausführen (bash, 180s Timeout) |
| `glob` | Dateien via Glob-Pattern finden |
| `grep` | Dateien nach Regex/Text durchsuchen |
| `todo_write` | Todo-Liste schreiben (als Datei im Workspace) |
### Memory-Tools (wenn UseMemory aktiviert)
| Tool | Beschreibung |
|----------------|-------------------------------------------|
| `memory_read` | Memory-Datei des Agents lesen |
| `memory_write` | Memory-Datei schreiben (überschreiben/append) |
| `memory_list` | Alle Memory-Dateien des Agents auflisten |
### Web-Suche (wenn WebSearchVersion konfiguriert)
Nutzt Anthropics eingebaute Web-Suche als Server-Side-Tool.
### Tool-Choice Strategien
- **`any`**: Erste Iteration erzwingt Tool-Nutzung, danach `auto`. Verhindert dass der Agent nur Text antwortet wenn Tools benötigt werden.
- **`auto`**: Claude entscheidet frei ob Tools nötig sind.
### Pfad-Sicherheit
Alle Dateipfade werden via `ResolvePath()` aufgelöst und gegen den Workspace/Memory-Ordner geprüft – Path-Traversal-Angriffe werden verhindert.
---
## Agent-System
Ein **Agent** definiert die Persönlichkeit und Fähigkeiten der AI:
| Eigenschaft | Beschreibung |
|-------------------|------------------------------------------------------------------|
| `Name` | Anzeigename |
| `Avatar` | Base64 Data-URL (auf 512px resized) |
| `Model` | `sonnet`, `sonnet-4-5`, `sonnet-4-6`, `opus`, `opus-4-5`, `opus-4-6`, `haiku`, `haiku-4-5` |
| `ToolChoice` | `any` oder `auto` |
| `CustomCommands` | JSON-Array mit Slash-Commands (Label + Prompt) |
| `AutoCommit` | `""` (nichts), `"mention"` (verbieten), `"enforce"` (erzwingen), `"forbid"` (strikt verboten) |
| `UseSoul` | SOUL.md in System-Prompt einbinden |
| `UseIdentity` | IDENTITY.md in System-Prompt einbinden |
| `UseUserInfo` | User-Persona in System-Prompt einbinden |
| `UseMemory` | Memory-Tools aktivieren |
| `WebSearchVersion`| Web-Suche aktivieren (z.B. `web_search_20260209`) |
### Model-Auflösung
```
"sonnet" → claude-sonnet-4-6
"sonnet-4-5" → claude-sonnet-4-5
"opus" → claude-opus-4-6
"haiku" → claude-haiku-4-5
```
---
## System-Prompt-Aufbau
Der `SystemPromptBuilder` erzeugt den System-Prompt modular aus konfigurierbaren **Blöcken**:
```
┌──────────────────────────────────────────┐
│ 1. IDENTITY.md (UseIdentity) │ → Wer ist der Agent?
│ 2. SOUL.md (UseSoul) │ → Persönlichkeit, Verhalten
│ 3. User-Persona (UseUserInfo) │ → Infos über den User
│ 4. Tool-Nutzung (Workspace + any) │ → "IMMER Tools benutzen"
│ 5. Workspace-Info │ → Tools + Workspace-Pfad
│ 6. Session-Kontext │ → Freiformtext
│ 7. Skills (Agent-Skills) │ → Skill-Prompts
│ 8. Memory (UseMemory) │ → Memory-Regeln + MEMORY.md Inhalt
│ 9. Git-Verhalten (AutoCommit) │ → Commit-Regeln
│10. Verhaltensregeln (Workspace + any) │ → "IMMER Tools aufrufen"
│11. Erinnerung (Workspace + any) │ → Höchste Priorität: Tool-Aufrufe!
│12. Markierte Nachrichten │ → Vom User als wichtig markierte Messages
└──────────────────────────────────────────┘
```
Jeder Block hat:
- **Icon** – Font Awesome Icon-Klasse
- **Label** – Beschreibender Titel
- **Content** – Markdown-Text
Die Blöcke sind über die API als JSON abrufbar (`GET /api/sessions/{id}/system-prompt-blocks`), sodass das Frontend sie einzeln inspizierbar darstellen kann.
---
## Memory-System
Jeder Agent hat ein eigenes **Dateisystem-basiertes Gedächtnis**:
```
data/agents/{agentId}/
├── IDENTITY.md # Identität (aus Template initialisiert)
├── SOUL.md # Persönlichkeit (aus Template initialisiert)
├── MEMORY.md # Haupt-Memory (kuratierte Informationen)
└── memory/ # Unterordner für Tages-Logs, Themen
├── 2025-07-13.md
└── ...
```
### Funktionsweise
1. **Initialisierung**: Beim Erstellen eines Agents werden `IDENTITY.md` und `SOUL.md` aus `Templates/` kopiert
2. **Lesen**: Der Agent kann seine Memory-Dateien via `memory_read` Tool lesen
3. **Schreiben**: Via `memory_write` (überschreiben oder append)
4. **Auflisten**: Via `memory_list` alle Dateien durchsuchen
5. **System-Prompt**: `MEMORY.md` Inhalt wird automatisch in den System-Prompt eingebettet
6. **IDENTITY.md** und **SOUL.md**: Werden als eigene System-Prompt-Blöcke eingebunden (wenn aktiviert)
### Sandbox
Alle Pfade werden gegen das Agent-Verzeichnis geprüft – kein Zugriff außerhalb möglich.
---
## Skill-System
Skills sind **Dateisystem-basierte Erweiterungen** die einem Agent zugeordnet werden können:
```
data/skills/{slug}/
├── SKILL.md # Metadaten (Name, Description, Version im Frontmatter)
├── PROMPT.md # System-Prompt-Erweiterung (in Agent-Prompt eingebettet)
├── _meta.json # Alternative Metadaten (Fallback)
└── output/ # Skill-Output (Bilder, Dateien, etc.)
```
### SKILL.md Frontmatter
```yaml
---
name: Mein Skill
description: Beschreibung
version: 1.0
---
```
### Agent-Zuordnung
Skills werden über die `agent_skills` Tabelle einem Agent zugeordnet. Der `PROMPT.md`-Inhalt aller zugeordneten Skills wird als ein System-Prompt-Block eingefügt.
### Workspace-Implikation
Wenn ein Agent Skills hat aber kein Workspace konfiguriert ist, wird automatisch `/tmp` als Workspace gesetzt (damit `execute` für Skill-Commands funktioniert).
---
## Telegram-Integration
Sessions können mit einem **Telegram Bot** verbunden werden:
### Konfiguration
Pro Session werden gespeichert:
- `TelegramBotToken` – Bot-Token von @BotFather
- `TelegramWebhookSecret` – Geheimer Token für Webhook-Verifizierung
- `TelegramChatId` – Verknüpfte Chat-ID
### Webhook-Flow
```
1. User konfiguriert Bot-Token in Session-Settings
2. User registriert Webhook (POST .../telegram/register-webhook)
→ Setzt Webhook-URL: {baseUrl}/api/telegram/webhook/{sessionId}
3. Telegram sendet Updates an Webhook
4. AuthMiddleware lässt Webhook-Requests durch (kein Cookie nötig)
5. TelegramEndpoint prüft X-Telegram-Bot-Api-Secret-Token Header
6. TelegramService verarbeitet Update:
- /start → Session verknüpfen
- /clear → History archivieren
- /status → Session-Info anzeigen
- /unlink → Verknüpfung aufheben
- Text → An Claude weiterleiten (Non-Streaming)
```
### Non-Streaming Chat
Telegram-Nachrichten werden über `AnthropicService.ChatNonStreaming()` verarbeitet. Die History wird genauso aus der DB aufgebaut wie beim Web-Chat. Antworten über 4096 Zeichen werden automatisch in Chunks aufgeteilt.
---
## Cronjob-System
Der `CronjobService` ist ein **BackgroundService** der minütlich nach fälligen Jobs prüft.
### Datenmodell
| Feld | Beschreibung |
|---------------------|------------------------------------------------|
| `CronExpression` | Standard-Cron-Format (5 Felder), via Cronos |
| `SessionId` | Session in der der Job läuft |
| `Prompt` | Text der als User-Message an Claude gesendet wird |
| `NotifySessionId` | Optionale Session für Benachrichtigung |
| `IsEnabled` | Aktiviert/Deaktiviert |
| `NextRunAt` | Nächste geplante Ausführung (UTC) |
### Ausführungsflow
```
1. CronjobService prüft jede Minute
2. Fällige Jobs (next_run_at <= jetzt) werden geladen
3. Für jeden Job:
a) ChatService.PrepareContext() – Chain + System-Prompt aufbauen
b) History aus DB laden
c) Prompt als User-Message anhängen + in DB speichern
d) AnthropicService.ChatNonStreaming() ausführen
e) Telegram-Benachrichtigung senden (auf Arbeits-Session)
f) Optional: Zusammenfassung in Notify-Session schreiben + Telegram dort
g) Nächste Ausführung berechnen + DB aktualisieren
```
### Benachrichtigungen
- **Arbeits-Session**: Wenn die Session Telegram hat, wird die Antwort dort gepostet
- **Notify-Session**: Wenn konfiguriert, wird eine Zusammenfassung in eine andere Session geschrieben und der Agent dort antwortet darauf
---
## Krea-Bildgenerierung
Die `KreaService` ermöglicht Bildgenerierung über die Krea API.
### Unterstützte Modelle
```
flux, flux-kontext, flux-1.1-pro, flux-1.1-pro-ultra,
nano-banana, nano-banana-pro, imagen-3, imagen-4, imagen-4-fast, imagen-4-ultra,
ideogram-2-turbo, ideogram-3, seedream-3, seedream-4,
chatgpt-image, runway-gen-4
```
### Flow
```
1. POST /api/images/generate { prompt, model, width, height, ... }
2. KreaService sendet Request an Krea API
3. Job-Polling bis Status "completed"
4. Bilder herunterladen nach data/images/
5. Metadaten als JSON speichern
6. Response mit Dateinamen + URLs
```
### Bild-Serving
- `GET /api/images` – Liste aller generierten Bilder (aus Metadaten-JSON)
- `GET /api/images/file/{filename}` – Einzelnes Bild ausliefern
---
## Auth & Multi-User
### Authentifizierung
- **Login**: Username + Passwort → SHA256 Hash-Vergleich → Token generieren
- **Token**: 32 Bytes Random, als `gott_token` HttpOnly Cookie (365 Tage)
- **Validierung**: Jeder API-Call prüft Token → User-ID
- **Logout**: Token aus DB löschen + Cookie entfernen
### Multi-User-Isolation
- Sessions sind an `user_id` gebunden
- Agents sind an `user_id` gebunden
- Cronjobs sind an `user_id` gebunden
- Jeder User sieht nur seine eigenen Daten
- Admin-Flag (`is_admin`) für Backup-Endpoint
### Default-User
Beim ersten Start wird automatisch ein Default-User erstellt (`DatabaseService.EnsureDefaultUser()`).
### User-Persona
Jeder User hat eine optionale **Persona** – ein Freitext der beschreibt wer er ist. Diese wird (wenn `UseUserInfo` am Agent aktiv ist) in den System-Prompt als "Dein Gegenüber" eingebettet.
---
## Nachrichten teilen (Shared Messages)
Einzelne Nachrichten oder ganze Threads können als **öffentliche Links** geteilt werden – ohne Login aufrufbar.
### Datenmodell
**Tabelle `shared_messages`:**
| Spalte | Typ | Beschreibung |
|------------------|---------|-------------------------------------------|
| `id` | INTEGER | Primary Key |
| `share_token` | TEXT | UUID – öffentlicher Zugangsschlüssel |
| `message_id` | INTEGER | FK auf `messages.id` |
| `user_id` | INTEGER | Wer hat geteilt |
| `include_context`| INTEGER | 0 = Einzelnachricht, 1 = Thread bis dahin |
| `created_at` | TEXT | Erstellzeitpunkt |
| `expires_at` | TEXT | Optional: Ablaufdatum |
### API-Endpunkte (`SharedEndpoint.cs`)
| Methode | Route | Auth | Beschreibung |
|----------|--------------------------------|------|---------------------------------------|
| `POST` | `/api/messages/{id}/share` | ✅ | Share erstellen (Body: `{includeContext}`) |
| `GET` | `/api/shared/{token}` | ❌ | Öffentlich: Geteilte Nachricht abrufen |
| `GET` | `/api/shared` | ✅ | Eigene Shares auflisten |
| `DELETE` | `/api/shared/{token}` | ✅ | Share-Link widerrufen |
### Frontend-Flow
1. **Share-Button** (🔗) erscheint an jeder Nachricht im Chat (neben Reply, Delete, Mark)
2. Klick öffnet **Kontext-Menü**: "Einzelne Nachricht" oder "Thread teilen"
3. `POST /api/messages/{id}/share` → Token zurück → URL in Zwischenablage kopiert
4. **Toast**: "Link kopiert!"
### Öffentliche Ansicht (`#/shared/{token}`)
- Route `#/shared/{token}` → `shared-page.js`
- **Kein Auth nötig** – Auth-Bypass in `app.js` + `AuthMiddleware`
- Minimales Layout: Header ("// gott · Geteilte Nachricht"), Nachrichten mit Markdown-Rendering
- Zwei Modi: `single` (eine Nachricht) oder `context` (Thread mit User/Assistant-Wechsel)
---
## Workspace & File-Explorer
### Workspace
Eine Session kann einen **Workspace-Pfad** haben (z.B. `/app/gott`). Dieser:
- Aktiviert die Datei-/Shell-Tools für den Agent
- Ermöglicht den File-Explorer im Frontend
- Bietet `git status` Informationen
- Erlaubt das Ausführen von Shell-Befehlen (foreground + background)
### File-Explorer API
| Endpoint | Beschreibung |
|-----------------------------------|----------------------------------------|
| `GET /api/workspace/tree` | Verzeichnisbaum (mit Ignore-Filtern) |
| `GET /api/workspace/file` | Dateiinhalt lesen (max 2MB) |
| `PUT /api/workspace/file` | Datei speichern |
| `GET /api/workspace/browse` | Verzeichnis-Browser (für Pfad-Auswahl)|
| `GET /api/workspace/raw` | Raw-Datei ausliefern (Bilder, PDFs) |
| `GET /api/workspace/agent/tree` | Agent-Memory-Verzeichnis |
| `GET/PUT /api/workspace/agent/file` | Agent-Memory-Dateien lesen/schreiben |
### Ignored Directories
`bin`, `obj`, `node_modules`, `.git`, `.vs`, `.idea`, `publish`, `dist`, `out`, `build`, `target`, `.cache`
### Session-Exec
`POST /api/sessions/{id}/exec` führt Shell-Befehle im Workspace aus:
- **foreground**: Synchron, wartet auf Ergebnis (30s Timeout)
- **background**: Fire-and-forget via `systemd-run`
---
## Windows Desktop App
Im `WindowsApp/`-Ordner liegt ein minimaler **WPF WebView2 Client**:
- .NET 10 Windows, `Microsoft.Web.WebView2`
- Lädt die Web-UI in einem nativen Fenster
- Server-URL konfigurierbar via `appsettings.json`
- Dark Background um weißen Flash zu vermeiden
- Externe Links öffnen im Standard-Browser
- Fenster: 930px breit, 95% Bildschirmhöhe, zentriert
---
## Deployment
### deploy.sh
```bash
#!/bin/bash
set -e
cd /app/gott
export PATH="$HOME/.dotnet:$PATH"
systemctl stop gott
dotnet publish -c Release -o publish
systemctl start gott
echo "OK"
```
### Verzeichnisse
- **Quell-Code**: `/app/gott/` (wwwroot/, Services/, etc.)
- **Build-Output**: `/app/gott/publish/`
- **Laufzeit-Daten**: `/app/gott/publish/data/` (DB, Agents, Images, Skills)
- **WICHTIG**: Änderungen IMMER in `wwwroot/` machen, NIEMALS in `publish/wwwroot/`
### systemd
Die Anwendung läuft als systemd Service (`gott.service`), Kestrel auf Port 19000.
---
## Konfiguration
### appsettings.json
```json
{
"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)
}
```
### Environment
- `ASPNETCORE_ENVIRONMENT=Production` → lädt `appsettings.Production.json`
- Tokens und Secrets sollten in `appsettings.Production.json` stehen (nicht in Git)
---
## Datenbank-Migrationen
Die `DatabaseService.InitializeDatabase()` handhabt Schema-Erstellung und Migrationen in einem einzigen Methoden-Aufruf:
1. **Tabellen-Erstellung** via `CREATE TABLE IF NOT EXISTS`
2. **Spalten-Migration** via `TryAddColumn()` – fängt "column already exists" ab
3. **Daten-Migration** (z.B. `auto_commit` von INTEGER zu TEXT, `use_web_search` zu `web_search_version`)
Dieses Pattern ermöglicht:
- Idempotente Ausführung bei jedem App-Start
- Keine separate Migrations-Verwaltung nötig
- Neue Features können einfach Spalten hinzufügen
- Abwärtskompatibel – bestehende Daten bleiben erhalten