const DEFAULT_MAX_TOTAL_PARTS = 20;
export async function runTeamLeaderExecution(options) {
    const maxTotalParts = options.maxTotalParts ?? DEFAULT_MAX_TOTAL_PARTS;
    const queue = [...options.initialParts];
    const plannedParts = [...options.initialParts];
    const partResults = [];
    const running = new Map();
    const scheduledIds = new Set(options.initialParts.map((part) => part.id));
    let nextPartIndex = 0;
    let leaderDone = false;
    let deferredDoneReason;
    const tryPlanMoreParts = async () => {
        if (leaderDone) {
            return;
        }
        if (deferredDoneReason && plannedParts.length === partResults.length && partResults.every(isSuccessfulPartResult)) {
            options.onPlanningDone?.({
                reason: deferredDoneReason,
                plannedParts: plannedParts.length,
                completedParts: partResults.length,
            });
            leaderDone = true;
            return;
        }
        const remainingPartBudget = maxTotalParts - plannedParts.length;
        if (remainingPartBudget <= 0) {
            leaderDone = true;
            return;
        }
        try {
            const feedback = await options.requestMoreParts({
                partResults,
                scheduledIds: [...scheduledIds],
                remainingPartBudget,
                unfinishedScheduledPartCount: plannedParts.length - partResults.length,
            });
            if (feedback.done) {
                if (plannedParts.length > partResults.length) {
                    deferredDoneReason = feedback.reasoning;
                    return;
                }
                options.onPlanningDone?.({
                    reason: feedback.reasoning,
                    plannedParts: plannedParts.length,
                    completedParts: partResults.length,
                });
                leaderDone = true;
                return;
            }
            const newParts = [];
            for (const newPart of feedback.parts) {
                if (scheduledIds.has(newPart.id)) {
                    continue;
                }
                scheduledIds.add(newPart.id);
                newParts.push(newPart);
            }
            if (newParts.length === 0) {
                if (plannedParts.length > partResults.length) {
                    return;
                }
                options.onPlanningNoNewParts?.({
                    reason: feedback.reasoning,
                    plannedParts: plannedParts.length,
                    completedParts: partResults.length,
                });
                leaderDone = true;
                return;
            }
            plannedParts.push(...newParts);
            queue.push(...newParts);
            deferredDoneReason = undefined;
            options.onPartsAdded?.({
                parts: newParts,
                reason: feedback.reasoning,
                totalPlanned: plannedParts.length,
            });
        }
        catch (error) {
            options.onPlanningError?.(error);
            leaderDone = true;
        }
    };
    while (queue.length > 0 || running.size > 0 || !leaderDone) {
        while (queue.length > 0 && running.size < options.maxConcurrency) {
            const part = queue.shift();
            if (!part) {
                break;
            }
            const partIndex = nextPartIndex;
            nextPartIndex += 1;
            options.onPartQueued?.(part, partIndex);
            const runningPart = options.runPart(part, partIndex).then((result) => ({ partId: part.id, result }));
            running.set(part.id, runningPart);
        }
        if (running.size > 0) {
            const completed = await Promise.race(running.values());
            running.delete(completed.partId);
            partResults.push(completed.result);
            options.onPartCompleted?.(completed.result);
            if (queue.length <= options.refillThreshold) {
                await tryPlanMoreParts();
            }
            continue;
        }
        if (leaderDone) {
            break;
        }
        await tryPlanMoreParts();
    }
    return { plannedParts, partResults };
}
function isSuccessfulPartResult(result) {
    return result.response.status === 'done';
}
//# sourceMappingURL=team-leader-execution.js.map