fix(web-probe): flag sealed duration drift (#739)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -2638,6 +2638,8 @@ function buildFindings(samples, control, network, errors, sampleMetrics, promptN
|
||||
if (elapsedZeroResets.length > 0) findings.push({ id: "turn-timing-total-elapsed-zero-reset", severity: "red", summary: "Code Agent total elapsed jumped from a non-zero value back to 0 seconds", count: elapsedZeroResets.length, samples: elapsedZeroResets.slice(0, 20) });
|
||||
const elapsedForwardJumps = Array.isArray(sampleMetrics?.turnTimingTotalElapsedForwardJumps) ? sampleMetrics.turnTimingTotalElapsedForwardJumps : [];
|
||||
if (elapsedForwardJumps.length > 0) findings.push({ id: "turn-timing-total-elapsed-forward-jump", severity: "red", summary: "Code Agent total elapsed jumped forward faster than browser sample interval", count: elapsedForwardJumps.length, samples: elapsedForwardJumps.slice(0, 20) });
|
||||
const terminalElapsedGrowth = Array.isArray(sampleMetrics?.turnTimingTerminalElapsedGrowth) ? sampleMetrics.turnTimingTerminalElapsedGrowth : [];
|
||||
if (terminalElapsedGrowth.length > 0) findings.push({ id: "turn-timing-terminal-elapsed-growth", severity: "red", summary: "terminal Code Agent card total elapsed changed after terminal status; completed/failed/canceled timing must be sealed", count: terminalElapsedGrowth.length, samples: terminalElapsedGrowth.slice(0, 20) });
|
||||
const recentUpdateSawtoothJumps = Array.isArray(sampleMetrics?.turnTimingRecentUpdateSawtoothJumps)
|
||||
? sampleMetrics.turnTimingRecentUpdateSawtoothJumps
|
||||
: Array.isArray(sampleMetrics?.turnTimingNonMonotonic)
|
||||
@@ -3718,6 +3720,7 @@ function prioritizeFindings(findings) {
|
||||
if (id.startsWith("code-agent-card-")) return 0.8;
|
||||
if (id.startsWith("round-completion-")) return 0.9;
|
||||
if (id.startsWith("turn-timing-total-elapsed")) return 1;
|
||||
if (id.startsWith("turn-timing-terminal-elapsed")) return 1.1;
|
||||
if (id.startsWith("turn-timing-recent-update")) return 2;
|
||||
if (id.includes("runtime-execution") || id.includes("prompt-chat-submit-failed")) return 3;
|
||||
return 10;
|
||||
@@ -4844,17 +4847,37 @@ function maxSelfReportedDurationEvidence(text) {
|
||||
const value = String(text || '');
|
||||
const lines = value.split(/\n+/).map((line) => line.trim()).filter(Boolean);
|
||||
let best = null;
|
||||
for (const line of lines) {
|
||||
if (!/耗时|用时|duration|elapsed/i.test(line)) continue;
|
||||
const seconds = parseSelfReportedRoundDurationSeconds(line);
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const line = lines[index];
|
||||
const previous = index > 0 ? lines[index - 1] : '';
|
||||
const next = index + 1 < lines.length ? lines[index + 1] : '';
|
||||
const candidateText = selfReportedDurationCandidateText(previous, line, next);
|
||||
if (!candidateText) continue;
|
||||
const seconds = parseSelfReportedRoundDurationSeconds(candidateText);
|
||||
if (!Number.isFinite(seconds)) continue;
|
||||
if (!best || seconds > best.seconds) {
|
||||
best = { kind: 'final-response-duration', seconds, preview: compactOneLine(line).slice(0, 240) };
|
||||
best = { kind: 'final-response-duration', seconds, preview: compactOneLine(candidateText).slice(0, 240) };
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
function selfReportedDurationCandidateText(previous, line, next) {
|
||||
const current = String(line || '');
|
||||
const before = String(previous || '');
|
||||
const after = String(next || '');
|
||||
const windowText = [before, current, after].filter(Boolean).join(' ');
|
||||
const hasDurationKeyword = /耗时|用时|duration|elapsed/i.test(current);
|
||||
const hasNearbyDurationHeading = /(?:本轮|整轮|全程|任务|round|turn)?\s*(?:耗时|用时|duration|elapsed)/i.test(before)
|
||||
|| /(?:本轮|整轮|全程|任务|round|turn)?\s*(?:耗时|用时|duration|elapsed)/i.test(after);
|
||||
const hasDurationValue = /(?:约|大约|around|about)?\s*\d+(?:\.\d+)?\s*(?:小时|分钟|分|秒|hour|hours|hr|hrs|min|mins|minute|minutes|sec|secs|second|seconds)/i.test(windowText);
|
||||
const hasRoundContext = /本轮|整轮|全程|从.+到|全部通过|smoke|benchmark|round|turn|completed|passed/i.test(windowText);
|
||||
if (hasDurationKeyword && hasDurationValue) return current;
|
||||
if (hasNearbyDurationHeading && hasDurationValue) return windowText;
|
||||
if (hasRoundContext && hasDurationValue && /(?:约|大约|around|about)\s*\d|\d+(?:\.\d+)?\s*(?:分钟|小时|minute|hour)/i.test(current)) return windowText;
|
||||
return '';
|
||||
}
|
||||
|
||||
function parseSelfReportedRoundDurationSeconds(text) {
|
||||
const value = String(text || '');
|
||||
const clock = value.match(/(?:耗时|用时|duration|elapsed)[^0-9]{0,24}(\d{1,2}:\d{2}:\d{2}|\d{1,2}:\d{2})/i);
|
||||
|
||||
Reference in New Issue
Block a user