From 2e9de070905cd36fa86e4d1f836d18261089695a Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 20 Aug 2026 19:54:39 +0000 Subject: [PATCH 1/4] fix(ai-gateway): disable DeepSeek discounted models Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- apps/web/src/lib/ai-gateway/providers/deepseek.ts | 5 +++-- apps/web/src/lib/ai-gateway/unavailable-models.ts | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/providers/deepseek.ts b/apps/web/src/lib/ai-gateway/providers/deepseek.ts index 1f7a375b78..377fba7b6d 100644 --- a/apps/web/src/lib/ai-gateway/providers/deepseek.ts +++ b/apps/web/src/lib/ai-gateway/providers/deepseek.ts @@ -4,13 +4,14 @@ export function isDeepseekModel(model: string) { return model.includes('deepseek'); } +// DeepSeek now uses time-of-day based pricing, which our static pricing catalog does not support. export const deepseek_v4_pro_discounted_model: KiloExclusiveModel = { public_id: 'deepseek/deepseek-v4-pro:discounted', internal_id: 'deepseek/deepseek-v4-pro-0813', display_name: 'DeepSeek: DeepSeek V4 Pro 0813 (lowest price)', description: 'This DeepSeek V4 Pro 0813 endpoint provides the lowest cost for multi-turn conversations for this model. This is accomplished with an exceptionally low cache read price. By using this endpoint you agree prompts and completions may be retained by DeepSeek and used to train future models.', - status: 'public', + status: 'disabled', context_length: 1048576, max_completion_tokens: 384000, gateway: 'openrouter', @@ -37,7 +38,7 @@ const deepseek_v4_flash_discounted_model: KiloExclusiveModel = { display_name: 'DeepSeek: DeepSeek V4 Flash 0731 (lowest price)', description: 'This DeepSeek V4 Flash 0731 endpoint provides the lowest cost for multi-turn conversations for this model. This is accomplished with an exceptionally low cache read price. By using this endpoint you agree prompts and completions may be retained by DeepSeek and used to train future models.', - status: 'public', + status: 'disabled', context_length: 1048576, max_completion_tokens: 384000, gateway: 'openrouter', diff --git a/apps/web/src/lib/ai-gateway/unavailable-models.ts b/apps/web/src/lib/ai-gateway/unavailable-models.ts index 4a0c319eef..1768b834a2 100644 --- a/apps/web/src/lib/ai-gateway/unavailable-models.ts +++ b/apps/web/src/lib/ai-gateway/unavailable-models.ts @@ -1,6 +1,8 @@ import { normalizeModelId } from '@/lib/ai-gateway/model-utils'; const unavailableModelIds: ReadonlySet = new Set([ + 'deepseek/deepseek-v4-flash:discounted', + 'deepseek/deepseek-v4-pro:discounted', 'google/gemma-4-26b-a4b-it:free', // usable through kilo-auto 'google/gemma-4-31b-it:free', 'nvidia/nemotron-3-nano-30b-a3b:free', From 4f985fb060b4741501057d906d4c5b6133dc6cf5 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 20 Aug 2026 19:57:54 +0000 Subject: [PATCH 2/4] fix(ai-gateway): rely on disabled model rejection Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- apps/web/src/lib/ai-gateway/unavailable-models.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/unavailable-models.ts b/apps/web/src/lib/ai-gateway/unavailable-models.ts index 1768b834a2..4a0c319eef 100644 --- a/apps/web/src/lib/ai-gateway/unavailable-models.ts +++ b/apps/web/src/lib/ai-gateway/unavailable-models.ts @@ -1,8 +1,6 @@ import { normalizeModelId } from '@/lib/ai-gateway/model-utils'; const unavailableModelIds: ReadonlySet = new Set([ - 'deepseek/deepseek-v4-flash:discounted', - 'deepseek/deepseek-v4-pro:discounted', 'google/gemma-4-26b-a4b-it:free', // usable through kilo-auto 'google/gemma-4-31b-it:free', 'nvidia/nemotron-3-nano-30b-a3b:free', From c75115c61742d2c7a5c313b769a174331b56fd34 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 20 Aug 2026 20:10:05 +0000 Subject: [PATCH 3/4] test(ai-gateway): use active exclusive model fixtures Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- apps/web/src/lib/ai-gateway/models.test.ts | 6 ++--- .../balance-check-eligibility.test.ts | 2 +- .../balance-check-eligibility.ts | 2 +- apps/web/src/lib/model-allow.server.test.ts | 18 +++++++------- .../effective-model-access.server.test.ts | 24 +++++++++---------- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/web/src/lib/ai-gateway/models.test.ts b/apps/web/src/lib/ai-gateway/models.test.ts index 0a10b4a14e..06cbb3a361 100644 --- a/apps/web/src/lib/ai-gateway/models.test.ts +++ b/apps/web/src/lib/ai-gateway/models.test.ts @@ -377,9 +377,6 @@ describe('shouldRedactModelNameInMicrodollarUsage', () => { describe('getKiloExclusiveInferenceProviderRestriction', () => { test('returns the routing allow-list for restricted exclusive models', () => { - expect( - getKiloExclusiveInferenceProviderRestriction(deepseek_v4_pro_discounted_model.public_id) - ).toEqual(new Set(['deepseek'])); expect( getKiloExclusiveInferenceProviderRestriction(gpt_5_6_sol_discounted_model.public_id) ).toEqual(new Set(['openai'])); @@ -389,6 +386,9 @@ describe('getKiloExclusiveInferenceProviderRestriction', () => { }); test('does not treat unrestricted exclusives or unknown ids as restricted', () => { + expect( + getKiloExclusiveInferenceProviderRestriction(deepseek_v4_pro_discounted_model.public_id) + ).toBeUndefined(); expect(getKiloExclusiveInferenceProviderRestriction(gpt_5_6_sol_stealth_model.public_id)).toBe( undefined ); diff --git a/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.test.ts b/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.test.ts index 0f4dcdba23..551b025059 100644 --- a/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.test.ts +++ b/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.test.ts @@ -16,7 +16,7 @@ jest.mock('@/lib/ai-gateway/byok', () => ({ import { computeCloudAgentNextBalanceCheckEligibility } from './balance-check-eligibility'; -const KILO_EXCLUSIVE_MODEL = 'deepseek/deepseek-v4-pro:discounted'; +const KILO_EXCLUSIVE_MODEL = 'openai/gpt-5.6-sol-discounted'; const NON_EXCLUSIVE_MODEL = 'anthropic/claude-sonnet-4'; const fakeDb = {} as never; diff --git a/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.ts b/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.ts index fd3d6c0ac5..052f475b81 100644 --- a/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.ts +++ b/apps/web/src/lib/cloud-agent-next/balance-check-eligibility.ts @@ -24,7 +24,7 @@ export type BalanceCheckModelEligibility = { * configured that can serve it, so the session is billed against the * user's own key rather than their balance. * - * Kilo-exclusive models (e.g. `deepseek/deepseek-v4-pro:discounted`) are + * Kilo-exclusive models (e.g. `openai/gpt-5.6-sol-discounted`) are * always excluded from the BYOK bypass: they are Kilo-funded and platform * billed, so even when `getModelUserByokProviders` reports a provider that * can route the model, they must still go through the worker-side balance diff --git a/apps/web/src/lib/model-allow.server.test.ts b/apps/web/src/lib/model-allow.server.test.ts index 8949acf8ee..220d306ea9 100644 --- a/apps/web/src/lib/model-allow.server.test.ts +++ b/apps/web/src/lib/model-allow.server.test.ts @@ -155,32 +155,32 @@ describe('model access predicates', () => { test('provider allow list hides restricted exclusive models when every restricted provider is disabled', async () => { const isAllowed = createAllowPredicateFromProviderAllowList( undefined, - ['openai', 'fireworks'], - lookup({ 'deepseek/deepseek-v4-pro': ['fireworks', 'deepseek'] }) + ['deepseek', 'fireworks'], + lookup({ 'openai/gpt-5.6-sol': ['fireworks', 'openai'] }) ); - await expect(isAllowed('deepseek/deepseek-v4-pro:discounted')).resolves.toBe(false); - await expect(isAllowed('deepseek/deepseek-v4-pro')).resolves.toBe(true); + await expect(isAllowed('openai/gpt-5.6-sol-discounted')).resolves.toBe(false); + await expect(isAllowed('openai/gpt-5.6-sol')).resolves.toBe(true); }); test('provider allow list keeps restricted exclusive models when a restricted provider remains enabled', async () => { const isAllowed = createAllowPredicateFromProviderAllowList( undefined, - ['openai', 'deepseek'], - lookup({ 'deepseek/deepseek-v4-pro': ['fireworks'] }) + ['openai', 'fireworks'], + lookup({ 'openai/gpt-5.6-sol': ['fireworks'] }) ); - await expect(isAllowed('deepseek/deepseek-v4-pro:discounted')).resolves.toBe(true); + await expect(isAllowed('openai/gpt-5.6-sol-discounted')).resolves.toBe(true); }); test('provider allow list still evaluates restricted exclusive models missing from the snapshot', async () => { const isAllowed = createAllowPredicateFromProviderAllowList( undefined, - ['deepseek'], + ['openai'], lookup({}) ); - await expect(isAllowed('deepseek/deepseek-v4-pro:discounted')).resolves.toBe(true); + await expect(isAllowed('openai/gpt-5.6-sol-discounted')).resolves.toBe(true); await expect(isAllowed('stealth/gpt-5.6-sol')).resolves.toBe(false); }); }); diff --git a/apps/web/src/lib/organizations/effective-model-access.server.test.ts b/apps/web/src/lib/organizations/effective-model-access.server.test.ts index 43deaef337..e3e6913b9d 100644 --- a/apps/web/src/lib/organizations/effective-model-access.server.test.ts +++ b/apps/web/src/lib/organizations/effective-model-access.server.test.ts @@ -263,15 +263,15 @@ describe('effective organization model access', () => { context({ organization: { ...context().organization, - settings: { provider_allow_list: ['openai', 'fireworks'], model_deny_list: [] }, + settings: { provider_allow_list: ['deepseek', 'fireworks'], model_deny_list: [] }, }, defaultPolicies: [{ type: 'model_access', data: { mode: 'all' } }], }) ); - const catalogLookup = async () => new Set(['fireworks', 'deepseek']); + const catalogLookup = async () => new Set(['fireworks', 'openai']); expect( - await getEffectiveModelDecision(policy, 'deepseek/deepseek-v4-pro:discounted', catalogLookup) + await getEffectiveModelDecision(policy, 'openai/gpt-5.6-sol-discounted', catalogLookup) ).toEqual({ allowed: false, denialSource: 'organization_provider' }); }); @@ -280,19 +280,19 @@ describe('effective organization model access', () => { context({ organization: { ...context().organization, - settings: { provider_allow_list: ['openai', 'deepseek'], model_deny_list: [] }, + settings: { provider_allow_list: ['openai', 'fireworks'], model_deny_list: [] }, }, defaultPolicies: [{ type: 'model_access', data: { mode: 'all' } }], }) ); const decision = await getEffectiveModelDecision( policy, - 'deepseek/deepseek-v4-pro:discounted', + 'openai/gpt-5.6-sol-discounted', async () => new Set(['fireworks']) ); expect(decision.allowed).toBe(true); - expect([...decision.eligibleProviderRoutes!]).toEqual(['deepseek']); + expect([...decision.eligibleProviderRoutes!]).toEqual(['openai']); }); it('does not apply exclusive restrictions to the unsuffixed catalog model', async () => { @@ -305,16 +305,16 @@ describe('effective organization model access', () => { defaultPolicies: [{ type: 'model_access', data: { mode: 'all' } }], }) ); - const catalogLookup = async () => new Set(['fireworks', 'deepseek']); + const catalogLookup = async () => new Set(['fireworks', 'openai']); const exclusive = await getEffectiveModelDecision( policy, - 'deepseek/deepseek-v4-pro:discounted', + 'openai/gpt-5.6-sol-discounted', catalogLookup ); const catalogModel = await getEffectiveModelDecision( policy, - 'deepseek/deepseek-v4-pro', + 'openai/gpt-5.6-sol', catalogLookup ); @@ -328,7 +328,7 @@ describe('effective organization model access', () => { context({ organization: { ...context().organization, - settings: { provider_allow_list: ['openai', 'deepseek'], model_deny_list: [] }, + settings: { provider_allow_list: ['openai'], model_deny_list: [] }, }, defaultPolicies: [{ type: 'model_access', data: { mode: 'all' } }], }) @@ -337,7 +337,7 @@ describe('effective organization model access', () => { const restricted = await getEffectiveModelDecision( policy, - 'deepseek/deepseek-v4-pro:discounted', + 'openai/gpt-5.6-sol-discounted', emptySnapshot ); const unrestricted = await getEffectiveModelDecision( @@ -347,7 +347,7 @@ describe('effective organization model access', () => { ); expect(restricted.allowed).toBe(true); - expect([...restricted.eligibleProviderRoutes!]).toEqual(['deepseek']); + expect([...restricted.eligibleProviderRoutes!]).toEqual(['openai']); expect(unrestricted).toEqual({ allowed: false, denialSource: 'organization_model' }); }); }); From e67711fd99b29d1b26be03535bd417e1ee5c8da2 Mon Sep 17 00:00:00 2001 From: chrarnoldus <12196001+chrarnoldus@users.noreply.github.com> Date: Thu, 20 Aug 2026 20:12:51 +0000 Subject: [PATCH 4/4] style(ai-gateway): format exclusive model fixture Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com> --- apps/web/src/lib/model-allow.server.test.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/web/src/lib/model-allow.server.test.ts b/apps/web/src/lib/model-allow.server.test.ts index 220d306ea9..a628a57864 100644 --- a/apps/web/src/lib/model-allow.server.test.ts +++ b/apps/web/src/lib/model-allow.server.test.ts @@ -174,11 +174,7 @@ describe('model access predicates', () => { }); test('provider allow list still evaluates restricted exclusive models missing from the snapshot', async () => { - const isAllowed = createAllowPredicateFromProviderAllowList( - undefined, - ['openai'], - lookup({}) - ); + const isAllowed = createAllowPredicateFromProviderAllowList(undefined, ['openai'], lookup({})); await expect(isAllowed('openai/gpt-5.6-sol-discounted')).resolves.toBe(true); await expect(isAllowed('stealth/gpt-5.6-sol')).resolves.toBe(false);