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).
This commit is contained in:
kaitranntt
2025-12-18 03:48:47 -05:00
parent 5f0fde9a61
commit 7653caba71
4 changed files with 161 additions and 23 deletions
+1 -1
View File
@@ -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(
+2 -2
View File
@@ -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',
};
/**
+146 -20
View File
@@ -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<CopilotModel[
const models: CopilotModel[] = response.data.map((m) => ({
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<CopilotModel[]>
* 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<string, string> = {
'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(' ');
}
+12
View File
@@ -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;
}
/**