/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */
import { tracePollingManager } from '../../services/traces/tracePoller.js';
import { asyncRunStorage } from '../../services/storage/index.js';
import { callBedrockJudge } from '../../services/evaluation/index.js';
import { buildJudgeMatcherEntry, formatExpectedOutcomesAsClaim, } from '../../lib/matchers/judgeAccessor.js';
import { buildEvaluatorErrorPatch } from '../../services/evaluation/evaluatorError.js';
import { DEFAULT_CONFIG } from '../../lib/constants.js';
/**
 * Ensure trace polling is running for a pending report. The provided
 * callbacks let the caller refresh local UI state when the judge finishes
 * (or fails). All callbacks are optional \u2014 omit them for fire-and-forget
 * background recovery.
 */
export function ensureTracePollingForReport(report, testCase, options) {
    // Only valid for trace-mode pending reports with a runId and a test case.
    if (report.metricsStatus !== 'pending' || !report.runId || !testCase)
        return;
    const existingState = tracePollingManager.getState(report.id);
    if (existingState?.running)
        return;
    tracePollingManager.startPolling(report.id, report.runId, {
        onTracesFound: async (_spans, updatedReport) => {
            try {
                const judgeModelId = report.modelId
                    ? (DEFAULT_CONFIG.models[report.modelId]?.model_id || report.modelId)
                    : undefined;
                const judgment = await callBedrockJudge(updatedReport.trajectory, {
                    expectedOutcomes: testCase.expectedOutcomes,
                    expectedTrajectory: testCase.expectedTrajectory,
                }, [], // No logs in trace mode \u2014 traces are the source of truth
                () => { }, judgeModelId);
                await asyncRunStorage.updateReport(report.id, {
                    metricsStatus: 'ready',
                    passFailStatus: judgment.passFailStatus,
                    metrics: judgment.metrics,
                    llmJudgeReasoning: judgment.llmJudgeReasoning,
                    // Unified judge surface (issue #230 follow-up).
                    matcherResults: [
                        buildJudgeMatcherEntry(judgment, {
                            claim: formatExpectedOutcomesAsClaim(testCase.expectedOutcomes),
                            model: judgeModelId,
                        }),
                    ],
                    improvementStrategies: judgment.improvementStrategies,
                });
                if (options?.onUpdated) {
                    const fresh = await asyncRunStorage.getReportById(report.id);
                    if (fresh)
                        options.onUpdated(fresh);
                }
            }
            catch (err) {
                await asyncRunStorage.updateReport(report.id, buildEvaluatorErrorPatch('judge_failed', err)).catch(() => { });
                if (options?.onError)
                    options.onError(err instanceof Error ? err : new Error(String(err)));
                if (options?.onUpdated) {
                    const fresh = await asyncRunStorage.getReportById(report.id);
                    if (fresh)
                        options.onUpdated(fresh);
                }
            }
        },
        onAttempt: () => { },
        onError: (error) => {
            if (options?.onError)
                options.onError(error);
        },
    });
}
//# sourceMappingURL=browserRecovery.js.map