182 Commits
Author SHA1 Message Date
MelekiandClaude Fable 5 81892d6e65 Agent: Max Output Tokens + Thinking deaktivieren einstellbar
Zwei neue Agent-Einstellungen (Frontend, DB-Migration additiv):
- MaxOutputTokens: hartes Ausgabelimit. CLI: CLAUDE_CODE_MAX_OUTPUT_TOKENS,
  API: max_tokens (statt hart 16384). 0 = aus.
- DisableThinking: CLI: CLAUDE_CODE_DISABLE_THINKING=1 + MAX_THINKING_TOKENS=0;
  entfernt CLAUDE_CODE_EFFORT_LEVEL (Explizit-Aus schlaegt Effort).
  API-Pfad ohne Aequivalent (Hint im UI).

Die einzigen zwei Parameter, die z.ai/GLM nachweislich honoriert
(Sampling-Parameter wie temperature/top_p werden dort still verworfen).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-03 17:54:11 +02:00
MelekiandClaude Opus 5 7305a5a50f OpenAI: Server-Key-Setting, Filter-Fix fuer o-Reihe, ehrlicher Modell-Refresh
Der Modell-Refresh war fuer OpenAI faktisch ein No-Op: der Key wurde nur aus
der api_keys-Tabelle geholt, und ohne Key blieb die alte Liste im Speicher
stehen und wurde direkt wieder in models_cache.json geschrieben - waehrend der
Endpoint pauschal Erfolg meldete.

- ServerSettingsService: neues Setting OpenAiApiKey (OpenAI war der einzige
  Provider ohne Server-Key, analog Gemini/MiniMax/z.ai)
- OpenAiService: ResolveOpenAiKey() (Setting -> api_keys), HasServerOpenAiKey(),
  ResolveProviderConfig zieht den Setting-Key auch im Chat
- OpenAiService: IsOpenAiChatModel() erfasst die o-Reihe inkl. bare IDs
  (o1, o3, kuenftig o5) - StartsWith("o3-") hat die verschluckt
- RefreshModelsFromApis() liefert ProviderRefreshResult[] pro Provider;
  ModelsEndpoint gibt providers[] zurueck, agent-page.js meldet uebersprungene
  Provider als Fehler-Toast statt pauschalem Erfolg
- ChatEndpoint/TelegramService/CronjobService: OpenAI ohne Agent-Key faellt auf
  den Server-Key zurueck statt hart abzubrechen
- ARCHITECTURE.md nachgezogen

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 11:55:22 +02:00
MelekiandClaude Opus 4.8 ace5036f00 Remote-Keep-Alive gegen 180s-Timeout + System-Prompt via Datei
Task 1 – Remote-Befehle laufen nicht mehr in einen starren 180s-Timeout:
- RemoteConnectionManager.ExecuteCommand nutzt jetzt einen INAKTIVITÄTS-
  Timeout (Watchdog auf LastProgressAt) statt hartem Wall-Clock-Limit; ein
  Befehl darf beliebig lange laufen, solange der Client Progress-Frames sendet.
- RemoteEndpoint: neuer "progress"-Case setzt die Frist zurück.
- InternalEndpoint (MCP-Pfad remote_execute): hartes CancellationTokenSource(180s)
  entfernt → nutzt konfigurierbares ExecuteTimeout-Setting + RequestAborted.
- remote.ps1 / remote.sh: senden während laufender Befehle alle 15s ein
  {"type":"progress"}-Keep-Alive; async stdout/stderr-Lesen gegen Pipe-Deadlocks.
- ToolService: Tool-Beschreibungen erklären den Inaktivitäts-Timeout.

Task 2 – System-Prompt über --system-prompt-file statt CLI-Argument:
- ClaudeCliService schreibt den vollen System-Prompt in eine Temp-Datei und
  übergibt --system-prompt-file, um das Windows-Kommandozeilen-Längenlimit zu
  umgehen. Cleanup im finally. Agent-Verhalten unverändert (MEMORY.md bleibt inline).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 09:21:55 +02:00
MelekiandClaude Opus 4.8 5f7dec6448 Generalize MCP servers, add model refresh button, add sonnet-5
- MCP: replace fixed single Unity field with a generic list of servers
  ({name, url, token?}); dynamic mcp-config + allowlist glob mcp__*<name>*
  per entry; new mcp-servers-ui.js editor (no data migration)
- Models: frontend refresh button wired to existing POST /api/models/refresh,
  reloads optgroups and restores selection
- Model: add sonnet-5 alias + dropdown option (bare "sonnet" stays 4.6)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 08:51:20 +02:00
MelekiandClaude Opus 4.8 418a22d18d docs: Kommentar-Schreibweise wf_<runId>.json zu <runId>.json vereinheitlicht
Die runId ist bereits mit "wf_" praefixiert; der Code erzeugt
<proj>/workflows/<runId>.json. Die Kurz-Referenzen in den Code-Kommentaren
(WorkflowProgressTracker, ClaudeCliService, AnthropicService, SessionEndpoint)
nutzten faelschlich das doppelte "wf_"-Praefix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:18:49 +02:00
MelekiandClaude Opus 4.8 2b95161596 Read workflow-status telemetry from CLI transcript files
Dynamic ultracode workflows run as a detached background task with their
own transcript dir, so their subagent events never flow through the main
-p stream. The previous parent_tool_use_id tap therefore captured nothing
for real workflows and the status stayed "none" the whole run.

Replace the tap with a file-based reader:
- TapWorkflowLaunch parses the "Transcript dir:" line from the Workflow
  tool_result and registers the run.
- WorkflowProgressTracker becomes a per-session registry of transcript
  paths (no longer a stream accumulator).
- WorkflowTelemetryReader reads journal.jsonl for live counts (running)
  and <runId>.json for rich per-agent telemetry (completed); FinalizeChain
  persists the rich JSON into chains.workflow_info.
- Modal renders phases + a per-agent list (label/phase/state/tokens/
  tool-calls/duration) instead of the obsolete tool breakdown.

Sync ARCHITECTURE.md, ARCHITECTURE_QUICK.md and README.md to the new
mechanism.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 18:14:42 +02:00
MelekiandClaude Opus 4.8 b6e546f618 Add workflow-status telemetry view and make panel modes on-demand
Workflow-status: a new WorkflowProgressTracker singleton taps the
suppressed dynamic-workflow subagent events (those carrying
parent_tool_use_id) into per-session telemetry without altering the
existing guard; the snapshot is serialized into the new chains.workflow_info
column on FinalizeChain (ChainId-matched so a panel member of the same
session cannot clear it) and exposed via GET /api/sessions/{id}/workflow-status
(live -> persisted -> none). The header menu gains a 'Workflow-Status' entry
with a modal that live-polls every 2s while running and self-stops on close.

Panel on-demand: Fusion/MoA is now a transient per-request multiModelMode
flag (like plan/ultracode) instead of a persisted session column. Session
settings keep only the panel members + moa_layers; the mode <select> was
removed and the composer dropdown drives the mode per request.

Docs: ARCHITECTURE.md, ARCHITECTURE_QUICK.md and README.md updated for both
features plus the already-shipped z.ai/GLM provider, GLM 5.2+ effort
passthrough, web-search-prime MCP and the ultracode toggle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 17:27:46 +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 0f3d658fd3 Add z.ai/GLM provider via per-process Claude CLI env injection
Route glm:-prefixed models through the CLI/Anthropic path: ResolveModelId
strips the glm: prefix, and CreateCliStartInfo activates the z.ai
Anthropic-compatible endpoint (ANTHROPIC_BASE_URL/AUTH_TOKEN) only for that
process when IsZaiModel matches, leaving every other request's OAuth login
untouched. GLM model list is loaded through the existing model cache and
exposed via /api/models/glm with a "GLM (z.ai)" optgroup in the agent form.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 14:01:43 +02:00
MelekiandClaude Opus 4.8 5c89adb6df Persist panel member token costs to DB via usage seed
Replace the separate panel_usage SSE event + frontend accumulator with
server-side seeding of the worker's usage object. Both the done-event and
FinalizeChain read from the same usage, so panel (Fusion/MoA) member tokens
now flow into the live badge AND the DB as a single source of truth — the
badge no longer drops to the worker-only value after F5.

- RunPanel takes a TokenUsage usageSink; accumulates member costs after the
  Task.WhenAll barrier (single-threaded, no lock)
- ChatEndpoint passes panelUsage as seedUsage to all three worker paths
- StreamChat / StreamChatViaCli / OpenAI StreamChat fold seedUsage into usage
  at creation time, so every exit path persists it
- OpenAI done-events extended with cacheCreation/cacheRead fields for live
  consistency when seeded by Anthropic members
- chat.js: remove redundant _panelUsage / _addPanelUsage / panel_usage
- TODO.md: mark the live-only v1 boundary closed, note the new mechanism

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:44:36 +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 b23eba32b4 Let session owners reassign their session to another user
Previously a session could only be reassigned to another user via a
manual DB UPDATE. This adds it to the session edit UI for every owner of
a session (not just admins) - the ownership check in HandleUpdate
(existing.UserId == userId) already guarantees the caller owns the
session, so handing over one's own session is safe.

Backend:
- ProfileEndpoint: new GET /api/users returning a minimal user directory
  (userId/username/displayName only) for any logged-in user. The
  admin-gated /api/admin/users stays the source for sensitive fields
  (defaultPath/canUseCli/isAdmin).
- SessionEndpoint.HandleUpdate: validate the target user exists (400 if
  not) and pass allowUserReassign: true to UpdateSession.
- DatabaseService.UpdateSession: new allowUserReassign flag; only then is
  a non-empty userId applied as user_id (empty/null is ignored - a
  session must always have an owner).

Frontend:
- index.html: hidden #sessionOwnerRow with a user picker card in the
  session edit form (existing sessions only).
- cards.js: buildUserCard helper for the picker.
- session-page.js: initSessionUserPicker loads users via apiGetUsers(),
  preselects the current owner, and on an actual owner change asks for
  confirmation (irreversible - the session leaves the user's own list).
- api.js: apiGetUsers() -> /api/users.
- ARCHITECTURE.md: document /api/users.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:52:53 +02:00
MelekiandClaude Opus 4.8 de07b49b67 Persist steering messages that arrive during chain finalization
A steering message confirmed to the user as injected:true could still be
lost: after the loop's last HasPending check it runs out and the chain
finalizes (done event + final messages still streaming — the "few extra
messages" the user sees), then the finally block called Clear() and threw
the queue away. A message arriving in that window was accepted
(IsStreaming still true, Stop runs only in finally) but never drained and
never persisted, so it vanished after F5. Platform-independent; Windows
only widened the window via slower CLI teardown.

Replace the queue with a per-session gated state: Open() at chain start,
Close() at chain end. TryEnqueue() and Close() are mutually exclusive via
a per-session lock, so a confirmed injection can no longer be lost — the
loop either drains it or Close() returns it as leftover. The endpoint now
opens the gate at chain start, uses TryEnqueue as the authoritative check
(false → client resends as a normal message), and in finally closes the
gate and persists any leftover as Type="steer" instead of discarding it,
so it survives F5 and the model sees it on the next message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:50:31 +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
MelekiandClaude Opus 4.7 3f913f14b5 Add per-agent reasoning effort
Opus 4.5+ and Sonnet 4.6+ support a new "effort" knob that controls how
much budget the model spends on thinking and tool calls. Plumb it through
end to end so each agent can pick its own level.

Storage & shape:
- New TEXT column agents.effort (default '') added via TryAddColumn.
- AgentRecord.Effort + INSERT/UPDATE in DatabaseService.Agents.cs.
- ChatContext.Effort + SubAgentContext.Effort so the value travels with the
  request alongside model and tool settings.

Agent editor:
- Effort dropdown above git-commit behavior in the agent form (low/medium/
  high/xhigh/max plus empty = "use default"). Always visible; on OpenAI
  providers the value is sent but silently ignored.
- agent-page.js load/save and AgentEndpoint create/update wired up.

Anthropic API path:
- StreamChat and RunNonStreamingToolLoop add output_config: { effort } when
  effort is set and not "high" – empty/null/"high" means "omit and let the
  API pick its default".
- Sub-agents (preparer/review/finalizer) get the parameter through
  RunAgentChat so each step uses its own agent's effort.

Anthropic CLI path:
- ClaudeCliService.ChatStreamingAsync takes an effort parameter and exports
  CLAUDE_CODE_EFFORT_LEVEL on the spawned process. Env-var beats the
  --effort flag because it also covers "max" and "ultracode".
- StreamChatViaCli, ChatNonStreamingViaCli, RunSubAgentViaCli, and the
  ChatEndpoint anthropic branches all hand the value through.

ARCHITECTURE.md / ARCHITECTURE_QUICK.md updated with the new field.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-31 21:33:32 +02:00
MelekiandClaude Opus 4.6 358d9328be fix(openai): Tool-Calling-Reliability verbessern (maxIterations, forced tool_choice, Thinking-Strip)
- maxIterations aus Server-Settings an OpenAI-StreamChat durchreichen (war hardcoded 10)
- Auto-Continue: tool_choice="required" erzwingt Tool-Call statt erneuter Ankündigung,
  wird nach erfolgreichem Tool-Call wieder auf "auto" zurückgesetzt
- Direktive Continuation-Message statt einfaches "Continue."
- StripOldThinking: <think>-Blöcke aus älteren Assistant-Messages entfernen (nur letzte 4 behalten),
  reduziert Kontext-Inflation die ab ~20k Tokens zu Tool-Call-Degradation führt
- reasoning_split=true entfernt (wird von MiniMax-API ignoriert)
- parallel_tool_calls=false für MiniMax (Streaming, Non-Streaming, Payload-Preview)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-14 12:16:55 +02:00
MelekiandClaude Opus 4.6 1fe04025d3 fix(openai): Auto-Context, Tool-Result-Matching, Payload-Preview, leere Bubbles
- Auto-Context (Embedding-Suche) für OpenAI-Provider aktiviert: BuildAutoContextAsync
  auf internal static refactored und in StreamChat + ChatNonStreaming integriert
- Tool-Results mit Role="tool" (OpenAI-Konvention) werden in BuildHistoryFromDb
  jetzt korrekt erkannt (vorher nur Role="user"/Anthropic)
- Payload-Preview zeigt für OpenAI-Provider echtes API-Format (function-Wrapper,
  tool_choice:"auto", max_tokens, stream_options, extra_body)
- Tool-Input (Argumente) wird im SSE tool_end-Event mitgesendet (fehlte im OpenAI-Pfad)
- Leere Bubbles durch Whitespace-only Text nach </think>-Extraktion behoben
  (Trim in DB-Save, BuildHistoryFromDb und Frontend-Guard)
- History-Toggle-Bug: var→const in for-Loop (Block-Scoping für Closures),
  tool_result-Matching per data-tool-call-id statt blindes letztes Element
- Non-Streaming max_tokens für MiniMax auf 32768 + extra_body.reasoning_split

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-14 11:16:40 +02:00
MelekiandClaude Opus 4.7 ecddbe5f36 fix(openai): ask_user_choice-Intercept, Interleaved Thinking in History, MiniMax-Debug-Log
OpenAI-kompatible Provider (MiniMax, DeepSeek-R1, QwQ, Kimi K2, etc.) verloren bei
jeder neuen Iteration ihre eigene Chain-of-Thought, weil thinking-Messages aus der
DB-History rausgefiltert wurden. Folge: Modell kündigt Action an, ruft Tool aber
nicht auf → Stream endet mit finish_reason:stop ohne Tool-Call. Zusätzlich fehlte
der ask_user_choice-Intercept (Tool wurde als unbekannt abgelehnt) und es gab keine
Diagnose-Möglichkeit für unerwartete Stop-Verhalten.

- ChatService.BuildHistoryFromDb(includeThinking): neuer Parameter, fügt
  thinking-Messages als {type:"thinking"}-Block in die Assistant-Message ein.
  Text/Tool-Use derselben Iteration werden via AppendToLastMessage angehängt
  → ein Assistant-Block enthält [thinking, text, tool_use…].
- OpenAiService.ConvertMessage + StreamChat + ChatNonStreaming: Thinking als
  <think>...</think>-Prefix dem Assistant-Content voranstellen (Per-Iteration und
  beim DB-History-Aufbau). Konvention von MiniMax-Docs, wird auch von DeepSeek-R1,
  QwQ, Kimi K2 verstanden.
- ChatEndpoint, SessionEndpoint, CronjobService, TelegramService, ToolService:
  includeThinking je nach Provider durchgereicht. Anthropic-Pfad bleibt aus
  (lehnt thinking-Blöcke ohne Signature ab).
- OpenAiService: ask_user_choice-Intercept im Streaming-Pfad (analog
  AnthropicService.Streaming) – Tool nicht ausführen, SSE user_choice rausschicken,
  mit stopReason awaiting_user_choice finalisieren und return.
- OpenAiService: MiniMax-SSE-Debug-Log in data/openai-debug/ (JSONL: Header +
  Roh-data-Zeilen + Summary mit promptTokens/completionTokens/finishReason/
  toolCalls/duration) – nur für provider=="minimax", nicht-blockierend.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 10:19:06 +02:00
Meleki d66f8d2e73 feat(minimax): Thinking-Parsing, 1h-Cache-TTL, Null-Safety, Provider-Integration
- Thinking-Streaming: Parse 'reasoning_details' (MiniMax mit reasoning_split),
  'reasoning' (Nvidia), 'reasoning_content' (DeepSeek/OpenAI-Compat),
  und inline <think>...</think>-Tags aus delta.content (Fallback)
- MiniMax: max_tokens=32768, stream_options={include_usage}, reasoning_split=true
- 1h-Prompt-Cache-TTL für API (extended-cache-ttl-2025-04-11 Header,
  Cache-Breakpoints auf System-Prompt + letztes Tool) und CLI (ENABLE_PROMPT_CACHING_1H=1)
- Null-Safety: choices/delta/tool_calls/usage null-Checks in Streaming + Non-Streaming
- finish_reason='length' → warning-Event + stopReason='max_tokens'
- MiniMax-Provider: BaseUrl, MinimaxApiKey-Setting, /api/models/minimax-Endpoint,
  Model-Dropdown, statische Fallback-Modelle, Cache-Laden mit Fallback
- Safety-Net: InvalidOperationException-Catch um SSE-Zeilen-Block
2026-05-14 00:55:32 +02:00
MelekiandClaude Opus 4.6 1526891cd9 feat: CLI-Fallback für Sub-Agents (Preparer/Review/Finalizer) wenn kein API-Key zugewiesen
Statt Hard-Error "Kein API-Key zugewiesen" nutzen Sub-Agents jetzt
Claude CLI als Fallback. Preparer wird nur übersprungen wenn weder
Key noch CLI verfügbar sind.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 10:11:34 +02:00
MelekiandClaude Opus 4.6 eccecf8f14 fix: Windows File-Explorer – Backslashes und Laufwerksübersicht
Pfade werden auf Windows nativ mit Backslashes zurückgegeben statt zu Forward-Slashes konvertiert. Navigation von Laufwerk (C:) zurück zur Laufwerksliste ermöglicht.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:37:06 +02:00
MelekiandClaude Opus 4.6 53cee67bef feat: Remote-Execute für Linux/Bash – OS-basierte Tool-Descriptions und remote.sh Script
Remote-Verbindungen erkennen jetzt das OS des Clients und passen die Tool-Description
dynamisch an (PowerShell für Windows, Bash für Linux). Neues remote.sh Script für
Linux/macOS-Clients mit embedded Python WebSocket-Client.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:31: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 f03fbd298e feat: User-Berechtigungen für Agent-Erstellung und CLI-Nutzung
- Neue Felder CanCreateAgents und CanUseCli im UserRecord (Default: true)
- DB-Migration mit Abwärtskompatibilität (bestehende User behalten alle Rechte)
- Admin-UI: Checkboxen für beide Berechtigungen pro User
- AgentEndpoint: Prüfung auf CanCreateAgents beim Erstellen
- ChatEndpoint: CLI-Fallback nur wenn CanUseCli erlaubt
- Frontend: Neuer-Agent-Button und Agent-Page bei fehlender Berechtigung gesperrt
- Chat: Proaktive Warnung wenn kein API-Key und keine CLI-Berechtigung
- Bug Fix: is_public fehlte im Agent-INSERT (Public Agents erst nach erneutem Speichern sichtbar)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:47:56 +01:00
MelekiandClaude Opus 4.6 500c00f948 feat: Unity MCP-Server Integration pro Session
Sessions können jetzt einen Unity MCP-Server (URL + Token) konfigurieren.
Die CLI erhält automatisch die MCP-Config mit korrektem Transport-Typ
(URL-basierte Erkennung: /sse → SSE, sonst HTTP für streamableHttp).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:34:47 +01:00
MelekiandClaude Opus 4.6 3e19da4d48 refactor: Backend-Deduplizierung – Parameter-Objekte, Shared Helpers, KeyCheckDispatcher
- ToolDefinitionOptions + ToolExecutionContext ersetzen lange Parameterlisten in ToolService
- AppendToLastMessage-Helper in ChatService eliminiert 5x duplizierte Logik
- OpenAiService: ResolveProviderConfig + BuildApiMessages + ConvertToOpenAiTools statt doppeltem Code
- Tool-Definitionen aus einer Quelle (Anthropic→OpenAI Konvertierung statt hardcodierter Liste)
- KeyCheckDispatcher zentralisiert Key-Check-Dispatch (ApiKeysEndpoint, KeyScanner, GitHubEventScanner)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 08:01:49 +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 3e0a69e7a4 feat: MCP-Tools ask_user_choice + memory_read/write/list, Text-Marker entfernt
MCP-Server erweitert um ask_user_choice (Long-Poll), memory_read, memory_write
und memory_list Tools. MCP-Config wird jetzt immer generiert (nicht nur bei
Remote-Verbindung). InternalEndpoint um PendingChoices + choice-respond Endpoint
ergänzt. Frontend differenziert CLI-Modus (choice-respond API) vs. API-Modus.
Gesamter :::ASK_USER_CHOICE::: Text-Marker-Mechanismus aus ClaudeCliService,
AnthropicService, markdown.js und stream-ui.js entfernt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 09:54:30 +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
MelekiandClaude Opus 4.6 ee0b817f25 fix: CLI-Stream überlebt Page-Reload (Token-Trennung workCt/sseCt)
workCt steuert den CLI-Prozess (nur Stop-Button), sseCt die SSE-Writes
(Client-Disconnect). Page-Reload cancelt nur sseCt → CLI läuft weiter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 07:01:00 +01:00
MelekiandClaude Opus 4.6 4af9430466 feat: Claude CLI Pfad mit ask_user_choice, Plan-Modus und Tool-Konfiguration
- ClaudeCliService: Marker-basierte ask_user_choice Erkennung im Stream-Parser
- AnthropicService: StreamChatViaCli mit allowUserChoice, planMode, webSearch
- BuildHistoryContext erweitert für tool_use/tool_result (Choice-Antworten)
- Tool-Use Records werden in DB persistiert (Poll-Kompatibilität)
- CLI Tools konfigurierbar: Workspace/Plan-Modus/WebSearch/kein Workspace
- OAuth DB-Felder für zukünftige Token-Verwaltung

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 22:25:39 +01:00
Meleki ab64a843fc refactor: AppPaths.WwwRoot – zentrale wwwroot-Pfadauflösung
- Neue statische Klasse AppPaths mit WwwRoot-Property
- Dev-Modus: ../../../wwwroot (Quell-Verzeichnis)
- Publish-Modus: Fallback auf BaseDirectory/wwwroot
- Program.cs + RemoteEndpoint.cs nutzen AppPaths statt eigener Logik
2026-03-15 10:57:14 +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 229e6d9e53 DB Explorer: Standardmäßig zur letzten Seite springen
- Backend: page=-1 wird als 'letzte Seite' interpretiert (COUNT + Berechnung)
- Frontend: Tabellen-Klick ruft page=-1 auf statt page=1
- Aufgelöster page-Wert aus API-Response für korrekte Anzeige (34/34 statt -1/34)
2026-03-15 10:20:59 +01:00
Meleki 02f5fe2faf Provider-Abstraktion: Agents unterstützen jetzt OpenAI + Anthropic
Backend:
- ChatEndpoint: Globaler OpenAI-Fallback entfernt, Key-Check pro Provider
- TelegramService/CronjobService: Provider-Weiche statt hardcoded Anthropic
- AnthropicService: Preparer/Review/Finalizer sind Provider-aware
- OpenAiService: Neue ChatNonStreaming()-Methode für agentic loop
- ToolService: send_to_session lädt Key des Ziel-Agents
- SubAgentContext: Provider-Feld hinzugefügt
- ChatService: BuildSubAgentContext setzt Provider

Frontend:
- Key-Switch-Modal: 'Kein Key'-Option zum Entfernen der Zuweisung
- ApiKeysEndpoint: keyId='none' löscht Key-Zuweisung
2026-03-14 22:59:33 +01:00
Meleki 1effc6d00f feat: API Key pro Agent statt pro User
- Neue Tabelle agent_api_keys (user_id, agent_id, key_id)
- Migration: bestehende selected_api_key_id auf alle Agents verteilt
- Backend: GetAgentApiKeyRecord(userId, agentId) in Chat, Telegram, Cronjobs
- Endpoints: select/selected mit ?agentId Query-Parameter
- Frontend: currentAgentId aus Session, alle Key-Calls agent-aware
- DeleteApiKey bereinigt agent_api_keys statt users.selected_api_key_id
2026-03-14 21:41:27 +01:00
Meleki e1a9117b4a fix: adopted_api_key_id konsistent als string key_id statt numerischer rowid
- CreateApiKey() gibt jetzt string key_id zurück statt long rowid
- SetScannedKeyAdopted() erwartet string statt long
- DeleteApiKey() direkter Vergleich statt Subquery
- DB-Explorer: PageSize Default auf 1000 erhöht
2026-03-14 17:30:59 +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 3cd35ebbfa feat: Stripe-Key-Checker, Krea AI Pattern, Scan-Progress-Tracking
- StripeKeyChecker: 2-Schritt-Check (/v1/balance + /v1/account), Live/Test-Erkennung, Balance, Account-Details
- KeyPatterns: Stripe-Patterns einkommentiert (sk_live_, sk_test_), Krea AI Pattern (UUID:Token), Mindest-Suchlänge 4
- KeyScannerService: Stripe-Check integriert, Auto-Check nach Scan entfernt (manuell separat), Progress-Tracking (Phase, Detail, Current/Total, KeysFound)
- ApiKeysEndpoint: Stripe in HandleCheck/HandleCheckAll/HandleAdopt, Progress im Status-Endpoint
- Frontend: Live-Fortschrittsanzeige mit Spinner, Phase, Query, Counter, Polling 1.5s, Krea AI in typeNames/typeIcons
2026-03-14 14:34:02 +01:00
Meleki 122000487c Refactor: Server-Settings von appsettings.json in DB-Tabelle (server_settings)
- Neuer ServerSettingsService: zentrale Settings in SQLite mit In-Memory-Cache
- Auto-Migration: bestehende appsettings.Production.json wird einmalig in DB übernommen
- Alle Services umgestellt: IConfiguration → ServerSettingsService (dynamisch, kein Neustart)
- Port bleibt als einziges Setting in appsettings.Production.json (erfordert Neustart)
- ServerSettingsEndpoint: liest/schreibt DB statt JSON-Datei, Port als Sonder-Setting
- IConfiguration komplett entfernt aus allen Services (ChatService, ToolService, AnthropicService,
  OpenAiService, KreaService, TelegramService, KeyScannerService, GitHubEventScannerService)
- AuthMiddleware: KreaApiKey dynamisch aus DB
- appsettings.json bereinigt: nur noch Port und Logging
- Dokumentation aktualisiert (ARCHITECTURE.md, ARCHITECTURE_QUICK.md, README.md)
2026-03-14 13:06:44 +01:00
Meleki 542a031172 feat: OpenAI Provider, Key-Checker Quota-Erkennung, persistierte Scanner-Logs
- OpenAI als vollwertiger Chat-Provider (Modell-Auswahl, Key-Routing, StreamChat)
- Hardcoded OpenAI-Modelle im Cache (gpt-5.x, gpt-4.1, o3, o4-mini etc.)
- /api/models/openai Endpoint, OpenAI-Optgroup im Agent-Dropdown
- Key-Routing: OpenAI-Key aus api_keys-Tabelle, Fallback via GetFirstActiveKeyByProvider
- OpenAI-Checker: 2-Schritt-Check (Models + chat/completions mit max_tokens=1)
- Google-Checker: 2-Schritt-Check (Models + generateContent mit maxOutputTokens=1)
- 429 insufficient_quota und billing_not_active korrekt als quota_exceeded erkannt
- Provider-Erkennung beim Adopt via KeyPatterns.DetectType() statt hardcoded anthropic
- HandleCheck/HandleCheckAll unterstützt jetzt Anthropic, OpenAI und Google
- Neue scanner_logs-Tabelle mit details-Spalte (JSON) für strukturierte Auswertung
- GitHubEventScannerService: AddLog persistiert in DB, detaillierte Key-Fund-Logs
- KeyScannerService: AddLog-Methode mit DB-Persistierung, detaillierte Logs
- Frontend: Ungeprüfte-prüfen-Button (sequenziell, stoppt bei valid)
- Frontend: Provider-Indicator im Key-Switch-Modal (Anthropic/OpenAI/Google)
- Frontend: Check-Button für alle Provider (nicht nur Anthropic)
2026-03-14 11:19:33 +01:00
Meleki c8859a89d0 Multi-Provider Key Scanner + Checker (OpenAI, Google, 15 Key-Typen)
- KeyPatterns.cs: Zentrale Pattern-Klasse für 15 Key-Typen
  (Anthropic, OpenAI, Google, AWS, GitHub, GitLab, HuggingFace, Stripe, SendGrid, Slack)
- OpenAiKeyChecker.cs: Prüft sk-proj/sk-svcacct/sk- Keys via /v1/models
  (Org, Modelle, RPM/TPM, Tier-Erkennung Free bis 5+)
- GoogleKeyChecker.cs: Prüft AIza-Keys via Gemini /v1/models
  (Gemini-Modelle, Maps-Key-Erkennung)
- KeyScannerService + GitHubEventScannerService: Dispatch nach Key-Typ
- ApiKeysEndpoint: GET /scanned/summary + ?type= Filter
- Frontend: 2-stufige UI (Typ-Übersicht → Keys pro Typ)
2026-03-13 20:43:20 +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 7352438b11 feat: Scanned-Keys 'Alle prüfen' Button + EasyMDE Refresh nach More-Toggle
- POST /api/admin/api-keys/scanned/recheck-all: prüft alle nicht-adoptierten Scanned-Keys sequenziell
- Button mit Loading-State, Ergebnis-Toast und Auto-Reload
- EasyMDE/CodeMirror refresh() nach initMoreButton() Einblenden (behebt leeren Editor-Bug)
2026-03-13 15:58:31 +01:00
Meleki a13355d7e9 Remote: Server-seitiger Heartbeat mit Timeout für tote WebSocket-Verbindungen
- Server sendet alle 30s Ping an Client, Client antwortet mit Pong
- LastActivityAt wird bei jeder empfangenen Nachricht aktualisiert
- Nach 90s Inaktivität wird Verbindung als tot erkannt und aufgeräumt
- HeartbeatLoop läuft parallel zum ReceiveLoop
- remote.ps1: ping-Handler hinzugefügt
2026-03-13 15:44:35 +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 cc46cf2bbc feat: HTTP/SOCKS Proxy-Support für alle HttpClient-Requests
- Program.cs: ProxyUrl aus Config lesen, WebProxy auf allen HttpClients via ConfigureHttpClientDefaults
- ServerSettingsEndpoint: ProxyUrl Setting im Frontend (Text-Feld)
- appsettings.json: ProxyUrl Default (leer = kein Proxy)
- Unterstützt HTTP und SOCKS5 Proxies (z.B. socks5://127.0.0.1:1080)
- Betrifft alle ausgehenden Requests: Anthropic, OpenAI, GitHub, Serper, Telegram, Krea
2026-03-13 10:09:45 +01:00
Meleki 192f41e91e feat: Serper Web Search als Agent-Tool
- ToolService: serper_web_search Tool-Definition + ExecuteSerperWebSearch()
  Google-Suche via Serper.dev API mit Titel, Link, Snippet
  Knowledge Graph + Answer Box + organische Ergebnisse
- AgentRecord: UseSerperSearch Property (Default: false)
- DB-Migration: use_serper_search Spalte
- AnthropicService + ChatService: useSerperSearch Parameter durchreichen
- ChatEndpoint + AgentEndpoint: useSerperSearch in API
- Frontend: Checkbox, Badge (Serper Search), laden/speichern
- Aktivierung: Agent-Checkbox + SerperApiKey in Server-Einstellungen
2026-03-13 09:41:56 +01:00
Meleki 558ded1ed5 feat: 3 Scan-Modi (Quick/Web/Full) für Key Scanner
- Quick-Scan: nur GitHub mit Dotenv, Text, Markdown + .env
- Web-Scan: nur Serper.dev (Google Dorks)
- Full-Scan: GitHub + Serper komplett (wie bisher)
- Backend: TriggerScan(mode), ScanGitHubQuick(), mode-basierte Quellsteuerung
- Endpoint: ?mode=quick|web|full Query-Parameter
- Frontend: 3 Buttons (⚡ Quick, 🌐 Web, 🔍 Full) mit gemeinsamer Scan-Logik
- Status-Anzeige zeigt Scan-Modus im Ergebnis
2026-03-13 09:33:18 +01:00