From f120d3e8126eee5a4d1271ca80702725fc25deac Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 11 Jun 2026 09:34:21 +0000 Subject: [PATCH] fix: surface AgentRun event payload summaries --- scripts/agentrun-cli-contract-test.ts | 11 +++ scripts/src/agentrun.ts | 124 ++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 15 deletions(-) diff --git a/scripts/agentrun-cli-contract-test.ts b/scripts/agentrun-cli-contract-test.ts index b087bc22..dd2569d9 100644 --- a/scripts/agentrun-cli-contract-test.ts +++ b/scripts/agentrun-cli-contract-test.ts @@ -123,6 +123,16 @@ assertCondition( "AgentRun logs must map --tail N into render-only client tailing for human and raw outputs", ); +assertCondition( + agentRunSource.includes("function agentRunEventSummary(item: Record, payload: Record): string") + && agentRunSource.includes("push(payload.failureKind)") + && agentRunSource.includes("push(error.message)") + && agentRunSource.includes("push(error.additionalDetails)") + && agentRunSource.includes("push(payload.phase)") + && agentRunSource.includes("function agentRunEventCommandId(item: Record, payload: Record): string"), + "AgentRun logs/events must render payload error, backend phase, and command id summaries by default", +); + assertCondition( agentRunSource.includes("function rerunWithoutDryRun(command: string): string") && agentRunSource.includes("options.dryRun ? [rerunWithoutDryRun(command)] : undefined"), @@ -146,6 +156,7 @@ console.log(JSON.stringify({ "AgentRun resource task dispatch and active task list visibility", "AgentRun resource failure output is visible in human mode", "AgentRun logs tail is enforced by the render-only client", + "AgentRun logs/events expose payload error and backend phase summaries", "AgentRun dry-run mutations keep resource-command follow-up", ], })); diff --git a/scripts/src/agentrun.ts b/scripts/src/agentrun.ts index f8595532..e6169e0b 100644 --- a/scripts/src/agentrun.ts +++ b/scripts/src/agentrun.ts @@ -873,24 +873,118 @@ function normalizeRunnerJobItems(data: unknown): Record[] { } function normalizeEventItems(data: unknown): Record[] { - return arrayRecords(record(data).items ?? data).map((item) => ({ - seq: item.seq, - type: item.type, - status: item.status ?? item.phase, - phase: item.phase, - commandId: item.commandId, - summary: item.summary ?? item.outputSummary ?? item.text ?? "", - })); + return arrayRecords(record(data).items ?? data).map((item) => { + const payload = record(item.payload); + return { + seq: item.seq, + type: item.type, + status: agentRunEventStatus(item, payload), + phase: item.phase ?? payload.phase, + commandId: agentRunEventCommandId(item, payload), + summary: agentRunEventSummary(item, payload), + }; + }); } function normalizeLogItems(data: unknown): Record[] { - return arrayRecords(record(data).items ?? data).map((item) => ({ - seq: item.seq, - type: item.type ?? item.role ?? "output", - status: item.status ?? item.phase ?? "", - commandId: item.commandId ?? "", - summary: item.summary ?? item.text ?? item.content ?? item.output ?? "", - })); + return arrayRecords(record(data).items ?? data).map((item) => { + const payload = record(item.payload); + return { + seq: item.seq, + type: item.type ?? item.role ?? "output", + status: agentRunEventStatus(item, payload), + commandId: agentRunEventCommandId(item, payload), + summary: agentRunEventSummary(item, payload), + }; + }); +} + +function agentRunEventCommandId(item: Record, payload: Record): string { + return stringOrNull(item.commandId) + ?? stringOrNull(payload.commandId) + ?? stringOrNull(record(payload.summary).commandId) + ?? "-"; +} + +function agentRunEventStatus(item: Record, payload: Record): string { + return stringOrNull(item.status) + ?? stringOrNull(item.phase) + ?? stringOrNull(payload.status) + ?? stringOrNull(payload.phase) + ?? stringOrNull(payload.failureKind) + ?? (item.type === "error" ? "error" : ""); +} + +function agentRunEventSummary(item: Record, payload: Record): string { + const type = stringOrNull(item.type); + const parts: string[] = []; + const push = (value: unknown): void => { + const text = eventText(value); + if (text !== null && !parts.includes(text)) parts.push(text); + }; + + if (type === "error") { + push(payload.failureKind); + const error = record(payload.error); + push(error.message); + push(error.additionalDetails); + if (payload.willRetry === true) push("willRetry=true"); + } + + if (type === "backend_status") { + push(payload.phase); + push(formatCountField("tools", record(payload.tools).count)); + push(formatCountField("bundles", record(payload.bundles).count)); + push(formatCountField("promptRefs", record(payload.promptRefs).count)); + push(payload.jobName); + push(payload.namespace); + } + + if (type === "tool_call") { + push(payload.summary); + push(payload.toolName); + push(payload.command); + const exitCode = payload.exitCode; + if (exitCode !== undefined && exitCode !== null) push(`exit=${String(exitCode)}`); + push(payload.outputSummary); + } + + if (type === "command_output") { + push(payload.summary); + push(payload.text); + } + + if (type === "assistant_message") { + push(payload.summary); + push(payload.text); + } + + push(item.summary); + push(item.outputSummary); + push(item.text); + push(payload.summary); + push(payload.outputSummary); + push(payload.text); + push(payload.message); + push(payload.reason); + + return parts.join("; "); +} + +function eventText(value: unknown): string | null { + const direct = stringOrNull(value); + if (direct !== null && direct.trim().length > 0) return direct.trim(); + const nested = record(value); + return stringOrNull(nested.text) + ?? stringOrNull(nested.message) + ?? stringOrNull(nested.reason) + ?? stringOrNull(nested.summary); +} + +function formatCountField(label: string, value: unknown): string | null { + if (typeof value === "number" && Number.isFinite(value)) return `${label}=${value}`; + if (typeof value === "string" && value.length > 0) return `${label}=${value}`; + return null; } function renderResourceTable(items: Record[], wide: boolean): string {