diff --git a/src/web-server/routes/route-helpers.ts b/src/web-server/routes/route-helpers.ts index 7a5e42b2..c5b79a25 100644 --- a/src/web-server/routes/route-helpers.ts +++ b/src/web-server/routes/route-helpers.ts @@ -44,13 +44,17 @@ function resolveProviderForModelCanonicalization( baseUrl: unknown, providerHint: unknown ): CLIProxyProvider | null { + const fromBaseUrl = resolveProviderFromBaseUrl(baseUrl); + if (fromBaseUrl) { + return fromBaseUrl; + } if (typeof providerHint === 'string' && providerHint.trim().length > 0) { const fromProviderHint = mapExternalProviderName(providerHint); if (fromProviderHint) { return fromProviderHint; } } - return resolveProviderFromBaseUrl(baseUrl); + return null; } function getDeniedModelReasonForProvider( diff --git a/tests/unit/web-server/route-helpers-model-denylist.test.ts b/tests/unit/web-server/route-helpers-model-denylist.test.ts index 02aea513..f9df3665 100644 --- a/tests/unit/web-server/route-helpers-model-denylist.test.ts +++ b/tests/unit/web-server/route-helpers-model-denylist.test.ts @@ -67,6 +67,34 @@ describe('route-helpers AGY denylist', () => { ); }); + it('keeps AGY denylist enforcement when CCS_DROID_PROVIDER is present', () => { + const settingsDir = path.join(tempHome, '.ccs'); + fs.mkdirSync(settingsDir, { recursive: true }); + const settingsPath = path.join(settingsDir, 'agy-profile.settings.json'); + fs.writeFileSync( + settingsPath, + JSON.stringify( + { + env: { + ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/agy', + ANTHROPIC_AUTH_TOKEN: 'test-token', + ANTHROPIC_MODEL: 'claude-sonnet-4-6', + ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-opus-4-6-thinking', + ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-sonnet-4-6', + ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-haiku-4-5', + CCS_DROID_PROVIDER: 'anthropic', + }, + }, + null, + 2 + ) + '\n' + ); + + expect(() => updateSettingsFile('agy-profile', { model: 'claude-sonnet-4.5' })).toThrow( + /denylist/i + ); + }); + it('canonicalizes legacy iflow model IDs on settings create', () => { createSettingsFile('iflow-profile', 'http://127.0.0.1:8317/api/provider/iflow', 'test-token', { model: 'kimi-k2.5',