Commit Graph
161 Commits
Author SHA1 Message Date
MelekiandClaude Opus 4.6 2494ca89b8 fix: Tool-Box mit sichtbarem Diff nicht mehr halbtransparent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:33:46 +01:00
MelekiandClaude Opus 4.6 dd7cf0ec93 feat: chatUsageBadge-Setting + Dashboard-Menü als Dropdown
- Neues Setting chatUsageBadge (default: false) blendet Usage-Badge im Chat ein/aus
- Dashboard-Links durch 3-Dot-Header-Menü ersetzt (einheitlich mit Chat)
- Admin-Items über admin-only Attribut gesteuert, dashboard-links CSS entfernt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 08:35:05 +01:00
MelekiandClaude Opus 4.6 92ecaf9dac fix: ask_user_choice Short-Poll, Freitext-Option, Stop-Kontext-Fix
- Long-Poll durch Short-Poll ersetzt (MCP-Server pollt jede Sekunde statt einer blockierenden HTTP-Anfrage)
- Expliziter Lambda-Rückgabetyp Task<IResult> für ASP.NET Minimal API Endpoints (behebt 200 empty body Bug)
- Freitext-Option bei Choice-Buttons ("Eigene Antwort…") für freie User-Eingabe
- Stop während ask_user_choice markiert Chain als awaiting_user_choice statt stopped (Kontext bleibt erhalten)
- ask_user_choice System-Prompt-Instruktion breiter formuliert (Quiz, Multiple-Choice etc.)
- Text wird jetzt immer in DB gespeichert, auch bei ask_user_choice
- Key-Check Model auf claude-haiku-4-5 geändert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 11:32:25 +01:00
MelekiandClaude Opus 4.6 3b068a7866 feat: MCP-Server für remote_execute + Inline-Choice-UI
- Python MCP-Server (stdio, JSON-RPC 2.0) für remote_execute via Claude CLI
- Interner API-Endpoint /api/internal/remote-execute mit Token-Auth
- MCP-Config wird automatisch generiert wenn Remote-Verbindung vorhanden
- Auth-Middleware: /api/internal/ von Auth ausgenommen
- Frontend: :::ASK_USER_CHOICE::: Blöcke als interaktive Buttons rendern
- Streaming: Unvollständige Choice-Blöcke werden während des Streams versteckt
- tool-ui.js: MCP-Tool-Namen generisch normalisieren (mcp__server__tool → tool)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 09:00:50 +01:00
Meleki 0e55e45497 UI: Remote-Modal und sp-loading Styling verbessern
- sp-loading: Flexbox-Layout statt text-align center
- Remote-Modal: Powershell-Befehl immer sichtbar (nicht nur bei leerer Liste)
- remote-card-content: Padding ergänzt
2026-03-15 11:08:51 +01:00
Meleki 24c0c79a64 cleanup: ungenutzte CSS-Klassen entfernt, sp-loading restyled
- .font-sm und .semi-transparent Utility-Klassen entfernt (nirgends verwendet)
- .sp-loading: code-Block mit eigenem Styling statt opacity
- modals.js: font-sm/semi-transparent Klassen aus Remote-Modal entfernt
2026-03-15 10:57:20 +01:00
Meleki 49ef6bedc6 feat: Payload-Preview im Chat-Menü + Reminder von hinten gezählt
- Neuer Endpoint GET /api/sessions/{id}/payload-preview
  Gibt den exakten Anthropic-API-Payload als JSON zurück (read-only)
- Chat-Menü: 'Payload anzeigen' öffnet Modal mit formatiertem JSON
- Reminder-Logik umgebaut: halbes Intervall (15) vor Ende,
  dann volle Intervalle (30) rückwärts statt von vorne gezählt
- CSS: Payload-Modal Styling, kleine Variable-Fixes
2026-03-15 10:46:51 +01:00
Meleki 79d7a88c5c feat: HuggingFace Hub Scanner - Spaces und Models nach API-Keys durchsuchen
- Neue ScanHuggingFace()-Methode: durchsucht Spaces und Models
- 6 Suchbegriffe (anthropic, claude, openai, api-key, chatgpt, gpt4)
- Rekursive Dateiliste, filtert nach relevanten Extensions
- Limits: 50 Dateien/Repo, 500KB/Datei, 300ms Delay
- Läuft in Web- und Full-Mode (nicht Quick)
- Optionales HuggingFaceToken-Setting für höhere Rate-Limits
- CSS: font-size Bereinigung in chat.css
2026-03-14 18:02:47 +01:00
Meleki ce50633e33 refactor: Inline-Styles durch CSS-Klassen ersetzt
- 40+ Utility-Klassen in form.css (clickable, text-danger, flex-row, loading-state, etc.)
- share-menu position/z-index in chat.css statt inline
- index.html: 0 Inline-Styles (hidden-Attribut, CSS-Klassen)
- 12 JS-Dateien bereinigt: style.cssText/style.* durch classList ersetzt
- Bugfix: var(--danger) → var(--dangerous) (nicht existierende Variable)
- display:none Toggles → hidden-Attribut wo passend
- Hardcoded font-sizes in chat.css → var(--font-size)

15 Dateien, nur Frontend (CSS/JS/HTML), kein Backend
2026-03-14 17:14:30 +01:00
Meleki e368abced0 Static Files direkt aus Quell-wwwroot laden, Publish-Kopie deaktiviert
- Program.cs: PhysicalFileProvider auf ../../../wwwroot (Fallback auf publish/wwwroot)
- Program.cs: No-Cache-Middleware für HTML/JS/CSS
- gott.csproj: PublishStaticWebAssets=false, CopyToPublishDirectory=Never für wwwroot
- CSS: DB-Explorer-Styling auf CSS-Variablen umgestellt
2026-03-14 16:44:44 +01:00
Meleki e61f3ef082 feat: DB-Explorer, Scanner-KeyTypes-Setting, Stripe-Checker, Anthropic-Auth-Fix, Progress-Tracking
Backend:
- Neuer Database Explorer Endpoint (GET /api/admin/db/tables, GET /api/admin/db/tables/{name})
- DatabaseService: public GetConnection() Methode
- StripeKeyChecker: 2-Schritt-Check (/v1/balance + /v1/account), erkennt Live/Test, Balance, Account-Details
- AnthropicKeyChecker: Auth-Header fix (x-api-key für API-Keys, Bearer für OAuth), 400-Handler für credit balance
- KeyPatterns: Stripe einkommentiert, Krea AI Pattern, AllTypes-Array, MinLength 4
- ServerSettingsService: string_array Typ (Get/SetStringArray), ScannerKeyTypes Setting mit Checkbox-Optionen
- ServerSettingsEndpoint: string_array Speichern (Array/CSV)
- KeyScannerService: GetActiveSearchPatterns() filtert nach ScannerKeyTypes, Progress-Tracking
- GitHubEventScannerService: CheckNewKeys nur für aktuelle Poll-Keys (statt alle unchecked), klarere Log-Meldung

Frontend:
- Database Explorer Page: Tabellenliste mit Klick -> Tabelleninhalt, Pagination, sticky Header
- Server Settings: Checkbox-Gruppe für string_array (Alle/Keine Buttons)
- API Keys: adoptedApiKeyId Fix (leerer String == null)
- Dashboard: DB-Explorer Link für Admins
- Scan-Progress: Live-Fortschritt mit Phase/Detail/Counter
2026-03-14 16:19:13 +01:00
Meleki eb8844a4f1 feat: GitHub Event Scanner - Echtzeit-Monitoring öffentlicher Pushes
- Neuer GitHubEventScannerService (BackgroundService)
  - Pollt /events API alle 30s, filtert PushEvents
  - Lädt Head-Commit-Diffs, scannt nach Key-Patterns
  - Ringbuffer (10k IDs) für Event-Deduplication
  - Gefundene Keys werden sofort geprüft (AnthropicKeyChecker)
  - Rate-Limit-Handling (403/429 → Pause bis Reset)
- Feature-Toggle in Server-Einstellungen (GitHubEventScanner)
- Status-Endpoint + Log-Endpoint (/api/admin/api-keys/event-scanner/*)
- Live-Status in API-Keys-Seite mit klappbarem Log
- Auto-Refresh alle 30s
- Plans/ in .gitignore
2026-03-13 18:38:32 +01:00
Meleki dde0fede7d User-spezifische API-Key-Auswahl, globales is_active entfernt
Backend:
- is_active komplett entfernt, durch is_public (Admin-Toggle) ersetzt
- Neues selected_api_key_id auf users-Tabelle
- AnthropicService: globaler _token entfernt, apiToken pro Request
- Token-Durchreichung: StreamChat → ProcessStream → RunAgentChat →
  RunPreparer/RunReview/RunFinalizer, ExecuteTool, send_to_session
- ChatEndpoint: User-Key aus DB laden, an StreamChat übergeben
- TelegramService: Key per bot.UserId auflösen
- CronjobService: Key per job.UserId auflösen
- Neue Endpoints: GET /api/api-keys/available, PUT /api/api-keys/select/{keyId},
  GET /api/api-keys/selected, PUT /api/admin/api-keys/{keyId}/public,
  POST /api/admin/api-keys/check-all
- Program.cs: AnthropicService ohne Token-Parameter

Frontend:
- API-Keys-Page: Public-Toggle (Globe/Lock) statt Activate/Deactivate
- Alle prüfen Button für Batch-Key-Check
- Chat: Key-Auswahl für alle User (nicht nur Admin)
- Dummy-Badge wenn kein Key ausgewählt
- Fallback-Badge bei Key ohne Usage-Daten
- Key-Switch-Modal: apiGetAvailableKeys + apiSelectApiKey
2026-03-13 12:27:03 +01:00
Meleki 8b1794d11e style(chat): Usage-Badge Overlay und Key-Switch-Modal CSS-Anpassungen
- Overlay: full-width mit zentriertem Inhalt, semi-transparenter Hintergrund
- Check-Button Styling in Usage-Badge integriert
- Key-Switch-Rows: Hover-Effekt, Usage-Badge max-width
- Padding und Border-Farben harmonisiert
2026-03-12 22:30:17 +01:00
Meleki 3ec9ebba45 Chat: Usage-Badge-Overlay mit Key-Switch-Modal
- Usage-Badge oben zentriert im Chat (nur Admin)
- Zeigt Sitzung/Woche-Balken des aktiven API-Keys
- Blendet bei Scroll-Up aus, bei Scroll-Down ein
- Klick auf Badge öffnet Key-Switch-Modal (via _createModal)
- Ganze Row klickbar für Key-Wechsel
- Refresh-Button neben Badge für manuellen Key-Check
- Badge aktualisiert sich automatisch bei neuen Nachrichten (pollHistory)
- Cleanup in destroy()
2026-03-12 20:03:30 +01:00
Meleki bdcfd1f8b3 API-Keys UI: Toggle+Check neben Badge, übernommene Keys ausblenden, Layout-Polish
- Toggle-Button (Aktivieren/Deaktivieren) links neben Usage-Badge
- Check-Button rechts neben Usage-Badge statt bei Actions
- '✅ Aktiv' aus Meta-Zeile entfernt (Toggle zeigt Status)
- 'Prüfe...' Text beim Check entfernt (Spinner im Button reicht)
- Übernommene Scanned-Keys komplett ausgeblendet statt halbtransparent
- isAdopted-Logik und Wrapper entfernt, Code entschachtelt
- admin-user-row: Border, Radius, Background hinzugefügt
- Aktive Keys visuell hervorgehoben (Primary-Border + Brightness)
- placeholder.css an gleichen Row-Style angeglichen
2026-03-12 19:19:35 +01:00
Meleki de388806cb API-Keys: Source-URL, einheitliches Status-Schema, passive Usage-Erfassung, Usage-Bars
- SourceUrl-Feld in api_keys: GitHub-URL bei adoptierten Scan-Keys gespeichert
- HandleAdopt: Name = user/repo (aus URL extrahiert), SourceUrl = vollständige URL
- Status-Schema vereinheitlicht: überall 'valid' statt 'ok'/'usage_limited'
- AnthropicKeyChecker.ExtractMetaFromHeaders(): passive Header-Auswertung
- AnthropicService: TryUpdateKeyMeta() nach jedem Chat-Request (fire-and-forget)
- DatabaseService: UpdateApiKeyMetaByToken() für passive Updates per Token
- Frontend: formatKeyStatus() zentrale Status-Labels für API-Keys + Scanned-Keys
- Frontend: createUsageBadge() zweizeiliger Balken (Sitzung/Woche) mit Farbstufen
- CSS: Usage-Badge mit Track/Fill, warn (>=70%) und danger (>=90%) Klassen
2026-03-12 18:33:37 +01:00
Meleki 608118a823 Key-Scanner: Auth-Header fix, 401-mit-Usage-Handling, breitere Suche, Live-Refresh
- AnthropicKeyChecker: Bearer-Auth + CLI-Header statt x-api-key (identisch mit AnthropicService)
- 401 mit Usage-Headern → 'usage_limited' statt 'invalid' (Key gültig, Limit erreicht)
- Haiku-Phase entfernt, Streaming-Logik entfernt → ein einfacher Request reicht
- KeyScannerService: SearchLanguages 1→13, PathExtensions 24 neue Pfad-Filter
- ApiKeysEndpoint: usage_limited als 'ok' ans Frontend
- Frontend: Adopt-Button auch bei quota_exceeded, Live-Refresh alle 3s während Scan
- CSS: Overflow-Ellipsis für lange URLs in Admin-Listen
2026-03-12 17:11:06 +01:00
Meleki db1a7c7f64 Refactoring + Dokumentation: api.js komprimiert (745→267 Zeilen), SseHelper extrahiert, DatabaseService in Partial Classes aufgeteilt, unbenutztes CSS entfernt, ARCHITECTURE.md/ARCHITECTURE_QUICK.md/README.md aktualisiert (neue Features: Embedding, Remote, API-Keys, 16 Tools) 2026-03-12 13:29:19 +01:00
Meleki a646e695cd feat: embedding model warning modal on frontend load
- InfoEndpoint: EmbeddingService injiziert, embeddingAvailable in /api/info Response
- title.js: _showEmbeddingWarning() Modal via _createModal() wenn Modell fehlt
- base.css: ol margin-left wie ul (geordnete Listen)
2026-03-11 14:38:27 +01:00
Meleki b1d449b997 Doppel-Klick Hard-Stop + ReadLineAsync Cancellation-Fix
Stop-Button: Zwei Stufen statt einer:
- 1. Klick: Graceful Stop (workCt) - laufende API-Calls/Tools abbrechen
- 2. Klick: Hard Stop (hardCt) - sofortiger Abbruch aus while-Loop

StreamingTracker: Zwei separate CancellationTokenSources (StopCts + HardCts),
Cancel() gibt 'graceful'/'hard'/null zurück je nach Stufe.

ReadLineAsync Cancellation-Fix: StreamReader.ReadLineAsync propagiert den
CancellationToken nicht zuverlässig an den underlying NetworkStream.
Bei extended thinking blockiert ReadLineAsync minutenlang ohne Reaktion
auf Cancellation. Fix: workCt.Register() disposed den HTTP-Stream,
damit ReadLineAsync sofort mit Exception abbricht.

Bug-Fix: OperationCanceledException in RunAgentChat/ChatNonStreaming wurde
vom generischen catch(Exception) geschluckt - Agent lief trotz Stop weiter.
Jetzt: catch(OperationCanceledException) { throw; } vor catch(Exception).

Frontend: Stop-Button zeigt Hard-Stop visuell (rot + Pulse-Animation),
SSE-Stream wird erst beim 2. Klick clientseitig abgebrochen.
2026-03-10 10:53:23 +01:00
Meleki ec73ccd71e Telegram Bots als eigenständige Entität mit eigener Page
- Neue Tabelle 'telegram_bots' (bot_id, name, bot_token, webhook_secret, is_public)
- Automatische Migration bestehender Session-Telegram-Configs in telegram_bots
- Sessions verweisen via telegram_bot_id auf Bot (mehrere Sessions pro Bot möglich)
- Webhook-URL: /api/telegram/webhook/{botId} statt {sessionId}
- Eigene Telegram-Bot-Page (wie Agent/Cronjob/Session) statt Modal
- Bot-Page: Name, Token, Secret, Webhook-Verwaltung (registrieren/status/entfernen), Löschen
- Dashboard: Telegram Bots Section mit Cards (Name, maskierter Token, Session-Count)
- Session-Page: Bot-Picker (wie Agent-Picker) statt Token-Input, Chat-ID readonly + Unlink-Button
- Public-Flag: Bot kann von anderen Usern in ihren Sessions ausgewählt werden
- Vereinfacht: 1 Session = max. 1 Telegram Chat, allowed_chat_ids entfällt
- /start zeigt Chat-ID an, /unlink entfernt (Unlink nur über Web-UI)
- Nachrichten-Routing: Bot + Chat-ID → Session Lookup
2026-03-08 19:27:05 +01:00
Meleki 3b7bdb7a20 feat: OpenClaw session import with sorted history
Backend:
- New OpenClawEndpoint with GET /api/openclaw/sessions and POST /api/openclaw/import
- Lists all OpenClaw sessions with preview messages, model, summary
- Imports user/assistant text messages (skips tool-use/tool-result)
- Cleans user messages (removes webchat prefixes, cron tags, conversation info blocks)
- Re-import support: deletes previous openclaw-import chains before importing
- New DatabaseService methods: CreateChainForImport, CreateMessageForImport, DeleteOpenClawImport
- Added SortKey to MessageRecord (computed: openclaw-import gets id-10B, else id)

History sorting:
- OpenClaw-imported messages always appear before native messages
- Sort by CASE WHEN tag='openclaw-import' THEN id-10000000000 ELSE id END
- Cursor-based paging updated from beforeId/afterId to beforeSortKey/afterSortKey
- All history queries (GetLatestActive, Before, After, CountBefore) updated

Frontend:
- Dashboard: new 'OpenClaw Import' menu item in session card dropdown
- Modal: shows OpenClaw sessions with metadata, summary, preview messages
- Imported messages display blue 'OC' badge in chat
- API functions: apiGetOpenclawSessions, apiImportOpenclawSession
- History paging updated to use sortKey cursors
2026-03-08 17:32:32 +01:00
Meleki 1fc6889ced Review-Agent: Default=Approved + vollständige Tool-Boxes für Sub-Agents
Backend:
- Review-Agent: Default = Approved (analog zum Preparer Default=Forward)
  Nur bei explizitem [FEEDBACK]-Tag wird Feedback zurückgespielt
  Verhindert Loop wenn Review-Agent bestätigt ohne [APPROVED]-Tag
- Neues SSE-Event {agentType}_tool_end für Sub-Agent Tool-Ergebnisse
  Sendet toolName, input, result, isError nach Tool-Ausführung

Frontend Streaming (stream-ui.js + chat.js):
- addReviewToolUse: Vollständige Tool-Box mit Loading-Spinner statt nur Name
- finishReviewToolBox: Befüllt Tool-Box nach tool_end mit Details (Pfad, Diff, Result)
- Event-Handler für preparer/review/finalizer_tool_end

Frontend History (history.js):
- _renderReviewGroup: Vollständige Tool-Boxes statt einfache Tool-Use-Indikatoren
- Tool-Result Look-Ahead für korrekte Zuordnung (toolCallId-Match)
- Web-Search-Sources in Review-Bubbles unterstützt
- Tool-Visibility-Filter (isToolVisible) auch für Sub-Agent-Tools

CSS:
- .review-tool-use → .review-tool-box (erbt normale Tool-Box-Styles)
2026-03-08 15:08:59 +01:00
Meleki 494f431963 feat: Vorbereiter-Agent (Preparer) für Sessions
- Neues optionales Session-Feld 'preparerAgentId' (DB + Model + API)
- PreparerContext im ChatContext für Agent-Konfiguration
- RunPreparer() in AnthropicService: führt Preparer vor dem Worker aus
  - [FORWARD] → aufbereiteter Prompt wird an Session-Agent weitergegeben
  - Ohne [FORWARD] → Rückfrage an User, Flow stoppt (preparer_query)
- Preparer-System-Prompt: erklärt Rolle, [FORWARD]-Mechanismus, Vorarbeit
- Preparer kann eigene Tools + Fähigkeiten aktiv nutzen
- ChatEndpoint: Preparer-Phase vor StreamChat integriert
- Frontend: SSE-Events (preparer_start/text/tool_use/done)
- Preparer-Bubble (Info-Farbe) mit Status Weitergeleitet/Rückfrage
- [Preparer: Name] → hübscher Header, [FORWARD] ausgeblendet
- [Vorbereitet von Name] → dezenter Header in User-Bubble
- Agent-Picker im Session-Form (vor Review-Agent)
2026-03-07 15:23:22 +01:00
Meleki f12fbfdc3e Adjust background color of user message buttons and timestamp 2026-03-07 12:36:52 +01:00
Meleki 6d95f9aec2 feat: Plan-Modus – Toggle im Chat zum Umschalten zwischen Plan/Ausführung
- Toggle-Button (🗺️) im Chat-Input-Bereich neben Explorer
- Plan-Modus wird per ChatRequest.planMode an Backend gesendet
- Backend: Write-Tools gefiltert (nur read_file, list_files, glob, grep,
  todo_write, memory_*, ask_user_choice bleiben), System-Prompt-Block
  ergänzt der Änderungen verbietet, tool_choice nie 'any' erzwungen
- ChainRecord.PlanMode: pro Chain gespeichert (informativ für History)
- Chain-Meta-Badge '📋 Plan-Modus' bei Plan-Chains
- Choice-Response erbt planMode vom vorherigen Chain
- CSS: .plan-mode-active Styling (Primary-Color Highlight)
- Placeholder wechselt zu 'Plannen...' wenn aktiv
- Plan-Modus wird bei Session-Wechsel zurückgesetzt
2026-03-07 12:07:39 +01:00
Meleki 89ceb61948 feat: Agent-Einstellung 'Rückfragen erlauben' (allowUserChoice)
- Neues Feld AllowUserChoice (bool, default true) im AgentRecord
- DB-Migration: allow_user_choice Spalte mit DEFAULT 1
- Agent-Form: Checkbox 'Rückfragen erlauben' nach 'Tool-Nutzung erzwingen'
- ToolService.GetToolDefinitions: neuer Parameter includeUserChoice
- ask_user_choice Tool wird nur eingebunden wenn Agent es erlaubt
- Review-Agents und Non-Streaming (Cronjobs) erhalten nie ask_user_choice
- ChatEndpoint reicht Agent.AllowUserChoice an StreamChat durch
2026-03-07 11:36:02 +01:00
Meleki 5f3e308975 feat: ask_user_choice Tool – interaktive Auswahlmöglichkeiten im Chat
Neues Tool 'ask_user_choice' analog zum AskUserQuestion aus dem Claude Agent SDK.
Claude kann dem User Multiple-Choice-Fragen stellen, wenn es mehrere sinnvolle
Wege gibt. Der User wählt per Button, Claude arbeitet mit der Antwort weiter.

Backend:
- ToolService: ask_user_choice Tool-Definition (question + choices[2-5])
- AnthropicService/ProcessStream: Tool wird NICHT ausgeführt, sondern als
  SSE-Event 'user_choice' an den Client gesendet. stopReason wird auf
  'awaiting_user_choice' gesetzt (mit Guard gegen Überschreibung durch
  message_delta)
- ChatEndpoint: Erkennung von Choice-Responses (choiceToolCallId + choiceResult),
  tool_result wird in die korrekte Chain gespeichert (wo der tool_use liegt),
  toolChoice wird auf 'auto' gesetzt damit Claude frei antworten kann
- ChatService: FindChainWithToolCall() zum Auffinden der richtigen Chain,
  BuildHistoryFromDb() erweitert um Choice-Chain-Erkennung (wenn letzte Chain
  leer/nur tool_result → vorletzte Chain vollständig rekonstruieren)
- ChatModels: ChatRequest um ChoiceToolCallId + ChoiceResult erweitert

Frontend:
- api.js: apiChatChoice() für Choice-Responses
- chat.js: handleStreamEvent() als shared Handler extrahiert (sendMessage +
  handleChoiceClick nutzen denselben Code), handleChoiceClick() startet neuen
  Stream nach Button-Klick
- ui.js: addChoiceBubble() (live/interaktiv) + addChoiceBubbleStatic() (History)
- history.js: Choice-Bubbles in _renderMessagesIntoFragment + renderMessages,
  Voraus-Suche nach zugehörigem tool_result, unbeantwortet = klickbare Buttons
- chat.css: Styling für Choice-Bubbles (Primary-Color-Outline-Buttons, Hover,
  Selected/Unselected States)

Robustheit:
- Backend-Fallback wenn Claude choices als String statt Array sendet
- Frontend-Guard: Array.isArray(choices) an allen 4 Render-Stellen
- Page-Refresh mit offener Choice → aktive Buttons werden korrekt gerendert
2026-03-07 11:30:55 +01:00
Meleki 6c38ccfe12 Web-Search: Streaming-Fix (pauseStreamBubble statt resumeStreamBubble), leere Suchergebnisse nicht speichern, Sources auf Shared-Pages anzeigen 2026-03-07 10:46:45 +01:00
Meleki d81dab635a fix(web-search): Text-Bubbles nach Web-Search zu einer Bubble zusammenführen
- history.js: _mergeConsecutiveAssistantTexts überspringt web_search_result
  Messages beim Suchen des vorherigen Text-Blocks, sodass Text vor und
  nach einer Web-Search in der History als eine Bubble gerendert wird
- Text-Blöcke werden mit doppeltem Zeilenumbruch statt Leerzeichen
  zusammengefügt (besseres Markdown-Rendering)
- chat.css: web_search Tool-Box von Opacity-Regel ausgenommen
2026-03-07 10:06:23 +01:00
Meleki f64052caf4 feat: Web-Search Sources anzeigen (Streaming + History + Archive + Shared)
Backend:
- web_search_tool_result Sources extrahieren (url, title)
- Als 'web_search_result' Message-Typ in DB persistieren
- Sources im web_search_end SSE-Event mitsenden
- Alle 3 Chat-Pfade: StreamChat, RunAgentChat, ChatNonStreaming

Frontend:
- renderToolBoxContent: Sources-Sektion mit klickbaren Domain-Links
- finishToolBox/addToolBoxStatic: sources-Parameter durchgereicht
- History: web_search_result Message-Typ in allen 3 Render-Pfaden
- web_search immer sichtbar (auch bei 'modifications' Filter)

CSS:
- .web-search-sources: Flex-Wrap Container
- .web-search-source: Domain-Pill mit Hover-Effekt, Title-Ellipsis
2026-03-07 09:56:09 +01:00
Meleki 4bec740765 feat: Finalizer-Agent – dritter Agent der nach Worker + Review einschreitet
Backend:
- SessionRecord + DB-Migration: finalizer_agent_id auf sessions
- ChatContext.FinalizerContext (Model, SystemPrompt, Tools, Workspace)
- ChatService: FinalizerContext aufbauen (analog zu ReviewContext)
- AnthropicService: RunFinalizer() nach Review-Phase (oder direkt nach Worker)
- RunReviewAgentChat() refactored zu generischem RunAgentChat()
  mit agentType-Parameter ('review' | 'finalizer') für SSE-Events und DB-Tags
- SSE-Events: finalizer_start, finalizer_text, finalizer_tool_use, finalizer_done

Frontend:
- Session-Page: Finalizer-Agent-Picker (im 'Weitere Einstellungen' Bereich)
- Chat: SSE-Events für Finalizer-Phase verarbeiten
- UI: addReviewBubble/finalizeReviewBubble unterstützen agentType 'finalizer'
  mit eigener Farbe (success-green) und Flag-Checkered-Icon
- renderMarkdown: [Finalizer: AgentName] Tags parsen
- History: Finalizer-Messages als .finalizer-bubble rendern
- Shared-Page: Finalizer-Messages korrekt erkennen und stylen
- Dashboard: Finalizer-Badge (flag-checkered) auf Session-Cards
2026-03-06 23:35:30 +01:00
Meleki bfd78278ab feat: Servereinstellungen-Seite für Admins
- Neuer Endpoint GET/PUT /api/admin/server-settings
  - Liest appsettings.Production.json (Fallback: appsettings.json → Standardwert)
  - Schreibt immer in appsettings.Production.json
  - Definierte Settings: AnthropicToken, MaxIterations, PayloadLogging, PayloadLoggingGzip, KreaToken, KreaApiKey
- Neue Frontend-Seite 'server-settings' (Admin-only)
  - Dynamisches Formular basierend auf Setting-Definitionen vom Backend
  - Password-Felder mit Eye-Toggle, Checkboxen für Booleans, Number-Inputs
  - Hinweis dass Neustart erforderlich ist
- Dashboard: Neuer Link 'Servereinstellungen' für Admins
- appsettings.Production.json vom Publish ausgeschlossen (CopyToPublishDirectory=Never)
2026-03-06 22:32:33 +01:00
Meleki 4775b8ded7 feat: Avatar Position-Offset (translate X/Y)
Backend:
- AgentRecord + SessionRecord: AvatarOffsetX, AvatarOffsetY Properties
- DB-Migration: avatar_offset_x/y REAL DEFAULT 0 auf agents + sessions
- Agent/Session Endpoints: Create + Update lesen/schreiben Offset-Felder
- GetSessionsWithStats: Offset-Felder ans Frontend

Frontend:
- Avatar-Editor: X/Y Offset-Slider (-50% bis +50%) im Modal
  - buildTransformStyle() Helper für transform: scale() translate()
  - getOffsetX()/getOffsetY() Public API
  - Reset bei Clear/AI-Generate/Upload
- ui.js: buildAgentCard + buildSessionCard rendern transform mit Offset
- Agent-Page + Session-Page: initialOffsetX/Y + Save
- CSS: .av-offset-row Styles (gruppiert mit .av-scale-row)
2026-03-06 21:14:51 +01:00
Meleki 6369f7f09c Review-Nachrichten: konsistentes Styling in History, Chat und Shared-Links
- renderMarkdown: [Review: Agent], [Review-Feedback ...], [APPROVED] Tags parsen
  → styled HTML-Header bzw. ausgeblendet (zentral für alle Views)
- history.js: Review-Messages als .review-bubble rendern statt .assistant/.user
  Review-Messages vom Merging ausgenommen
- shared-page.js: Review-Messages erkennen → .review-bubble Klasse
  Merge-Logik schützt Review-Messages vor Zusammenführung
- addReviewBubbleStatic(): Neue Funktion für History-Rendering mit allen
  Buttons (Reply, Delete, Mark, Share)
- chat.css: .review-inline-header, .review-inline-feedback Styles
2026-03-06 17:31:30 +01:00
Meleki 5fe3f8ac87 feat: Review-Agent (Multi-Agent-Kommunikation)
- Session hat optionalen ReviewAgentId + MaxReviewIterations
- Nach end_turn des Worker-Agents wird der Review-Agent aufgerufen
- Review-Agent bekommt Worker-Konversation als Kontext + kann Tools nutzen
- [APPROVED] in Review-Antwort → fertig, sonst Feedback an Worker
- Worker korrigiert und wird erneut reviewed (max N Runden)
- SSE-Events: review_start, review_text, review_tool_use, review_feedback, review_approved
- Chat-UI: Review-Phase als eigene Bubble mit Header, Text, Status
- Session-Page: Review-Agent-Picker (gleicher Agent-Card-Helper)
- Dashboard: Review-Agent-Badge auf Session-Cards
- DB-Migration: review_agent_id, max_review_iterations auf sessions
2026-03-06 16:04:00 +01:00
Meleki 1b9cc29421 Admin: Login-Link mit window.location.origin statt Server-Host
- Backend gibt nur Token zurück statt fertigen Link
- Frontend baut Link via window.location.origin zusammen
- Zeigt korrekte Domain/Port statt internes http://127.0.0.1

Backend:
- AdminEndpoint: POST /api/admin/users/{userId}/login-link gibt { token }
- AuthEndpoint: GET /api/auth/autologin?token=xxx setzt Cookie + redirect
- AuthMiddleware: autologin-Route von Auth ausgenommen

Frontend:
- api.js: apiAdminGetLoginLink() Funktion
- admin-page.js: Login-as-User Button → Login-Link Button mit Modal
- form.css: Styling für Login-Link Modal
2026-03-06 14:35:01 +01:00
Meleki e45498ac50 Session-Cards: buildSessionCard() Helper + Picker-Modal für Cronjob-Formular
- buildSessionCard(session, agent) Helper in ui.js (analog zu buildAgentCard)
  Erzeugt .card mit Avatar, Name, Badges (Agent, Kontext, Telegram) und Meta (Nachrichten, Archiv, Workspace)
- Dashboard refactored: Session-Cards nutzen buildSessionCard() statt inline HTML
- Cronjob-Formular: <select> für Session und Benachrichtigungs-Session durch
  klickbare Session-Cards + Picker-Modal ersetzt
- openSessionPickerModal() mit filterWithAgent-Option (Session-Dropdown nur
  Sessions mit Agent, Notify-Dropdown alle Sessions)
- CSS: .session-select-card und .session-select-change Klassen analog zu agent-*
2026-03-06 14:05:32 +01:00
Meleki 92c20402eb refactor: Agent-Auswahl in Session-Form als Card + Picker-Modal
- buildAgentCard() Helper in ui.js erstellt (wiederverwendbar für Dashboard + Picker)
- Session-Form: select-Dropdown durch klickbare Agent-Card ersetzt
- Agent-Picker-Modal zeigt alle Agents mit identischen Cards wie am Dashboard
- Dashboard refactored: nutzt buildAgentCard() statt dupliziertem Inline-HTML
- Kein duplizierter Code mehr für Agent-Card-Rendering (Badges, Skills, Avatar)
2026-03-06 14:01:27 +01:00
Meleki 5661e55898 style(mobile): shared-content padding for mobile view 2026-03-06 12:40:20 +01:00
Meleki 34cecd03a1 refactor: Avatar-Editor als wiederverwendbares Modal-Modul
- Neues avatar-editor.js: Upload, Paste, AI-Generate, Scale, Clear in einem Modal
- Session + Agent Pages: ~280 Zeilen doppelter Avatar-Code → je 5 Zeilen AvatarEditor.init/destroy
- Avatar-Preview klickbar → öffnet Modal mit allen Einstellungen
- chat.css: Shared-Content Message-Styling (max-width, border)
2026-03-06 11:55:00 +01:00
Meleki 057d37d76f feat: Avatar Scale (0.5×–3×) + Krea AI Bildgenerierung für Avatare
Backend:
- SessionRecord + AgentRecord: neues Feld AvatarScale (double, Default 1.0)
- DatabaseService: avatar_scale Migration, in Create/Update/GetWithStats
- SessionEndpoint + AgentEndpoint: avatarScale in Create/Update
- api.js: apiKreaStatus(), apiKreaGenerate()

Frontend:
- Session + Agent Templates: Range-Slider (0.5×–3×) in Avatar-Section
- Krea AI Generate: Prompt-Input + Magic-Button (nur wenn KreaToken konfiguriert)
- Live-Preview: transform: scale() auf Avatar-Vorschau
- Dashboard: scale() auf Session- und Agent-Card-Images
- form.css: avatar-scale-row + avatar-ai-section Styling
2026-03-06 10:59:09 +01:00
Meleki 4ebbeaa818 feat: shared-page message merging + UI reorganization
Shared Page:
- Merge consecutive assistant text messages (same iteration)
- Add iteration field to thread API response
- Unified rendering for single/thread messages

UI Reorganization (manual changes):
- Session + Agent forms: collapsible 'Weitere Einstellungen' section
- Agent defaults: tool_choice unchecked, web_search 2025, model opus-4-6
- Profile: default-path field hidden, divider removed
- Form spacing adjustments, .more toggle style
2026-03-06 08:52:27 +01:00
Meleki 4e1ed81f37 feat: DefaultPath als Base-Path für User-Workspaces
- WorkspaceHelper.cs: Zentrale Workspace-Auflösung (relativ → absolut)
- Session-Workspace wird relativ zum User-DefaultPath gespeichert
- System-Prompt bekommt aufgelösten absoluten Pfad
- Path-Traversal-Schutz: '..' in Workspace-Pfaden blockiert
- Browse-API gibt '..' nicht mehr als Eintrag zurück
- Folder-Browser: basePath-Limit, Back-Button navigiert zum Parent
- DefaultPath nur durch Admin bearbeitbar (Profil: readonly)
- Legacy: Absolute Pfade in session.Workspace weiterhin kompatibel
2026-03-05 22:49:09 +01:00
Meleki 8e7bda50f9 feat: Ordner erstellen/löschen im File Explorer
Backend (WorkspaceEndpoint.cs):
- POST /api/workspace/mkdir – Ordner im Session-Workspace erstellen
- DELETE /api/workspace/dir – Leeren Ordner im Session-Workspace löschen
- POST /api/workspace/agent/mkdir – Ordner im Agent-Memory erstellen
- DELETE /api/workspace/agent/dir – Leeren Ordner im Agent-Memory löschen
- POST /api/workspace/browse/mkdir – Ordner im Folder-Browser erstellen
- Sicherheit: Path-Traversal-Schutz, Root nicht löschbar, nicht-leer → 409

Frontend (file-explorer.js):
- 📁+ Button im Header für neuen Ordner (File Explorer + Folder Browser)
- 🗑️ Button bei jedem Ordner (erscheint on hover, nur File Explorer)
- Validierung: ungültige Zeichen werden abgelehnt

CSS:
- base.css: Icon-Button mit zwei Icons (folder + plus)
- file-explorer.css: Ordner-Zeile als Flex (Label + Delete-Button)
2026-03-05 21:01:09 +01:00
Meleki df68843e82 feat: EasyMDE-Editor für Persona und Session-Kontext
- profile-page.js: #profilePersona textarea → EasyMDE mit Toolbar und Dark-Theme
- session-page.js: #sessionContext textarea → EasyMDE mit Toolbar und Dark-Theme
- form.css: Override-Styles für EasyMDE in Formularen (height: auto, border-radius)
- base.css: ul margin-left für korrekte Listen-Einrückung
- Beide Editoren: sauberes Cleanup via toTextArea() in destroy()
- Nutzt bestehende fe-mde-wrap Styles aus file-explorer.css
2026-03-05 20:24:30 +01:00
Meleki 9140c4fcc7 feat(dashboard): klickbare Session-Cards + UI-Verbesserungen
- Session-Cards mit Agent sind klickbar (navigiert zum Chat)
- Card-Menü bleibt nutzbar via pointer-events Logik
- Menü-Reihenfolge: Bearbeiten vor Chat öffnen
- Session-Beschreibung: textarea → input (einzeilig)
- Globale Link-Styles (a { color: var(--primary) })
2026-03-05 19:50:43 +01:00
Meleki 3ef78b5eb1 feat: Admin-Benutzerverwaltung + Dashboard-Layout-Fixes
Backend:
- AdminEndpoint.cs: 5 Endpunkte (List, Create, Update, Reset PW, Delete) - Admin-only
- DatabaseService: CreateUser(), UpdateUserAdmin(), DeleteUser() (kaskadiert Tokens + Shares)
- Route in Program.cs registriert

Frontend:
- admin-page.js: User-Liste mit Edit/Delete, Inline-Formular Create/Edit
- api.js: 5 Admin-API-Funktionen
- index.html: Template tpl-admin, Script-Tag, Dashboard-Link 'Benutzerverwaltung'
- dashboard.js: Admin-Link nur für Admins sichtbar
- form.css: Styles für admin-user-list, admin-user-row, admin-checkbox-row
- dashboard.css: Header-Overflow-Fix, Agents vor Cronjobs
- index.html: Template-Reihenfolge Agents vor Cronjobs

TODO: User-Management als erledigt markiert
2026-03-05 19:19:16 +01:00
Meleki 489b5e0eb0 feat: Timestamps + LaTeX/KaTeX-Rendering im Chat
Timestamps (dd.MM.yyyy HH:mm:ss):
- Neuer _formatTimestamp() + _addTimestamp() Helper in ui.js
- Timestamp bei allen User- und Assistant-Nachrichten (live, history, archiv)
- Erscheint on hover, halbtransparent, rechts oben an der Bubble

LaTeX/Math-Rendering mit KaTeX 0.16.21:
- KaTeX lokal eingebunden (JS + CSS + 21 woff2-Fonts)
- renderMarkdown() schützt LaTeX vor Markdown-Parsing
- $$...$$ → Block-Math (zentriert), $...$ → Inline-Math
- Fehlerhafte Ausdrücke als <code> Fallback
- KaTeX-Display Styling in markdown.css

Weitere Änderungen:
- theme.css: Neue --info Farbe
- Blockquote-Styling: info-Farbe statt halbtransparent
2026-03-05 18:25:03 +01:00