From a82540e7db631eee30bb66f6db6d0fb869a424d2 Mon Sep 17 00:00:00 2001 From: Meleki Date: Fri, 6 Mar 2026 13:12:42 +0100 Subject: [PATCH] docs: ARCHITECTURE.md + ARCHITECTURE_QUICK.md aktualisiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Neue Kapitel in ARCHITECTURE.md: - Admin-Benutzerverwaltung (CRUD, Impersonate) - Avatar-System (Editor-Modal, Scale, AI-Generate) - LaTeX/Math-Rendering (KaTeX-Pipeline) Erweiterte Kapitel: - Projektstruktur: WorkspaceHelper, AdminEndpoint, avatar-editor.js, admin-page.js, KaTeX-Dateien - Tech-Stack: KaTeX 0.16.21 - Datenmodell: default_path, avatar_scale, telegram_allowed_chat_ids - Endpoints: Admin (16 Gruppen), Workspace (mkdir/rmdir) - Chat-Pipeline: CancellationToken-Propagierung (Stop-Button) - Telegram: Chat-ID-Whitelist + Zugriffskontrolle - Auth: DefaultPath als Base-Path, Impersonate - Workspace: WorkspaceHelper, relativer Pfad-Auflösung - Frontend: avatar-editor.js, admin-page, KaTeX, Timestamps ARCHITECTURE_QUICK.md: - Admin-Endpoint, WorkspaceHelper, KaTeX, DefaultPath, Impersonate, CancellationToken --- ARCHITECTURE.md | 231 +++++++++++++++++++++++++++++++++++------- ARCHITECTURE_QUICK.md | 20 ++-- 2 files changed, 211 insertions(+), 40 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 35e3c86..520bf07 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -28,12 +28,15 @@ 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) +17. [Admin-Benutzerverwaltung](#admin-benutzerverwaltung) +18. [Nachrichten teilen (Shared Messages)](#nachrichten-teilen-shared-messages) +19. [Workspace & File-Explorer](#workspace--file-explorer) +20. [Avatar-System](#avatar-system) +21. [LaTeX/Math-Rendering](#latexmath-rendering) +22. [Windows Desktop App](#windows-desktop-app) +23. [Deployment](#deployment) +24. [Konfiguration](#konfiguration) +25. [Datenbank-Migrationen](#datenbank-migrationen) --- @@ -46,10 +49,10 @@ ├─────────────────────────────────────────────────────────────┤ │ ASP.NET 10 Minimal API │ │ http://0.0.0.0:19000 │ -├──────┬──────┬──────┬──────┬──────┬──────┬──────┬───────────┤ -│ Auth │ Chat │ Hist │ Sess │Agent │ Tele │ Cron │ Krea │ -│ │ SSE │ │ │ │ gram │ jobs │ Images │ -├──────┴──────┴──────┴──────┴──────┴──────┴──────┴───────────┤ +├──────┬──────┬──────┬──────┬──────┬──────┬──────┬──────┬────┤ +│ Auth │ Chat │ Hist │ Sess │Agent │ Tele │ Cron │ Krea │Adm │ +│ │ SSE │ │ │ │ gram │ jobs │ Img │ in │ +├──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┴────┤ │ Services Layer │ │ AnthropicService · ChatService · ToolService │ │ DatabaseService · MemoryService · SkillService │ @@ -78,6 +81,7 @@ | **Cron** | Cronos (Cron-Expression-Parsing) | | **Frontend** | Vanilla JavaScript SPA (kein Framework) | | **Markdown** | marked.js (Client-side Rendering) | +| **LaTeX** | KaTeX 0.16.21 (Math-Rendering, self-hosted mit woff2-Fonts) | | **Editor** | CodeMirror 5 + EasyMDE | | **Icons** | Font Awesome | | **Fonts** | Inter, JetBrains Mono (self-hosted) | @@ -120,7 +124,8 @@ gott/ │ ├── 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 +│ ├── StreamingTracker.cs # Concurrent Tracking aktiver Streams +│ └── WorkspaceHelper.cs # Workspace-Pfad-Auflösung (relativ → absolut) │ ├── Endpoints/ # HTTP API (Minimal API) │ ├── AuthEndpoint.cs # Login, Logout, Me @@ -134,6 +139,7 @@ gott/ │ ├── KreaEndpoint.cs # Generate, List, File-Serve │ ├── SkillEndpoint.cs # List, Agent-Skill-Mapping, Output-Files │ ├── SharedEndpoint.cs # Nachrichten teilen (öffentliche Links) +│ ├── AdminEndpoint.cs # Admin: User-CRUD, Impersonate (Admin-only) │ ├── ProfileEndpoint.cs # Profil, Persona, Passwort │ ├── SettingsEndpoint.cs # User-Settings (JSON blob) │ ├── BackupEndpoint.cs # Backup als tar.gz Download @@ -158,16 +164,18 @@ gott/ │ │ ├── main.css # Sidebar, Layout-Struktur │ │ ├── chat.css # Chat-Nachrichten, Bubbles │ │ ├── dashboard.css # Dashboard-Grid -│ │ ├── form.css # Formulare, Inputs -│ │ ├── markdown.css # Markdown-Rendering-Styles +│ │ ├── form.css # Formulare, Inputs, Avatar-Editor-Modal +│ │ ├── markdown.css # Markdown + KaTeX 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 +│ │ ├── katex.min.css # KaTeX Math-Rendering Styles │ │ ├── codemirror.min.css # CodeMirror Editor -│ │ └── easymde.min.css # EasyMDE Editor +│ │ ├── easymde.min.css # EasyMDE Editor +│ │ └── fonts/ # KaTeX woff2 Fonts (21 Dateien) │ ├── js/ │ │ ├── app.js # App-Initialisierung, Auth-Check │ │ ├── router.js # Client-side SPA Router @@ -177,6 +185,7 @@ gott/ │ │ ├── history.js # History-Rendering, Pagination │ │ ├── session.js # Session-Verwaltung │ │ ├── file-explorer.js # File-Explorer Komponente +│ │ ├── avatar-editor.js # Wiederverwendbares Avatar-Editor-Modal │ │ ├── commands-ui.js # Custom-Commands UI │ │ ├── emoji.js # Emoji-Picker │ │ ├── emoji.userdata.js # Häufig genutzte Emojis @@ -189,6 +198,7 @@ gott/ │ │ │ ├── agent-page.js # Agent-Editor │ │ │ ├── cronjob-page.js # Cronjob-Verwaltung │ │ │ ├── profile-page.js # Profil-Bearbeitung +│ │ │ ├── admin-page.js # Admin: Benutzerverwaltung │ │ │ ├── settings-page.js # App-Einstellungen │ │ │ ├── login-page.js # Login-Formular │ │ │ └── shared-page.js # Öffentliche geteilte Nachricht @@ -197,6 +207,7 @@ gott/ │ │ ├── codemirror.min.js # Code Editor │ │ ├── codemirror.cjs # CM CommonJS Wrapper │ │ ├── easymde.min.js # Markdown Editor +│ │ ├── katex.min.js # KaTeX Math-Rendering Engine │ │ └── cm-mode-*.min.js # CodeMirror Syntax-Modes │ ├── fonts/ # Self-hosted Fonts (Inter, JetBrains Mono) │ └── lib/font-awesome/ # Font Awesome Icons @@ -251,10 +262,10 @@ Message (1) ─── (*) SharedMessage | Tabelle | Beschreibung | |-------------------|-----------------------------------------------------| -| `users` | Benutzer (username, password_hash, persona, settings) | +| `users` | Benutzer (username, password_hash, persona, settings, default_path) | | `tokens` | Auth-Tokens (token → user_id) | -| `agents` | AI-Agenten (model, soul, identity, memory, tools) | -| `sessions` | Chat-Sessions (workspace, context, telegram-config) | +| `agents` | AI-Agenten (model, soul, identity, memory, tools, avatar_scale) | +| `sessions` | Chat-Sessions (workspace, context, telegram-config, avatar_scale, telegram_allowed_chat_ids) | | `chains` | Request-Chains (model, tokens, iterations, timing) | | `messages` | Einzelne Nachrichten (text, tool_use, tool_result) | | `attachments` | Datei-Anhänge (base64, image/document) | @@ -296,7 +307,7 @@ Die `Program.cs` ist der zentrale Einstiegspunkt und konfiguriert: 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 +5. **Endpoint-Mapping** – Alle 16 Endpoint-Gruppen registriert 6. **Server** – Kestrel auf `http://0.0.0.0:19000` Initialisierungsreihenfolge: @@ -317,6 +328,7 @@ AuthService → DatabaseService → EnsureDefaultUser | `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 | +| `WorkspaceHelper` | Static | Workspace-Pfad-Auflösung (relativ → absolut), Path-Traversal-Schutz | | `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 | @@ -337,7 +349,8 @@ Alle Endpoints folgen dem **Minimal API**-Pattern mit Extension Methods (`MapXxx | **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` | +| **Admin** | `/api/admin/` | `GET users`, `POST users`, `PUT users/{id}`, `PUT users/{id}/password`, `DELETE users/{id}`, `POST users/{id}/impersonate` (Admin-only) | +| **Workspace** | `/api/workspace/` | `GET tree`, `GET/PUT file`, `GET browse`, `POST mkdir`, `DELETE dir`, `POST browse/mkdir`, `GET agent/tree`, `GET/PUT agent/file`, `POST agent/mkdir`, `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` | @@ -397,6 +410,7 @@ Das Frontend ist eine **Single-Page Application** ohne Build-Step, komplett in V | `#/cronjobs` | `cronjob-page.js` | Cronjob-Verwaltung | | `#/profile` | `profile-page.js` | Profil | | `#/settings` | `settings-page.js` | App-Einstellungen | +| `#/admin` | `admin-page.js` | Benutzerverwaltung (Admin-only) | | `#/login` | `login-page.js` | Login | | `#/shared/{token}` | `shared-page.js` | Öffentliche geteilte Nachricht (kein Auth) | @@ -405,10 +419,11 @@ Das Frontend ist eine **Single-Page Application** ohne Build-Step, komplett in V - **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 +- **chat.js** – SSE-Stream-Handling, Markdown-Rendering (mit KaTeX), Tool-Output-Darstellung - **history.js** – Chat-History laden, paginieren, rendern - **session.js** – Session-State-Management -- **file-explorer.js** – Workspace File-Explorer Panel +- **file-explorer.js** – Workspace File-Explorer Panel (Dateien, Ordner erstellen/löschen, Folder-Browser) +- **avatar-editor.js** – Wiederverwendbares Avatar-Editor-Modal (Upload, Paste, AI-Generate, Scale) - **commands-ui.js** – Custom-Commands UI-Komponente - **emoji.js** – Emoji-Picker mit Kategorien und Suche - **tooltip.js** – Tooltip-System für Hover-Infos @@ -452,6 +467,7 @@ Der Chat-Flow von User-Input bis zur gerenderten Antwort: │ • Tool-Results → nächste Iteration │ │ → Messages in DB persistieren │ │ → Stop wenn: end_turn / max_iterations│ + │ → CancellationToken bei Abbruch │ └─────────────────────────────────────────┘ ↓ 5. Frontend: SSE Events empfangen und rendern @@ -460,6 +476,15 @@ Der Chat-Flow von User-Input bis zur gerenderten Antwort: • "done" → Token-Stats, Dauer, Model anzeigen ``` +### Abbruch (Stop-Button) + +Das `CancellationToken` wird durchgängig propagiert: +1. Frontend: `AbortController.abort()` → SSE-Fetch abgebrochen +2. ASP.NET: `RequestAborted` Token wird gecancelled +3. `AnthropicService`: `ThrowIfCancellationRequested()` am Loop-Anfang, vor/nach Tool-Execution +4. `WriteSseEvent()`: Alle SSE-Writes mit CancellationToken → sofortiger Abbruch bei Client-Disconnect +5. Chain wird mit `StopReason = "client_disconnected"` finalisiert + ### Streaming vs Non-Streaming - **Web-Chat**: Streaming via SSE (`text/event-stream`). Tokens werden in Echtzeit gerendert. @@ -652,7 +677,8 @@ Sessions können mit einem **Telegram Bot** verbunden werden: Pro Session werden gespeichert: - `TelegramBotToken` – Bot-Token von @BotFather - `TelegramWebhookSecret` – Geheimer Token für Webhook-Verifizierung -- `TelegramChatId` – Verknüpfte Chat-ID +- `TelegramChatId` – Verknüpfte Chat-ID (Owner) +- `TelegramAllowedChatIds` – Kommagetrennte Chat-ID-Whitelist für Zugriffskontrolle ### Webhook-Flow @@ -664,13 +690,23 @@ Pro Session werden gespeichert: 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 + - /start → Session verknüpfen (nur wenn noch kein Owner ODER Whitelist-Match) - /clear → History archivieren - /status → Session-Info anzeigen - /unlink → Verknüpfung aufheben - Text → An Claude weiterleiten (Non-Streaming) ``` +### Zugriffskontrolle (Chat-ID-Whitelist) + +Nicht jeder Telegram-User darf den Bot nutzen: + +1. **Erster `/start`**: Kein Owner → User wird automatisch Owner (`TelegramChatId` gesetzt) +2. **Fremder `/start`**: User bekommt `🔒 Zugriff verweigert` + seine Chat-ID angezeigt +3. **Owner-Benachrichtigung**: Owner erhält `🔔 Zugriffsanfrage` mit Username + Chat-ID +4. **Freigabe**: Owner/Admin trägt Chat-ID in Session-Settings ein (`TelegramAllowedChatIds`) +5. **Prüfung**: Alle Commands + Nachrichten prüfen via `IsChatIdAllowed()` (Owner + Whitelist) + ### 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. @@ -760,7 +796,18 @@ chatgpt-image, runway-gen-4 - 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 +- Admin-Flag (`is_admin`) für Backup-Endpoint, Admin-Benutzerverwaltung, Impersonate + +### Default-Path (Base-Path) + +Jeder User hat einen optionalen `DefaultPath` – den Basis-Ordner für alle Workspaces. Wird **nur vom Admin** gesetzt. + +- **Session-Workspace**: Speichert nur den **relativen Pfad** zum DefaultPath (z.B. `myapp` statt `/home/user/projects/myapp`) +- **Auflösung**: `WorkspaceHelper.ResolveWorkspace()` kombiniert DefaultPath + relativen Workspace → absoluter Pfad +- **System-Prompt**: Bekommt den **aufgelösten absoluten Pfad**, damit der Agent korrekt navigieren kann +- **Path-Traversal-Schutz**: `..` in relativen Workspace-Pfaden wird blockiert (400 Bad Request) +- **Legacy-Support**: Absolute Pfade in `session.Workspace` funktionieren weiterhin als Fallback +- **Folder-Browser**: Startet beim DefaultPath, User kann nicht über den Base-Path hinaus navigieren ### Default-User @@ -772,6 +819,37 @@ Jeder User hat eine optionale **Persona** – ein Freitext der beschreibt wer er --- +## Admin-Benutzerverwaltung + +Admins können alle User verwalten über `AdminEndpoint.cs` (alle Endpoints erfordern `is_admin`). + +### API-Endpunkte + +| Methode | Route | Beschreibung | +|----------|-----------------------------------------|-------------------------------------------| +| `GET` | `/api/admin/users` | Alle User auflisten | +| `POST` | `/api/admin/users` | Neuen User erstellen | +| `PUT` | `/api/admin/users/{id}` | User bearbeiten (Name, Username, Admin, DefaultPath) | +| `PUT` | `/api/admin/users/{id}/password` | Passwort zurücksetzen | +| `DELETE` | `/api/admin/users/{id}` | User löschen (+ Tokens, Shared Messages) | +| `POST` | `/api/admin/users/{id}/impersonate` | Als anderer User einloggen (Login-as-User) | + +### Impersonate (Login-as-User) + +Admins können sich als beliebiger User einloggen ohne dessen Passwort zu kennen: +1. `POST /api/admin/users/{id}/impersonate` → Erstellt Token für Zieluser +2. Setzt neuen `gott_token`-Cookie → Admin-Session wird zum Zieluser +3. `location.reload()` → Frontend lädt mit neuem User-Kontext + +### Frontend (`admin-page.js`) + +- Erreichbar über Dashboard-Link "Benutzerverwaltung" (nur für Admins sichtbar) +- User-Liste als Cards mit Edit/Delete/Impersonate-Buttons +- Inline-Formular für Create/Edit +- Sich selbst löschen ist nicht möglich + +--- + ## Nachrichten teilen (Shared Messages) Einzelne Nachrichten oder ganze Threads können als **öffentliche Links** geteilt werden – ohne Login aufrufbar. @@ -818,23 +896,37 @@ Einzelne Nachrichten oder ganze Threads können als **öffentliche Links** getei ### Workspace -Eine Session kann einen **Workspace-Pfad** haben (z.B. `/app/gott`). Dieser: +Eine Session kann einen **Workspace-Pfad** haben. Dieser wird **relativ** zum `DefaultPath` des Users gespeichert (z.B. `myapp`) und via `WorkspaceHelper.ResolveWorkspace()` zum absoluten Pfad aufgelöst. Der Workspace: - 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) +### WorkspaceHelper + +`Services/WorkspaceHelper.cs` – Statische Hilfsklasse für Workspace-Pfade: + +| Methode | Beschreibung | +|----------------------------|-----------------------------------------------------------| +| `ResolveWorkspace(session, user)` | Relativer Workspace + DefaultPath → absoluter Pfad | +| `ValidateRelativeWorkspace(workspace)` | Prüft auf `..`, `~`, absolute Pfade → null bei ungültig | +| `ToRelativeWorkspace(absolute, defaultPath)` | Absoluter Pfad → relativ zum DefaultPath | + ### 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 | +| Endpoint | Beschreibung | +|-------------------------------------|------------------------------------------| +| `GET /api/workspace/tree` | Verzeichnisbaum (mit Ignore-Filtern) | +| `GET /api/workspace/file` | Dateiinhalt lesen (max 2MB) | +| `PUT /api/workspace/file` | Datei speichern | +| `POST /api/workspace/mkdir` | Ordner erstellen im Workspace | +| `DELETE /api/workspace/dir` | Leeren Ordner löschen im Workspace | +| `GET /api/workspace/browse` | Verzeichnis-Browser (für Pfad-Auswahl) | +| `POST /api/workspace/browse/mkdir` | Ordner erstellen per absolutem Pfad | +| `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 | +| `POST /api/workspace/agent/mkdir` | Ordner erstellen im Agent-Memory | ### Ignored Directories @@ -848,6 +940,77 @@ Eine Session kann einen **Workspace-Pfad** haben (z.B. `/app/gott`). Dieser: --- +## Avatar-System + +Sessions und Agents können ein **Bild/Avatar** haben mit konfigurierbarem Zoom. + +### Datenfelder + +| Feld | Tabellen | Beschreibung | +|------|----------|-------------| +| `image` / `avatar` | `sessions` / `agents` | Base64-kodiertes Bild (JPEG, max 512px via ImageService) | +| `avatar_scale` | `sessions`, `agents` | Zoom-Faktor (0.5× – 3×, Default 1.0), angewandt via CSS `transform: scale()` | + +### Avatar-Editor (`avatar-editor.js`) + +Wiederverwendbares Modal-Modul, genutzt in Session- und Agent-Pages: + +```javascript +const editor = AvatarEditor.init({ + previewEl: document.querySelector('.avatar-preview'), + currentImage: existingBase64OrNull, + currentScale: 1.0, + onImageChange: (base64) => { /* Preview aktualisieren */ }, + onScaleChange: (scale) => { /* Live-Preview skalieren */ } +}); +// Werte auslesen: editor.getImage(), editor.getScale() +// Aufräumen: editor.destroy() +``` + +**Features:** +- **Upload**: Datei-Input für Bild-Upload +- **Paste**: Ctrl+V → Bild aus Zwischenablage einfügen +- **AI-Generate**: Text-Prompt → Krea API → Bild generieren (nur wenn `KreaToken` konfiguriert) +- **Scale**: Range-Slider 0.5× – 3× mit Live-Preview +- **Clear**: Bild entfernen + +### Dashboard-Darstellung + +Cards zeigen Avatare mit `transform: scale(avatarScale)` im `.card-image` Container (`overflow: hidden`). + +--- + +## LaTeX/Math-Rendering + +Chat-Nachrichten unterstützen **LaTeX-Formeln** via KaTeX: + +### Syntax + +- `$$...$$` → **Block-Math** (zentriert, eigene Zeile) +- `$...$` → **Inline-Math** (im Fließtext) + +### Rendering-Pipeline (in `ui.js` `renderMarkdown()`) + +``` +1. Code-Blöcke extrahieren und schützen (Platzhalter) +2. Block-LaTeX ($$...$$) extrahieren und schützen +3. Inline-LaTeX ($...$) extrahieren und schützen +4. Markdown-Rendering via marked.js +5. Code-Blöcke wiederherstellen +6. LaTeX-Platzhalter durch KaTeX.renderToString() ersetzen +7. Bei fehlerhaftem LaTeX: Fallback als +``` + +### Abhängigkeiten + +- `wwwroot/js/lib/katex.min.js` – KaTeX Engine (v0.16.21) +- `wwwroot/css/katex.min.css` – Styles +- `wwwroot/css/fonts/` – 21 woff2-Fonts (self-hosted) + +Funktioniert überall wo `renderMarkdown()` aufgerufen wird: Chat, Streaming, History, Archiv, Shared Page. + +--- + ## Windows Desktop App Im `WindowsApp/`-Ordner liegt ein minimaler **WPF WebView2 Client**: diff --git a/ARCHITECTURE_QUICK.md b/ARCHITECTURE_QUICK.md index 08d8bb2..528bc9f 100644 --- a/ARCHITECTURE_QUICK.md +++ b/ARCHITECTURE_QUICK.md @@ -6,7 +6,7 @@ ## Tech-Stack -**.NET 10** Minimal API · **SQLite** + Dapper · **Anthropic Claude API** (SSE Streaming) · **Vanilla JS** SPA · **Kestrel** auf Port 19000 +**.NET 10** Minimal API · **SQLite** + Dapper · **Anthropic Claude API** (SSE Streaming) · **Vanilla JS** SPA · **KaTeX** (Math) · **Kestrel** auf Port 19000 --- @@ -17,7 +17,7 @@ gott/ ├── Program.cs # Startup, DI, Middleware, Routing ├── appsettings.json # Tokens, API-Keys, Limits ├── Models/ # Records (reine Daten) -├── Services/ # Business-Logic (alle Singletons) +├── Services/ # Business-Logic (alle Singletons + WorkspaceHelper) ├── Endpoints/ # HTTP API (Minimal API MapXxx-Pattern) ├── Middleware/ # AuthMiddleware ├── Templates/ # Vorlagen für neue Agents (IDENTITY, SOUL, USER) @@ -51,10 +51,10 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At | Tabelle | Zweck | |---------|-------| -| `users` | Login, Persona, Settings (JSON) | +| `users` | Login, Persona, Settings (JSON), DefaultPath | | `tokens` | Auth-Tokens → User | -| `agents` | AI-Agenten (Model, Tools, Config) | -| `sessions` | Chat-Sessions (Workspace, Context, Telegram) | +| `agents` | AI-Agenten (Model, Tools, Config, AvatarScale) | +| `sessions` | Chat-Sessions (Workspace, Context, Telegram, AvatarScale, AllowedChatIds) | | `chains` | Ein Request-Response-Zyklus (Tokens, Timing, Iterations) | | `messages` | Einzelne Nachrichten (text / tool_use / tool_result / error) | | `attachments` | Base64-Anhänge (Bilder, Dokumente) | @@ -75,7 +75,8 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At | History | `/api/history` | GET history, poll, archive, marks, delete | | Sessions | `/api/sessions/` | CRUD + system-prompt, exec, git-status | | Agents | `/api/agents/` | CRUD | -| Workspace | `/api/workspace/` | tree, file read/write, browse, agent-files | +| Admin | `/api/admin/` | User CRUD, impersonate (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 | @@ -97,6 +98,7 @@ User 1──* Agent 1──* Session 1──* Chain 1──* Message 1──* At | **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 | @@ -121,11 +123,14 @@ User-Input → POST /api/chat (SSE) → Token-für-Token an Client streamen → Bei tool_use → ToolService.Execute() → Ergebnis zurück → neuer API Call → Loop bis end_turn oder max_iterations (100) + → CancellationToken bei Stop-Button → 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 (12 Tools) @@ -179,6 +184,7 @@ User-Input → POST /api/chat (SSE) | `#/cronjobs` | `cronjob-page.js` | Cronjobs | | `#/profile` | `profile-page.js` | Profil | | `#/settings` | `settings-page.js` | Einstellungen | +| `#/admin` | `admin-page.js` | Benutzerverwaltung (Admin) | | `#/login` | `login-page.js` | Login | | `#/shared/{token}` | `shared-page.js` | Geteilte Nachricht (öffentlich, kein Auth) | @@ -189,6 +195,8 @@ User-Input → POST /api/chat (SSE) 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, Telegram-Webhook und `GET /api/shared/{token}` brauchen kein Auth +4. **Impersonate**: Admin kann via `POST /api/admin/users/{id}/impersonate` als anderer User einloggen +5. **DefaultPath**: Pro User ein Basis-Ordner (nur vom Admin setzbar), Session-Workspaces sind relativ dazu ---