import { classifyRuntimeFailure } from "../failure-classification.js";
export function createToolFailurePersistence(input) {
    return async (toolCallId, toolInput, resumeContext, error, outputOverride) => {
        const { runtime, shellDebugBase, toolName, turn } = input;
        if (await runtime.failurePersistence.toolCallHasTerminalResult(turn, toolCallId)) {
            return undefined;
        }
        if (shellDebugBase) {
            runtime.tracing.logShellToolDebug(runtime.cwd, "shell.failure_persist.start", {
                ...shellDebugBase,
                callId: toolCallId,
                error: runtime.tracing.describeErrorForDebugLog(error),
            });
        }
        let failureRecoverability;
        let failureScope;
        let failureKind;
        let errorCode;
        let output = outputOverride;
        const turnTermination = runtime.interruptions.readTurnTerminatedResponse(error);
        if (turnTermination) {
            output = output ?? (await runtime.runCheckpoints.getLatestTurnFailureMessage(turn.id));
            switch (turnTermination.turn.status) {
                case "blocked":
                    failureKind = "denied";
                    failureRecoverability = "blocked";
                    failureScope = "tool";
                    break;
                case "interrupted":
                    failureKind = "interrupted";
                    failureRecoverability = "interrupted";
                    failureScope = "tool";
                    break;
                case "failed":
                    failureKind = "execution-failed";
                    failureRecoverability = "terminal";
                    failureScope = "tool";
                    break;
                default:
                    return undefined;
            }
        }
        else {
            const failure = classifyRuntimeFailure(error);
            failureRecoverability = failure.recoverability;
            failureScope = failure.scope;
            failureKind = failure.failureKind;
            errorCode = failure.errorCode;
            if (failureScope !== "tool" &&
                failureRecoverability !== "blocked" &&
                failureRecoverability !== "interrupted") {
                failureScope = "tool";
            }
            output =
                output ??
                    (error instanceof Error && error.message.trim().length > 0
                        ? error.message
                        : "Unknown tool failure");
        }
        const toolResultMetadata = input.getToolResultMetadata();
        const failureOutput = output ?? "Unknown tool failure";
        const resultToolName = resumeContext?.toolName ?? toolName;
        await runtime.failurePersistence.appendToolFailureResultIfMissing(turn, {
            ...(errorCode ? { errorCode } : {}),
            ...(toolResultMetadata?.envelope ? { envelopeOverride: toolResultMetadata.envelope } : {}),
            failureKind,
            ...(toolResultMetadata?.forceTracePersistence ? { forceTracePersistence: true } : {}),
            ...(toolResultMetadata?.outputManaged ? { outputManaged: true } : {}),
            output: failureOutput,
            ...(resumeContext ? { resumeContext } : {}),
            ...(toolResultMetadata?.structuredContent
                ? { structuredContent: toolResultMetadata.structuredContent }
                : {}),
            ...(toolResultMetadata?.traceOutput ? { traceOutput: toolResultMetadata.traceOutput } : {}),
            toolCallId,
            toolInput,
            toolName: resultToolName,
        });
        if (shellDebugBase) {
            runtime.tracing.logShellToolDebug(runtime.cwd, "shell.failure_persist.done", {
                ...shellDebugBase,
                callId: toolCallId,
                failureKind,
                failureRecoverability,
                failureScope,
            });
        }
        if (failureScope === "tool" &&
            failureRecoverability !== "blocked" &&
            failureRecoverability !== "interrupted") {
            return failureOutput;
        }
        return undefined;
    };
}
//# sourceMappingURL=tool-failure-persistence.js.map