From ec6face8db78e9c5cad4f91dcfd39e08665e1415 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Thu, 18 Dec 2025 04:58:49 -0500 Subject: [PATCH] fix(copilot): use gpt-4.1 as default model and 127.0.0.1 for local connections Key changes: - Changed default model from claude-sonnet-4.5 to gpt-4.1 (free tier compatible) - Updated all Claude models to minPlan: 'pro' (requires paid Copilot subscription) - Replaced 'localhost' with '127.0.0.1' for more reliable local connections (bypasses DNS resolution and potential IPv6 issues) - Updated UI presets: replaced Claude Haiku with Raptor Mini in free tier - Fixed FREE_PRESETS to only include actually free models This fixes the "model_not_supported" error when using free tier GitHub Copilot subscription, which doesn't have access to Claude models. --- src/config/unified-config-types.ts | 3 ++- src/copilot/copilot-daemon.ts | 3 ++- src/copilot/copilot-executor.ts | 4 +++- src/copilot/copilot-models.ts | 22 +++++++++++++------ src/web-server/routes.ts | 3 ++- .../copilot/copilot-config-form.tsx | 13 ++++++----- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/config/unified-config-types.ts b/src/config/unified-config-types.ts index 787b373b..a692173c 100644 --- a/src/config/unified-config-types.ts +++ b/src/config/unified-config-types.ts @@ -253,6 +253,7 @@ export interface SecretsConfig { /** * Default Copilot configuration. * Strictly opt-in - disabled by default. + * Uses gpt-4.1 as default model (free tier compatible). */ export const DEFAULT_COPILOT_CONFIG: CopilotConfig = { enabled: false, @@ -261,7 +262,7 @@ export const DEFAULT_COPILOT_CONFIG: CopilotConfig = { account_type: 'individual', rate_limit: null, wait_on_limit: true, - model: 'claude-sonnet-4.5', + model: 'gpt-4.1', // Free tier compatible }; /** diff --git a/src/copilot/copilot-daemon.ts b/src/copilot/copilot-daemon.ts index 73fe69e6..36d492f7 100644 --- a/src/copilot/copilot-daemon.ts +++ b/src/copilot/copilot-daemon.ts @@ -17,12 +17,13 @@ const PID_FILE = path.join(getCopilotDir(), 'daemon.pid'); /** * Check if copilot-api daemon is running on the specified port. + * Uses 127.0.0.1 instead of localhost for more reliable local connections. */ export async function isDaemonRunning(port: number): Promise { return new Promise((resolve) => { const req = http.request( { - hostname: 'localhost', + hostname: '127.0.0.1', port, path: '/usage', method: 'GET', diff --git a/src/copilot/copilot-executor.ts b/src/copilot/copilot-executor.ts index c6e67633..012fb385 100644 --- a/src/copilot/copilot-executor.ts +++ b/src/copilot/copilot-executor.ts @@ -40,8 +40,10 @@ export function generateCopilotEnv(config: CopilotConfig): Record { const req = http.request( { - hostname: 'localhost', + // Use 127.0.0.1 instead of localhost for more reliable local connections + hostname: '127.0.0.1', port, path: '/v1/models', method: 'GET', @@ -171,7 +178,7 @@ export async function fetchModelsFromDaemon(port: number): Promise 0 ? models : DEFAULT_COPILOT_MODELS); } else { @@ -206,9 +213,10 @@ export async function getAvailableModels(port: number): Promise /** * Get the default model. + * Uses gpt-4.1 as it's available on free tier. */ export function getDefaultModel(): string { - return 'claude-sonnet-4.5'; + return 'gpt-4.1'; } /** diff --git a/src/web-server/routes.ts b/src/web-server/routes.ts index 14424d10..710eccb0 100644 --- a/src/web-server/routes.ts +++ b/src/web-server/routes.ts @@ -1826,9 +1826,10 @@ apiRoutes.get('/copilot/settings/raw', (_req: Request, res: Response): void => { // If file doesn't exist, return default structure with all model mappings if (!fs.existsSync(settingsPath)) { // Create settings structure matching CLIProxy pattern - always include all model mappings + // Use 127.0.0.1 instead of localhost for more reliable local connections const defaultSettings = { env: { - ANTHROPIC_BASE_URL: `http://localhost:${copilotConfig.port}`, + ANTHROPIC_BASE_URL: `http://127.0.0.1:${copilotConfig.port}`, ANTHROPIC_AUTH_TOKEN: 'copilot-managed', ANTHROPIC_MODEL: defaultModel, ANTHROPIC_DEFAULT_OPUS_MODEL: copilotConfig.opus_model || defaultModel, diff --git a/ui/src/components/copilot/copilot-config-form.tsx b/ui/src/components/copilot/copilot-config-form.tsx index 47603aa7..b7da407a 100644 --- a/ui/src/components/copilot/copilot-config-form.tsx +++ b/ui/src/components/copilot/copilot-config-form.tsx @@ -39,6 +39,7 @@ const CodeEditor = lazy(() => // Model presets for quick configuration // Grouped by tier: Free (available to all) and Paid (requires Pro+) +// Note: ALL Claude models require paid Copilot subscription const FREE_PRESETS = [ { name: 'GPT-4.1 (Free)', @@ -57,12 +58,12 @@ const FREE_PRESETS = [ haiku: 'gpt-5-mini', }, { - name: 'Claude Haiku 4.5 (Free)', - description: 'Free tier - fast Anthropic model', - default: 'claude-haiku-4.5', - opus: 'claude-haiku-4.5', - sonnet: 'claude-haiku-4.5', - haiku: 'claude-haiku-4.5', + name: 'Raptor Mini (Free)', + description: 'Free tier - fine-tuned for coding', + default: 'raptor-mini', + opus: 'raptor-mini', + sonnet: 'raptor-mini', + haiku: 'raptor-mini', }, ];