web: show system items in worker console
This commit is contained in:
@@ -718,7 +718,7 @@ Deno.test("projectConsole preserves in-progress assistant protocol stream", () =
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("projectConsole keeps protocol lifecycle events out of the console surface", () => {
|
Deno.test("projectConsole hides lifecycle events and renders system items", () => {
|
||||||
const projection = projectConsole([
|
const projection = projectConsole([
|
||||||
{
|
{
|
||||||
eventId: "30",
|
eventId: "30",
|
||||||
@@ -743,12 +743,24 @@ Deno.test("projectConsole keeps protocol lifecycle events out of the console sur
|
|||||||
eventId: "34",
|
eventId: "34",
|
||||||
event: {
|
event: {
|
||||||
event: "system_item",
|
event: "system_item",
|
||||||
data: { item: { kind: "note", content: "internal" } },
|
data: {
|
||||||
|
item: {
|
||||||
|
kind: "notification",
|
||||||
|
message: "Ticket queued",
|
||||||
|
body: "Reread Ticket 00001KZ6TSGG5 before acting.",
|
||||||
|
},
|
||||||
|
},
|
||||||
} satisfies Event,
|
} satisfies Event,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
assertEquals(projection.lines, []);
|
assertEquals(projection.lines.length, 1);
|
||||||
|
assertEquals(projection.lines[0].kind, "system");
|
||||||
|
assertEquals(projection.lines[0].title, "System · notification");
|
||||||
|
assertEquals(
|
||||||
|
projection.lines[0].body,
|
||||||
|
"Reread Ticket 00001KZ6TSGG5 before acting.",
|
||||||
|
);
|
||||||
assertEquals(projection.status, "running");
|
assertEquals(projection.status, "running");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -859,6 +871,42 @@ Deno.test("projectConsole renders snapshot entries and in-flight output", () =>
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("projectConsole restores system items from snapshot entries", () => {
|
||||||
|
const projection = projectConsole([{
|
||||||
|
eventId: "system-snapshot",
|
||||||
|
event: {
|
||||||
|
event: "snapshot",
|
||||||
|
data: {
|
||||||
|
entries: [{
|
||||||
|
kind: "system_item",
|
||||||
|
ts: 1,
|
||||||
|
item: {
|
||||||
|
kind: "notification",
|
||||||
|
message: "Worker completed",
|
||||||
|
body: "Child Worker coder-1 completed.",
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
greeting: {
|
||||||
|
worker_name: "Worker",
|
||||||
|
cwd: "/repo",
|
||||||
|
provider: "provider",
|
||||||
|
model: "model",
|
||||||
|
scope_summary: "bounded",
|
||||||
|
tools: [],
|
||||||
|
context_window: 100,
|
||||||
|
context_tokens: 20,
|
||||||
|
},
|
||||||
|
status: "idle",
|
||||||
|
},
|
||||||
|
} satisfies Event,
|
||||||
|
}]);
|
||||||
|
|
||||||
|
assertEquals(projection.lines.length, 1);
|
||||||
|
assertEquals(projection.lines[0].kind, "system");
|
||||||
|
assertEquals(projection.lines[0].title, "System · notification");
|
||||||
|
assertEquals(projection.lines[0].body, "Child Worker coder-1 completed.");
|
||||||
|
});
|
||||||
|
|
||||||
Deno.test("projectConsole reseeds visible rows from segment rotation", () => {
|
Deno.test("projectConsole reseeds visible rows from segment rotation", () => {
|
||||||
const projection = projectConsole([
|
const projection = projectConsole([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ export function applyProtocolEvent(
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "system_item":
|
case "system_item":
|
||||||
// System items are protocol/internal context, not console output.
|
next.lines.push(systemItemLine(envelope.eventId, event.data.item));
|
||||||
break;
|
break;
|
||||||
case "text_delta":
|
case "text_delta":
|
||||||
appendStreaming(
|
appendStreaming(
|
||||||
@@ -397,6 +397,17 @@ function line(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function systemItemLine(eventId: string, item: unknown): ConsoleLine {
|
||||||
|
if (!isRecord(item)) {
|
||||||
|
return line(eventId, "system", "System item", jsonPreview(item));
|
||||||
|
}
|
||||||
|
const itemKind = stringField(item, "kind") ?? "item";
|
||||||
|
const title = `System · ${itemKind.replaceAll("_", " ")}`;
|
||||||
|
const body = stringField(item, "body") ?? stringField(item, "message") ??
|
||||||
|
stringField(item, "content") ?? jsonPreview(item);
|
||||||
|
return line(eventId, "system", title, body);
|
||||||
|
}
|
||||||
|
|
||||||
function upsertStatusLine(
|
function upsertStatusLine(
|
||||||
projection: ConsoleProjection,
|
projection: ConsoleProjection,
|
||||||
id: string,
|
id: string,
|
||||||
@@ -1140,6 +1151,9 @@ function applyLogEntry(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "system_item":
|
||||||
|
projection.lines.push(systemItemLine(eventId, entry["item"]));
|
||||||
|
break;
|
||||||
case "assistant_item":
|
case "assistant_item":
|
||||||
case "tool_result":
|
case "tool_result":
|
||||||
applyLoggedItem(projection, eventId, entry["item"]);
|
applyLoggedItem(projection, eventId, entry["item"]);
|
||||||
|
|||||||
Reference in New Issue
Block a user