Pluralize subagent counts in tool group summaries

A tool group with several subagent calls now reads "4 subagents"
instead of "4 subagent". A group with one subagent call still reads
"1 subagent".
This commit is contained in:
Pranit committed 2026-10-27 11:20:30 -04:00
1 parent 70866b2712
commit 8625c8f600
2 files changed
+27 -8

No files matched your search

+25 -6
View File
@@ -151,6 +151,7 @@ const category_labels = [_][]const u8{
"browser",
};
const command_category_index = 5;
const subagent_category_index = 6;
const Summary = struct {
total: usize = 0,
@@ -182,7 +183,7 @@ fn categoryIndex(kind: types.ToolActivityKind) ?usize {
.edit => 3,
.open => 4,
.command => command_category_index,
.subagent => 6,
.subagent => subagent_category_index,
.ask => null,
};
}
@@ -531,10 +532,11 @@ fn formatGroupSummary(alloc: std.mem.Allocator, summary: Summary) ![]u8 {
const index = next_index orelse break;
emitted[index] = true;
const count = summary.categories[index];
const label = if (index == command_category_index and count != 1)
"commands"
else
category_labels[index];
const label = if (count == 1) category_labels[index] else switch (index) {
command_category_index => "commands",
subagent_category_index => "subagents",
else => category_labels[index],
};
try appendSegment(&out.writer, count, label);
}
try appendSegment(&out.writer, summary.completion_unreported, "unreported");
@@ -1490,7 +1492,7 @@ test "grouped subagent status keeps the vertical continuation for middle rows" {
defer projection.deinit(alloc);
try std.testing.expectEqualStrings(
"● 4 tool calls · 4 subagent\n" ++
"● 4 tool calls · 4 subagents\n" ++
"├ Subagent working · inspect auth\n│ glm-5.3-flash · max\n" ++
"├ Subagent working · inspect auth\n│ glm-5.3-flash · max\n" ++
"├ Subagent working · inspect auth\n│ glm-5.3-flash · max\n" ++
@@ -1499,6 +1501,23 @@ test "grouped subagent status keeps the vertical continuation for middle rows" {
);
}
test "group summary uses singular and plural subagent labels" {
const alloc = std.testing.allocator;
var summary: Summary = .{ .total = 2 };
summary.categories[command_category_index] = 1;
summary.categories[subagent_category_index] = 1;
const single = try formatGroupSummary(alloc, summary);
defer alloc.free(single);
try std.testing.expectEqualStrings("● 2 tool calls · 1 command · 1 subagent", single);
summary = .{ .total = 5 };
summary.categories[command_category_index] = 2;
summary.categories[subagent_category_index] = 3;
const plural = try formatGroupSummary(alloc, summary);
defer alloc.free(plural);
try std.testing.expectEqualStrings("● 5 tool calls · 3 subagents · 2 commands", plural);
}
test "small minimal tool groups surface canonical action targets" {
const alloc = std.testing.allocator;
const entries = [_]TranscriptEntry{
@@ -6369,7 +6369,7 @@ describe.skipIf(!tmuxAvailable())("TUI gateway stream lifecycle", () => {
}
await session.waitForText(finalText, TIMEOUT);
const compact = await session.captureFullScrollback();
expect(compact).toContain("● 5 tool calls · 4 subagent · 1 read");
expect(compact).toContain("● 5 tool calls · 4 subagents · 1 read");
expect(compact).toContain("Invalid Agent failed · Check failure visibility");
expect(compact).not.toContain("Invalid Agent replied");
for (let index = 0; index < tasks.length; index += 1) {
@@ -6400,7 +6400,7 @@ describe.skipIf(!tmuxAvailable())("TUI gateway stream lifecycle", () => {
session = await TmuxSession.create({ cmd: `${FX_BIN} --resume-last`, cwd: workspace, env, width: 110, height: 35, stderrPath: join(root, "resumed-stderr.log") });
await session.waitForText(finalText, TIMEOUT);
const resumed = await session.captureFullScrollback();
expect(resumed).toContain("● 5 tool calls · 4 subagent · 1 read");
expect(resumed).toContain("● 5 tool calls · 4 subagents · 1 read");
expect(resumed).toContain("Invalid Agent failed · Check failure visibility");
expect(resumed).toContain("Subagent finished · Check one-off cleanup");
expect(resumed).toContain("reviewer replied · Check replay again");