ui: filter worker console protocol noise
This commit is contained in:
parent
11d94d3866
commit
9ae9b0a043
|
|
@ -11,6 +11,14 @@ function assert(condition: unknown, message: string): asserts condition {
|
|||
}
|
||||
}
|
||||
|
||||
function assertEquals<T>(actual: T, expected: T): void {
|
||||
const actualJson = JSON.stringify(actual);
|
||||
const expectedJson = JSON.stringify(expected);
|
||||
if (actualJson !== expectedJson) {
|
||||
throw new Error(`Expected ${expectedJson}, got ${actualJson}`);
|
||||
}
|
||||
}
|
||||
|
||||
Deno.test("workerConsoleHref encodes runtime and worker target authority", () => {
|
||||
assert(
|
||||
workerConsoleHref({
|
||||
|
|
@ -45,7 +53,7 @@ Deno.test("segmentsToText preserves protocol segment semantics", () => {
|
|||
);
|
||||
});
|
||||
|
||||
Deno.test("projectConsole projects initial console output and live protocol rows", () => {
|
||||
Deno.test("projectConsole projects initial console output and live visible protocol rows", () => {
|
||||
const projection = projectConsole(
|
||||
[
|
||||
{
|
||||
|
|
@ -120,8 +128,8 @@ Deno.test("projectConsole projects initial console output and live protocol rows
|
|||
"tool event row expected",
|
||||
);
|
||||
assert(
|
||||
projection.lines.some((line) => line.kind === "usage"),
|
||||
"usage event row expected",
|
||||
!projection.lines.some((line) => line.kind === "usage"),
|
||||
"usage should update the summary without rendering a console row",
|
||||
);
|
||||
assert(
|
||||
projection.lines.some((line) => line.kind === "error" && line.error),
|
||||
|
|
@ -133,6 +141,37 @@ Deno.test("projectConsole projects initial console output and live protocol rows
|
|||
);
|
||||
});
|
||||
|
||||
Deno.test("projectConsole keeps protocol lifecycle events out of the console surface", () => {
|
||||
const projection = projectConsole([], [
|
||||
{
|
||||
cursor: "30",
|
||||
event: { event: "status", data: { status: "running" } } satisfies Event,
|
||||
},
|
||||
{
|
||||
cursor: "31",
|
||||
event: { event: "llm_call_end", data: { llm_call: 0 } } satisfies Event,
|
||||
},
|
||||
{
|
||||
cursor: "32",
|
||||
event: { event: "turn_end", data: { turn: 0, result: "finished" } } satisfies Event,
|
||||
},
|
||||
{
|
||||
cursor: "33",
|
||||
event: { event: "run_end", data: { result: "finished" } } satisfies Event,
|
||||
},
|
||||
{
|
||||
cursor: "34",
|
||||
event: {
|
||||
event: "system_item",
|
||||
data: { item: { kind: "note", content: "internal" } },
|
||||
} satisfies Event,
|
||||
},
|
||||
]);
|
||||
|
||||
assertEquals(projection.lines, []);
|
||||
assertEquals(projection.status, "running");
|
||||
});
|
||||
|
||||
Deno.test("projectConsole uses snapshot for state without rendering it as console output", () => {
|
||||
const projection = projectConsole([], [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,14 +98,7 @@ export function applyProtocolEvent(
|
|||
);
|
||||
break;
|
||||
case "system_item":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"system",
|
||||
"system item",
|
||||
jsonPreview(event.data.item),
|
||||
),
|
||||
);
|
||||
// System items are protocol/internal context, not console output.
|
||||
break;
|
||||
case "text_delta":
|
||||
appendStreaming(
|
||||
|
|
@ -189,7 +182,6 @@ export function applyProtocolEvent(
|
|||
break;
|
||||
case "usage":
|
||||
next.usage = usageText(event.data);
|
||||
next.lines.push(line(envelope.cursor, "usage", "usage", next.usage));
|
||||
break;
|
||||
case "error":
|
||||
next.lines.push(
|
||||
|
|
@ -212,179 +204,28 @@ export function applyProtocolEvent(
|
|||
break;
|
||||
case "status":
|
||||
next.status = event.data.status;
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "status", event.data.status),
|
||||
);
|
||||
break;
|
||||
case "invoke_start":
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "invoke start", event.data.kind),
|
||||
);
|
||||
break;
|
||||
case "turn_start":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"turn start",
|
||||
`turn ${event.data.turn}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "turn_end":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"turn end",
|
||||
`turn ${event.data.turn} · ${event.data.result}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "llm_call_start":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"llm call start",
|
||||
`call ${event.data.llm_call}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "llm_call_end":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"llm call end",
|
||||
`call ${event.data.llm_call}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "llm_retry":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"llm retry",
|
||||
`${event.data.error} · attempt ${event.data.failed_attempt}/${event.data.max_attempts}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "llm_continuation":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"llm continuation",
|
||||
`${event.data.reason} · attempt ${event.data.attempt}/${event.data.max_attempts}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "run_end":
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "run end", event.data.result),
|
||||
);
|
||||
break;
|
||||
case "alert":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
`alert · ${event.data.level}`,
|
||||
event.data.message,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "memory_worker":
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "memory worker", event.data.message),
|
||||
);
|
||||
break;
|
||||
case "segment_rotated":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"segment rotated",
|
||||
jsonPreview(event.data.entry),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "completions":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"completions",
|
||||
`${event.data.kind} · ${event.data.entries.length} entries`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "rewind_targets":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"rewind targets",
|
||||
`${event.data.targets.length} targets · head ${event.data.head_entries}`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "rewind_applied":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"rewind applied",
|
||||
`${event.data.summary.discarded_entries} discarded · ${event.data.summary.truncated_to_entries} retained`,
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "workers_listed":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"workers listed",
|
||||
jsonPreview(event.data.workers),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "worker_restored":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"worker restored",
|
||||
jsonPreview(event.data.result),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "peer_registered":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"peer registered",
|
||||
jsonPreview(event.data.result),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case "compact_start":
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "compact start", "compaction started"),
|
||||
);
|
||||
break;
|
||||
case "compact_done":
|
||||
next.lines.push(
|
||||
line(
|
||||
envelope.cursor,
|
||||
"status",
|
||||
"compact done",
|
||||
event.data.new_segment_id,
|
||||
),
|
||||
);
|
||||
// These are protocol/status/control events. TUI Console does not append
|
||||
// them to the conversation surface; browser Console should not either.
|
||||
break;
|
||||
case "compact_failed":
|
||||
next.lines.push(
|
||||
|
|
@ -401,9 +242,6 @@ export function applyProtocolEvent(
|
|||
break;
|
||||
case "shutdown":
|
||||
next.status = "shutdown";
|
||||
next.lines.push(
|
||||
line(envelope.cursor, "status", "shutdown", "worker shut down"),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { defineConfig } from 'vite';
|
|||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
server: {
|
||||
allowedHosts: ['develop.hareworks.net'],
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:8787',
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user