From 17ba4840ddc51a7c1638eb8de5c13cfe5fb5654d Mon Sep 17 00:00:00 2001 From: Meleki Date: Fri, 19 Jun 2026 17:47:41 +0200 Subject: [PATCH] Hide subagent stream events in the CLI parser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a panel member spawned a subagent via the Agent tool, the Claude CLI emitted the subagent's internal steps as separate top-level messages carrying parent_tool_use_id: tool_use blocks arrived as type:"assistant" (no handler → dropped) and the matching tool_result as type:"user", which created a nameless, label-less collapsible box in the frontend — both in the live stream and in the persisted history (same segment source). Skip any top-level event with a non-empty parent_tool_use_id at the single stream JSON parser, so subagent internals never become CliStreamEvents. This covers worker and panel-member paths at once. The Agent tool call itself (parent_tool_use_id=null) stays visible, and the final result event — which aggregates subagent tokens — carries no parent_tool_use_id, so the token balance is unaffected. Co-Authored-By: Claude Opus 4.8 --- Services/ClaudeCliService.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Services/ClaudeCliService.cs b/Services/ClaudeCliService.cs index 2f1dc47..7c0a00f 100644 --- a/Services/ClaudeCliService.cs +++ b/Services/ClaudeCliService.cs @@ -385,6 +385,21 @@ public class ClaudeCliService var json = JsonSerializer.Deserialize(line); var type = json.TryGetProperty("type", out var t) ? t.GetString() : null; + // Subagent-Events ausblenden: Top-Level-Messages mit gesetztem + // parent_tool_use_id stammen aus einem per 'Agent'-Tool gespawnten + // Subagenten. Deren Interna (tool_use kommt als type:"assistant" ohne + // Handler → verworfen; tool_result als type:"user" → erzeugte sonst eine + // namenlose, label-lose Box) werden konsequent unterdrückt – konsistent + // zum Session-Agent. Die Tool-Box des Agent-Aufrufs selbst hat + // parent_tool_use_id=null und bleibt sichtbar; der finale 'result'-Event + // (Tokens, inkl. aggregierter Subagent-Tokens) trägt ebenfalls keins. + if (json.TryGetProperty("parent_tool_use_id", out var parentToolUseId) + && parentToolUseId.ValueKind == JsonValueKind.String + && !string.IsNullOrEmpty(parentToolUseId.GetString())) + { + continue; + } + if (type == "stream_event" && json.TryGetProperty("event", out var evt)) { var evtType = evt.TryGetProperty("type", out var et) ? et.GetString() : null;