docs: ARCHITECTURE.md + ARCHITECTURE_QUICK.md aktualisiert
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
This commit is contained in:
1 parent
011b26c37f
commit
a82540e7db
2 files changed
+211
-40
No files matched your search
+197
-34
@@ -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 <code class="katex-error">
|
||||
```
|
||||
|
||||
### 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**:
|
||||
|
||||
+14
-6
@@ -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
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user