feat(ui): render user tool_result blocks as one-line summaries

This commit is contained in:
Mika Kuns
2026-04-21 15:13:00 +02:00
parent ec679e45ed
commit 374e811e78

View File

@@ -120,7 +120,100 @@ public class StreamLineFormatter
return true; return true;
} }
private static string? FormatUser(JsonElement root) => null; private static string? FormatUser(JsonElement root)
{
if (!TryGetContentArray(root, out var content))
return null;
var sb = new StringBuilder();
foreach (var block in content.EnumerateArray())
{
if (block.ValueKind != JsonValueKind.Object) continue;
if (!block.TryGetProperty("type", out var blockTypeProp)) continue;
if (blockTypeProp.GetString() != "tool_result") continue;
var summary = BuildToolResultSummary(root, block);
if (!string.IsNullOrEmpty(summary))
{
sb.Append("→ ");
sb.Append(summary);
sb.Append('\n');
}
}
return sb.Length == 0 ? null : sb.ToString();
}
private static string BuildToolResultSummary(JsonElement root, JsonElement block)
{
var isError = block.TryGetProperty("is_error", out var errProp)
&& errProp.ValueKind == JsonValueKind.True;
var contentText = ResolveContentText(block);
if (isError)
{
var msg = FirstNonEmptyLine(contentText);
return string.IsNullOrEmpty(msg) ? "error" : $"error: {Truncate(msg, MaxArgChars)}";
}
// tool_use_result.file.numLines shortcut for Read-style results
if (root.TryGetProperty("tool_use_result", out var tur)
&& tur.ValueKind == JsonValueKind.Object
&& tur.TryGetProperty("file", out var file)
&& file.ValueKind == JsonValueKind.Object
&& file.TryGetProperty("numLines", out var nl)
&& nl.ValueKind == JsonValueKind.Number
&& nl.TryGetInt32(out var lines))
{
return $"{lines} lines";
}
if (string.IsNullOrWhiteSpace(contentText))
return "ok";
var first = FirstNonEmptyLine(contentText);
return Truncate(first, MaxArgChars);
}
private static string ResolveContentText(JsonElement block)
{
if (!block.TryGetProperty("content", out var c))
return "";
if (c.ValueKind == JsonValueKind.String)
return c.GetString() ?? "";
if (c.ValueKind == JsonValueKind.Array)
{
var sb = new StringBuilder();
foreach (var part in c.EnumerateArray())
{
if (part.ValueKind != JsonValueKind.Object) continue;
if (!part.TryGetProperty("type", out var pt)) continue;
if (pt.GetString() != "text") continue;
if (part.TryGetProperty("text", out var t) && t.ValueKind == JsonValueKind.String)
{
if (sb.Length > 0) sb.Append('\n');
sb.Append(t.GetString());
}
}
return sb.ToString();
}
return "";
}
private static string FirstNonEmptyLine(string s)
{
if (string.IsNullOrEmpty(s)) return "";
foreach (var raw in s.Split('\n'))
{
var line = raw.TrimEnd('\r').Trim();
if (line.Length > 0) return line;
}
return "";
}
private static string? FormatResult(JsonElement root) private static string? FormatResult(JsonElement root)
{ {