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>
This commit is contained in:
MelekiandClaude Opus 4.8 committed 2026-06-18 18:08:55 +02:00
1 parent 0f87ccdcab
commit 47557c9724
4 files changed
+82 -10

No files matched your search

+15
View File
@@ -90,6 +90,21 @@ public class TokenUsage
public long OutputTokens { get; set; }
public long CacheCreationTokens { get; set; }
public long CacheReadTokens { get; set; }
/// <summary>
/// Addiert die Werte von <paramref name="other"/> auf. NICHT thread-safe – der einzige
/// Aufrufer (Panel-Engine) summiert die Member-Usage erst NACH der Task.WhenAll-Barrier,
/// also single-threaded. Jeder Member befüllt seine EIGENE TokenUsage parallel; geteilt
/// wird nichts → kein Lock/Interlocked nötig.
/// </summary>
public void Add(TokenUsage other)
{
if (other == null) return;
InputTokens += other.InputTokens;
OutputTokens += other.OutputTokens;
CacheCreationTokens += other.CacheCreationTokens;
CacheReadTokens += other.CacheReadTokens;
}
}
/// <summary>