feat(cliproxy): deprecate claude thinking models in agy provider

Deprecated 2 Claude thinking models:
- gemini-claude-opus-4-5-thinking
- gemini-claude-sonnet-4-5-thinking

These models have compatibility issues with Antigravity.
A new deprecation system was added with badges and warnings in the UI.
This commit is contained in:
kaitranntt
2025-12-06 08:44:09 -05:00
parent 95e98313b8
commit 63b3ca7760
3 changed files with 136 additions and 12 deletions
+39 -10
View File
@@ -23,6 +23,10 @@ export interface ModelEntry {
broken?: boolean;
/** Issue URL for broken models */
issueUrl?: string;
/** Model is deprecated - show warning when selected */
deprecated?: boolean;
/** Deprecation reason/message */
deprecationReason?: string;
}
/**
@@ -46,16 +50,6 @@ export const MODEL_CATALOG: Partial<Record<CLIProxyProvider, ProviderCatalog>> =
displayName: 'Antigravity',
defaultModel: 'gemini-3-pro-preview',
models: [
{
id: 'gemini-claude-opus-4-5-thinking',
name: 'Claude Opus 4.5 Thinking',
description: 'Most capable, extended thinking',
},
{
id: 'gemini-claude-sonnet-4-5-thinking',
name: 'Claude Sonnet 4.5 Thinking',
description: 'Balanced with extended thinking',
},
{
id: 'gemini-claude-sonnet-4-5',
name: 'Claude Sonnet 4.5',
@@ -66,6 +60,22 @@ export const MODEL_CATALOG: Partial<Record<CLIProxyProvider, ProviderCatalog>> =
name: 'Gemini 3 Pro',
description: 'Google latest model via Antigravity',
},
{
id: 'gemini-claude-opus-4-5-thinking',
name: 'Claude Opus 4.5 Thinking',
description: 'Most capable, extended thinking',
deprecated: true,
deprecationReason:
'Thinking models are deprecated due to compatibility issues with Antigravity',
},
{
id: 'gemini-claude-sonnet-4-5-thinking',
name: 'Claude Sonnet 4.5 Thinking',
description: 'Balanced with extended thinking',
deprecated: true,
deprecationReason:
'Thinking models are deprecated due to compatibility issues with Antigravity',
},
],
},
gemini: {
@@ -126,3 +136,22 @@ export function getModelIssueUrl(provider: CLIProxyProvider, modelId: string): s
const model = findModel(provider, modelId);
return model?.issueUrl;
}
/**
* Check if model is deprecated
*/
export function isModelDeprecated(provider: CLIProxyProvider, modelId: string): boolean {
const model = findModel(provider, modelId);
return model?.deprecated === true;
}
/**
* Get deprecation reason for deprecated model
*/
export function getModelDeprecationReason(
provider: CLIProxyProvider,
modelId: string
): string | undefined {
const model = findModel(provider, modelId);
return model?.deprecationReason;
}
+15 -2
View File
@@ -67,7 +67,8 @@ 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') : '';
const brokenBadge = model.broken ? color(' [BROKEN]', 'error') : '';
return `${model.name}${tierBadge}${brokenBadge}`;
const deprecatedBadge = model.deprecated ? color(' [DEPRECATED]', 'warning') : '';
return `${model.name}${tierBadge}${brokenBadge}${deprecatedBadge}`;
}
/**
@@ -78,8 +79,9 @@ function formatModelDetailed(model: ModelEntry, isCurrent: boolean): string {
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 deprecatedBadge = model.deprecated ? color(' [DEPRECATED]', 'warning') : '';
const desc = model.description ? dim(` - ${model.description}`) : '';
return ` ${marker} ${name}${tierBadge}${brokenBadge}${desc}`;
return ` ${marker} ${name}${tierBadge}${brokenBadge}${deprecatedBadge}${desc}`;
}
/**
@@ -136,6 +138,7 @@ export async function configureProviderModel(
console.error(
dim(' Models marked [Paid Tier] require a paid Google account (not free tier).')
);
console.error(dim(' Models marked [DEPRECATED] are not recommended for use.'));
console.error('');
// Interactive selection
@@ -211,6 +214,15 @@ export async function configureProviderModel(
console.error(ok(`Model set to: ${bold(displayName)}`));
console.error(dim(` Config saved: ${settingsPath}`));
// Show deprecation warning if model is deprecated
if (selectedEntry?.deprecated) {
console.error('');
console.error(color('[!] DEPRECATION WARNING', 'warning'));
const reason = selectedEntry.deprecationReason || 'This model is deprecated';
console.error(dim(` ${reason}`));
console.error(dim(' Consider using a non-deprecated model for better compatibility.'));
}
// Show info for Claude models about thinking token limit
if (isClaude) {
console.error('');
@@ -261,6 +273,7 @@ export async function showCurrentConfig(provider: CLIProxyProvider): Promise<voi
console.error('');
console.error(bold('Available models:'));
console.error(dim(' [Paid Tier] = Requires paid Google account (not free tier)'));
console.error(dim(' [DEPRECATED] = Not recommended for use'));
console.error('');
catalog.models.forEach((m) => {
const isCurrent = m.id === currentModel;
+82
View File
@@ -214,4 +214,86 @@ describe('Model Catalog', () => {
}
});
});
describe('Deprecated models', () => {
it('Claude Opus 4.5 Thinking is marked as deprecated', () => {
const { MODEL_CATALOG } = modelCatalog;
const opus = MODEL_CATALOG.agy.models.find(
(m) => m.id === 'gemini-claude-opus-4-5-thinking'
);
assert(opus, 'Should include Claude Opus 4.5 Thinking');
assert.strictEqual(opus.deprecated, true, 'Should be marked as deprecated');
assert(opus.deprecationReason, 'Should have deprecation reason');
});
it('Claude Sonnet 4.5 Thinking is marked as deprecated', () => {
const { MODEL_CATALOG } = modelCatalog;
const sonnetThinking = MODEL_CATALOG.agy.models.find(
(m) => m.id === 'gemini-claude-sonnet-4-5-thinking'
);
assert(sonnetThinking, 'Should include Claude Sonnet 4.5 Thinking');
assert.strictEqual(sonnetThinking.deprecated, true, 'Should be marked as deprecated');
assert(sonnetThinking.deprecationReason, 'Should have deprecation reason');
});
it('deprecated models are at the bottom of the list', () => {
const { MODEL_CATALOG } = modelCatalog;
const models = MODEL_CATALOG.agy.models;
// Find indices of deprecated models
const opusIdx = models.findIndex((m) => m.id === 'gemini-claude-opus-4-5-thinking');
const sonnetThinkingIdx = models.findIndex(
(m) => m.id === 'gemini-claude-sonnet-4-5-thinking'
);
// Find indices of non-deprecated models
const sonnetIdx = models.findIndex((m) => m.id === 'gemini-claude-sonnet-4-5');
const geminiIdx = models.findIndex((m) => m.id === 'gemini-3-pro-preview');
// Deprecated models should come after non-deprecated models
assert(opusIdx > sonnetIdx, 'Opus Thinking should be below non-deprecated Sonnet');
assert(opusIdx > geminiIdx, 'Opus Thinking should be below non-deprecated Gemini');
assert(
sonnetThinkingIdx > sonnetIdx,
'Sonnet Thinking should be below non-deprecated Sonnet'
);
assert(
sonnetThinkingIdx > geminiIdx,
'Sonnet Thinking should be below non-deprecated Gemini'
);
});
});
describe('isModelDeprecated', () => {
it('returns true for deprecated models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'gemini-claude-opus-4-5-thinking'), true);
assert.strictEqual(isModelDeprecated('agy', 'gemini-claude-sonnet-4-5-thinking'), true);
});
it('returns false for non-deprecated models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'gemini-claude-sonnet-4-5'), false);
assert.strictEqual(isModelDeprecated('agy', 'gemini-3-pro-preview'), false);
});
it('returns false for unknown models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'unknown-model'), false);
});
});
describe('getModelDeprecationReason', () => {
it('returns deprecation reason for deprecated models', () => {
const { getModelDeprecationReason } = modelCatalog;
const reason = getModelDeprecationReason('agy', 'gemini-claude-opus-4-5-thinking');
assert(reason, 'Should have deprecation reason');
assert(typeof reason === 'string', 'Reason should be a string');
});
it('returns undefined for non-deprecated models', () => {
const { getModelDeprecationReason } = modelCatalog;
assert.strictEqual(getModelDeprecationReason('agy', 'gemini-claude-sonnet-4-5'), undefined);
});
});
});