Commit Graph
13 Commits
Author SHA1 Message Date
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 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.8 a58f279eaa Add effort badge to chain summary
Snapshot the agent's effort onto the chain (like model) so it survives
reload, archive and shared chains, then show it in the chain-end meta line.

- ChainRecord.Effort + chains.effort column (TryAddColumn migration).
- CreateChain INSERT carries the value.
- ChatService snapshots agent.Effort at chain creation, but only for Claude
  models – OpenAI providers store '' so there is no misleading badge.
- Anthropic streaming + CLI done-events include effort for the live path.
- chat.js buildMetaBadges renders "Effort: <level>" after the model badge,
  only when a value is set.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 22:08:44 +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 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
Meleki 1ece62ce8c feat(cache): 1h-Prompt-Cache-TTL für API und Claude CLI
Anthropic hat Anfang März 2026 die Default-Cache-TTL stillschweigend
von 1h auf 5min gesenkt. Bei Sessions mit Pausen >5min wird der Cache
jedes Mal neu geschrieben (teuer). Dieser Commit aktiviert die
extended 1h-TTL über beide Pfade.

API-Pfad (AnthropicService):
- Beta-Header "extended-cache-ttl-2025-04-11" hinzugefügt
- Falsches Top-Level cache_control (Root-Level wurde ignoriert) entfernt
- Neue Helper ApplyCacheControlToLast() setzt cache_control idempotent
  auf das letzte Element via JSON-Roundtrip zu Dictionary
- 2 Cache-Breakpoints pro Iteration:
  * Letztes Tool (cached gesamten Tool-Block)
  * Letzter System-Prompt-Block (cached System-Prompt)
- Sub-Agent-Loop (Preparer/Review/Finalizer): String-System-Prompt wird
  bei Bedarf in Block-Form mit cache_control konvertiert

CLI-Pfad (ClaudeCliService):
- Env-Var ENABLE_PROMPT_CACHING_1H=1 für jeden CLI-Child-Prozess gesetzt
  (offizieller Opt-in seit Claude CLI 2.1.108, gilt für API-Key,
  Bedrock, Vertex, Foundry)
2026-05-13 06:46:26 +02:00
MelekiandClaude Opus 4.7 01346a952e Revert: UTF-8-Encoding-Fixes für Claude CLI auf Windows
Setzt die folgenden Commits zurück, da sie das Problem nicht behoben haben:
- e75c437 fix(encoding): UTF-8 prozess-global + 16-KB-StreamReader für CLI-Output
- bfd550e fix: UTF-8-Encoding gehärtet (SSE-Reader + CLI-Workspace)
- 32aad7f fix: UTF-8-Encoding für Claude CLI auf Windows erzwingen

Trotz cmd.exe-Wrapper mit chcp 65001, explizitem UTF-8-StreamReader (16 KB Buffer,
ohne BOM-Detection), Console.OutputEncoding global auf UTF-8 und LANG/LC_ALL/
PYTHONIOENCODING-Env-Vars treten weiterhin Replacement-Chars (�) für Umlaute
und Em-Dashes auf Windows auf. Der Bug muss separat per Diagnose-Logging
nachgestellt werden.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:27:16 +02:00
MelekiandClaude Opus 4.7 bfd550e090 fix: UTF-8-Encoding gehärtet (SSE-Reader + CLI-Workspace)
- AnthropicService.Streaming.cs + OpenAiService.cs: SSE-StreamReader nutzt
  jetzt expliziten UTF-8-Encoder mit 16-KB-Buffer (statt default 1 KB) und
  ohne BOM-Detection. Verhindert intermittierende Replacement-Chars (�),
  die entstehen können, wenn Multi-Byte-UTF-8-Sequenzen ungünstig über die
  Read-Boundary eines NetworkStreams gesplittet werden.
- ClaudeCliService.cs: cmd.exe-Wrapper jetzt mit /D (AutoRun-Skripte aus
  Registry deaktivieren) und WorkingDirectory wird auf den Session-Workspace
  gesetzt. Vorher erbte der Child-Prozess das CWD von gott (bei Windows-
  Diensten C:\WINDOWS\system32).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 12:08:56 +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 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 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 1c622abb37 refactor: AnthropicService partial-class Aufteilung + ToolPayloadOptions + Non-Streaming Deduplizierung
- AnthropicService.cs (337 Zeilen): Felder, Konstruktor, Setters, Utilities
- AnthropicService.Streaming.cs (750 Zeilen): StreamChat, ProcessStream, SSE-Parsing
- AnthropicService.Agents.cs (680 Zeilen): RunAgentChat, ChatNonStreaming, Review/Preparer/Finalizer
- AnthropicService.Cli.cs (530 Zeilen): StreamChatViaCli, MCP-Config, CLI-Helpers
- AddToolsToPayload: 12 Bool-Parameter → ToolPayloadOptions Record
- RunAgentChat + ChatNonStreaming → gemeinsame RunNonStreamingToolLoop-Methode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 14:54:39 +01:00