diff --git a/src/cliproxy/model-catalog.ts b/src/cliproxy/model-catalog.ts index 6c19ab7c..52ec7e62 100644 --- a/src/cliproxy/model-catalog.ts +++ b/src/cliproxy/model-catalog.ts @@ -295,11 +295,13 @@ export const MODEL_CATALOG: Partial> = name: 'Claude Opus 4.7', description: 'Latest flagship model', nativeImageInput: true, + // Opus 4.7 only supports adaptive thinking on the Anthropic API; manual + // thinking.type: "enabled" with budget_tokens is rejected with 400. + // Expose effort levels; the proxy translates these into adaptive effort. thinking: { - type: 'budget', - min: 1024, - max: 128000, - zeroAllowed: false, + type: 'levels', + levels: ['low', 'medium', 'high', 'xhigh'], + maxLevel: 'xhigh', dynamicAllowed: true, }, extendedContext: true, diff --git a/tests/unit/cliproxy/model-catalog.test.js b/tests/unit/cliproxy/model-catalog.test.js index 5023bf32..4f5649b1 100644 --- a/tests/unit/cliproxy/model-catalog.test.js +++ b/tests/unit/cliproxy/model-catalog.test.js @@ -147,9 +147,11 @@ describe('Model Catalog', () => { const opus47 = MODEL_CATALOG.claude.models.find((m) => m.id === 'claude-opus-4-7'); assert(opus47, 'Should include Claude Opus 4.7'); assert.strictEqual(opus47.name, 'Claude Opus 4.7'); - // Claude provider differs from AGY: zero thinking budget is disallowed, - // and extended (1M) context is available on the Anthropic API. - assert.strictEqual(opus47.thinking.zeroAllowed, false); + // Opus 4.7 requires adaptive thinking (type: 'levels'); manual budget_tokens + // is rejected by the Anthropic API with 400. Extended (1M) context is available. + assert.strictEqual(opus47.thinking.type, 'levels'); + assert.deepStrictEqual(opus47.thinking.levels, ['low', 'medium', 'high', 'xhigh']); + assert.strictEqual(opus47.thinking.maxLevel, 'xhigh'); assert.strictEqual(opus47.extendedContext, true); });