import { isDelegatedWorkflowStep } from '../step-kind.js';
import { evaluatePromotion } from './PromotionEvaluator.js';
import { mergeProviderOptions, PROVIDER_OPTION_PATHS } from '../../../infra/config/providerOptions.js';
function isPromotionStep(step) {
    return step.kind !== 'system' && step.kind !== 'workflow_call';
}
function getProviderOptionValue(options, path) {
    if (!options)
        return undefined;
    return path.split('.').reduce((current, part) => {
        if (current === undefined || current === null || typeof current !== 'object') {
            return undefined;
        }
        return current[part];
    }, options);
}
function setProviderOptionValue(options, path, value) {
    const parts = path.split('.');
    let current = options;
    for (const part of parts.slice(0, -1)) {
        const next = current[part];
        if (next === undefined || next === null || typeof next !== 'object' || Array.isArray(next)) {
            current[part] = {};
        }
        current = current[part];
    }
    current[parts[parts.length - 1]] = value;
}
function filterPromotionProviderOptions(baseSources, promotionOptions) {
    if (!promotionOptions) {
        return undefined;
    }
    const result = {};
    for (const path of PROVIDER_OPTION_PATHS) {
        const value = getProviderOptionValue(promotionOptions, path);
        if (value === undefined) {
            continue;
        }
        const baseSource = baseSources?.[path];
        if (baseSource === 'env' || baseSource === 'cli') {
            continue;
        }
        setProviderOptionValue(result, path, value);
    }
    return Object.keys(result).length > 0
        ? result
        : undefined;
}
function resolvePromotedModel(baseProviderInfo, promotion) {
    if (promotion.model !== undefined) {
        return { model: promotion.model, modelSource: 'promotion' };
    }
    if (promotion.providerSpecified) {
        return { model: undefined, modelSource: undefined };
    }
    return {
        model: baseProviderInfo.model,
        modelSource: baseProviderInfo.modelSource,
    };
}
function resolvePromotionProviderOptionsSources(baseSources, promotionOptions) {
    if (!promotionOptions) {
        return baseSources;
    }
    const sources = {
        ...baseSources,
    };
    for (const path of PROVIDER_OPTION_PATHS) {
        if (getProviderOptionValue(promotionOptions, path) !== undefined) {
            sources[path] = 'promotion';
        }
    }
    return Object.keys(sources).length > 0 ? sources : undefined;
}
export async function resolvePromotionRuntime(context, step, stepIteration, runtime) {
    if (!isPromotionStep(step) || !step.promotion || step.promotion.length === 0) {
        return runtime;
    }
    if (isDelegatedWorkflowStep(step)) {
        throw new Error(`Step "${step.name}" promotion is only supported for normal agent steps`);
    }
    if (stepIteration === undefined) {
        throw new Error(`Step "${step.name}" promotion requires a normal agent step execution`);
    }
    const baseProviderInfo = context.resolveStepProviderModel(step, runtime);
    const promotion = await evaluatePromotion(step, {
        cwd: context.cwd,
        stepIteration,
        previousResponseContent: context.previousResponseContent,
        structuredCaller: context.structuredCaller,
        resolvedProvider: baseProviderInfo.provider,
        resolvedModel: baseProviderInfo.model,
    });
    if (!promotion) {
        return runtime;
    }
    const promotionProviderOptions = filterPromotionProviderOptions(baseProviderInfo.providerOptionsSources, promotion.providerOptions);
    const promotedModel = resolvePromotedModel(baseProviderInfo, promotion);
    return {
        ...runtime,
        providerInfo: {
            ...baseProviderInfo,
            provider: promotion.provider ?? baseProviderInfo.provider,
            providerSource: promotion.provider !== undefined ? 'promotion' : baseProviderInfo.providerSource,
            model: promotedModel.model,
            modelSource: promotedModel.modelSource,
            providerOptions: mergeProviderOptions(baseProviderInfo.providerOptions, promotionProviderOptions),
            providerOptionsSources: resolvePromotionProviderOptionsSources(baseProviderInfo.providerOptionsSources, promotionProviderOptions),
        },
    };
}
//# sourceMappingURL=promotion-runtime.js.map