mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
feat(cliproxy): add warning for broken claude proxy models on agy
- add broken flag to model catalog for models with known issues - display [BROKEN] badge in model selection and config display - show warning message when starting with a broken model - link to tracking issue: CLIProxyAPI#415 Claude proxy models (gemini-claude-*) currently fail with tool calls due to upstream CLIProxyAPI bug. Warning helps users know to switch to gemini-3-pro-preview until fixed.
This commit is contained in:
@@ -26,8 +26,8 @@ import {
|
||||
} from './config-generator';
|
||||
import { isAuthenticated } from './auth-handler';
|
||||
import { CLIProxyProvider, ExecutorConfig } from './types';
|
||||
import { configureProviderModel } from './model-config';
|
||||
import { supportsModelConfig } from './model-catalog';
|
||||
import { configureProviderModel, getCurrentModel } from './model-config';
|
||||
import { supportsModelConfig, isModelBroken, getModelIssueUrl, findModel } from './model-catalog';
|
||||
|
||||
/** Default executor configuration */
|
||||
const DEFAULT_CONFIG: ExecutorConfig = {
|
||||
@@ -170,7 +170,24 @@ export async function execClaudeWithCLIProxy(
|
||||
await configureProviderModel(provider, false); // false = only if not configured
|
||||
}
|
||||
|
||||
// 5. Ensure user settings file exists (creates from defaults if not)
|
||||
// 5. Check for known broken models and warn user
|
||||
const currentModel = getCurrentModel(provider);
|
||||
if (currentModel && isModelBroken(provider, currentModel)) {
|
||||
const modelEntry = findModel(provider, currentModel);
|
||||
const issueUrl = getModelIssueUrl(provider, currentModel);
|
||||
console.error('');
|
||||
console.error(
|
||||
`[!] Warning: ${modelEntry?.name || currentModel} has known issues with Claude Code`
|
||||
);
|
||||
console.error(' Tool calls will fail. Use "gemini-3-pro-preview" instead.');
|
||||
if (issueUrl) {
|
||||
console.error(` Tracking: ${issueUrl}`);
|
||||
}
|
||||
console.error(` Run "ccs ${provider} --config" to change model.`);
|
||||
console.error('');
|
||||
}
|
||||
|
||||
// 6. Ensure user settings file exists (creates from defaults if not)
|
||||
ensureProviderSettings(provider);
|
||||
|
||||
// 6. Generate config file
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface ModelEntry {
|
||||
tier?: 'free' | 'paid';
|
||||
/** Optional description for the model */
|
||||
description?: string;
|
||||
/** Model has known issues - show warning when selected */
|
||||
broken?: boolean;
|
||||
/** Issue URL for broken models */
|
||||
issueUrl?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,16 +50,22 @@ export const MODEL_CATALOG: Partial<Record<CLIProxyProvider, ProviderCatalog>> =
|
||||
id: 'gemini-claude-opus-4-5-thinking',
|
||||
name: 'Claude Opus 4.5 Thinking',
|
||||
description: 'Most capable, extended thinking',
|
||||
broken: true,
|
||||
issueUrl: 'https://github.com/router-for-me/CLIProxyAPI/issues/415',
|
||||
},
|
||||
{
|
||||
id: 'gemini-claude-sonnet-4-5-thinking',
|
||||
name: 'Claude Sonnet 4.5 Thinking',
|
||||
description: 'Balanced with extended thinking',
|
||||
broken: true,
|
||||
issueUrl: 'https://github.com/router-for-me/CLIProxyAPI/issues/415',
|
||||
},
|
||||
{
|
||||
id: 'gemini-claude-sonnet-4-5',
|
||||
name: 'Claude Sonnet 4.5',
|
||||
description: 'Fast and capable',
|
||||
broken: true,
|
||||
issueUrl: 'https://github.com/router-for-me/CLIProxyAPI/issues/415',
|
||||
},
|
||||
{
|
||||
id: 'gemini-3-pro-preview',
|
||||
@@ -107,3 +117,19 @@ export function findModel(provider: CLIProxyProvider, modelId: string): ModelEnt
|
||||
if (!catalog) return undefined;
|
||||
return catalog.models.find((m) => m.id === modelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if model has known issues
|
||||
*/
|
||||
export function isModelBroken(provider: CLIProxyProvider, modelId: string): boolean {
|
||||
const model = findModel(provider, modelId);
|
||||
return model?.broken === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get issue URL for broken model
|
||||
*/
|
||||
export function getModelIssueUrl(provider: CLIProxyProvider, modelId: string): string | undefined {
|
||||
const model = findModel(provider, modelId);
|
||||
return model?.issueUrl;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ export function getCurrentModel(provider: CLIProxyProvider): string | undefined
|
||||
function formatModelOption(model: ModelEntry): string {
|
||||
// Tier badge: clarify that "paid" means paid Google account (not free tier)
|
||||
const tierBadge = model.tier === 'paid' ? color(' [Paid Tier]', 'warning') : '';
|
||||
return `${model.name}${tierBadge}`;
|
||||
const brokenBadge = model.broken ? color(' [BROKEN]', 'error') : '';
|
||||
return `${model.name}${tierBadge}${brokenBadge}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,8 +56,9 @@ function formatModelDetailed(model: ModelEntry, isCurrent: boolean): string {
|
||||
const marker = isCurrent ? color('>', 'success') : ' ';
|
||||
const name = isCurrent ? bold(model.name) : model.name;
|
||||
const tierBadge = model.tier === 'paid' ? color(' [Paid Tier]', 'warning') : '';
|
||||
const brokenBadge = model.broken ? color(' [BROKEN]', 'error') : '';
|
||||
const desc = model.description ? dim(` - ${model.description}`) : '';
|
||||
return ` ${marker} ${name}${tierBadge}${desc}`;
|
||||
return ` ${marker} ${name}${tierBadge}${brokenBadge}${desc}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user