fix(cliproxy): scope Opus 4.7 rollout to verified providers

This commit is contained in:
Tam Nhu Tran committed 2026-04-20 13:26:53 -04:00
1 parent de0f8b3264
commit 571538dc1c
11 files changed
+29 -113

No files matched your search

+14 -30
View File
@@ -66,21 +66,7 @@ describe('Model Catalog', () => {
describe('AGY models', () => {
it('has correct default model', () => {
const { MODEL_CATALOG } = modelCatalog;
assert.strictEqual(MODEL_CATALOG.agy.defaultModel, 'claude-opus-4-7-thinking');
});
it('includes Claude Opus 4.7 Thinking', () => {
const { MODEL_CATALOG } = modelCatalog;
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-7-thinking');
assert(opus, 'Should include Claude Opus 4.7 Thinking');
assert.strictEqual(opus.name, 'Claude Opus 4.7 Thinking');
});
it('includes Claude Opus 4.7 (non-thinking)', () => {
const { MODEL_CATALOG } = modelCatalog;
const opus = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-opus-4-7');
assert(opus, 'Should include Claude Opus 4.7');
assert.strictEqual(opus.name, 'Claude Opus 4.7');
assert.strictEqual(MODEL_CATALOG.agy.defaultModel, 'claude-opus-4-6-thinking');
});
it('includes Claude Opus 4.6 Thinking', () => {
@@ -131,9 +117,9 @@ describe('Model Catalog', () => {
assert.strictEqual(flash.tier, undefined, 'AGY models should not have paid tier');
});
it('has 7 models total', () => {
it('has 5 models total', () => {
const { MODEL_CATALOG } = modelCatalog;
assert.strictEqual(MODEL_CATALOG.agy.models.length, 7);
assert.strictEqual(MODEL_CATALOG.agy.models.length, 5);
});
});
@@ -291,11 +277,11 @@ describe('Model Catalog', () => {
});
describe('findModel', () => {
it('finds Claude Opus 4.7 Thinking in agy', () => {
it('finds Claude Opus 4.7 in claude', () => {
const { findModel } = modelCatalog;
const model = findModel('agy', 'claude-opus-4-7-thinking');
const model = findModel('claude', 'claude-opus-4-7');
assert(model, 'Should find model');
assert.strictEqual(model.name, 'Claude Opus 4.7 Thinking');
assert.strictEqual(model.name, 'Claude Opus 4.7');
});
it('finds Claude Opus 4.6 Thinking in agy', () => {
@@ -342,10 +328,10 @@ describe('Model Catalog', () => {
it('falls back to the next supported model when the default is excluded', () => {
const { getSuggestedReplacementModel } = modelCatalog;
expect(getSuggestedReplacementModel('agy', 'claude-opus-4-7-thinking')).toBe(
'claude-opus-4-7'
expect(getSuggestedReplacementModel('agy', 'claude-opus-4-6-thinking')).toBe(
'claude-sonnet-4-6'
);
expect(getSuggestedReplacementModel('agy')).toBe('claude-opus-4-7-thinking');
expect(getSuggestedReplacementModel('agy')).toBe('claude-opus-4-6-thinking');
});
it('returns undefined when no provider catalog exists', () => {
@@ -406,10 +392,10 @@ describe('Model Catalog', () => {
});
describe('Thinking models ordering', () => {
it('Claude Opus 4.7 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-7-thinking');
assert(opus, 'Should include Claude Opus 4.7 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');
});
@@ -429,14 +415,14 @@ describe('Model Catalog', () => {
const models = MODEL_CATALOG.agy.models;
// Find indices of thinking models
const opus47Idx = models.findIndex((m) => m.id === 'claude-opus-4-7-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 the remaining non-Claude model
const geminiIdx = models.findIndex((m) => m.id === 'gemini-3.1-pro-high');
// Primary Claude choices should appear ahead of Gemini fallback.
assert(opus47Idx < geminiIdx, 'Opus 4.7 should be above Gemini');
assert(opusIdx < geminiIdx, 'Opus should be above Gemini');
assert(sonnetThinkingIdx < geminiIdx, 'Sonnet should be above Gemini');
});
});
@@ -444,7 +430,6 @@ describe('Model Catalog', () => {
describe('isModelDeprecated', () => {
it('returns false for active AGY Claude models', () => {
const { isModelDeprecated } = modelCatalog;
assert.strictEqual(isModelDeprecated('agy', 'claude-opus-4-7-thinking'), false);
assert.strictEqual(isModelDeprecated('agy', 'claude-opus-4-6-thinking'), false);
assert.strictEqual(isModelDeprecated('agy', 'claude-sonnet-4-6'), false);
});
@@ -463,7 +448,6 @@ describe('Model Catalog', () => {
describe('getModelDeprecationReason', () => {
it('returns undefined for active AGY Claude models', () => {
const { getModelDeprecationReason } = modelCatalog;
assert.strictEqual(getModelDeprecationReason('agy', 'claude-opus-4-7-thinking'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'claude-opus-4-6-thinking'), undefined);
assert.strictEqual(getModelDeprecationReason('agy', 'claude-sonnet-4-6'), undefined);
});
+8
View File
@@ -26,6 +26,13 @@ describe('DEFAULT_CURSOR_MODELS', () => {
expect(providers.has('google')).toBe(true);
});
it('keeps both Claude 4.6 Opus and Claude 4.7 Opus in the fallback catalog', () => {
const ids = DEFAULT_CURSOR_MODELS.map((model) => model.id);
expect(ids).toContain('claude-4.6-opus');
expect(ids).toContain('claude-4.7-opus');
expect(ids).toContain('claude-4.7-opus-fast-mode');
});
it('has exactly one default model', () => {
const defaults = DEFAULT_CURSOR_MODELS.filter((m) => m.isDefault);
expect(defaults).toHaveLength(1);
@@ -88,6 +95,7 @@ describe('detectProvider', () => {
it('detects anthropic models', () => {
expect(detectProvider('claude-4.5-sonnet')).toBe('anthropic');
expect(detectProvider('claude-4.6-opus')).toBe('anthropic');
expect(detectProvider('claude-4.7-opus')).toBe('anthropic');
});
it('detects openai models', () => {
-6
View File
@@ -155,12 +155,6 @@ describe('model-pricing', () => {
expect(opus47.outputPerMillion).toBe(25.0);
});
it('should return correct pricing for Claude Opus 4.7 thinking variant', () => {
const opus47t = getModelPricing('claude-opus-4-7-thinking');
expect(opus47t.inputPerMillion).toBe(5.0);
expect(opus47t.outputPerMillion).toBe(25.0);
});
it('should match date-stamped Claude Opus 4.7 to correct pricing', () => {
const opus47dated = getModelPricing('claude-opus-4-7-20260401');
expect(opus47dated.inputPerMillion).toBe(5.0);