import { DELEGATE_TASKS_TOOL_NAME } from "../../provider/provider-tool-names.js";
import { persistToolOutput } from "./tool-result-persistence.js";
export async function executeDelegateTool(input) {
    const { activeSkillIds, approvalTurn, currentPhaseName, options, persistTerminalToolFailure, previewCallId, profile, runtime, toolInput, turn, } = input;
    const toolName = DELEGATE_TASKS_TOOL_NAME;
    const normalized = runtime.delegation.normalizeDelegateTasksInput(toolInput);
    const normalizedInput = runtime.delegation.serializeDelegateTasksInput(normalized);
    if (options.customLoopReplay) {
        const replayed = runtime.replay.takeCustomLoopToolReplayResult(options.customLoopReplay, toolName, normalizedInput);
        if (replayed !== undefined) {
            return replayed;
        }
    }
    if (input.delayReasoningPreludeForReplay) {
        await input.appendReasoningPrelude();
    }
    const displayInput = JSON.stringify(normalizedInput);
    const toolCallItem = runtime.toolCalls.createToolCallItem(turn, toolName, displayInput, previewCallId, normalizedInput, options.resumeContext?.providerToolName);
    if (!options.skipPrelude) {
        await runtime.items.pushItems([toolCallItem]);
    }
    const authorizationTurn = approvalTurn ?? turn;
    const toolAuthorization = await runtime.approvals.authorizeCapability(authorizationTurn, profile, { group: "tool", toolName }, toolCallItem.callId, options.resumeCheckpoint?.kind === "approval" ? options.resumeCheckpoint : undefined, options.resumeContext, turn);
    if (toolAuthorization !== "allow") {
        const termination = runtime.interruptions.createTurnTerminatedError(toolAuthorization);
        await persistTerminalToolFailure(toolCallItem.callId, normalizedInput, undefined, termination);
        throw termination;
    }
    const delegateResumeContext = {
        ...(options.resumeContext ?? {
            activeSkillIds,
            availableTools: [],
            approvalTurnId: approvalTurn?.id,
            cacheControl: undefined,
            messages: [],
            mode: "tool-plan",
            phaseName: currentPhaseName,
            profileName: profile.name,
            requiredToolConstraint: undefined,
            systemPrompt: undefined,
            toolCallId: toolCallItem.callId,
            toolInput: normalizedInput,
            toolName,
            toolStepCount: 0,
            ...(input.reasoning ? { reasoning: input.reasoning } : {}),
        }),
        toolCallId: toolCallItem.callId,
        toolInput: normalizedInput,
    };
    let blockedOutput;
    try {
        blockedOutput = await runtime.hooks.applyPreToolUseHooks({
            policyDecision: "allow",
            profileName: profile.name,
            threadId: turn.threadId,
            toolCallId: toolCallItem.callId,
            toolInput: normalizedInput,
            toolName,
        });
    }
    catch (error) {
        const failureOutput = await persistTerminalToolFailure(toolCallItem.callId, normalizedInput, delegateResumeContext, error);
        if (failureOutput !== undefined) {
            return failureOutput;
        }
        throw error;
    }
    if (blockedOutput) {
        await persistToolOutput({
            output: blockedOutput,
            resumeContext: delegateResumeContext,
            runtime,
            toolCallId: toolCallItem.callId,
            toolInput: normalized,
            toolName,
            turn,
        });
        return blockedOutput;
    }
    await runtime.checkpointPersistence.saveToolDispatchCheckpoint(turn.id, delegateResumeContext);
    const delegateStartedAt = Date.now();
    let output;
    try {
        output =
            normalized.tasks.length === 1
                ? await runtime.delegation.executeDelegateTaskInvocation(turn, profile, activeSkillIds, normalized.tasks[0])
                : await runtime.delegation.executeDelegateTaskBatchInvocation(turn, profile, activeSkillIds, normalized.tasks);
    }
    catch (error) {
        const failureOutput = await persistTerminalToolFailure(toolCallItem.callId, normalizedInput, delegateResumeContext, error);
        if (failureOutput !== undefined) {
            return failureOutput;
        }
        throw error;
    }
    let finalOutput;
    try {
        const postHookResult = await runtime.hooks.applyPostToolUseHooks({
            elapsedMs: Math.max(0, Date.now() - delegateStartedAt),
            profileName: profile.name,
            result: output,
            threadId: turn.threadId,
            toolCallId: toolCallItem.callId,
            toolInput: normalizedInput,
            toolName,
        });
        finalOutput = postHookResult.output;
    }
    catch (error) {
        const failureOutput = await persistTerminalToolFailure(toolCallItem.callId, normalizedInput, delegateResumeContext, error);
        if (failureOutput !== undefined) {
            return failureOutput;
        }
        throw error;
    }
    await persistToolOutput({
        output: finalOutput,
        resumeContext: delegateResumeContext,
        runtime,
        toolCallId: toolCallItem.callId,
        toolInput: normalized,
        toolName,
        turn,
    });
    return finalOutput;
}
//# sourceMappingURL=delegate-tool-execution.js.map