import { mergeModelRequestOptions } from "../llm/model-options.js";
import { parseRequestedModelId } from "../model-spec.js";
import { BUILTIN_MODELS } from "./model-catalog.js";
function resolveConfiguredCliModel(provider, config) {
    const cli = config?.cli;
    const raw = (() => {
        if (provider === "claude")
            return cli?.claude?.model;
        if (provider === "codex")
            return cli?.codex?.model;
        if (provider === "gemini")
            return cli?.gemini?.model;
        if (provider === "agent")
            return cli?.agent?.model;
        if (provider === "openclaw")
            return cli?.openclaw?.model;
        if (provider === "opencode")
            return cli?.opencode?.model;
        if (provider === "agy")
            return null;
        if (provider === "pi")
            return cli?.pi?.model;
        return cli?.copilot?.model;
    })();
    return typeof raw === "string" && raw.trim().length > 0 ? raw.trim() : null;
}
function resolveRequestedCliModelFromConfig(requestedModel, config) {
    if (requestedModel.kind !== "fixed" || requestedModel.transport !== "cli")
        return requestedModel;
    if (requestedModel.cliModel)
        return requestedModel;
    const configuredModel = resolveConfiguredCliModel(requestedModel.cliProvider, config);
    if (!configuredModel)
        return requestedModel;
    return {
        ...requestedModel,
        userModelId: `cli/${requestedModel.cliProvider}/${configuredModel}`,
        cliModel: configuredModel,
    };
}
function applyModelConfigOptions(requestedModel, modelConfig) {
    if (requestedModel.kind !== "fixed" || requestedModel.transport === "cli")
        return requestedModel;
    if (!modelConfig || !("id" in modelConfig))
        return requestedModel;
    const requestOptions = mergeModelRequestOptions(requestedModel.requestOptions, {
        ...(modelConfig.serviceTier ? { serviceTier: modelConfig.serviceTier } : {}),
        ...((modelConfig.reasoningEffort ?? modelConfig.thinking)
            ? { reasoningEffort: modelConfig.reasoningEffort ?? modelConfig.thinking }
            : {}),
        ...(modelConfig.textVerbosity ? { textVerbosity: modelConfig.textVerbosity } : {}),
    });
    return requestOptions ? { ...requestedModel, requestOptions } : requestedModel;
}
export function resolveModelSelection({ config, configForCli, configPath, envForRun, explicitModelArg, }) {
    const modelMap = (() => {
        const out = new Map();
        for (const [name, model] of Object.entries(BUILTIN_MODELS)) {
            out.set(name.toLowerCase(), { name, model });
        }
        const raw = config?.models;
        if (!raw)
            return out;
        for (const [name, model] of Object.entries(raw)) {
            out.set(name.toLowerCase(), { name, model });
        }
        return out;
    })();
    const defaultModelResolution = (() => {
        if (typeof envForRun.SUMMARIZE_MODEL === "string" &&
            envForRun.SUMMARIZE_MODEL.trim().length > 0) {
            return { value: envForRun.SUMMARIZE_MODEL.trim(), source: "env" };
        }
        const modelFromConfig = config?.model;
        if (modelFromConfig) {
            if ("id" in modelFromConfig && typeof modelFromConfig.id === "string") {
                const id = modelFromConfig.id.trim();
                if (id.length > 0)
                    return { value: id, source: "config" };
            }
            if ("name" in modelFromConfig && typeof modelFromConfig.name === "string") {
                const name = modelFromConfig.name.trim();
                if (name.length > 0)
                    return { value: name, source: "config" };
            }
            if ("mode" in modelFromConfig && modelFromConfig.mode === "auto") {
                return { value: "auto", source: "config" };
            }
        }
        return { value: "auto", source: "default" };
    })();
    const explicitModelInput = explicitModelArg?.trim() ?? "";
    const requestedModelInput = (explicitModelInput || defaultModelResolution.value).trim();
    const requestedModelSource = explicitModelInput.length > 0 ? "explicit" : defaultModelResolution.source;
    const requestedModelInputLower = requestedModelInput.toLowerCase();
    const wantsFreeNamedModel = requestedModelInputLower === "free";
    const namedModelMatch = requestedModelInputLower !== "auto" ? (modelMap.get(requestedModelInputLower) ?? null) : null;
    const namedModelConfig = namedModelMatch?.model ?? null;
    const isNamedModelSelection = Boolean(namedModelMatch);
    const selectedModelConfig = isNamedModelSelection && namedModelConfig
        ? namedModelConfig
        : requestedModelSource === "config"
            ? (config?.model ?? null)
            : null;
    const configForModelSelection = isNamedModelSelection && namedModelConfig
        ? { ...(configForCli ?? {}), model: namedModelConfig }
        : configForCli;
    const requestedModel = (() => {
        if (isNamedModelSelection && namedModelConfig) {
            if ("id" in namedModelConfig) {
                return applyModelConfigOptions(parseRequestedModelId(namedModelConfig.id), namedModelConfig);
            }
            if ("mode" in namedModelConfig && namedModelConfig.mode === "auto")
                return { kind: "auto" };
            throw new Error(`Invalid model "${namedModelMatch?.name ?? requestedModelInput}": unsupported model config`);
        }
        if (requestedModelInputLower !== "auto" && !requestedModelInput.includes("/")) {
            throw new Error(`Unknown model "${requestedModelInput}". Define it in ${configPath ?? "~/.summarize/config.json"} under "models", or use a provider-prefixed id like openai/...`);
        }
        return applyModelConfigOptions(parseRequestedModelId(requestedModelInput), selectedModelConfig);
    })();
    const requestedModelResolved = resolveRequestedCliModelFromConfig(requestedModel, configForModelSelection);
    const requestedModelLabel = isNamedModelSelection
        ? requestedModelInput
        : requestedModelResolved.kind === "auto"
            ? "auto"
            : requestedModelResolved.userModelId;
    const isFallbackModel = requestedModelResolved.kind === "auto";
    const isImplicitAutoSelection = requestedModelResolved.kind === "auto" && requestedModelSource === "default";
    return {
        requestedModel: requestedModelResolved,
        requestedModelInput,
        requestedModelLabel,
        isNamedModelSelection,
        isImplicitAutoSelection,
        wantsFreeNamedModel,
        configForModelSelection,
        isFallbackModel,
    };
}
//# sourceMappingURL=model-selection.js.map