mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-20 02:17:05 +00:00
fix(cliproxy): scope Opus 4.7 rollout to verified providers
This commit is contained in:
1 parent
de0f8b3264
commit
571538dc1c
11 files changed
+29
-113
No files matched your search
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user