Merge pull request #845 from pikasTech/fix/issue844-trace-json-contract

fix(v02): expose trace render json summary
This commit is contained in:
Lyon
2026-06-04 18:29:33 +08:00
committed by GitHub
2 changed files with 52 additions and 1 deletions
+27
View File
@@ -1400,6 +1400,33 @@ test("hwlab-cli client agent trace can render with the Web trace row path", asyn
assert.ok(result.payload.body.renderedRowCount >= 1);
assert.ok(result.payload.body.rows.some((row: any) => //u.test(row.header)));
assert.equal(JSON.stringify(result.payload.body.rows).includes("session:reused"), false);
assert.equal(result.payload.traceStatus, "completed");
assert.equal(result.payload.rendered.traceStatus, "completed");
assert.equal(result.payload.rendered.render, "web");
assert.equal(result.payload.rendered.renderedRowCount, result.payload.body.renderedRowCount);
assert.deepEqual(result.payload.rendered.rows, result.payload.body.rows);
assert.deepEqual(result.payload.data, result.payload.rendered);
});
test("hwlab-cli client agent trace exposes missing Web render state without a body-path trap", async () => {
const result = await runHwlabCli(["client", "agent", "trace", "trc_missing", "--base-url", "http://web.test", "--cookie", "hwlab_session=session-a", "--render", "web"], {
fetchImpl: async () => new Response(JSON.stringify({
status: "missing",
traceId: "trc_missing",
eventCount: 0,
events: []
}), { status: 200 })
});
assert.equal(result.exitCode, 0);
assert.equal(result.payload.status, "succeeded");
assert.equal(result.payload.traceStatus, "missing");
assert.equal(result.payload.body.status, "missing");
assert.equal(result.payload.rendered.traceStatus, "missing");
assert.equal(result.payload.rendered.sourceEventCount, 0);
assert.equal(result.payload.rendered.renderedRowCount, 0);
assert.deepEqual(result.payload.rendered.rows, []);
assert.deepEqual(result.payload.data, result.payload.rendered);
});
test("hwlab-cli Web trace render does not treat AgentRun result-ready as final assistant text", async () => {
+25 -1
View File
@@ -630,7 +630,7 @@ async function agentCommand(context: any) {
const pathName = `/v1/agent/chat/trace/${encodeURIComponent(traceId)}`;
const response = await requestJson({ ...context, method: "GET", path: pathName });
const traceBody = traceBodyForCli(response.body, context.parsed);
return responsePayload("client.agent.trace", response, context, { route: route("GET", pathName), traceId, body: traceBody });
return responsePayload("client.agent.trace", response, context, { route: route("GET", pathName), traceId, body: traceBody, ...traceResponseAliases(traceBody, context.parsed) });
}
if (subcommand === "inspect") {
const pathName = agentInspectPath(context);
@@ -2435,6 +2435,30 @@ function webTraceRenderBody(traceObject: any, parsed: ParsedArgs) {
});
}
function traceResponseAliases(traceBody: any, parsed: ParsedArgs) {
if (text(parsed.render) !== "web" || !traceBody || typeof traceBody !== "object") return {};
const rendered = pruneUndefined({
traceId: traceBody.traceId ?? null,
traceStatus: traceBody.status ?? null,
render: traceBody.render,
renderer: traceBody.renderer,
sourceEventCount: traceBody.sourceEventCount,
renderedRowCount: traceBody.renderedRowCount,
returnedRowCount: traceBody.returnedRowCount,
noiseEventCount: traceBody.noiseEventCount,
omittedNoiseCount: traceBody.omittedNoiseCount,
rowLimit: traceBody.rowLimit,
rows: traceBody.rows,
eventCountMismatch: traceBody.eventCountMismatch,
assistantText: traceBody.assistantText
});
return {
traceStatus: traceBody.status ?? null,
rendered,
data: rendered
};
}
function compactTraceRenderRow(row: any) {
return pruneUndefined({
rowId: row?.rowId ?? null,