import { collectPromptDeliverableFailures, hasCompletionGuardTool, } from "../artifact-obligations.js";
import { classifyRuntimeFailure } from "../failure-classification.js";
import { promptDeliverableMissingObservation } from "./deliverable-observation.js";
import { buildTerminalOutputInvalidRepair } from "./provider-terminal-output-handler.js";
import { buildToolFollowUpMessages, toProviderHistoryCompletedToolCall, } from "./provider-tool-loop.js";
import { semanticToolInputDigest } from "./provider-tool-repeat-guard.js";
import { buildReplayProviderTurnBudget } from "./provider-replay-budget.js";
import { isRoutingDowngradeEligible, } from "./provider-replay-context.js";
import { repairReplayToolOutputWithObservation, } from "./provider-replay-tool-output-repair-runner.js";
import { resolveProviderTurnActionPolicy, resolveProviderVisibleTools, resolveUnresolvedToolConstraint, } from "./tool-constraint.js";
export async function repairReplayedToolOutputProviderResponse(input) {
    const { payload, runtime, turn } = input;
    let { responseText } = input;
    if (payload.allowPlanUpdate || payload.allowPhaseResult) {
        return responseText;
    }
    const currentToolResult = payload.toolResultItem ??
        (await runtime
            .listItems(turn.threadId)
            .then((items) => [...items]
            .reverse()
            .find((item) => item.turnId === turn.id &&
            item.kind === "tool-result" &&
            item.callId === payload.toolCallId)));
    if (payload.mode === "tool-plan" &&
        payload.messages.length === 0 &&
        payload.availableTools.length === 0) {
        return `Tool ${payload.toolName} result: ${currentToolResult?.output ?? payload.toolOutput ?? responseText}`;
    }
    const stableInputDigest = payload.toolInputStableDigest ??
        payload.toolEnvelope?.inputStableDigest ??
        semanticToolInputDigest(payload.toolInput);
    const completedToolCalls = [
        ...(payload.completedToolCalls?.map((call) => toProviderHistoryCompletedToolCall(call)) ?? []),
        {
            errorCode: currentToolResult?.errorCode,
            failureKind: currentToolResult?.failureKind,
            outcome: currentToolResult?.outcome ?? "success",
            inputStableDigest: stableInputDigest,
            replayPolicy: runtime.resolveReplayPolicyForFollowUp(payload.toolName),
            ...(payload.providerToolName ? { providerToolName: payload.providerToolName } : {}),
            toolCallId: payload.toolCallId,
            toolInput: runtime.renderToolInputForProviderHistory(payload.toolName, payload.toolInput),
            toolName: payload.toolName,
            toolOutput: currentToolResult?.output ?? payload.toolOutput ?? "",
        },
    ];
    const unresolvedRequiredToolConstraint = resolveUnresolvedToolConstraint(payload.requiredToolConstraint, completedToolCalls);
    const repairMessages = buildToolFollowUpMessages(payload.messages, completedToolCalls, payload.availableTools, runtime.renderToolInputForProviderHistory);
    const repairEscalationLevel = payload.advancedPhase
        ? await runtime.advancedPhaseReopenCount(turn.id)
        : 0;
    const fixedReplayRoute = Boolean(payload.routeConfigOverride);
    const replayProfile = runtime.requireProfile(payload.profileName);
    const replayProviderTurnBudget = buildReplayProviderTurnBudget({
        defaultMaxProviderTurns: runtime.defaultMaxProviderTurns,
        enabled: payload.providerTurnBudgeted ?? false,
        maxProviderTurnsForProfile: (profile) => runtime.maxProviderTurnsForProfile(profile),
        profile: replayProfile,
        providerTurnCount: payload.providerTurnCount,
    });
    const repairRoute = runtime.resolveProviderRoute({
        downgradeEligible: isRoutingDowngradeEligible(payload.phaseName),
        escalationLevel: repairEscalationLevel,
        fixedRouteConfigOverride: fixedReplayRoute,
        operation: "repair",
        phaseName: payload.phaseName,
        profileName: payload.profileName,
        routeConfigOverride: payload.routeConfigOverride,
        threadId: turn.threadId,
        toolStepCount: payload.toolStepCount + completedToolCalls.length,
        turnId: turn.id,
    });
    try {
        responseText = runtime.assertValidTerminalAssistantText(responseText);
    }
    catch (error) {
        const failure = classifyRuntimeFailure(error);
        if (failure.errorCode !== "TERMINAL_OUTPUT_INVALID") {
            throw error;
        }
        const deliverableFailures = hasCompletionGuardTool(payload.availableTools) &&
            (payload.artifactObligations?.length ?? 0) > 0
            ? await runtime.collectArtifactObligationFailuresForTurn(turn, payload.artifactObligations ?? [])
            : [];
        const repairRequiredToolConstraint = deliverableFailures.length > 0 ? undefined : unresolvedRequiredToolConstraint;
        const visibleTools = resolveProviderVisibleTools(payload.availableTools, repairRequiredToolConstraint, repairMessages);
        const terminalRepair = buildTerminalOutputInvalidRepair({
            baseActionPolicy: resolveProviderTurnActionPolicy({
                allowPhaseResult: false,
                allowPlanUpdate: false,
                requestKind: "decide",
                requiredToolConstraint: repairRequiredToolConstraint,
                visibleTools,
            }),
            deliverableFailures,
            observationToolNames: visibleTools.map((tool) => tool.name),
            text: responseText,
            visibleTools,
        });
        return repairReplayToolOutputWithObservation({
            completedToolCalls,
            fixedReplayRoute,
            payload,
            repairActionPolicyOverride: terminalRepair.actionPolicy,
            repairCode: "TERMINAL_OUTPUT_INVALID",
            repairMessages,
            repairObservation: terminalRepair.observation,
            repairRouteConfig: repairRoute.config,
            responseRepairDeliverableFailures: deliverableFailures,
            replayProfile,
            replayProviderTurnBudget,
            requiresDeliverableAssertion: terminalRepair.requiresDeliverableAssertion,
            suppressStructuredControls: terminalRepair.suppressStructuredControls,
            runtime,
            turn,
            unresolvedRequiredToolConstraint,
        });
    }
    if (!hasCompletionGuardTool(payload.availableTools)) {
        return responseText;
    }
    const deliverableFailures = (payload.artifactObligations?.length ?? 0) > 0
        ? await runtime.collectArtifactObligationFailuresForTurn(turn, payload.artifactObligations ?? [])
        : collectPromptDeliverableFailures(repairMessages, runtime.cwd);
    if (deliverableFailures.length === 0) {
        return responseText;
    }
    return repairReplayToolOutputWithObservation({
        completedToolCalls,
        fixedReplayRoute,
        payload,
        repairCode: "PROMPT_DELIVERABLE_MISSING",
        repairMessages,
        repairObservation: promptDeliverableMissingObservation(deliverableFailures),
        repairRouteConfig: repairRoute.config,
        replayProfile,
        replayProviderTurnBudget,
        requiresDeliverableAssertion: true,
        suppressStructuredControls: true,
        runtime,
        turn,
        unresolvedRequiredToolConstraint,
    });
}
//# sourceMappingURL=provider-replay-tool-output-repair.js.map