From 7653caba710f847ff4c25fcc5b68f1b0381dd2d2 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Thu, 18 Dec 2025 03:48:47 -0500 Subject: [PATCH] feat(copilot): add complete model catalog with plan tiers Add 19 GitHub Copilot supported models with metadata: - Anthropic: claude-sonnet-4.5, claude-sonnet-4, claude-opus-4.5, claude-opus-4.1, claude-haiku-4.5 - OpenAI: gpt-5.2, gpt-5.1-codex-max, gpt-5.1-codex, gpt-5.1-codex-mini, gpt-5.1, gpt-5-codex, gpt-5, gpt-5-mini, gpt-4.1 - Google: gemini-3-pro, gemini-3-flash, gemini-2.5-pro - xAI: grok-code-fast-1 - Fine-tuned: raptor-mini Each model includes: - minPlan: free, pro, pro+, business, enterprise - multiplier: 0 = free tier, 0.25-0.33 = cheap, 1 = standard, 3-10 = premium - preview: boolean for non-GA models Update default model to claude-sonnet-4.5 (standard multiplier). --- src/config/unified-config-loader.ts | 2 +- src/config/unified-config-types.ts | 4 +- src/copilot/copilot-models.ts | 166 ++++++++++++++++++++++++---- src/copilot/types.ts | 12 ++ 4 files changed, 161 insertions(+), 23 deletions(-) diff --git a/src/config/unified-config-loader.ts b/src/config/unified-config-loader.ts index 72f27ceb..632d2d6d 100644 --- a/src/config/unified-config-loader.ts +++ b/src/config/unified-config-loader.ts @@ -325,7 +325,7 @@ function generateYamlWithComments(config: UnifiedConfig): string { lines.push('# Setup: npx copilot-api auth (authenticate with GitHub)'); lines.push('# Usage: ccs copilot (switch to copilot profile)'); lines.push('#'); - lines.push('# Models: claude-opus-4-5-20250514, claude-sonnet-4-20250514, gpt-4.1, o3'); + lines.push('# Models: claude-sonnet-4.5, claude-opus-4.5, gpt-5.1, gemini-2.5-pro'); lines.push('# Account types: individual, business, enterprise'); lines.push('# ----------------------------------------------------------------------------'); lines.push( diff --git a/src/config/unified-config-types.ts b/src/config/unified-config-types.ts index 4653f3a2..46fb5e76 100644 --- a/src/config/unified-config-types.ts +++ b/src/config/unified-config-types.ts @@ -175,7 +175,7 @@ export interface CopilotConfig { rate_limit: number | null; /** Wait instead of error when rate limit is hit (default: true) */ wait_on_limit: boolean; - /** Default model ID (e.g., claude-opus-4-5-20250514) */ + /** Default model ID (e.g., claude-sonnet-4.5) */ model: string; /** Model mapping for Claude tiers - maps opus/sonnet/haiku to specific models */ opus_model?: string; @@ -259,7 +259,7 @@ export const DEFAULT_COPILOT_CONFIG: CopilotConfig = { account_type: 'individual', rate_limit: null, wait_on_limit: true, - model: 'claude-opus-4-5-20250514', + model: 'claude-sonnet-4.5', }; /** diff --git a/src/copilot/copilot-models.ts b/src/copilot/copilot-models.ts index c95bc94d..5dfc62ea 100644 --- a/src/copilot/copilot-models.ts +++ b/src/copilot/copilot-models.ts @@ -2,6 +2,8 @@ * 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 */ import * as http from 'http'; @@ -10,19 +12,132 @@ import { CopilotModel } from './types'; /** * 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 */ export const DEFAULT_COPILOT_MODELS: CopilotModel[] = [ + // Anthropic Models { - id: 'claude-opus-4-5-20250514', - name: 'Claude Opus 4.5', + id: 'claude-sonnet-4.5', + name: 'Claude Sonnet 4.5', provider: 'anthropic', isDefault: true, + 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: 'free', + 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', 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, + }, + + // Fine-tuned Models + { + id: 'raptor-mini', + name: 'Raptor Mini', + provider: 'openai', + minPlan: 'free', + multiplier: 0, + preview: true, }, - { id: 'claude-sonnet-4-20250514', name: 'Claude Sonnet 4', provider: 'anthropic' }, - { id: 'gpt-4.1', name: 'GPT-4.1', provider: 'openai' }, - { id: 'gpt-4.1-mini', name: 'GPT-4.1 Mini', provider: 'openai' }, - { id: 'o3', name: 'O3', provider: 'openai' }, - { id: 'o4-mini', name: 'O4 Mini', provider: 'openai' }, ]; /** @@ -55,8 +170,8 @@ export async function fetchModelsFromDaemon(port: number): Promise ({ id: m.id, name: formatModelName(m.id), - provider: m.id.includes('claude') ? 'anthropic' : 'openai', - isDefault: m.id === 'claude-opus-4-5-20250514', + provider: detectProvider(m.id), + isDefault: m.id === 'claude-sonnet-4.5', })); resolve(models.length > 0 ? models : DEFAULT_COPILOT_MODELS); } else { @@ -93,22 +208,33 @@ export async function getAvailableModels(port: number): Promise * Get the default model. */ export function getDefaultModel(): string { - return 'claude-opus-4-5-20250514'; + return 'claude-sonnet-4.5'; +} + +/** + * Detect provider from model ID. + */ +function detectProvider(modelId: string): 'openai' | 'anthropic' { + 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: string): string { - // Convert model IDs to readable names - const nameMap: Record = { - 'claude-opus-4-5-20250514': 'Claude Opus 4.5', - 'claude-sonnet-4-20250514': 'Claude Sonnet 4', - 'gpt-4.1': 'GPT-4.1', - 'gpt-4.1-mini': 'GPT-4.1 Mini', - o3: 'O3', - 'o4-mini': 'O4 Mini', - }; + // Find model in catalog for metadata + const model = DEFAULT_COPILOT_MODELS.find((m) => m.id === modelId); + if (model) { + let name = model.name; + if (model.preview) name += ' (Preview)'; + return name; + } - return nameMap[modelId] || modelId; + // Fallback: convert kebab-case to title case + return modelId + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); } diff --git a/src/copilot/types.ts b/src/copilot/types.ts index 51b308f8..e0429a1d 100644 --- a/src/copilot/types.ts +++ b/src/copilot/types.ts @@ -35,6 +35,12 @@ export interface CopilotStatus { daemon: CopilotDaemonStatus; } +/** + * Copilot plan tier for model availability. + * Based on GitHub Copilot plans. + */ +export type CopilotPlanTier = 'free' | 'pro' | 'pro+' | 'business' | 'enterprise'; + /** * Copilot model information. */ @@ -45,6 +51,12 @@ export interface CopilotModel { provider: 'openai' | 'anthropic'; /** Whether this is the default model */ isDefault?: boolean; + /** Minimum plan tier required (free = available to all) */ + minPlan?: CopilotPlanTier; + /** Premium request multiplier (0 = free, higher = more expensive) */ + multiplier?: number; + /** Whether this model is in preview */ + preview?: boolean; } /**