Files
gott/ARCHITECTURE_QUICK.md
T
MelekiandClaude Opus 4.7 b47ca33259 docs: Doku-Diskrepanzen bereinigt (MaxHistory 220, Opus 4.7, Review-Iterationen)
- README: MaxHistory Default 120 → 220 (entspricht Code)
- ARCHITECTURE.md: Modell-Liste um opus-4-7, opus-4-7[1m], opus-4-6[1m], sonnet-4-6[1m] ergänzt
- ARCHITECTURE.md + QUICK: Review-Tool-Loop von 25 → 20 Iterationen korrigiert (laut MaxIterations in AnthropicService.Agents.cs)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 17:06:10 +02:00

23 KiB
Raw Blame History

ARCHITECTURE_QUICK.md – Schnellreferenz

Kurzfassung der ARCHITECTURE.md für schnelles Nachschlagen beim Entwickeln.


Tech-Stack

.NET 10 Minimal API · SQLite + Dapper · Anthropic Claude API (SSE Streaming + Claude CLI) · OpenAI-kompatible APIs (Nvidia, Pollinations, Gemini, OpenAI) · ONNX Runtime (Sentence-Embeddings) · 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, inkl. ApiKeyRecord)
├── Services/                   # Business-Logic (Singletons + Static Helpers)
│   ├── DatabaseService*.cs     # Partial Classes (Core, Sessions, Agents, Users, Integrations)
│   ├── AnthropicService*.cs    # Partial Classes (Core, Streaming, Agents, Cli)
│   ├── ClaudeCliService.cs     # Claude Code CLI Wrapper (OAuth-basiert)
│   ├── SseHelper.cs            # Shared SSE-Utilities
│   ├── EmbeddingService.cs     # Lokales Sentence-Embedding (ONNX)
│   ├── VectorSearchService.cs  # Semantische Suche
│   ├── RemoteConnectionManager.cs # WebSocket Remote-Verbindungen
│   ├── AppPaths.cs             # Zentrale Pfade (WwwRoot, Dev vs. Publish)
│   ├── KeyScannerService.cs    # GitHub API-Key-Scanner
│   ├── GitHubEventScannerService.cs # Echtzeit-Scanner (GitHub Events API)
│   ├── KeyPatterns.cs          # Zentrale Key-Pattern-Definitionen (Regex + Typ-Erkennung)
│   ├── KeyCheckDispatcher.cs   # Zentraler Key-Check-Dispatcher (alle Provider)
│   ├── AnthropicKeyChecker.cs  # Anthropic Key-Validierung + Usage-Auswertung
│   ├── OpenAiKeyChecker.cs     # OpenAI Key-Validierung
│   ├── GoogleKeyChecker.cs     # Google/Gemini Key-Validierung
│   └── StripeKeyChecker.cs     # Stripe Key-Validierung
├── 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/ui-helpers.js        # DOM-Helpers ($, esc, truncate), Toast, ScrollDown
│   ├── js/markdown.js          # Markdown-Rendering (renderMarkdown, LaTeX-Schutz)
│   ├── js/cards.js             # Card-Builder (buildSessionCard, buildAgentCard, buildTelegramBotCard)
│   ├── js/msg-actions.js       # Nachrichten-Aktionen (Delete, Mark, Share, Reply)
│   ├── js/tool-ui.js           # Tool-Boxes, Diffs, Visibility-Logik
│   ├── js/modals.js            # Modale Dialoge (System-Prompt, Command-Output)
│   ├── js/stream-ui.js         # Stream-Bubble, Review-Streaming
│   ├── js/bubbles.js           # Message Bubbles (User, Assistant, Error, Choice)
│   ├── js/chat.js              # SSE-Stream-Handling, sendMessage, Plan-Mode
│   ├── js/history.js           # History laden, Polling, Rendering
│   ├── js/archive.js           # Archiv-Loading
│   ├── js/reply.js             # Reply/Quote-Handling
│   ├── js/files.js             # File-Upload, Workspace-Refs
│   ├── js/typing-phrases.js    # Zufällige Typing-Indicator-Texte
│   ├── js/pages/               # Seiten-Komponenten (inkl. api-keys-page.js, telegram-bot-page.js, db-explorer-page.js)
│   └── css/                    # Styles (theme.css = CSS Variables)
├── WindowsApp/                 # WPF + WebView2 Desktop Client
└── Build/                      # ⛔ NICHT editieren!
    ├── Linux/
    │   ├── bin/  obj/  publish/
    └── Windows/
        ├── bin/  obj/  publish/
    └── 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
User 1──* TelegramBot 1──* Session (via telegram_bot_id)
Tabelle Zweck
users Login, DisplayName, IsAdmin, Persona, Settings (JSON), DefaultPath
tokens Auth-Tokens → User
agents AI-Agenten (Model – z.B. claude-sonnet-4-6 oder nvidia:model-id, CustomCommands, AutoCommit, UseSoul/Identity/UserInfo/Memory/AutoContext, UseGitHubSearch, UseSerperSearch, WebSearch, AllowUserChoice, TaskInstruction, AvatarScale/Offset, AvatarSmall, IsPublic)
sessions Chat-Sessions (Description, Image, ImageSmall, Workspace, Context, CustomCommands, TelegramBotId, TelegramChatId, AvatarScale/Offset, PreparerAgentId, ReviewAgentId, MaxReviewIterations, FinalizerAgentId)
chains Ein Request-Response-Zyklus (Tokens, Timing, Iterations, PlanMode, ToolChoice, ToolNames, StreamErrorInfo, ArchiveId)
messages Einzelne Nachrichten (text / tool_use / tool_result / error / web_search_result / auto_context), Tag für Sub-Agent-Markierung oder Import-Herkunft (openclaw-import), thought_signature (Gemini)
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_bots Telegram Bots (BotToken, WebhookSecret, Name, IsPublic) – eigenständige Entität, 1 Bot → N Sessions
api_keys API-Keys (key_id, provider, name, api_key, is_active, status, plan, usage_7d, usage_5h, source_url, is_public, refresh_token, access_token_expires_at, oauth_provider) – mehrere Keys pro Provider möglich, Zuweisung pro Agent
agent_api_keys API-Key-Zuweisung pro User+Agent (user_id, agent_id, key_id) – ersetzt globales users.selected_api_key_id
scanned_keys Gescannte GitHub-Keys (api_key, source_url, source, type, status, plan, usage_7d, usage_5h, adopted_api_key_id, deleted)
scanner_logs Scanner-Logs (timestamp, type, message, scanner)
server_settings Server-Settings (key, value, type) – verwaltet über ServerSettingsService
message_embeddings Sentence-Embeddings für semantische Suche (message_id, vector BLOB)
memory_file_embeddings Embeddings von Memory-Dateien (agent_id, file_path, chunk_index, vector BLOB)

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, system-prompt-blocks, payload-preview, streaming, exec, git-status
Agents /api/agents/ CRUD + available (inkl. public agents, inline Skills)
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/ Bot-CRUD, webhook/{botId} (unauth), session-config, registration
OpenClaw /api/openclaw/ Import von OpenClaw-Sessions (sessions, import)
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
Models /api/models/ GET nvidia, GET pollinations, GET gemini, GET openai, POST refresh
API Keys /api/admin/api-keys/ CRUD + check, check-all, scan, event-scanner, scanned (recheck/adopt/delete), scanner-logs (Admin) + /api/api-keys/ available, select, selected (User)
Remote /api/remote WebSocket für Remote-Clients, GET connections, POST assign/unassign, GET /remote.ps1 (Windows), GET /remote.sh (Linux/macOS)
Internal /api/internal/ MCP-Server: remote-execute, ask-user-choice, memory-read/write/list (Token-gesichert) + POST /api/chat/choice-respond (normale Auth)
DB Explorer /api/admin/db/ tables, table-data (Admin-only)
Info /api/info GET → Build-Zeitstempel + Embedding-Verfügbarkeit
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 + CLI-Fallback, passive Usage-Aktualisierung (partial class: Core, Streaming, Agents, Cli)
ClaudeCliService Claude Code CLI Wrapper (OAuth-basiert, kein API-Key nötig)
OpenAiService OpenAI-kompatible Provider (Nvidia, Pollinations, Gemini, OpenAI) mit Tool-Calling, Streaming + Non-Streaming, Modell-Caching
SseHelper Shared SSE-Utilities: WriteSseEvent, TryWriteSse, FinalizeChain, TruncateToolResult (static)
ToolService Tool-Definitionen + Ausführung (19 Tools, inkl. github_code_search, serper_web_search)
WorkspaceHelper Workspace-Pfad-Auflösung (relativ → absolut), Path-Traversal-Schutz (static)
SystemPromptBuilder System-Prompt aus modularen Blöcken zusammenbauen + Reminder-Generierung (static)
MemoryService Agent-Gedächtnis auf Dateisystem
SkillService Skill-Discovery aus Dateisystem
TelegramService Telegram Bot API (Bot-basiert, Multi-Session-Routing)
CronjobService BackgroundService, minütlicher Cron-Check
KreaService Krea API Bildgenerierung + Job-Polling
ImageService Bild-Resize + WebP-Konvertierung (512px + 256px Thumbnail)
EmbeddingService Lokales Sentence-Embedding via all-MiniLM-L6-v2 (ONNX, 384 Dimensionen)
VectorSearchService Semantische Suche über Message-Embeddings + Memory-File-Embeddings
EmbeddingBackgroundService Backfill bestehender Messages + Live-Embedding neuer Messages/Memory-Files
RemoteConnectionManager WebSocket-basierte Remote-Verbindungen, Command-Execution auf Remote-Clients
StreamingTracker Tracking aktiver Streams + CancellationTokenSource pro Session für Stop
AppPaths Zentrale Pfade (WwwRoot, Dev vs. Publish-Modus) (static)
KeyScannerService API-Key-Scanner (GitHub Code Search, GitHub Issues/PRs, HuggingFace Hub, Google/Serper), täglicher Scan
GitHubEventScannerService Echtzeit-Scanner: GitHub Public Events API (PushEvent-Diffs nach geleakten Keys), 30s Poll-Intervall
KeyPatterns Zentrale Key-Pattern-Definitionen für alle Scanner (Regex, Typ-Erkennung, Display-Names) (static)
KeyCheckDispatcher Zentraler Dispatcher für Key-Checks aller Provider, normalisiertes Ergebnis (static)
AnthropicKeyChecker Key-Validierung via Anthropic API, Usage-Header-Auswertung (Plan, 7d/5h Usage)
OpenAiKeyChecker OpenAI Key-Validierung (Models-Endpoint, Rate-Limits, Organization)
GoogleKeyChecker Google/Gemini Key-Validierung (Models + Quota-Check)
StripeKeyChecker Stripe Key-Validierung (Balance, Account-Info, Payouts/Charges)
ServerSettingsService Server-Settings Verwaltung (In-Memory-Cache + DB), Cleanup obsoleter Settings

Chat-Pipeline (Flow)

User-Input → POST /api/chat (SSE)
  → ChatService.BuildContext()
    → History aus DB laden (letzte N Chains)
    → SystemPromptBuilder: 11 Blöcke zusammensetzen (+ Plan-Modus/Preparer-Blöcke)
    → Tool-Definitionen vom ToolService holen (im Plan-Modus: nur Read-only)
  → API-Key auflösen: GetAgentApiKeyRecord(userId, agentId) – Anthropic ohne Key → CLI-Fallback oder Fehler, keyless Provider → OK
  → Preparer-Phase (optional, wenn PreparerAgentId gesetzt):
    → RunPreparer() → Provider-Weiche: Anthropic → RunAgentChat(), OpenAI → ChatNonStreaming()
    → Antwort ohne [QUESTION] → automatisch weiterleiten (Default = Forward)
    → [QUESTION] → Rückfrage an User, Flow stoppt
  → AnthropicService.StreamChat() / StreamChatViaCli() / OpenAiService.StreamChat()
    → 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 20 Tool-Iterationen pro Run, bis zu N Feedback-Runden)
      → [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

Passive Usage-Aktualisierung: Nach jedem API-Request (Streaming, Sub-Agent, NonStreaming) werden die Response-Header ausgelesen und Plan/Usage des aktiven API-Keys in der DB aktualisiert – kein separater Check nötig.

History-Optimierung: Max 220 Messages (MaxHistory-Setting). Ä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. System-Prompt-Reminder alle ~30 Messages.

Auto-Context (Vector-Search): Wenn UseAutoContext aktiv, wird vor jedem Request via VectorSearchService semantisch passender Kontext aus früheren Messages + Memory-Files gesucht und als <recalled_context>-Block in den System-Prompt injiziert. Wird im Frontend als aufklappbare Auto-Context-Box angezeigt (Live via SSE-Event auto_context + History via messages-Eintrag mit Role="system", Type="auto_context"). Wird aus der API-History gefiltert (kein Doppel-Send).

Rendering: Markdown via marked.js + LaTeX via KaTeX ($$...$$ Block, $...$ Inline). Timestamps im Format dd.MM.yyyy HH:mm:ss on hover.


Tool-System (19 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, konfigurierbares Timeout)
background_execute Shell-Befehl als Hintergrund-Prozess starten (gibt PID zurück)
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
memory_search Semantische Suche über vergangene Chat-Nachrichten und Memory-Dateien
remote_execute Shell-Befehl auf verbundenem Remote-Client ausführen (via WebSocket)
send_to_session Nachricht an eine andere Session senden und Agent-Antwort auslösen
ask_user_choice Interaktive Rückfrage mit 2-5 Auswahlmöglichkeiten (wenn AllowUserChoice aktiv)
github_code_search Durchsucht öffentliche GitHub-Repos nach Code (GitHub Code Search API)
serper_web_search Internet-Suche via Google (Serper.dev API)

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: Automatisch any wenn Workspace/Skills/Memory vorhanden, sonst auto. Wird zu none bei /no-tools. Einzelne Tools forcierbar via /tool:toolname.


System-Prompt (11+ 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. Workspace – Pfad-Info, Tool-Liste
  6. Rückfragen – Hinweis zu ask_user_choice (wenn AllowUserChoice aktiv)
  7. Context – Session-Kontext (custom system prompt)
  8. Skills – Zugeordnete Skill-Prompts
  9. Memory – Aktueller MEMORY.md-Inhalt + Regeln
  10. Git – Commit-Verhalten (wenn AutoCommit konfiguriert)
  11. Markierte Nachrichten – Vom User als wichtig markiert
  • [Plan-Modus] – Überspringt 10; Read-only Tools; "Nur analysieren"
  • [Preparer-Block] – Instruktionen für Vorbereiter-Agents

Tool-Choice: Automatisch any wenn Workspace/Skills/Memory vorhanden, sonst auto. Nicht konfigurierbar pro Agent.

History-Reminder: Alle ~30 Messages wird ein automatisch generierter Reminder injiziert ([System Reminder] Beachte weiterhin den System-Prompt (...)) – bekämpft "Lost-in-the-Middle"-Problem.


Frontend-Routing

Hash-Route Page-Datei Beschreibung
#/ dashboard.js Session-Übersicht (sortiert nach letzter Chat-Nachricht)
#/chat/{id} chat-page.js Chat (inkl. Usage-Badge-Overlay + Key-Switch-Modal)
#/session/{id} session-page.js Session-Settings
#/agent/{id} agent-page.js Agent-Editor
#/telegram-bot/{id} telegram-bot-page.js Telegram-Bot-Editor
#/cronjobs cronjob-page.js Cronjobs
#/profile profile-page.js Profil
#/settings settings-page.js Einstellungen
#/admin admin-page.js Benutzerverwaltung (Admin)
#/api-keys api-keys-page.js API-Key-Verwaltung + GitHub-Scanner + Event-Scanner (Admin)
#/db-explorer db-explorer-page.js Datenbank-Explorer (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 (/api/telegram/webhook/{botId}), GET /api/shared/{token}, GET /api/images/file/*, /api/remote (WebSocket) 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)

{
  "Port": 19000                // Server-Port (Default 19000, erfordert Neustart)
}

Hinweis: AnthropicToken wird über die API-Key-Verwaltung im Admin-Bereich verwaltet (DB-Tabelle api_keys), nicht mehr über appsettings.json.

Verwaltung über Admin-UI (#/server-settings): Liest appsettings.Production.json (Fallback: appsettings.json → Default). Schreibt immer in appsettings.Production.json.


Deployment

./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 SubAgentContext für Preparer, Review und Finalizer. RunPreparer() im ChatEndpoint (vor StreamChat). RunReview() + RunFinalizer() in AnthropicService. Alle nutzen Provider-Weiche: Anthropic → RunAgentChat(), OpenAI → ChatNonStreaming() (mit Tag-Markierung, Sub-Agent-Messages aus API-History gefiltert).

CLI-Fallback für Sub-Agents: Wenn ein Sub-Agent (Preparer, Review, Finalizer) keinem API-Key zugewiesen ist und die Claude CLI verfügbar ist, wird automatisch RunSubAgentViaCli() genutzt. Erst wenn weder Key noch CLI verfügbar sind, wird der Sub-Agent übersprungen (kein Hard-Error mehr).

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 Build/*/publish/wwwroot/
  • ⛔ Build/*/publish/data/gott.db niemals manuell modifizieren/löschen
  • ⛔ Build/ generell nicht anfassen
  • 🔧 .NET 10 ohne Nullable, ohne Implicit Usings
  • 📦 DB-Migrationen sind idempotent (IF NOT EXISTS Pattern in DatabaseService)
  • 🗂️ Native Pfade (Windows: \, Linux/macOS: /) – Backend liefert OS-Pfade, Frontend matcht beide via [\\/]