"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getManagedModelPrefix = exports.buildCliproxyRoutingHints = exports.MANAGED_MODEL_PREFIXES = void 0;
exports.MANAGED_MODEL_PREFIXES = {
    gemini: 'gcli',
    agy: 'agy',
};
const PROVIDER_OWNER_HINTS = {
    gemini: ['google'],
    agy: ['antigravity'],
    claude: ['anthropic'],
    codex: ['openai'],
    qwen: ['alibaba', 'qwen'],
    iflow: ['iflow'],
    kimi: ['kimi', 'moonshot'],
    kiro: ['kiro', 'aws'],
    ghcp: ['github', 'copilot'],
};
function normalize(value) {
    return typeof value === 'string' ? value.trim().toLowerCase() : '';
}
function getManagedPrefix(provider) {
    const normalizedProvider = normalize(provider);
    if (normalizedProvider in exports.MANAGED_MODEL_PREFIXES) {
        return exports.MANAGED_MODEL_PREFIXES[normalizedProvider];
    }
    return null;
}
function getDisplayName(provider, catalogs) {
    const normalizedProvider = normalize(provider);
    const catalog = catalogs[normalizedProvider];
    return catalog?.displayName?.trim() || null;
}
function inferProvider(model) {
    const type = normalize(model.type);
    const owner = normalize(model.owned_by);
    const directMatches = {
        antigravity: 'agy',
        'github-copilot': 'ghcp',
        copilot: 'ghcp',
        anthropic: 'claude',
        'gemini-cli': 'gemini',
    };
    if (type && directMatches[type]) {
        return directMatches[type];
    }
    for (const [provider, hints] of Object.entries(PROVIDER_OWNER_HINTS)) {
        if (hints.some((hint) => type.includes(hint) || owner.includes(hint))) {
            return provider;
        }
    }
    return null;
}
function buildSummary(providerDisplayName, hint) {
    if (!hint.pinnedAvailable) {
        return `${hint.modelId} does not currently advertise a live pinned route for ${hint.pinnedModelId}. Reconnect or refresh managed prefixes before treating it as pinned.`;
    }
    if (hint.unprefixedStatus === 'safe') {
        return `${hint.modelId} currently resolves to ${providerDisplayName}. Use ${hint.pinnedModelId} to keep it pinned.`;
    }
    if (hint.unprefixedStatus === 'shadowed' && hint.effectiveDisplayName) {
        return `${hint.modelId} currently resolves to ${hint.effectiveDisplayName}. Use ${hint.pinnedModelId} to force ${providerDisplayName}.`;
    }
    return `${hint.modelId} is not advertised unprefixed right now. Use ${hint.pinnedModelId} to target ${providerDisplayName}.`;
}
function buildCliproxyRoutingHints(catalogs, mergedModels) {
    const mergedModelMap = new Map();
    for (const model of mergedModels) {
        const key = normalize(model.id);
        if (key && !mergedModelMap.has(key)) {
            mergedModelMap.set(key, model);
        }
    }
    const result = {};
    for (const [providerKey, catalog] of Object.entries(catalogs)) {
        if (!catalog) {
            continue;
        }
        const prefix = getManagedPrefix(providerKey);
        if (!prefix) {
            continue;
        }
        let safeCount = 0;
        let shadowedCount = 0;
        let prefixOnlyCount = 0;
        const models = catalog.models.map((model) => {
            const pinnedCandidates = mergedModels
                .filter((candidate) => normalize(candidate.id).endsWith(`/${normalize(model.id)}`))
                .filter((candidate) => inferProvider(candidate) === providerKey)
                .map((candidate) => candidate.id)
                .sort((left, right) => left.localeCompare(right));
            const managedPinnedId = `${prefix}/${model.id}`;
            const pinnedAvailable = pinnedCandidates.includes(managedPinnedId);
            const mergedModel = mergedModelMap.get(normalize(model.id));
            const effectiveProvider = mergedModel ? inferProvider(mergedModel) : null;
            const effectiveDisplayName = effectiveProvider && getDisplayName(effectiveProvider, catalogs)
                ? getDisplayName(effectiveProvider, catalogs)
                : mergedModel?.owned_by?.trim() || null;
            let unprefixedStatus = 'prefix-only';
            if (!mergedModel) {
                prefixOnlyCount += 1;
            }
            else if (effectiveProvider === providerKey) {
                unprefixedStatus = 'safe';
                safeCount += 1;
            }
            else {
                unprefixedStatus = 'shadowed';
                shadowedCount += 1;
            }
            const hint = {
                modelId: model.id,
                modelName: model.name?.trim() || model.id,
                prefix,
                pinnedModelId: managedPinnedId,
                recommendedModelId: managedPinnedId,
                pinnedAvailable,
                unprefixedStatus,
                effectiveProvider,
                effectiveDisplayName,
                effectiveOwnedBy: mergedModel?.owned_by?.trim() || null,
                summary: '',
            };
            hint.summary = buildSummary(catalog.displayName, hint);
            return hint;
        });
        result[providerKey] = {
            provider: providerKey,
            displayName: catalog.displayName,
            prefix,
            safeCount,
            shadowedCount,
            prefixOnlyCount,
            models,
        };
    }
    return result;
}
exports.buildCliproxyRoutingHints = buildCliproxyRoutingHints;
function getManagedModelPrefix(provider) {
    return getManagedPrefix(provider);
}
exports.getManagedModelPrefix = getManagedModelPrefix;
//# sourceMappingURL=cliproxy-model-routing.js.map