"use strict";
/**
 * Copilot Model Catalog
 *
 * Manages available models from copilot-api.
 * Based on GitHub Copilot supported models:
 * https://docs.github.com/copilot/reference/ai-models/supported-models
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDefaultModel = exports.getAvailableModels = exports.fetchModelsFromDaemon = exports.DEFAULT_COPILOT_MODELS = void 0;
const http = __importStar(require("http"));
const DEFAULT_COPILOT_MODEL_ID = 'gpt-4.1';
const MAX_MODELS_BODY_SIZE = 1024 * 1024; // 1MB
/**
 * Default models available through copilot-api.
 * Used as fallback when API is not reachable.
 * Source: GitHub Copilot Supported Models (Dec 2025)
 *
 * Plan tiers: free, pro, pro+, business, enterprise
 * Multipliers: 0 = free tier, 0.25-0.33 = cheap, 1 = standard, 3-10 = premium
 */
exports.DEFAULT_COPILOT_MODELS = [
    // Anthropic Models - All require paid Copilot subscription
    {
        id: 'claude-sonnet-4.5',
        name: 'Claude Sonnet 4.5',
        provider: 'anthropic',
        minPlan: 'pro',
        multiplier: 1,
    },
    {
        id: 'claude-sonnet-4',
        name: 'Claude Sonnet 4',
        provider: 'anthropic',
        minPlan: 'pro',
        multiplier: 1,
    },
    {
        id: 'claude-opus-4.5',
        name: 'Claude Opus 4.5',
        provider: 'anthropic',
        minPlan: 'pro',
        multiplier: 3,
        preview: true,
    },
    {
        id: 'claude-opus-4.1',
        name: 'Claude Opus 4.1',
        provider: 'anthropic',
        minPlan: 'pro',
        multiplier: 10,
    },
    {
        id: 'claude-haiku-4.5',
        name: 'Claude Haiku 4.5',
        provider: 'anthropic',
        minPlan: 'pro', // Requires paid Copilot subscription
        multiplier: 0.33,
    },
    // OpenAI Models
    {
        id: 'gpt-5.2',
        name: 'GPT-5.2',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 1,
        preview: true,
    },
    {
        id: 'gpt-5.1-codex-max',
        name: 'GPT-5.1 Codex Max',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 1,
    },
    { id: 'gpt-5.1-codex', name: 'GPT-5.1 Codex', provider: 'openai', minPlan: 'pro', multiplier: 1 },
    {
        id: 'gpt-5.1-codex-mini',
        name: 'GPT-5.1 Codex Mini',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 0.33,
        preview: true,
    },
    { id: 'gpt-5.1', name: 'GPT-5.1', provider: 'openai', minPlan: 'pro', multiplier: 1 },
    {
        id: 'gpt-5-codex',
        name: 'GPT-5 Codex',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 1,
        preview: true,
    },
    { id: 'gpt-5', name: 'GPT-5', provider: 'openai', minPlan: 'pro', multiplier: 1 },
    { id: 'gpt-5-mini', name: 'GPT-5 Mini', provider: 'openai', minPlan: 'free', multiplier: 0 },
    {
        id: 'gpt-4.1',
        name: 'GPT-4.1',
        provider: 'openai',
        isDefault: true,
        minPlan: 'free',
        multiplier: 0,
    },
    // Google Models
    {
        id: 'gemini-3-pro',
        name: 'Gemini 3 Pro',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 1,
        preview: true,
    },
    {
        id: 'gemini-3-flash',
        name: 'Gemini 3 Flash',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 0.33,
        preview: true,
    },
    {
        id: 'gemini-2.5-pro',
        name: 'Gemini 2.5 Pro',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 1,
    },
    // xAI Models
    {
        id: 'grok-code-fast-1',
        name: 'Grok Code Fast 1',
        provider: 'openai',
        minPlan: 'pro',
        multiplier: 0.25,
    },
];
/**
 * Fetch available models from running copilot-api daemon.
 *
 * @param port The port copilot-api is running on
 * @returns List of available models
 */
async function fetchModelsFromDaemon(port) {
    return new Promise((resolve) => {
        let resolved = false;
        const safeResolve = (models) => {
            if (resolved)
                return;
            resolved = true;
            resolve(models);
        };
        const req = http.request({
            // Use 127.0.0.1 instead of localhost for more reliable local connections
            hostname: '127.0.0.1',
            port,
            path: '/v1/models',
            method: 'GET',
            timeout: 5000,
        }, (res) => {
            let data = '';
            res.on('data', (chunk) => {
                data += chunk;
                if (data.length > MAX_MODELS_BODY_SIZE) {
                    req.destroy();
                    safeResolve(exports.DEFAULT_COPILOT_MODELS);
                }
            });
            res.on('end', () => {
                try {
                    const response = JSON.parse(data);
                    if (Array.isArray(response.data)) {
                        const models = response.data
                            .map(mapDaemonModel)
                            .filter((model) => model !== null);
                        safeResolve(models.length > 0 ? models : exports.DEFAULT_COPILOT_MODELS);
                    }
                    else {
                        safeResolve(exports.DEFAULT_COPILOT_MODELS);
                    }
                }
                catch {
                    safeResolve(exports.DEFAULT_COPILOT_MODELS);
                }
            });
        });
        req.on('error', () => {
            safeResolve(exports.DEFAULT_COPILOT_MODELS);
        });
        req.on('timeout', () => {
            req.destroy();
            safeResolve(exports.DEFAULT_COPILOT_MODELS);
        });
        req.end();
    });
}
exports.fetchModelsFromDaemon = fetchModelsFromDaemon;
/**
 * Get available models (from daemon or defaults).
 */
async function getAvailableModels(port) {
    return fetchModelsFromDaemon(port);
}
exports.getAvailableModels = getAvailableModels;
/**
 * Get the default model.
 * Uses gpt-4.1 as it's available on free tier.
 */
function getDefaultModel() {
    return DEFAULT_COPILOT_MODEL_ID;
}
exports.getDefaultModel = getDefaultModel;
/**
 * Detect provider from model ID.
 */
function detectProvider(modelId) {
    if (modelId.includes('claude'))
        return 'anthropic';
    return 'openai';
}
/**
 * Format model ID to human-readable name.
 * Includes badges for preview and plan tier.
 */
function formatModelName(modelId) {
    // Find model in catalog for metadata
    const model = exports.DEFAULT_COPILOT_MODELS.find((m) => m.id === modelId);
    if (model) {
        let name = model.name;
        if (model.preview)
            name += ' (Preview)';
        return name;
    }
    // Fallback: convert kebab-case to title case
    return modelId
        .split('-')
        .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
        .join(' ');
}
function normalizeLimitValue(value) {
    return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : undefined;
}
function extractLimits(limits) {
    if (!limits)
        return undefined;
    const normalized = {
        maxContextWindowTokens: normalizeLimitValue(limits.max_context_window_tokens),
        maxOutputTokens: normalizeLimitValue(limits.max_output_tokens),
        maxPromptTokens: normalizeLimitValue(limits.max_prompt_tokens),
    };
    return Object.values(normalized).some((value) => value !== undefined) ? normalized : undefined;
}
function mapDaemonModel(entry) {
    if (typeof entry.id !== 'string')
        return null;
    const id = entry.id.trim();
    if (!id)
        return null;
    const defaultMeta = exports.DEFAULT_COPILOT_MODELS.find((model) => model.id === id);
    const limits = extractLimits(entry.capabilities?.limits);
    return {
        ...defaultMeta,
        id,
        name: typeof entry.name === 'string' && entry.name.trim().length > 0
            ? entry.name.trim()
            : (defaultMeta?.name ?? formatModelName(id)),
        provider: defaultMeta?.provider ?? detectProvider(id),
        isDefault: id === DEFAULT_COPILOT_MODEL_ID,
        ...(limits ? { limits } : {}),
    };
}
//# sourceMappingURL=copilot-models.js.map