import { approveToolCall, approveToolCalls, createOperationAllowance, rejectToolCall, updateAgentSettings, } from "../../../services/agentService";
/**
 * Approval execution for the approval card. Pure module (no React) so the
 * batch/single routing and the partial-completion filtering are directly
 * unit-testable. Unlike the old in-component handlers, failures THROW so the
 * card can surface an inline retryable error instead of a console line or an
 * alert().
 */
export function dispatchToolApprovalResolved(detail) {
    window.dispatchEvent(new CustomEvent("agent:toolApprovalResolved", { detail }));
}
/**
 * Approve or reject a set of pending tool calls.
 *
 * Approving more than one call uses the batch endpoint and dispatches
 * "agent:toolApprovalResolved" only for the ids the server reports as
 * approved (falling back to all when the response omits the list) — this
 * partial-completion filter is what keeps "Approve All" from executing a call
 * twice. Rejection (and single approval) goes through the per-call endpoints.
 */
export async function resolvePendingToolCalls(params) {
    const { agentId, pending, approved } = params;
    if (!agentId || pending.length === 0)
        return;
    if (approved && pending.length > 1) {
        const result = await approveToolCalls({
            agentId,
            toolCalls: pending.map((item) => ({
                messageId: item.dbMessageId || item.messageId,
                toolCallId: item.toolCallId,
            })),
        });
        const approvedToolCallIds = result.approvedToolCallIds && result.approvedToolCallIds.length > 0
            ? new Set(result.approvedToolCallIds)
            : new Set(pending.map((item) => item.toolCallId));
        pending.forEach((item) => {
            if (!approvedToolCallIds.has(item.toolCallId)) {
                return;
            }
            dispatchToolApprovalResolved({
                agentId,
                messageId: item.dbMessageId || item.messageId,
                toolCallId: item.toolCallId,
                approved: true,
            });
        });
        return;
    }
    const actionLabel = approved ? "approve" : "reject";
    const failures = [];
    await Promise.all(pending.map(async (item) => {
        try {
            const callParams = {
                agentId,
                messageId: item.dbMessageId || item.messageId,
                toolCallId: item.toolCallId,
            };
            if (approved) {
                await approveToolCall(callParams);
            }
            else {
                await rejectToolCall(callParams);
            }
            dispatchToolApprovalResolved({
                agentId,
                messageId: item.dbMessageId || item.messageId,
                toolCallId: item.toolCallId,
                approved,
            });
        }
        catch (error) {
            console.error(`Failed to ${actionLabel} tool call ${item.toolCallId}:`, error);
            failures.push(error);
        }
    }));
    if (failures.length > 0) {
        const first = failures[0];
        const detail = first instanceof Error ? ` ${first.message}` : "";
        throw new Error(`Failed to ${actionLabel} ${failures.length} of ${pending.length} tool call${pending.length !== 1 ? "s" : ""}.${detail}`);
    }
}
/**
 * Switch the agent to autonomous mode, then approve the remaining pending
 * calls so the paused run continues (the mode change alone does not release a
 * run waiting for approval). `onSwitched` fires as soon as the settings
 * update succeeds so the UI mode state can update even if the follow-up
 * approval fails.
 */
export async function switchToAutonomousAndApprove(params) {
    const { agentId, pending, onSwitched } = params;
    if (!agentId)
        return;
    const result = await updateAgentSettings(agentId, { mode: "autonomous" });
    if (result.success === false || result.updates?.mode === false) {
        throw new Error("Mode change was not applied");
    }
    onSwitched?.();
    if (pending.length > 0) {
        await resolvePendingToolCalls({ agentId, pending, approved: true });
    }
}
/**
 * Create a subtree delete allowance for the pending call's parent item, then
 * approve the call itself.
 */
export async function approveWithDeleteAllowance(params) {
    const { agentId, pending, allowableScope } = params;
    if (!agentId || !allowableScope.parentItemId)
        return;
    await createOperationAllowance({
        agentId,
        itemId: allowableScope.parentItemId,
        operationType: "delete",
        scopeType: "itemSubtree",
    });
    await approveToolCall({
        agentId,
        messageId: pending.dbMessageId || pending.messageId,
        toolCallId: pending.toolCallId,
    });
    dispatchToolApprovalResolved({
        agentId,
        messageId: pending.dbMessageId || pending.messageId,
        toolCallId: pending.toolCallId,
        approved: true,
    });
}
//# sourceMappingURL=approvalActions.js.map