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.
This commit is contained in:
kaitranntt
2025-12-18 04:58:49 -05:00
parent 2c6dfe746b
commit ec6face8db
6 changed files with 31 additions and 17 deletions
+2 -1
View File
@@ -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
};
/**
+2 -1
View File
@@ -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<boolean> {
return new Promise((resolve) => {
const req = http.request(
{
hostname: 'localhost',
hostname: '127.0.0.1',
port,
path: '/usage',
method: 'GET',
+3 -1
View File
@@ -40,8 +40,10 @@ export function generateCopilotEnv(config: CopilotConfig): Record<string, string
const sonnetModel = config.sonnet_model || config.model;
const haikuModel = config.haiku_model || config.model;
// Use 127.0.0.1 instead of localhost for more reliable local connections
// (bypasses DNS resolution and potential IPv6 issues)
return {
ANTHROPIC_BASE_URL: `http://localhost:${config.port}`,
ANTHROPIC_BASE_URL: `http://127.0.0.1:${config.port}`,
ANTHROPIC_AUTH_TOKEN: 'dummy', // copilot-api handles auth internally
ANTHROPIC_MODEL: config.model,
// Model tier mapping - allows different models for opus/sonnet/haiku
+15 -7
View File
@@ -18,12 +18,11 @@ import { CopilotModel } from './types';
* Multipliers: 0 = free tier, 0.25-0.33 = cheap, 1 = standard, 3-10 = premium
*/
export const DEFAULT_COPILOT_MODELS: CopilotModel[] = [
// Anthropic Models
// Anthropic Models - All require paid Copilot subscription
{
id: 'claude-sonnet-4.5',
name: 'Claude Sonnet 4.5',
provider: 'anthropic',
isDefault: true,
minPlan: 'pro',
multiplier: 1,
},
@@ -53,7 +52,7 @@ export const DEFAULT_COPILOT_MODELS: CopilotModel[] = [
id: 'claude-haiku-4.5',
name: 'Claude Haiku 4.5',
provider: 'anthropic',
minPlan: 'free',
minPlan: 'pro', // Requires paid Copilot subscription
multiplier: 0.33,
},
@@ -93,7 +92,14 @@ export const DEFAULT_COPILOT_MODELS: CopilotModel[] = [
},
{ 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 },
{
id: 'gpt-4.1',
name: 'GPT-4.1',
provider: 'openai',
isDefault: true,
minPlan: 'free',
multiplier: 0,
},
// Google Models
{
@@ -150,7 +156,8 @@ export async function fetchModelsFromDaemon(port: number): Promise<CopilotModel[
return new Promise((resolve) => {
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<CopilotModel[
id: m.id,
name: formatModelName(m.id),
provider: detectProvider(m.id),
isDefault: m.id === 'claude-sonnet-4.5',
isDefault: m.id === 'gpt-4.1', // Free tier default
}));
resolve(models.length > 0 ? models : DEFAULT_COPILOT_MODELS);
} else {
@@ -206,9 +213,10 @@ export async function getAvailableModels(port: number): Promise<CopilotModel[]>
/**
* 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';
}
/**
+2 -1
View File
@@ -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,
@@ -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',
},
];