fix: 增加 result tool call 摘要

This commit is contained in:
Codex
2026-06-09 21:41:26 +08:00
parent e54b7fe0a4
commit 0dc5a3f966
3 changed files with 72 additions and 2 deletions
+61 -1
View File
@@ -1,6 +1,10 @@
import type { AgentRunStore } from "./store.js";
import type { CommandRecord, JsonRecord, JsonValue, RunEvent, RunRecord, RunnerJobRecord, TerminalStatus } from "../common/types.js";
import { outputBytesFromPayload, outputTruncatedFromPayload } from "../common/output.js";
import { boundedTextSummary, outputBytesFromPayload, outputTruncatedFromPayload } from "../common/output.js";
const maxToolCallSummaryItems = 40;
const toolCallCommandLimitChars = 600;
const toolCallFieldLimitChars = 200;
export async function buildRunResult(store: AgentRunStore, runId: string, commandId?: string): Promise<JsonRecord> {
const run = await store.getRun(runId);
@@ -37,6 +41,7 @@ export async function buildRunResult(store: AgentRunStore, runId: string, comman
lastSeq: events.at(-1)?.seq ?? 0,
eventCount: events.length,
artifactSummary: artifactSummary(scopedEvents),
toolCallSummary: toolCallSummary(scopedEvents),
sessionRef: sessionSummary(run),
resourceBundleRef: resourceBundleSummary(run, events),
runnerJobCount: jobs.length,
@@ -145,6 +150,61 @@ function artifactSummary(events: RunEvent[]): JsonRecord {
return { commandOutputEvents, diffEvents, toolCallEvents, outputChars, outputBytes, truncatedEvents: outputTruncatedEvents, outputTruncatedEvents, stdoutSummary: streamSummary.stdout, stderrSummary: streamSummary.stderr };
}
function toolCallSummary(events: RunEvent[]): JsonRecord {
const toolCallEvents = events.filter((event) => event.type === "tool_call");
const statusCounts: Record<string, number> = {};
const exitCodeCounts: Record<string, number> = {};
for (const event of toolCallEvents) {
const status = typeof event.payload.status === "string" && event.payload.status.length > 0 ? event.payload.status : "unknown";
statusCounts[status] = (statusCounts[status] ?? 0) + 1;
const exitCode = normalizedExitCode(event.payload.exitCode);
if (exitCode !== null) exitCodeCounts[String(exitCode)] = (exitCodeCounts[String(exitCode)] ?? 0) + 1;
}
const window = toolCallEvents.slice(-maxToolCallSummaryItems);
return {
count: toolCallEvents.length,
statusCounts,
exitCodeCounts,
items: window.map((event) => toolCallItemSummary(event)),
itemsOmitted: Math.max(0, toolCallEvents.length - window.length),
itemWindow: "latest",
valuesPrinted: false,
};
}
function toolCallItemSummary(event: RunEvent): JsonRecord {
const payload = event.payload;
return {
seq: event.seq,
createdAt: event.createdAt,
method: boundedOptionalString(payload.method, toolCallFieldLimitChars),
toolName: boundedOptionalString(payload.toolName, toolCallFieldLimitChars),
type: boundedOptionalString(payload.type, toolCallFieldLimitChars),
itemId: boundedOptionalString(payload.itemId, toolCallFieldLimitChars),
status: boundedOptionalString(payload.status, toolCallFieldLimitChars),
exitCode: normalizedExitCode(payload.exitCode),
processId: boundedOptionalString(payload.processId, toolCallFieldLimitChars),
cwd: boundedOptionalString(payload.cwd, toolCallFieldLimitChars),
command: boundedOptionalString(payload.command, toolCallCommandLimitChars),
commandTruncated: optionalStringTruncated(payload.command, toolCallCommandLimitChars),
valuesPrinted: false,
};
}
function boundedOptionalString(value: JsonValue | undefined, limitChars: number): string | null {
if (typeof value !== "string") return null;
return boundedTextSummary(value, { limitChars }).text as string;
}
function optionalStringTruncated(value: JsonValue | undefined, limitChars: number): boolean {
if (typeof value !== "string") return false;
return boundedTextSummary(value, { limitChars }).outputTruncated === true;
}
function normalizedExitCode(value: JsonValue | undefined): number | null {
return typeof value === "number" && Number.isFinite(value) ? value : null;
}
function attemptFromEvents(events: RunEvent[]): string | null {
for (const event of [...events].reverse()) {
const value = event.payload.attemptId;