export function diagnoseSwebenchRun(finalJsonValue, fallbackText = '') {
    const root = asRecord(finalJsonValue);
    const runtimeFailure = asRecord(root?.['runtime_failure']);
    const diagnostic = asRecord(runtimeFailure?.['diagnostic']);
    const status = numberField(diagnostic, 'status') ?? numberField(runtimeFailure, 'status');
    const kind = stringField(runtimeFailure, 'kind') ?? stringField(diagnostic, 'kind');
    const message = stringField(runtimeFailure, 'message') ?? stringField(diagnostic, 'message');
    const detail = stringField(diagnostic, 'detail') ?? stringField(runtimeFailure, 'detail');
    const searchable = [kind, message, detail, fallbackText].filter(Boolean).join('\n');
    const providerFailure = Boolean(runtimeFailure);
    const quotaExhausted = providerFailure && status === 403 && /\b(usage limit|quota|billing cycle)\b/i.test(searchable);
    const stopReason = stringField(root, 'stop_reason');
    const taskNoProgress = stopReason === 'task_no_progress' || /\btask_no_progress\b/i.test(searchable);
    const portCollision = /\b(EADDRINUSE|address already in use|Port \d+ is already in use)\b/i.test(searchable);
    return {
        runtime_failure_kind: kind,
        runtime_failure_status: status,
        runtime_failure_message: message,
        runtime_failure_detail: detail,
        provider_failure: providerFailure || undefined,
        provider_quota_exhausted: quotaExhausted || undefined,
        task_no_progress: taskNoProgress || undefined,
        port_collision: portCollision || undefined,
    };
}
export function shouldWriteSwebenchPrediction(record) {
    if (record.patch_bytes > 0)
        return true;
    return false;
}
export function isPostPatchTimeoutPreservedPatch(record) {
    if (record.post_patch_timeout_preserved_patch)
        return true;
    return record.post_patch_timeout &&
        record.patch_bytes > 0 &&
        !record.parse_ok &&
        /\bstdout was empty\b/i.test(record.error ?? '');
}
export function summarizeSwebenchRecords(rows, expected, label) {
    const scoreEligibleRows = rows.filter(shouldWriteSwebenchPrediction);
    return {
        label,
        expected,
        completed: rows.length,
        scoreEligiblePredictions: scoreEligibleRows.length,
        parseFailures: rows.filter((r) => !r.parse_ok && !isPostPatchTimeoutPreservedPatch(r)).length,
        emptyPatches: rows.filter((r) => r.patch_bytes === 0).length,
        unscoredEmptyPatches: rows.filter((r) => r.patch_bytes === 0 && !shouldWriteSwebenchPrediction(r)).length,
        providerFailures: rows.filter((r) => r.provider_failure).length,
        providerQuotaFailures: rows.filter((r) => r.provider_quota_exhausted).length,
        taskNoProgressStops: rows.filter((r) => r.task_no_progress).length,
        taskNoProgressRecoveryAttempts: rows.filter((r) => r.task_no_progress_recovery_attempted).length,
        taskNoProgressRecovered: rows.filter((r) => r.task_no_progress_recovered).length,
        timeoutEmptyStdout: rows.filter((r) => r.timeout_empty_stdout).length,
        postPatchTimeoutPreservedPatches: rows.filter(isPostPatchTimeoutPreservedPatch).length,
        portCollisions: rows.filter((r) => r.port_collision).length,
        instancesWithApprovalDenials: rows.filter((r) => r.approval_denials.length > 0).length,
        interactivePromptDetections: rows.filter((r) => r.interactive_prompt_detected).length,
        timeouts: rows.filter((r) => r.timed_out).length,
        postPatchTimeouts: rows.filter((r) => r.post_patch_timeout).length,
        totalDurationMs: rows.reduce((sum, r) => sum + (r.duration_ms ?? 0), 0),
        avgDurationMs: rows.length > 0 ? Math.round(rows.reduce((sum, r) => sum + (r.duration_ms ?? 0), 0) / rows.length) : 0,
        totalPatchBytes: rows.reduce((sum, r) => sum + r.patch_bytes, 0),
    };
}
function asRecord(value) {
    return value !== null && typeof value === 'object' ? value : undefined;
}
function stringField(value, key) {
    const raw = value?.[key];
    return typeof raw === 'string' && raw.trim() ? raw : undefined;
}
function numberField(value, key) {
    const raw = value?.[key];
    if (typeof raw === 'number' && Number.isFinite(raw))
        return raw;
    if (typeof raw === 'string') {
        const parsed = Number.parseInt(raw, 10);
        if (Number.isFinite(parsed))
            return parsed;
    }
    return undefined;
}
//# sourceMappingURL=swebench-run-records.js.map