From ac0186d62f41926c33938e51aa265f3fbc015d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=AD=20Adriano?= Date: Wed, 1 Jul 2026 17:13:41 -0300 Subject: [PATCH 1/3] chore(THU-645): drop Kimi K2.6 --- src/defaults/model-profiles.test.ts | 4 ++-- src/defaults/model-profiles.ts | 1 - src/defaults/model-profiles/index.ts | 3 --- src/defaults/model-profiles/kimi.ts | 32 ---------------------------- src/defaults/models.ts | 22 ------------------- 5 files changed, 2 insertions(+), 60 deletions(-) delete mode 100644 src/defaults/model-profiles/kimi.ts diff --git a/src/defaults/model-profiles.test.ts b/src/defaults/model-profiles.test.ts index 68c279d8f..cb05a6826 100644 --- a/src/defaults/model-profiles.test.ts +++ b/src/defaults/model-profiles.test.ts @@ -77,8 +77,8 @@ describe('hashModelProfile', () => { }) describe('defaultModelProfiles', () => { - test('contains four profiles', () => { - expect(defaultModelProfiles).toHaveLength(4) + test('contains three profiles', () => { + expect(defaultModelProfiles).toHaveLength(3) }) test('each profile has a non-null modelId', () => { diff --git a/src/defaults/model-profiles.ts b/src/defaults/model-profiles.ts index ecca0434f..84acc2556 100644 --- a/src/defaults/model-profiles.ts +++ b/src/defaults/model-profiles.ts @@ -5,7 +5,6 @@ export { defaultModelProfileDeepseekV4Pro, defaultModelProfileGlm52, - defaultModelProfileKimiK26, defaultModelProfileOpus48, defaultModelProfiles, hashModelProfile, diff --git a/src/defaults/model-profiles/index.ts b/src/defaults/model-profiles/index.ts index 5740d2f4e..58a73ce10 100644 --- a/src/defaults/model-profiles/index.ts +++ b/src/defaults/model-profiles/index.ts @@ -6,12 +6,10 @@ import { hashValues } from '@/lib/utils' import type { ModelProfile } from '@/types' import { defaultModelProfileDeepseekV4Pro } from './deepseek' import { defaultModelProfileGlm52 } from './glm' -import { defaultModelProfileKimiK26 } from './kimi' import { defaultModelProfileOpus48 } from './opus' export { defaultModelProfileDeepseekV4Pro } from './deepseek' export { defaultModelProfileGlm52 } from './glm' -export { defaultModelProfileKimiK26 } from './kimi' export { defaultModelProfileOpus48 } from './opus' /** @@ -47,6 +45,5 @@ export const hashModelProfile = (profile: ModelProfile): string => export const defaultModelProfiles: ReadonlyArray = [ defaultModelProfileOpus48, defaultModelProfileDeepseekV4Pro, - defaultModelProfileKimiK26, defaultModelProfileGlm52, ] as const diff --git a/src/defaults/model-profiles/kimi.ts b/src/defaults/model-profiles/kimi.ts deleted file mode 100644 index 55bc4635c..000000000 --- a/src/defaults/model-profiles/kimi.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -import type { ModelProfile } from '@/types' -import { defaultModelKimiK26 } from '@/defaults/models' - -export const defaultModelProfileKimiK26: ModelProfile = { - modelId: defaultModelKimiK26.id, - temperature: 0.2, - maxSteps: 20, - maxAttempts: 2, - nudgeThreshold: 6, - useSystemMessageModeDeveloper: 0, - providerOptions: null, - toolsOverride: null, - linkPreviewsOverride: null, - chatModeAddendum: null, - searchModeAddendum: null, - researchModeAddendum: null, - citationReinforcementEnabled: 0, - citationReinforcementPrompt: null, - nudgeFinalStep: null, - nudgePreventive: null, - nudgeRetry: null, - nudgeSearchFinalStep: null, - nudgeSearchPreventive: null, - nudgeSearchRetry: null, - deletedAt: null, - defaultHash: null, - userId: null, -} diff --git a/src/defaults/models.ts b/src/defaults/models.ts index a667ca798..3104a1654 100644 --- a/src/defaults/models.ts +++ b/src/defaults/models.ts @@ -79,27 +79,6 @@ export const defaultModelDeepseekV4Pro: Model = { userId: null, } -export const defaultModelKimiK26: Model = { - id: '019e7580-2b0c-77d6-8b99-16a99abe4591', - name: 'Kimi K2.6', - provider: 'tinfoil', - model: 'kimi-k2-6', - isSystem: 1, - enabled: 1, - isConfidential: 1, - contextWindow: 131072, - toolUsage: 1, - startWithReasoning: 0, - supportsParallelToolCalls: 0, - deletedAt: null, - apiKey: null, - url: null, - defaultHash: null, - vendor: 'moonshot', - description: 'Confidential chat via Tinfoil', - userId: null, -} - export const defaultModelGlm52: Model = { id: '019e7580-2b0e-719c-a43f-d2b56e7f31b4', name: 'GLM 5.2', @@ -128,6 +107,5 @@ export const defaultModelGlm52: Model = { export const defaultModels: ReadonlyArray = [ defaultModelOpus48, defaultModelDeepseekV4Pro, - defaultModelKimiK26, defaultModelGlm52, ] as const From 51675882f92024bddfa9a4e876b82687e79003a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=AD=20Adriano?= Date: Thu, 2 Jul 2026 07:43:03 -0300 Subject: [PATCH 2/3] feat(THU-645): route DeepSeek V4 Flash through Fireworks --- backend/src/inference/routes.test.ts | 2 +- backend/src/inference/routes.ts | 4 ++++ backend/src/tinfoil/routes.test.ts | 2 +- .../ui/model-selector/model-selector.test.ts | 2 +- src/defaults/model-profiles.ts | 2 +- src/defaults/model-profiles/deepseek.ts | 6 +++--- src/defaults/model-profiles/index.ts | 6 +++--- src/defaults/models.ts | 20 ++++++++++++------- 8 files changed, 27 insertions(+), 17 deletions(-) diff --git a/backend/src/inference/routes.test.ts b/backend/src/inference/routes.test.ts index cbb109b22..591215f3f 100644 --- a/backend/src/inference/routes.test.ts +++ b/backend/src/inference/routes.test.ts @@ -263,7 +263,7 @@ describe('Inference Routes', () => { }) it('should validate all supported models', () => { - const expectedModels = ['mistral-medium-3.1', 'mistral-large-3', 'sonnet-4.5', 'opus-4.8'] + const expectedModels = ['mistral-medium-3.1', 'mistral-large-3', 'sonnet-4.5', 'opus-4.8', 'deepseek-v4-flash'] expect(Object.keys(supportedModels)).toEqual(expectedModels) }) diff --git a/backend/src/inference/routes.ts b/backend/src/inference/routes.ts index 46b02910c..f0799b128 100644 --- a/backend/src/inference/routes.ts +++ b/backend/src/inference/routes.ts @@ -47,6 +47,10 @@ export const supportedModels: Record = { internalName: 'claude-opus-4-8', omitTemperature: true, }, + 'deepseek-v4-flash': { + provider: 'fireworks', + internalName: 'accounts/fireworks/models/deepseek-v4-flash', + }, } /** diff --git a/backend/src/tinfoil/routes.test.ts b/backend/src/tinfoil/routes.test.ts index 4eb12ff51..8a4ae255a 100644 --- a/backend/src/tinfoil/routes.test.ts +++ b/backend/src/tinfoil/routes.test.ts @@ -151,7 +151,7 @@ describe('createTinfoilRoutes', () => { it('forwards JSON bodies untouched (parse: none keeps the stream intact)', async () => { const app = buildApp() - const jsonBody = JSON.stringify({ model: 'deepseek-v4-pro', messages: [] }) + const jsonBody = JSON.stringify({ model: 'glm-5-2', messages: [] }) await drain( await app.handle( diff --git a/src/components/ui/model-selector/model-selector.test.ts b/src/components/ui/model-selector/model-selector.test.ts index 057d81b29..984988cde 100644 --- a/src/components/ui/model-selector/model-selector.test.ts +++ b/src/components/ui/model-selector/model-selector.test.ts @@ -102,7 +102,7 @@ describe('needsApiKey', () => { test('system tinfoil rows do not need a key (injected by backend proxy)', () => { const model = makeModel({ id: 'tinfoil-system', - name: 'DeepSeek V4 Pro', + name: 'GLM 5.2', provider: 'tinfoil', isSystem: 1, apiKey: null, diff --git a/src/defaults/model-profiles.ts b/src/defaults/model-profiles.ts index 84acc2556..f96a286e5 100644 --- a/src/defaults/model-profiles.ts +++ b/src/defaults/model-profiles.ts @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ export { - defaultModelProfileDeepseekV4Pro, + defaultModelProfileDeepseekV4Flash, defaultModelProfileGlm52, defaultModelProfileOpus48, defaultModelProfiles, diff --git a/src/defaults/model-profiles/deepseek.ts b/src/defaults/model-profiles/deepseek.ts index 2bfcc1e31..17eca6352 100644 --- a/src/defaults/model-profiles/deepseek.ts +++ b/src/defaults/model-profiles/deepseek.ts @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import type { ModelProfile } from '@/types' -import { defaultModelDeepseekV4Pro } from '@/defaults/models' +import { defaultModelDeepseekV4Flash } from '@/defaults/models' -export const defaultModelProfileDeepseekV4Pro: ModelProfile = { - modelId: defaultModelDeepseekV4Pro.id, +export const defaultModelProfileDeepseekV4Flash: ModelProfile = { + modelId: defaultModelDeepseekV4Flash.id, temperature: 0.2, maxSteps: 20, maxAttempts: 2, diff --git a/src/defaults/model-profiles/index.ts b/src/defaults/model-profiles/index.ts index 58a73ce10..d4e4e7a11 100644 --- a/src/defaults/model-profiles/index.ts +++ b/src/defaults/model-profiles/index.ts @@ -4,11 +4,11 @@ import { hashValues } from '@/lib/utils' import type { ModelProfile } from '@/types' -import { defaultModelProfileDeepseekV4Pro } from './deepseek' +import { defaultModelProfileDeepseekV4Flash } from './deepseek' import { defaultModelProfileGlm52 } from './glm' import { defaultModelProfileOpus48 } from './opus' -export { defaultModelProfileDeepseekV4Pro } from './deepseek' +export { defaultModelProfileDeepseekV4Flash } from './deepseek' export { defaultModelProfileGlm52 } from './glm' export { defaultModelProfileOpus48 } from './opus' @@ -44,6 +44,6 @@ export const hashModelProfile = (profile: ModelProfile): string => /** All default model profiles for iteration */ export const defaultModelProfiles: ReadonlyArray = [ defaultModelProfileOpus48, - defaultModelProfileDeepseekV4Pro, + defaultModelProfileDeepseekV4Flash, defaultModelProfileGlm52, ] as const diff --git a/src/defaults/models.ts b/src/defaults/models.ts index 3104a1654..67346b68e 100644 --- a/src/defaults/models.ts +++ b/src/defaults/models.ts @@ -58,14 +58,20 @@ export const defaultModelOpus48: Model = { userId: null, } -export const defaultModelDeepseekV4Pro: Model = { +/** + * DeepSeek V4 Flash reuses the row id originally assigned to V4 Pro (Tinfoil). + * Tinfoil is dropping V4 Pro, so unmodified rows are upgraded in place to the + * Fireworks-backed Flash variant routed through the Thunderbolt backend. + * Fireworks doesn't provide TEE isolation, so isConfidential is 0. + */ +export const defaultModelDeepseekV4Flash: Model = { id: '019e70af-e5b2-76d0-9ede-f22d8265bb14', - name: 'DeepSeek V4 Pro', - provider: 'tinfoil', - model: 'deepseek-v4-pro', + name: 'DeepSeek V4 Flash', + provider: 'thunderbolt', + model: 'deepseek-v4-flash', isSystem: 1, enabled: 1, - isConfidential: 1, + isConfidential: 0, contextWindow: 131072, toolUsage: 1, startWithReasoning: 0, @@ -75,7 +81,7 @@ export const defaultModelDeepseekV4Pro: Model = { url: null, defaultHash: null, vendor: 'deepseek', - description: 'Confidential reasoning via Tinfoil', + description: 'Fast DeepSeek reasoning', userId: null, } @@ -106,6 +112,6 @@ export const defaultModelGlm52: Model = { */ export const defaultModels: ReadonlyArray = [ defaultModelOpus48, - defaultModelDeepseekV4Pro, + defaultModelDeepseekV4Flash, defaultModelGlm52, ] as const From 5b3019c9fc98545e748b118d3b9c550bd7825b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=AD=20Adriano?= Date: Thu, 2 Jul 2026 08:03:39 -0300 Subject: [PATCH 3/3] fix(THU-645): assign DeepSeek V4 Flash a fresh id --- src/defaults/models.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/defaults/models.ts b/src/defaults/models.ts index 67346b68e..529720f4b 100644 --- a/src/defaults/models.ts +++ b/src/defaults/models.ts @@ -59,13 +59,15 @@ export const defaultModelOpus48: Model = { } /** - * DeepSeek V4 Flash reuses the row id originally assigned to V4 Pro (Tinfoil). - * Tinfoil is dropping V4 Pro, so unmodified rows are upgraded in place to the - * Fireworks-backed Flash variant routed through the Thunderbolt backend. - * Fireworks doesn't provide TEE isolation, so isConfidential is 0. + * Flash ships under a fresh id — not the retired V4 Pro id. Reusing Pro's id + * would flip isConfidential 1→0 on threads that were created encrypted + * (isEncrypted mirrors the model's isConfidential at creation), stranding them + * because the model picker and send guard both enforce isEncrypted === isConfidential. + * cleanupRemovedDefaults soft-deletes the Pro row instead, so those threads + * surface as "model retired" rather than broken. */ export const defaultModelDeepseekV4Flash: Model = { - id: '019e70af-e5b2-76d0-9ede-f22d8265bb14', + id: '019f227e-d640-727d-ba12-d51bd7d0a3d6', name: 'DeepSeek V4 Flash', provider: 'thunderbolt', model: 'deepseek-v4-flash',