fix: make sentinel quick verify wait for turns (#920)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-26 01:48:51 +08:00
committed by GitHub
parent edfddd2445
commit 8080c810b9
3 changed files with 261 additions and 35 deletions
+2
View File
@@ -154,6 +154,8 @@ export interface NodeWebProbeObserveOptions {
analyzeArchivePrefix: string | null;
analyzeTailSamples: number | null;
full: boolean;
raw: boolean;
compactRaw: boolean;
stateDir: string | null;
jobId: string | null;
force: boolean;
+61 -6
View File
@@ -185,6 +185,7 @@ export function parseNodeWebProbeObserveOptions(
"--sample-seq",
"--timestamp",
"--turn",
"--compact-raw",
"--archive-prefix",
"--tail-samples",
"--state-dir",
@@ -208,7 +209,7 @@ export function parseNodeWebProbeObserveOptions(
"--workspace-root",
"--workspace-root-ref",
"--root",
]), new Set(["--force", "--full", "--text-stdin"]));
]), new Set(["--force", "--full", "--raw", "--text-stdin"]));
const commandTypeRaw = optionValue(args, "--type") ?? null;
const commandType = commandTypeRaw === null ? null : parseNodeWebProbeObserveCommandType(commandTypeRaw);
const stateDir = optionValue(args, "--state-dir") ?? indexed?.stateDir ?? null;
@@ -306,6 +307,8 @@ export function parseNodeWebProbeObserveOptions(
analyzeArchivePrefix,
analyzeTailSamples,
full: args.includes("--full"),
raw: args.includes("--raw"),
compactRaw: args.includes("--compact-raw"),
stateDir,
jobId,
force: args.includes("--force"),
@@ -1160,7 +1163,8 @@ export function runNodeWebProbeObserveCollect(options: NodeWebProbeObserveOption
].join("\n");
const result = runTransWorkspaceStdinScript(options.node, spec.workspace, script, options.commandTimeoutSeconds);
const collect = parseJsonObject(result.stdout);
return withWebObserveCollectRendered({
const compactRaw = options.raw && options.compactRaw;
const payload = {
ok: result.exitCode === 0 && collect !== null && collect.ok !== false,
status: result.exitCode === 0 && collect !== null ? "collected" : "blocked",
command: webObserveCommandLabel("collect", options),
@@ -1172,11 +1176,62 @@ export function runNodeWebProbeObserveCollect(options: NodeWebProbeObserveOption
requestedFile: options.collectFile,
requestedGrep: options.collectGrep,
degradedReason: collect === null ? "collect-json-parse-failed" : null,
collect,
wrapper: buildWebObserveWrapperForObserveOptions("collect", options, spec.workspace),
result: collect === null ? compactCommandResultWithStdoutTail(result) : compactCommandResult(result),
collect: compactRaw ? compactObserveCollectForRaw(collect) : collect,
wrapper: compactRaw
? { mode: "wrapper-only", action: "collect", node: options.node, lane: options.lane, id: webObserveIdFromOptions(options), stateDir: options.stateDir, valuesRedacted: true }
: buildWebObserveWrapperForObserveOptions("collect", options, spec.workspace),
result: compactRaw ? { exitCode: result.exitCode, timedOut: result.timedOut, stdoutBytes: Buffer.byteLength(result.stdout), stderrBytes: Buffer.byteLength(result.stderr) } : collect === null ? compactCommandResultWithStdoutTail(result) : compactCommandResult(result),
valuesRedacted: true,
});
};
return options.raw ? payload : withWebObserveCollectRendered(payload);
}
function compactObserveCollectForRaw(collect: Record<string, unknown> | null): Record<string, unknown> | null {
if (collect === null) return null;
const rows = Array.isArray(collect.rows) ? collect.rows.map((item) => {
const row = observeRecord(item);
const finalResponse = observeRecord(row.finalResponse);
return {
round: row.round ?? null,
commandId: row.commandId ?? null,
userHash: row.userHash ?? null,
userBytes: row.userBytes ?? null,
traceId: row.traceId ?? null,
status: row.status ?? null,
elapsedSeconds: row.elapsedSeconds ?? null,
recentUpdateSeconds: row.recentUpdateSeconds ?? null,
marks: row.marks ?? null,
firstSeq: row.firstSeq ?? null,
lastSeq: row.lastSeq ?? null,
lastTs: row.lastTs ?? null,
finalResponse: {
preview: finalResponse.preview ?? null,
textHash: finalResponse.textHash ?? null,
textBytes: finalResponse.textBytes ?? null,
empty: finalResponse.empty === true,
},
valuesRedacted: true,
};
}) : undefined;
return {
ok: collect.ok !== false,
command: collect.command,
view: collect.view,
stateDir: collect.stateDir,
turnCount: collect.turnCount,
...(rows === undefined ? {} : { rows }),
renderedText: typeof collect.renderedText === "string" ? collect.renderedText : undefined,
sourceFiles: Array.isArray(collect.sourceFiles) ? collect.sourceFiles : undefined,
blocker: collect.blocker,
sampleSeq: collect.sampleSeq,
traceId: collect.traceId,
finalResponse: collect.finalResponse,
valuesRedacted: true,
};
}
function observeRecord(value: unknown): Record<string, unknown> {
return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}
export function runNodeWebProbeObserveAnalyze(options: NodeWebProbeObserveOptions, spec: HwlabRuntimeLaneSpec): Record<string, unknown> | RenderedCliResult {