fix(agy): remove deprecated 4.5 selector options

This commit is contained in:
Tam Nhu Tran committed 2026-03-03 03:10:53 +07:00
1 parent dbe8f6f68c
commit 5913f730ac
6 files changed
+88 -123

No files matched your search

@@ -3,16 +3,28 @@ import { findModel, supportsThinking } from '../../../src/cliproxy/model-catalog
describe('model-catalog compatibility lookups', () => {
it('finds agy Claude models using dotted major.minor IDs', () => {
const dottedThinking = findModel('agy', 'claude-sonnet-4.5-thinking');
const dottedNonThinking = findModel('agy', 'claude-sonnet-4.5');
const dottedThinking = findModel('agy', 'claude-opus-4.6-thinking');
const dottedNonThinking = findModel('agy', 'claude-sonnet-4.6');
expect(dottedThinking?.id).toBe('claude-sonnet-4-5-thinking');
expect(dottedNonThinking?.id).toBe('claude-sonnet-4-5');
expect(dottedThinking?.id).toBe('claude-opus-4-6-thinking');
expect(dottedNonThinking?.id).toBe('claude-sonnet-4-6');
});
it('maps legacy agy 4.5 IDs to canonical 4.6 catalog models', () => {
const legacyOpusThinking = findModel('agy', 'claude-opus-4.5-thinking');
const legacySonnetThinking = findModel('agy', 'claude-sonnet-4.5-thinking');
const legacySonnet = findModel('agy', 'claude-sonnet-4.5');
expect(legacyOpusThinking?.id).toBe('claude-opus-4-6-thinking');
expect(legacySonnetThinking?.id).toBe('claude-sonnet-4-6');
expect(legacySonnet?.id).toBe('claude-sonnet-4-6');
});
it('supports thinking checks for dotted agy model IDs', () => {
expect(supportsThinking('agy', 'claude-opus-4.6-thinking')).toBe(true);
expect(supportsThinking('agy', 'claude-sonnet-4.5')).toBe(false);
expect(supportsThinking('agy', 'claude-sonnet-4.6')).toBe(true);
expect(supportsThinking('agy', 'claude-opus-4.5-thinking')).toBe(true);
expect(supportsThinking('agy', 'claude-sonnet-4.5')).toBe(true);
});
it('maps legacy sonnet 4.6 thinking aliases to canonical agy model', () => {
+43 -47
View File
@@ -69,20 +69,11 @@ describe('Model Catalog', () => {
assert.strictEqual(MODEL_CATALOG.agy.defaultModel, 'claude-opus-4-6-thinking');
});
it('includes Claude Opus 4.5 Thinking', () => {
it('includes Claude Opus 4.6 Thinking', () => {
const { MODEL_CATALOG } = modelCatalog;
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-5-thinking');
assert(opus, 'Should include Claude Opus 4.5 Thinking');
assert.strictEqual(opus.name, 'Claude Opus 4.5 Thinking');
});
it('includes Claude Sonnet 4.5 Thinking', () => {
const { MODEL_CATALOG } = modelCatalog;
const sonnetThinking = MODEL_CATALOG.agy.models.find(
(m) => m.id === 'claude-sonnet-4-5-thinking'
);
assert(sonnetThinking, 'Should include Claude Sonnet 4.5 Thinking');
assert.strictEqual(sonnetThinking.name, 'Claude Sonnet 4.5 Thinking');
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-6-thinking');
assert(opus, 'Should include Claude Opus 4.6 Thinking');
assert.strictEqual(opus.name, 'Claude Opus 4.6 Thinking');
});
it('includes Claude Sonnet 4.6', () => {
@@ -92,11 +83,12 @@ describe('Model Catalog', () => {
assert.strictEqual(sonnet.name, 'Claude Sonnet 4.6');
});
it('includes Claude Sonnet 4.5', () => {
it('does not include deprecated Claude 4.5 AGY models', () => {
const { MODEL_CATALOG } = modelCatalog;
const sonnet = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-sonnet-4-5');
assert(sonnet, 'Should include Claude Sonnet 4.5');
assert.strictEqual(sonnet.name, 'Claude Sonnet 4.5');
const ids = MODEL_CATALOG.agy.models.map((m) => m.id);
assert.strictEqual(ids.includes('claude-opus-4-5-thinking'), false);
assert.strictEqual(ids.includes('claude-sonnet-4-5-thinking'), false);
assert.strictEqual(ids.includes('claude-sonnet-4-5'), false);
});
it('includes Gemini 3 Pro (free via Antigravity)', () => {
@@ -108,9 +100,9 @@ describe('Model Catalog', () => {
assert.strictEqual(gem3.tier, undefined, 'AGY models should not have paid tier');
});
it('has 6 models total', () => {
it('has 3 models total', () => {
const { MODEL_CATALOG } = modelCatalog;
assert.strictEqual(MODEL_CATALOG.agy.models.length, 6);
assert.strictEqual(MODEL_CATALOG.agy.models.length, 3);
});
});
@@ -203,11 +195,11 @@ describe('Model Catalog', () => {
});
describe('findModel', () => {
it('finds Claude Opus 4.5 Thinking in agy', () => {
it('finds Claude Opus 4.6 Thinking in agy', () => {
const { findModel } = modelCatalog;
const model = findModel('agy', 'claude-opus-4-5-thinking');
const model = findModel('agy', 'claude-opus-4-6-thinking');
assert(model, 'Should find model');
assert.strictEqual(model.name, 'Claude Opus 4.5 Thinking');
assert.strictEqual(model.name, 'Claude Opus 4.6 Thinking');
});
it('finds Gemini 2.5 Pro in gemini', () => {
@@ -217,6 +209,16 @@ describe('Model Catalog', () => {
assert.strictEqual(model.name, 'Gemini 2.5 Pro');
});
it('maps legacy AGY 4.5 IDs to supported 4.6 models', () => {
const { findModel } = modelCatalog;
const legacyOpus = findModel('agy', 'claude-opus-4-5-thinking');
const legacySonnetThinking = findModel('agy', 'claude-sonnet-4-5-thinking');
const legacySonnet = findModel('agy', 'claude-sonnet-4-5');
assert.strictEqual(legacyOpus?.id, 'claude-opus-4-6-thinking');
assert.strictEqual(legacySonnetThinking?.id, 'claude-sonnet-4-6');
assert.strictEqual(legacySonnet?.id, 'claude-sonnet-4-6');
});
it('returns undefined for unknown model', () => {
const { findModel } = modelCatalog;
const model = findModel('agy', 'unknown-model');
@@ -269,19 +271,17 @@ describe('Model Catalog', () => {
});
describe('Thinking models ordering', () => {
it('Claude Opus 4.5 Thinking is not deprecated', () => {
it('Claude Opus 4.6 Thinking is not deprecated', () => {
const { MODEL_CATALOG } = modelCatalog;
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-5-thinking');
assert(opus, 'Should include Claude Opus 4.5 Thinking');
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-6-thinking');
assert(opus, 'Should include Claude Opus 4.6 Thinking');
assert.strictEqual(opus.deprecated, undefined, 'Should not be marked as deprecated');
});
it('Claude Sonnet 4.5 Thinking is not deprecated', () => {
it('Claude Sonnet 4.6 is not deprecated', () => {
const { MODEL_CATALOG } = modelCatalog;
const sonnetThinking = MODEL_CATALOG.agy.models.find(
(m) => m.id === 'claude-sonnet-4-5-thinking'
);
assert(sonnetThinking, 'Should include Claude Sonnet 4.5 Thinking');
const sonnetThinking = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-sonnet-4-6');
assert(sonnetThinking, 'Should include Claude Sonnet 4.6');
assert.strictEqual(
sonnetThinking.deprecated,
undefined,
@@ -294,31 +294,27 @@ describe('Model Catalog', () => {
const models = MODEL_CATALOG.agy.models;
// Find indices of thinking models
const opusIdx = models.findIndex((m) => m.id === 'claude-opus-4-5-thinking');
const sonnetThinkingIdx = models.findIndex((m) => m.id === 'claude-sonnet-4-5-thinking');
const opusIdx = models.findIndex((m) => m.id === 'claude-opus-4-6-thinking');
const sonnetThinkingIdx = models.findIndex((m) => m.id === 'claude-sonnet-4-6');
// Find indices of non-thinking models
const sonnetIdx = models.findIndex((m) => m.id === 'claude-sonnet-4-5');
// Find indices of the remaining non-Claude model
const geminiIdx = models.findIndex((m) => m.id === 'gemini-3-pro-preview');
// Thinking models should come before non-thinking models
assert(opusIdx < sonnetIdx, 'Opus Thinking should be above non-thinking Sonnet');
assert(opusIdx < geminiIdx, 'Opus Thinking should be above non-thinking Gemini');
assert(sonnetThinkingIdx < sonnetIdx, 'Sonnet Thinking should be above non-thinking Sonnet');
assert(sonnetThinkingIdx < geminiIdx, 'Sonnet Thinking should be above non-thinking Gemini');
// Primary Claude choices should appear ahead of Gemini fallback.
assert(opusIdx < geminiIdx, 'Opus should be above Gemini');
assert(sonnetThinkingIdx < geminiIdx, 'Sonnet should be above Gemini');
});
});
describe('isModelDeprecated', () => {
it('returns false for thinking models (no longer deprecated)', () => {
it('returns false for active AGY Claude models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'claude-opus-4-5-thinking'), false);
assert.strictEqual(isModelDeprecated('agy', 'claude-sonnet-4-5-thinking'), false);
assert.strictEqual(isModelDeprecated('agy', 'claude-opus-4-6-thinking'), false);
assert.strictEqual(isModelDeprecated('agy', 'claude-sonnet-4-6'), false);
});
it('returns false for non-deprecated models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'claude-sonnet-4-5'), false);
assert.strictEqual(isModelDeprecated('agy', 'gemini-3-pro-preview'), false);
});
@@ -329,15 +325,15 @@ describe('Model Catalog', () => {
});
describe('getModelDeprecationReason', () => {
it('returns undefined for thinking models (no longer deprecated)', () => {
it('returns undefined for active AGY Claude models', () => {
const { getModelDeprecationReason } = modelCatalog;
assert.strictEqual(getModelDeprecationReason('agy', 'claude-opus-4-5-thinking'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'claude-sonnet-4-5-thinking'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'claude-opus-4-6-thinking'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'claude-sonnet-4-6'), undefined);
});
it('returns undefined for non-deprecated models', () => {
const { getModelDeprecationReason } = modelCatalog;
assert.strictEqual(getModelDeprecationReason('agy', 'claude-sonnet-4-5'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'gemini-3-pro-preview'), undefined);
});
});
});
@@ -64,6 +64,13 @@ describe('model-id-normalizer', () => {
expect(normalizeModelIdForProvider('claude-opus-4.6-thinking', 'agy')).toBe(
'claude-opus-4-6-thinking'
);
expect(normalizeModelIdForProvider('claude-opus-4.5-thinking', 'agy')).toBe(
'claude-opus-4-6-thinking'
);
expect(normalizeModelIdForProvider('claude-sonnet-4.5-thinking', 'agy')).toBe(
'claude-sonnet-4-6'
);
expect(normalizeModelIdForProvider('claude-sonnet-4.5', 'agy')).toBe('claude-sonnet-4-6');
expect(normalizeModelIdForProvider('claude-opus-4.6-thinking', 'gemini')).toBe(
'claude-opus-4.6-thinking'
);
@@ -98,9 +105,9 @@ describe('model-id-normalizer', () => {
describe('env normalization', () => {
it('normalizes model env vars for antigravity only', () => {
const input: NodeJS.ProcessEnv = {
ANTHROPIC_MODEL: 'claude-sonnet-4.6-thinking',
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-4.6-thinking',
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-4.6',
ANTHROPIC_MODEL: 'claude-sonnet-4.5-thinking',
ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-4.5-thinking',
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-4.5',
ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-haiku-4.5',
UNRELATED: 'keep-me',
};
@@ -113,7 +120,7 @@ describe('model-id-normalizer', () => {
expect(normalized.UNRELATED).toBe('keep-me');
const unchanged = normalizeModelEnvVarsForProvider(input, 'gemini');
expect(unchanged.ANTHROPIC_MODEL).toBe('claude-sonnet-4.6-thinking');
expect(unchanged.ANTHROPIC_MODEL).toBe('claude-sonnet-4.5-thinking');
expect(unchanged.UNRELATED).toBe('keep-me');
});
});