Commit Graph
7 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 47557c9724 Include panel member tokens in the chain cost badge
Panel member token usage was tracked but discarded, so the cost badge only
ever showed the worker's tokens — misleading for MoA where the real cost is
roughly rounds x agents. Collect each member's usage and add it to the badge.

Each member fills its own TokenUsage in parallel (Anthropic loop via the
existing memberUsage, CLI via the now-captured CliChatResult return value;
OpenAI members stay null, nachruestbar). RunPanel sums them after the
Task.WhenAll barrier — single-threaded, so no lock or Interlocked needed —
across all MoA rounds and emits a panel_usage SSE event before panel_done.
The frontend adds those tokens onto the worker totals in the done handler so
the badge reflects the full chain cost.

- SseHelper: add TokenUsage.Add()
- AnthropicService.Panel.cs: PanelMemberResult.Usage, accumulate per round
  after the barrier, emit panel_usage; RunPanelMemberViaCli returns usage
- chat.js: _panelUsage state, panel_usage case, add to worker tokens on done,
  reset on stream start
- TODO.md: check off the member-token item

v1 limit: live badge only — FinalizeChain still persists worker tokens, so a
reload shows worker-only cost.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 18:08:55 +02:00
MelekiandClaude Opus 4.8 0f87ccdcab Persist MoA intermediate layers so they survive reload
Previously only the final proposer layer was persisted, so after a reload
the intermediate MoA rounds and their "Runde k/N" dividers were gone — the
history showed only the last refined round, not the full live view. Persist
every proposer round instead, tagging each member's JSON transcript with
its layer index, and rebuild the round structure on reload.

- AnthropicService.Panel.cs: persist every round unconditionally; drop the
  now-dead persist parameter and isFinalLayer local; write layer/totalLayers
  into the transcript; iteration = layer*100+index+1 so DB rows are
  layer-aware (no UNIQUE constraint on chain_id/iteration, id-based ordering)
- history.js: group panel bubbles by layer on reload and insert the
  "Runde k / N" divider on round change for MoA (totalLayers > 1), matching
  the live startPanelLayer view; back-compat for old format (default layer 1)
- TODO.md: check off the MoA persistence item

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 18:03:37 +02:00
MelekiandClaude Opus 4.8 c32d1e004f Fix panel member streaming and persist full transcript with images
Three related panel-member improvements:

Tool-box streaming fix: correlate tool boxes by tool ID instead of a
single pointer (fixes orphaned spinners and empty boxes when a member
calls multiple tools in one message), forward CLI ToolEnd to capture the
tool input (command/path), normalize tool names, clean up orphaned
spinners on finalize, and add a blinking cursor during text streaming.

Image/screenshot support: CLI panel members now extract image refs from
the last user message (like the worker) and drop them as temp files
readable via the Read tool, so members can see screenshots and file
attachments instead of being blind on image-based questions.

Reload persistence: each member persists a structured JSON transcript
({name, model, segments:[text|tool]}) instead of plain text, so a reload
restores text AND tool boxes interleaved exactly like live. history.js
renders the transcript and keeps back-compat for the old [Panel: Name]
plaintext format.

- AnthropicService.Agents.cs: NonStreamingLoopCallbacks.TranscriptSink,
  loop collects text/tool segments, tool input added to combined event
- AnthropicService.Panel.cs: CLI member ID-correlation + ToolEnd input +
  image refs + transcript; RunPanelMember persists one JSON transcript
- stream-ui.js: tool boxes keyed by ID, name normalization, cursor,
  orphaned-spinner cleanup
- history.js: render JSON transcript with tool boxes, plaintext fallback

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 16:51:40 +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 f21ed9ff9f Stream panel member responses live with a parallel SSE write-lock
Panel members now stream token-by-token and show tool uses in real time
(like the session agent) instead of delivering text only at completion.
The key constraint is byte-level safety: N members flushing SSE frames
concurrently on the shared HttpResponse would interleave and corrupt the
stream, so a SemaphoreSlim gate serializes the writes (not the model work).

- SseHelper.TryWriteSse takes an optional write-lock (default null, backward
  compatible)
- NonStreamingLoopCallbacks carries SseGate + MemberIndex; _text/_tool/_error
  events are tagged with the member index (review/finalizer stay at -1, no gate)
- CLI members forward TextDelta/ToolStart/ToolResult live instead of
  discarding everything but the final text
- Anthropic-API members stream per tool-round via the loop callbacks; OpenAI
  members fall back to collected text at panel_member_done
- Frontend demuxes by member index into per-bubble interleaved text/tool
  rendering

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 13:18:13 +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