fix: reduce AgentRun trace noise for HWLAB CLI
This commit is contained in:
@@ -665,11 +665,13 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
}
|
||||
const now = nowIso();
|
||||
const runnerTrace = traceStore.snapshot(traceId, agentRunTraceMeta({}, {}));
|
||||
const terminalEventCreatedAt = agentRunResultTraceCreatedAt(runnerTrace, now);
|
||||
if (terminalStatus === "completed" && String(result?.reply ?? "").trim()) {
|
||||
traceStore.append(traceId, {
|
||||
type: "result",
|
||||
status: "completed",
|
||||
label: "agentrun:result:completed",
|
||||
createdAt: terminalEventCreatedAt,
|
||||
message: "AgentRun result is ready for HWLAB short-connection polling.",
|
||||
runId: base.agentRun.runId,
|
||||
commandId: base.agentRun.commandId,
|
||||
@@ -706,6 +708,7 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
type: "result",
|
||||
status: canceled ? "canceled" : "failed",
|
||||
label: `agentrun:result:${canceled ? "canceled" : terminalStatus || "failed"}`,
|
||||
createdAt: terminalEventCreatedAt,
|
||||
errorCode: canceled ? "agentrun_canceled" : result?.failureKind ?? "agentrun_failed",
|
||||
message: result?.failureMessage ?? result?.blocker?.message ?? (canceled ? "AgentRun command was canceled." : "AgentRun command failed without a completed reply."),
|
||||
runId: base.agentRun.runId,
|
||||
@@ -753,6 +756,11 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
};
|
||||
}
|
||||
|
||||
function agentRunResultTraceCreatedAt(runnerTrace = {}, fallback) {
|
||||
const last = String(runnerTrace?.lastEvent?.createdAt ?? runnerTrace?.updatedAt ?? "");
|
||||
return Number.isFinite(Date.parse(last)) ? last : fallback;
|
||||
}
|
||||
|
||||
function decorateAgentRunRunningResult({ base, mapping, traceStore, traceId }) {
|
||||
return {
|
||||
...base,
|
||||
@@ -780,6 +788,7 @@ function mapAgentRunEvent(event, mapping = {}) {
|
||||
if (!event || typeof event !== "object") return null;
|
||||
const payload = event.payload && typeof event.payload === "object" ? event.payload : {};
|
||||
const base = {
|
||||
createdAt: event.createdAt ?? null,
|
||||
source: "agentrun",
|
||||
sourceSeq: event.seq ?? null,
|
||||
runId: event.runId ?? mapping.runId ?? null,
|
||||
|
||||
@@ -35,3 +35,17 @@ test("code agent trace store retains six thousand regular events", () => {
|
||||
assert.equal(snapshot.events[0].label, "event:1");
|
||||
assert.equal(snapshot.events.at(-1).label, "event:6000");
|
||||
});
|
||||
|
||||
test("code agent trace store preserves upstream event timestamps", () => {
|
||||
const traceStore = createCodeAgentTraceStore({ maxEvents: 10 });
|
||||
const traceId = "trc_trace-store-upstream-time";
|
||||
traceStore.append(traceId, {
|
||||
type: "backend",
|
||||
status: "running",
|
||||
label: "agentrun:backend:turn/completed",
|
||||
createdAt: "2026-06-01T16:35:40.939Z"
|
||||
}, { now: "2026-06-01T16:35:56.171Z" });
|
||||
const snapshot = traceStore.snapshot(traceId);
|
||||
assert.equal(snapshot.events[0].createdAt, "2026-06-01T16:35:40.939Z");
|
||||
assert.equal(snapshot.elapsedMs, 0);
|
||||
});
|
||||
|
||||
@@ -306,6 +306,7 @@ function normalizeTraceEvent(event, { traceId, seq, now, fallbackRunnerKind } =
|
||||
const status = safeToken(event.status ?? "observed");
|
||||
const toolName = safeText(event.toolName ?? event.name, 120);
|
||||
const label = safeText(event.label, 180) || labelFor({ type, status, toolName });
|
||||
const eventCreatedAt = safeTimestamp(event.createdAt) ?? timestampFor(now);
|
||||
return dropUndefined({
|
||||
seq,
|
||||
traceId,
|
||||
@@ -313,7 +314,7 @@ function normalizeTraceEvent(event, { traceId, seq, now, fallbackRunnerKind } =
|
||||
stage: safeToken(event.stage ?? type),
|
||||
status,
|
||||
label,
|
||||
createdAt: timestampFor(now),
|
||||
createdAt: eventCreatedAt,
|
||||
elapsedMs: typeof event.elapsedMs === "number" ? Math.max(0, Math.trunc(event.elapsedMs)) : null,
|
||||
runnerKind: safeText(event.runnerKind ?? fallbackRunnerKind, 140),
|
||||
source: safeText(event.source, 120),
|
||||
@@ -362,7 +363,7 @@ function normalizeAssistantDelta(delta, { traceId, now, fallbackRunnerKind } = {
|
||||
traceId,
|
||||
itemId: safeText(delta.itemId, 180),
|
||||
chunk,
|
||||
createdAt: timestampFor(now),
|
||||
createdAt: safeTimestamp(delta.createdAt) ?? timestampFor(now),
|
||||
runnerKind: safeText(delta.runnerKind ?? fallbackRunnerKind, 140),
|
||||
sessionId: safeText(delta.sessionId, 180),
|
||||
sessionStatus: safeText(delta.sessionStatus, 80),
|
||||
@@ -374,6 +375,13 @@ function normalizeAssistantDelta(delta, { traceId, now, fallbackRunnerKind } = {
|
||||
});
|
||||
}
|
||||
|
||||
function safeTimestamp(value) {
|
||||
const text = safeText(value, 80);
|
||||
if (!text) return null;
|
||||
const ms = Date.parse(text);
|
||||
return Number.isFinite(ms) ? new Date(ms).toISOString() : null;
|
||||
}
|
||||
|
||||
function assistantStreamsSnapshot(trace) {
|
||||
if (!(trace?.assistantStreams instanceof Map)) return [];
|
||||
return [...trace.assistantStreams.values()].map((stream) => ({ ...stream }));
|
||||
|
||||
@@ -355,6 +355,7 @@ test("cloud api /v1/agent/chat delegates v0.2 turns to AgentRun v0.1 over adapte
|
||||
assert.ok(traceBody.events.some((event) => event.label === "agentrun:assistant:message"));
|
||||
const commandTraceEvent = traceBody.events.find((event) => event.label === "item/commandExecution:completed");
|
||||
assert.equal(commandTraceEvent.toolName, "commandExecution");
|
||||
assert.equal(commandTraceEvent.createdAt, "2026-06-01T00:00:00.500Z");
|
||||
assert.match(commandTraceEvent.command, /device-pod-cli\.ts profile list/u);
|
||||
assert.match(commandTraceEvent.stdoutSummary, /profile\.list/u);
|
||||
|
||||
|
||||
@@ -70,12 +70,18 @@ test("trace display rows render assistant item text when stream snapshot is abse
|
||||
test("trace display rows suppress low-value AgentRun backend noise", () => {
|
||||
const events = [
|
||||
event(1, "agentrun:request:accepted", { message: "accepted" }),
|
||||
event(2, "agentrun:backend:command-created"),
|
||||
event(3, "agentrun:backend:thread/status/changed"),
|
||||
event(4, "agentrun:backend:thread/tokenUsage/updated"),
|
||||
event(5, "agentrun:backend:account/rateLimits/updated"),
|
||||
event(6, "agentrun:backend:codex-app-server-starting"),
|
||||
commandEvent(7, "item/commandExecution:completed", {
|
||||
event(2, "agentrun:run:reused"),
|
||||
event(3, "agentrun:command:created"),
|
||||
event(4, "agentrun:runner-job:reused"),
|
||||
event(5, "agentrun:backend:command-created"),
|
||||
event(6, "agentrun:backend:thread/status/changed"),
|
||||
event(7, "agentrun:backend:thread/tokenUsage/updated"),
|
||||
event(8, "agentrun:backend:account/rateLimits/updated"),
|
||||
event(9, "agentrun:backend:codex-app-server-starting"),
|
||||
event(10, "agentrun:backend:thread/goal/cleared"),
|
||||
event(11, "agentrun:backend:item/agentMessage:started"),
|
||||
event(12, "agentrun:backend:item/agentMessage:completed"),
|
||||
commandEvent(13, "item/commandExecution:completed", {
|
||||
itemId: "call_1",
|
||||
command: "/bin/sh -lc 'bun tools/device-pod-cli.ts profile list --api-base-url http://74.48.78.17:19666'",
|
||||
status: "completed",
|
||||
@@ -83,24 +89,30 @@ test("trace display rows suppress low-value AgentRun backend noise", () => {
|
||||
durationMs: 708,
|
||||
stdoutSummary: '{"ok":true,"action":"profile.list","body":{"devicePods":[{"devicePodId":"D601-F103-V2"}]}}'
|
||||
}),
|
||||
event(8, "agentrun:output:stdout", {
|
||||
event(14, "agentrun:output:stdout", {
|
||||
type: "output",
|
||||
status: "running",
|
||||
message: '{"ok":true,"action":"profile.list"}'
|
||||
}),
|
||||
event(9, "agentrun:assistant:message", {
|
||||
event(15, "agentrun:assistant:message", {
|
||||
type: "assistant",
|
||||
status: "running",
|
||||
message: "当前可见 1 个 device-pod。"
|
||||
}),
|
||||
event(10, "agentrun:terminal:completed", { type: "result", terminal: true, status: "completed" })
|
||||
event(16, "agentrun:terminal:completed", { type: "result", terminal: true, status: "completed" })
|
||||
];
|
||||
|
||||
const rows = traceDisplayRows({ traceId: "trc_agentrun_noise", events }, events);
|
||||
const text = rows.map((row) => `${row.header}\n${row.body ?? ""}`).join("\n---\n");
|
||||
|
||||
assert.equal(traceNoiseEventCount(events), 4);
|
||||
assert.equal(traceNoiseEventCount(events), 12);
|
||||
assert.equal(/agentrun:request:accepted/u.test(text), false);
|
||||
assert.equal(/agentrun:run:reused/u.test(text), false);
|
||||
assert.equal(/runner-job:reused/u.test(text), false);
|
||||
assert.equal(/thread\/status\/changed/u.test(text), false);
|
||||
assert.equal(/thread\/goal\/cleared/u.test(text), false);
|
||||
assert.equal(/item\/agentMessage/u.test(text), false);
|
||||
assert.equal(/terminal completed/u.test(text), false);
|
||||
assert.equal(/tokenUsage/u.test(text), false);
|
||||
assert.match(text, /工具调用/u);
|
||||
assert.match(text, /device-pod-cli\.ts profile list/u);
|
||||
|
||||
@@ -595,7 +595,7 @@ function traceRequestSummaryRow(trace, event, promptEvent = event) {
|
||||
return {
|
||||
rowId: `trace-request:${event.seq ?? "accepted"}`,
|
||||
seq: event.seq ?? null,
|
||||
tone: "warn",
|
||||
tone: traceEventTone(event),
|
||||
header: `${clock} 请求接受${prompt ? `,提示词:"${compactTraceOneLine(prompt, 120)}"` : ""}`,
|
||||
body: null
|
||||
};
|
||||
@@ -923,7 +923,8 @@ function isTerminalAssistantTraceEvent(event) {
|
||||
|
||||
function isRequestTraceEvent(event) {
|
||||
const label = String(event?.label ?? "");
|
||||
return label === "request:accepted-short-connection" ||
|
||||
return label === "agentrun:request:accepted" ||
|
||||
label === "request:accepted-short-connection" ||
|
||||
label === "request:accepted" ||
|
||||
label === "request:received";
|
||||
}
|
||||
@@ -950,6 +951,7 @@ function traceNonEmptyString(value) {
|
||||
|
||||
function isNoisyTraceEvent(event) {
|
||||
const label = String(event?.label ?? "");
|
||||
if (isAgentRunLifecycleNoiseEvent(event)) return true;
|
||||
if (isToolOutputChunkTraceEvent(event)) return false;
|
||||
if (isCommandExecutionTraceEvent(event) || isAssistantMessageTraceEvent(event)) return false;
|
||||
if (isRequestTraceEvent(event) || isSetupTraceEvent(event) || isCompletionTraceEvent(event)) return false;
|
||||
@@ -960,8 +962,22 @@ function isNoisyTraceEvent(event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAgentRunLifecycleNoiseEvent(event) {
|
||||
const label = String(event?.label ?? "");
|
||||
if (!label.startsWith("agentrun:")) return false;
|
||||
const status = String(event?.status ?? "").toLowerCase();
|
||||
if (["failed", "blocked", "canceled", "cancelled", "error", "timeout", "degraded"].includes(status)) return false;
|
||||
if (event?.errorCode) return false;
|
||||
return label === "agentrun:request:accepted" ||
|
||||
label === "agentrun:run:reused" ||
|
||||
label === "agentrun:command:created" ||
|
||||
label === "agentrun:runner-job:reused" ||
|
||||
label === "agentrun:terminal:completed" ||
|
||||
/^agentrun:backend:(item\/agentMessage:(started|completed)|thread\/goal\/cleared)$/u.test(label);
|
||||
}
|
||||
|
||||
function isLowValueAgentRunBackendEvent(label) {
|
||||
return /^agentrun:backend:(run-created|command-created|runner-job-created|thread\/status\/changed|thread\/tokenUsage\/updated|account\/rateLimits\/updated|remoteControl\/status\/changed|configWarning|codex-app-server-closed|session-updated|command-terminal)$/u.test(String(label ?? ""));
|
||||
return /^agentrun:backend:(run-created|command-created|runner-job-created|thread\/status\/changed|thread\/tokenUsage\/updated|account\/rateLimits\/updated|remoteControl\/status\/changed|configWarning|codex-app-server-closed|session-updated|command-terminal|item\/agentMessage:(started|completed)|thread\/goal\/cleared)$/u.test(String(label ?? ""));
|
||||
}
|
||||
|
||||
function isToolOutputChunkTraceEvent(event) {
|
||||
|
||||
Reference in New Issue
Block a user