Commit Graph
174 Commits
Author SHA1 Message Date
MelekiandClaude Opus 4.8 5b1802efee Replace mode toggle cycle with a dropdown menu
The composite mode control (#planModeBtn) now opens a dropdown menu
instead of cycling, following the emoji-picker pattern: each mode is an
entry with icon + label + description, the active one marked with a
check. Direct jumps between modes are now possible, so selecting
plan/ultracode resets the persisted panel mode to avoid running both the
panel and the CLI worker. Unified the active button states.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 15:57:34 +02:00
MelekiandClaude Opus 4.8 d5854a3f4b Add ultracode toggle that runs a request as a native dynamic workflow
A new transient per-request toggle state (off→plan→ultracode→fusion→moa)
that whitelists the CLI's Workflow + Task tools so Anthropic's native
dynamic-workflow orchestration runs in gott's headless -p mode without a
permission gate (the engine silently denies Workflow otherwise). Effort is
raised to xhigh (the real ultracode equivalent; "ultracode" itself is not a
valid effort value) without downgrading an explicit max. Only enabled for
Claude models (z.ai/GLM has no workflow runtime) and not in plan mode. The
frontend injects a "use a workflow" hint, like plan mode injects its own.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 15:35:38 +02:00
MelekiandClaude Opus 4.8 e6770bb5f8 Fix shared-bot Telegram agent resolution and add effort badge
- TelegramService: build the chat context with the session owner instead
  of the bot owner, so a public/shared bot resolves the agent for foreign
  sessions; credentials/CLI permission stay with the bot owner.
- Agent cards: render an effort badge next to the model badge when an
  agent has an explicit reasoning effort set.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 12:56:42 +02:00
MelekiandClaude Opus 4.8 8e5a961e94 Show per-member token usage badges on panel bubbles
memberUsage was already populated for CLI members (from the result event)
and Anthropic-API members (via the tool loop), but it was never written to
the panel_member_done SSE event or the persisted content JSON, so the
frontend had no token data to render.

Add the token fields (input/output/cacheRead/cacheCreation) to both the
SSE event and the persisted JSON, and render them via a shared
buildPanelMemberMeta helper used by both the live stream and history, so
the badge survives F5. OpenAI members (no per-turn tokens), error members,
and pre-existing history without token fields fall through to no badge.

The badge is display-only; aggregation into the worker/chain total via
seedUsage is unchanged, so there is no double counting and no DB migration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 17:47:49 +02:00
MelekiandClaude Opus 4.8 1b203707ec Merge plan and panel toggles into one composer button
The composer had two separate mode buttons (plan + panel). Fold them into a
single #planModeBtn that cycles through every operating mode in one place:
Off -> Plan -> Fusion -> MoA -> Off. Cleaner UI, one affordance instead of two.

Plan stays transient (reset on session switch, never persisted) while
Fusion/MoA persist to the session via apiUpdateSession({multiModelMode}) and
are read server-side from ctx.MultiModelMode. The compat var _planModeActive
is kept in sync (true iff mode === 'plan') so sendMessage and modals.js read
it unchanged. No text label — icon + tint only.

- index.html: drop the separate panel button, reuse #planModeBtn
- chat.css: unified states (plan/fusion/moa tints) on #planModeBtn
- chat.js: cycleCompositeMode / initCompositeMode / _renderCompositeBtn
  replace the split plan/panel functions
- chat-page.js: single wiring block, init from session.multiModelMode
- ARCHITECTURE_QUICK.md: document the unified toggle

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:11:13 +02:00
MelekiandClaude Opus 4.8 b7ff928340 Add Mixture-of-Agents (MoA) mode on top of Fusion
Extend the panel engine with a layer loop: Fusion is one proposer round,
MoA runs N rounds where each round after the first sees the previous
round's responses via <previous_layer_responses> and refines its answer.
Only the final round is persisted; intermediate rounds are live-only.
Rounds are clamped to 1-5.

- SessionRecord + migration: moa_layers column (default 2)
- RunPanel: layer loop with per-member cloned message injection
- CloneForMember / BuildPreviousLayerBlock helpers for member isolation
- SSE: panel_layer_start / panel_layer_done events
- Frontend: layer_index composite keying, round dividers, MoA option
- Docs: ARCHITECTURE + ARCHITECTURE_QUICK updated

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 13:46:28 +02:00
MelekiandClaude Opus 4.8 268f11fa6d Add multi-model panel with Fusion mode
Panel agents answer the user prompt in parallel (read-only, non-streaming);
their responses are merged into the worker's last user message as a
<panel_responses> block, and the session agent synthesizes one final
streamed answer. The RunPanel engine is built layer-ready for future MoA.

- New session fields: multi_model_mode (off/fusion), panel_agent_ids (CSV)
  with idempotent column migration
- New partial Services/AnthropicService.Panel.cs holding the RunPanel engine
- Provider-agnostic members: Anthropic RunNonStreamingToolLoop / OpenAI
  CompleteText / CLI plan-mode; all forced read-only, persisted with Tag=panel
- SSE events: panel_start, panel_member_start, panel_member_done, panel_done
- Frontend: multi-agent picker, live panel bubbles, history rendering
- Graceful degradation: panel errors fall back to worker-only

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 12:55:06 +02:00
MelekiandClaude Opus 4.8 f2fd493e5f Add live steering injection into running chains
Let the user inject a message into a running chain instead of only being
able to abort it. While a chain streams, typing + Enter sends the text to
a new /api/chat/steer endpoint; it is drained at the next iteration
boundary, wrapped with a hint so the model actively classifies it
("complements the task -> keep working" vs. "changes course -> adjust"),
and stored as a Type="steer" user message so it survives reload.

Shared infrastructure (provider-agnostic):
- SteeringQueue: out-of-band queue keyed by sessionId, mirrored from
  StreamingTracker (Enqueue/Drain/Clear).
- Program.cs registers it as a singleton and passes it to AnthropicService.
- ChatEndpoint: POST /api/chat/steer enqueues only while IsStreaming,
  Clear() in the finally.
- ChatService.BuildHistoryFromDb groups Type="steer" so no two
  consecutive user turns are produced on re-chat.
- Frontend api.js/chat.js/bubbles.js/history.js + chat.css render the
  optimistic steer bubble and the steer_injected SSE event; Enter during
  a stream sends a steer instead of being blocked.

Anthropic API path:
- Drain point B (tool boundary, merged into the tool_result user turn)
  and C (turn end -> inject + continue instead of finalize).

Claude CLI path (kill-and-restart):
- The agentic loop runs inside the claude child, so true mid-turn inject
  is impossible. On a pending steer the child is killed at the next tool
  boundary, progress is rebuilt from the DB as a <work_in_progress>
  transcript, and the CLI is restarted with the steer appended.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 06:49:58 +02:00
Meleki 1c9b6e3e63 change message system info font-size 2026-05-14 12:43:31 +02:00
MelekiandClaude Opus 4.6 c23e22eefe fix: Auto-Context Markdown-Rendering in History-Ansicht
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 10:24:44 +02:00
MelekiandClaude Opus 4.6 9fe6bed59b feat: Auto-Context im Frontend anzeigen und in DB persistieren
- recalled_context-Header verstärkt (klare Nutzungs-Anweisung statt passivem Hinweis)
- SSE-Event 'auto_context' ans Frontend senden für Live-Anzeige
- Auto-Context als Message (type=auto_context) in DB speichern
- Aufklappbare Auto-Context-Box im Chat-Stream und History-Rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 09:28:56 +02:00
MelekiandClaude Opus 4.6 3f2baa1639 feat: AutoContext-Suche grundlegend verbessern + Embedding-Debug-Tool
Hybrid-Suche (Vektor + FTS5-Keyword), Recency-Boost, Query-Erweiterung
(letzte 2-3 User-Messages), Chunk-Overlapping, FullText-Speicherung,
konfigurierbares Embedding-Modell/MaxSeqLen, deduplizierter AutoContext-
Code (Streaming + CLI shared), Admin-Diagnose-Seite mit Re-Embed-Funktion.
Threshold von 0.45 auf 0.35 gesenkt (Hybrid-Suche ist präziser).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 08:50:41 +02:00
MelekiandClaude Opus 4.6 4960b57ec7 feat: Nvidia API direkt-Anbindung mit Thinking-Mode Support
Neues Server-Setting NvidiaApiKey – wenn gesetzt, wird direkt
integrate.api.nvidia.com verwendet statt g4f.space Proxy.
Thinking-Modelle (kimi-k2, qwq, deepseek-r1) erhalten automatisch
chat_template_kwargs und reasoning-Output wird als klappbare
Denkprozess-Bubble im Chat angezeigt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 09:09:02 +01:00
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