feat(desktop): rebuild agent activity feed around a classifier registry and twelve render classes (#1381)

Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Co-authored-by: npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w <52a228d6edf316ec6812ac3c9fc0d696ab59fc7954d77e7be31eedcddf91335b@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub14vtk7pvazqrq9639qu7e560wnqtl0d53ca4gjuvq6jzf3k2el23qqlwa7f <ab176f059d100602ea25073d9a69ee9817f7b691c76a897180d48498d959faa2@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
Taylor Ho
2026-06-30 12:19:06 -07:00
committed by GitHub
parent 42ec17f137
commit 5cc09e6989
62 changed files with 6695 additions and 838 deletions

View File

@@ -0,0 +1,327 @@
import assert from "node:assert/strict";
import test from "node:test";
import {
buildTranscriptDisplayBlocks,
flattenDisplayBlocks,
formatTurnSetupLabel,
} from "./agentSessionTranscriptGrouping.ts";
const baseTimestamp = "2026-06-14T22:20:23.000Z";
function lifecycle(id, title, acpSource, turnId, text = "") {
return {
id,
type: "lifecycle",
title,
text,
timestamp: baseTimestamp,
acpSource,
turnId,
sessionId: "sess-1",
channelId: "channel-1",
};
}
function userPrompt(id, text, turnId) {
return {
id,
type: "message",
role: "user",
title: "Buzz event",
text,
timestamp: baseTimestamp,
acpSource: "session/prompt:user",
turnId,
sessionId: "sess-1",
channelId: "channel-1",
};
}
function promptContext(id, turnId) {
return {
id,
type: "metadata",
title: "Prompt context",
sections: [{ title: "Channel", body: "general" }],
timestamp: baseTimestamp,
acpSource: "session/prompt:context",
turnId,
sessionId: "sess-1",
channelId: "channel-1",
};
}
function assistantMessage(id, text, turnId) {
return {
id,
type: "message",
role: "assistant",
title: "Assistant",
text,
timestamp: "2026-06-14T22:20:47.000Z",
acpSource: "agent_message_chunk",
turnId,
sessionId: "sess-1",
channelId: "channel-1",
};
}
function toolCall(id, turnId) {
return {
id,
type: "tool",
title: "Shell",
toolName: "buzz-dev-mcp__shell",
buzzToolName: null,
status: "completed",
args: {},
result: "ok",
isError: false,
timestamp: "2026-06-14T22:20:47.000Z",
startedAt: "2026-06-14T22:20:47.000Z",
completedAt: "2026-06-14T22:20:47.400Z",
acpSource: "tool_call_update",
turnId,
sessionId: "sess-1",
channelId: "channel-1",
};
}
test("buildTranscriptDisplayBlocks bundles user prompt, setup, and context together", () => {
const rawItems = [
lifecycle(
"turn",
"Turn started",
"turn_started",
"turn-1",
"Triggered by 1 event.",
),
lifecycle("session", "Session ready", "session_resolved", "turn-1"),
userPrompt("prompt", "@Ned deliberate, wider pass", "turn-1"),
promptContext("context", "turn-1"),
assistantMessage("assistant", "Thinking out loud.", "turn-1"),
toolCall("tool", "turn-1"),
];
const blocks = buildTranscriptDisplayBlocks(rawItems);
const displayOrder = flattenDisplayBlocks(blocks).map((item) => item.id);
assert.deepEqual(displayOrder, [
"prompt",
"turn",
"session",
"context",
"assistant",
"tool",
]);
const turnBlock = blocks[0];
assert.equal(turnBlock?.kind, "turn");
assert.equal(turnBlock.segments[0]?.kind, "prompt");
const promptSegment = turnBlock.segments[0];
assert.equal(promptSegment.user.id, "prompt");
assert.equal(promptSegment.context?.id, "context");
assert.equal(promptSegment.setup.length, 2);
assert.equal(turnBlock.segments[1]?.kind, "item");
assert.equal(turnBlock.segments[2]?.kind, "item");
});
test("buildTranscriptDisplayBlocks collapses setup lifecycle inside prompt bundle", () => {
const rawItems = [
lifecycle("turn", "Turn started", "turn_started", "turn-1"),
lifecycle("session", "Session ready", "session_resolved", "turn-1"),
userPrompt("prompt", "hello", "turn-1"),
];
const blocks = buildTranscriptDisplayBlocks(rawItems);
assert.equal(blocks.length, 1);
assert.equal(blocks[0]?.kind, "turn");
const turnBlock = blocks[0];
assert.equal(turnBlock.segments.length, 1);
assert.equal(turnBlock.segments[0]?.kind, "prompt");
assert.equal(
formatTurnSetupLabel(turnBlock.segments[0].setup),
"Turn started · Session ready",
);
});
test("buildTranscriptDisplayBlocks hides setup and context when prompt is missing", () => {
const rawItems = [
lifecycle("turn", "Turn started", "turn_started", "turn-1"),
lifecycle("session", "Session ready", "session_resolved", "turn-1"),
promptContext("context", "turn-1"),
toolCall("tool", "turn-1"),
];
const blocks = buildTranscriptDisplayBlocks(rawItems);
const displayOrder = flattenDisplayBlocks(blocks).map((item) => item.id);
assert.deepEqual(displayOrder, ["tool"]);
});
test("buildTranscriptDisplayBlocks drops setup-and-context-only turns", () => {
const rawItems = [
lifecycle("turn", "Turn started", "turn_started", "turn-1"),
lifecycle("session", "Session ready", "session_resolved", "turn-1"),
promptContext("context", "turn-1"),
];
const blocks = buildTranscriptDisplayBlocks(rawItems);
assert.deepEqual(blocks, []);
});
test("buildTranscriptDisplayBlocks leaves error lifecycle prominent outside prompt bundle", () => {
const rawItems = [
lifecycle("turn", "Turn started", "turn_started", "turn-1"),
userPrompt("prompt", "hello", "turn-1"),
lifecycle(
"error",
"Turn error",
"turn_error",
"turn-1",
"timeout: agent hung",
),
];
const blocks = buildTranscriptDisplayBlocks(rawItems);
const displayOrder = flattenDisplayBlocks(blocks).map((item) => item.id);
assert.deepEqual(displayOrder, ["prompt", "turn", "error"]);
assert.equal(blocks[0]?.segments[0]?.kind, "prompt");
assert.equal(blocks[0]?.segments[1]?.kind, "item");
assert.equal(blocks[0]?.segments[1]?.item.id, "error");
});
test("buildTranscriptDisplayBlocks passes through items without turnId", () => {
const orphan = {
id: "orphan",
type: "lifecycle",
title: "Wire parse error",
text: "bad json",
timestamp: baseTimestamp,
acpSource: "acp_parse_error",
channelId: "channel-1",
};
const blocks = buildTranscriptDisplayBlocks([orphan]);
assert.equal(blocks.length, 1);
assert.equal(blocks[0]?.kind, "single");
assert.equal(blocks[0]?.item.id, "orphan");
});
test("buildTranscriptDisplayBlocks groups same-kind tool runs within a turn", () => {
const items = [1, 2, 3].map((index) => ({
id: `tool:${index}`,
type: "tool",
renderClass: "generic",
descriptor: {
renderClass: "generic",
label: "Read file",
preview: `file-${index}.ts`,
groupKey: "read_file",
},
title: "read_file",
toolName: "read_file",
buzzToolName: null,
status: "completed",
args: { path: `file-${index}.ts` },
result: "",
isError: false,
timestamp: "2026-06-18T00:00:00Z",
startedAt: "2026-06-18T00:00:00Z",
completedAt: "2026-06-18T00:00:01Z",
turnId: "turn-1",
sessionId: "sess-1",
channelId: "chan-1",
}));
const [block] = buildTranscriptDisplayBlocks(items);
assert.equal(block.kind, "turn");
assert.equal(block.segments.length, 1);
assert.equal(block.segments[0].kind, "summary");
assert.equal(block.segments[0].summary.label, "Read 3 files");
});
test("buildTranscriptDisplayBlocks groups consecutive file edit tool runs", () => {
const items = [1, 2].map((index) => ({
id: `edit:${index}`,
type: "tool",
renderClass: "file-edit",
descriptor: {
renderClass: "file-edit",
label: "Edited file",
preview: `src/file-${index}.ts`,
groupKey: "file-edit:str_replace",
},
title: "str_replace",
toolName: "str_replace",
buzzToolName: null,
status: "completed",
args: { path: `src/file-${index}.ts` },
result: "",
isError: false,
timestamp: "2026-06-18T00:00:00Z",
startedAt: "2026-06-18T00:00:00Z",
completedAt: "2026-06-18T00:00:01Z",
turnId: "turn-1",
sessionId: "sess-1",
channelId: "chan-1",
}));
const [block] = buildTranscriptDisplayBlocks(items);
assert.equal(block.kind, "turn");
assert.equal(block.segments.length, 1);
assert.equal(block.segments[0].kind, "summary");
assert.equal(block.segments[0].summary.label, "Edited 2 files");
assert.equal(block.segments[0].summary.renderClass, "file-edit");
assert.deepEqual(
block.segments[0].summary.items.map((item) => item.id),
["edit:1", "edit:2"],
);
});
test("buildTranscriptDisplayBlocks keeps non-contiguous same-kind runs expanded", () => {
const mkTool = (id, label, renderClass = "generic", groupKey = label) => ({
id,
type: "tool",
renderClass,
descriptor: {
renderClass,
label,
preview: id,
source: "harness",
groupKey,
},
title: label,
toolName: label,
buzzToolName: null,
status: "completed",
args: {},
result: "",
isError: false,
timestamp: "2026-06-18T00:00:00Z",
startedAt: "2026-06-18T00:00:00Z",
completedAt: "2026-06-18T00:00:01Z",
turnId: "turn-1",
sessionId: "sess-1",
channelId: "chan-1",
});
const [block] = buildTranscriptDisplayBlocks([
mkTool("read-1", "Read file", "generic", "read_file"),
mkTool("shell-1", "Ran command", "shell", "shell:command"),
mkTool("read-2", "Read file", "generic", "read_file"),
mkTool("read-3", "Read file", "generic", "read_file"),
]);
assert.equal(block.kind, "turn");
assert.deepEqual(
block.segments.map((segment) => segment.kind),
["item", "item", "item", "item"],
);
});