import { BestAgentError } from "@best-agent/foundation";
import { authorizePreparedToolExecution } from "./tool-capability-evaluation.js";
import { runPreToolUseHooks } from "./tool-hook-runner.js";
import { persistToolOutput } from "./tool-result-persistence.js";
export async function authorizeToolExecutionFlow(input) {
    const { options, persistTerminalToolFailure, prepared, preparedToolResumeContext, previewCallId, profile, runtime, shellDebugBase, toolName, toolResumeContext, turn, } = input;
    if (input.threadMode === "plan") {
        await runtime.capability.assertPlanModeToolAllowed(toolName, prepared, turn.threadId);
        if (!profile.allowedTools.includes(toolName)) {
            throw new BestAgentError("TOOL_NOT_ALLOWED", `Tool ${toolName} is not allowed by the ${profile.name} profile.`);
        }
    }
    const toolCallItem = runtime.toolCalls.createToolCallItem(turn, toolName, prepared.displayInput, options.skipPrelude ? toolResumeContext.toolCallId : previewCallId, prepared.normalizedInput, toolResumeContext.providerToolName);
    if (!options.skipPrelude) {
        await runtime.items.pushItems([toolCallItem]);
    }
    if (shellDebugBase) {
        runtime.tracing.logShellToolDebug(runtime.cwd, "shell.tool_call.ready", {
            ...shellDebugBase,
            callId: toolCallItem.callId,
            skipPrelude: options.skipPrelude,
        });
    }
    const webSearchBudget = runtime.webSearchBudget.reserveWebSearchBudget(turn, toolName);
    const toolDefinition = runtime.preparedTools.tools.getDefinition(toolName);
    const capabilityEvaluation = await authorizePreparedToolExecution({
        authorizationTurn: input.authorizationTurn,
        options,
        persistTerminalToolFailure,
        prepared,
        preparedToolResumeContext,
        profile,
        runtime,
        shellDebugBase,
        toolCallId: toolCallItem.callId,
        toolDefinition,
        toolName,
        turn,
    });
    if (capabilityEvaluation.failureOutput !== undefined) {
        return { kind: "terminal-failure", output: capabilityEvaluation.failureOutput };
    }
    const preHook = await runPreToolUseHooks({
        persistTerminalToolFailure,
        prepared,
        preparedToolResumeContext,
        profile,
        runtime,
        shellDebugBase,
        toolCallId: toolCallItem.callId,
        toolName,
        turn,
    });
    if (preHook.failureOutput !== undefined) {
        return { kind: "terminal-failure", output: preHook.failureOutput };
    }
    if (preHook.blockedOutput) {
        await persistToolOutput({
            output: preHook.blockedOutput,
            resumeContext: {
                ...preparedToolResumeContext,
                toolCallId: toolCallItem.callId,
            },
            runtime,
            toolCallId: toolCallItem.callId,
            toolInput: prepared.normalizedInput,
            toolName,
            turn,
        });
        return { kind: "blocked", output: preHook.blockedOutput };
    }
    return {
        kind: "authorized",
        executionSandboxProfile: capabilityEvaluation.executionSandboxProfile,
        toolCallId: toolCallItem.callId,
        toolDefinition,
        webSearchBudget,
    };
}
//# sourceMappingURL=tool-execution-authorization-flow.js.map