import assert from "node:assert/strict"; import test from "node:test"; import { traceDisplayRows } from "./app-trace.ts"; test("trace display rows render request, setup, command, assistant markdown, and completion path", () => { const trace = { traceId: "trc_trace_contract", events: traceEvents(), assistantStreams: [{ itemId: "assistant-final", text: "# 处理完成\n\n- trace markdown ok" }] }; const rows = traceDisplayRows(trace, trace.events); const text = rows.map((row) => `${row.header}\n${row.body ?? ""}`).join("\n---\n"); assert.match(text, /请求接受.*请检查 trace/u); assert.match(text, /会话复用/u); assert.match(text, /工具调用/u); assert.match(text, /hostJobId=job-trace-1/u); assert.match(text, /助手最后一条消息,轮次完成/u); assert.match(text, /# 处理完成/u); assert.equal(rows.some((row) => row.bodyFormat === "markdown"), true); }); test("trace display rows render completion when no terminal assistant event exists", () => { const events = [ event(1, "request:accepted", { promptSummary: "只跑完成事件" }), event(2, "turn:completed", { status: "completed" }) ]; const rows = traceDisplayRows({ traceId: "trc_completion", events }, events); assert.equal(rows.some((row) => /轮次完成/u.test(row.header)), true); }); test("trace display rows render assistant item text when stream snapshot is absent", () => { const events = [ event(1, "request:accepted", { promptSummary: "请列出 device-pod" }), event(2, "assistant:item_completed", { type: "assistant_message", status: "completed", itemId: "msg_item_0", message: "当前有以下 **5 个 device-pod** 可用。" }), commandEvent(3, "item/commandExecution:completed", { itemId: "cmd-trace-2", command: "grep -rn device-pod /workspace/hwlab", status: "completed", exitCode: 0, stdoutSummary: "success=true" }), event(4, "assistant:completed", { type: "assistant_message", terminal: true, status: "completed", itemId: "assistant-final", message: "可以继续指定要操作的 device-pod。" }) ]; const rows = traceDisplayRows({ traceId: "trc_assistant_item_text", events }, events); const text = rows.map((row) => `${row.header}\n${row.body ?? ""}`).join("\n---\n"); assert.match(text, /🤖 助手消息(第一条)/u); assert.match(text, /当前有以下 \*\*5 个 device-pod\*\* 可用/u); assert.match(text, /工具调用/u); assert.match(text, /助手最后一条消息/u); assert.match(text, /可以继续指定要操作的 device-pod/u); }); function traceEvents() { return [ event(1, "request:accepted", { promptSummary: "请检查 trace" }), event(2, "session:reused"), commandEvent(3, "item/commandExecution:started", { itemId: "cmd-trace-1", command: "bash -lc 'build start'" }), { ...event(4, "item/commandExecution/outputDelta", { type: "tool_call", status: "output_chunk", itemId: "cmd-trace-1", outputSummary: '{"hostJobId":"job-trace-1","success":true}' }) }, commandEvent(5, "item/commandExecution:completed", { itemId: "cmd-trace-1", command: "bash -lc 'build status'", status: "completed", exitCode: 0, durationMs: 1200 }), event(6, "assistant:completed", { type: "assistant_message", terminal: true, status: "completed", itemId: "assistant-final" }) ]; } function commandEvent(seq, label, fields) { return event(seq, label, { type: "tool_call", toolName: "commandExecution", ...fields }); } function event(seq, label, fields = {}) { return { traceId: "trc_trace_contract", seq, label, type: fields.type ?? "event", status: fields.status ?? "observed", createdAt: new Date(1779690000000 + seq * 1000).toISOString(), ...fields }; }