Skip to content

Commit 03a335e

Browse files
authored
[codex] Add DeepSeek V4 Flash to freebuff (#641)
1 parent 550be1e commit 03a335e

20 files changed

Lines changed: 200 additions & 57 deletions

File tree

agents/__tests__/base2.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, test } from 'bun:test'
22

33
import {
4+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
45
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
56
FREEBUFF_KIMI_MODEL_ID,
67
FREEBUFF_MINIMAX_MODEL_ID,
@@ -13,6 +14,7 @@ describe('base2 reviewer selection', () => {
1314
[FREEBUFF_MINIMAX_MODEL_ID, 'code-reviewer-minimax'],
1415
[FREEBUFF_KIMI_MODEL_ID, 'code-reviewer-kimi'],
1516
[FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID, 'code-reviewer-deepseek'],
17+
[FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID, 'code-reviewer-deepseek-flash'],
1618
])('uses matching reviewer for model %p', (model, expectedReviewer) => {
1719
const base2 = createBase2('free', { model })
1820

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID } from '@codebuff/common/constants/freebuff-models'
2+
3+
import { createBase2 } from './base2'
4+
5+
const definition = {
6+
...createBase2('free', {
7+
model: FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
8+
}),
9+
id: 'base2-free-deepseek-flash',
10+
displayName: 'Buffy the DeepSeek Flash Free Orchestrator',
11+
}
12+
13+
export default definition

agents/base2/base2-free-deepseek.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { createBase2 } from './base2'
44

55
const definition = {
66
...createBase2('free', {
7-
noAskUser: true,
87
model: FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
98
}),
109
id: 'base2-free-deepseek',
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID } from '@codebuff/common/constants/freebuff-models'
2+
3+
import { publisher } from '../constants'
4+
import type { SecretAgentDefinition } from '../types/secret-agent-definition'
5+
import { createReviewer } from './code-reviewer'
6+
7+
const definition: SecretAgentDefinition = {
8+
id: 'code-reviewer-deepseek-flash',
9+
publisher,
10+
...createReviewer(FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID),
11+
}
12+
13+
export default definition

agents/types/agent-definition.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ export type ModelName =
417417
// DeepSeek
418418
| 'deepseek/deepseek-v4-pro'
419419
| 'deepseek-v4-pro'
420+
| 'deepseek/deepseek-v4-flash'
421+
| 'deepseek-v4-flash'
420422
| 'deepseek/deepseek-chat-v3-0324'
421423
| 'deepseek/deepseek-chat-v3-0324:nitro'
422424
| 'deepseek/deepseek-r1-0528'

common/src/__tests__/free-agents.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, test } from 'bun:test'
22

33
import {
4+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
45
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
56
FREEBUFF_GEMINI_PRO_MODEL_ID,
67
FREEBUFF_KIMI_MODEL_ID,
@@ -24,6 +25,9 @@ describe('free mode agent model allowlist', () => {
2425
expect(
2526
getFreebuffRootAgentIdForModel(FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID),
2627
).toBe('base2-free-deepseek')
28+
expect(
29+
getFreebuffRootAgentIdForModel(FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID),
30+
).toBe('base2-free-deepseek-flash')
2731
})
2832

2933
test('allows each freebuff root agent only with its configured model', () => {
@@ -48,6 +52,12 @@ describe('free mode agent model allowlist', () => {
4852
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
4953
),
5054
).toBe(true)
55+
expect(
56+
isFreeModeAllowedAgentModel(
57+
'base2-free-deepseek-flash',
58+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
59+
),
60+
).toBe(true)
5161
})
5262

5363
test('allows each freebuff reviewer agent only with its configured model', () => {
@@ -72,6 +82,12 @@ describe('free mode agent model allowlist', () => {
7282
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
7383
),
7484
).toBe(true)
85+
expect(
86+
isFreeModeAllowedAgentModel(
87+
'code-reviewer-deepseek-flash',
88+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
89+
),
90+
).toBe(true)
7591
})
7692

7793
test('allows legacy code-reviewer-lite with freebuff reviewer models', () => {
@@ -90,6 +106,12 @@ describe('free mode agent model allowlist', () => {
90106
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
91107
),
92108
).toBe(true)
109+
expect(
110+
isFreeModeAllowedAgentModel(
111+
'code-reviewer-lite',
112+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
113+
),
114+
).toBe(true)
93115
})
94116

95117
test('allows the browser-use subagent with its bundled model', () => {

common/src/__tests__/freebuff-models.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, expect, test } from 'bun:test'
33
import {
44
canFreebuffModelSpawnGeminiThinker,
55
DEFAULT_FREEBUFF_MODEL_ID,
6+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
67
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
78
FREEBUFF_GLM_MODEL_ID,
89
FREEBUFF_KIMI_MODEL_ID,
@@ -12,6 +13,7 @@ import {
1213
getFreebuffDeploymentAvailabilityLabel,
1314
isFreebuffDeploymentHours,
1415
isFreebuffModelId,
16+
isFreebuffPremiumModelId,
1517
isSupportedFreebuffModelId,
1618
} from '../constants/freebuff-models'
1719

@@ -27,6 +29,16 @@ describe('freebuff model availability', () => {
2729
expect(deepseek?.warning).toBe('Collects data for training')
2830
})
2931

32+
test('DeepSeek V4 Flash is selectable and unlimited', () => {
33+
expect(FREEBUFF_MODELS.map((model) => model.id)).toContain(
34+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
35+
)
36+
expect(isFreebuffModelId(FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID)).toBe(true)
37+
expect(isFreebuffPremiumModelId(FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID)).toBe(
38+
false,
39+
)
40+
})
41+
3042
test('only smart freebuff models can spawn the gemini-thinker subagent', () => {
3143
expect(canFreebuffModelSpawnGeminiThinker(FREEBUFF_KIMI_MODEL_ID)).toBe(
3244
true,
@@ -37,6 +49,9 @@ describe('freebuff model availability', () => {
3749
expect(canFreebuffModelSpawnGeminiThinker(FREEBUFF_MINIMAX_MODEL_ID)).toBe(
3850
false,
3951
)
52+
expect(
53+
canFreebuffModelSpawnGeminiThinker(FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID),
54+
).toBe(false)
4055
})
4156

4257
test('supports GLM 5.1 as a legacy server-side model without selecting it for new clients', () => {

common/src/constants/free-agents.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { parseAgentId } from '../util/agent-id-parsing'
22

33
import { FREEBUFF_GEMINI_THINKER_AGENT_ID } from './freebuff-gemini-thinker'
44
import {
5+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
56
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
67
FREEBUFF_GEMINI_PRO_MODEL_ID,
78
FREEBUFF_GLM_MODEL_ID,
@@ -28,6 +29,7 @@ export const FREEBUFF_ROOT_AGENT_IDS = [
2829
'base2-free',
2930
'base2-free-kimi',
3031
'base2-free-deepseek',
32+
'base2-free-deepseek-flash',
3133
] as const
3234
const FREEBUFF_ROOT_AGENT_ID_SET: ReadonlySet<string> = new Set(
3335
FREEBUFF_ROOT_AGENT_IDS,
@@ -40,12 +42,14 @@ export const FREEBUFF_ROOT_AGENT_ID_BY_MODEL: Record<string, string> = {
4042
[FREEBUFF_MINIMAX_MODEL_ID]: 'base2-free',
4143
[FREEBUFF_KIMI_MODEL_ID]: 'base2-free-kimi',
4244
[FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID]: 'base2-free-deepseek',
45+
[FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID]: 'base2-free-deepseek-flash',
4346
}
4447

4548
export const FREEBUFF_REVIEWER_AGENT_ID_BY_MODEL: Record<string, string> = {
4649
[FREEBUFF_MINIMAX_MODEL_ID]: 'code-reviewer-minimax',
4750
[FREEBUFF_KIMI_MODEL_ID]: 'code-reviewer-kimi',
4851
[FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID]: 'code-reviewer-deepseek',
52+
[FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID]: 'code-reviewer-deepseek-flash',
4953
}
5054

5155
export function getFreebuffRootAgentIdForModel(model: string): string {
@@ -66,10 +70,12 @@ export const FREE_MODE_AGENT_MODELS: Record<string, Set<string>> = {
6670
FREEBUFF_MINIMAX_MODEL_ID,
6771
FREEBUFF_GLM_MODEL_ID,
6872
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
73+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
6974
FREEBUFF_KIMI_MODEL_ID,
7075
]),
7176
'base2-free-kimi': new Set([FREEBUFF_KIMI_MODEL_ID]),
7277
'base2-free-deepseek': new Set([FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID]),
78+
'base2-free-deepseek-flash': new Set([FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID]),
7379

7480
// File exploration agents
7581
'file-picker': new Set(['google/gemini-2.5-flash-lite']),
@@ -93,12 +99,16 @@ export const FREE_MODE_AGENT_MODELS: Record<string, Set<string>> = {
9399
]),
94100
'code-reviewer-kimi': new Set([FREEBUFF_KIMI_MODEL_ID]),
95101
'code-reviewer-deepseek': new Set([FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID]),
102+
'code-reviewer-deepseek-flash': new Set([
103+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
104+
]),
96105
// Legacy freebuff clients spawned code-reviewer-lite under provider-specific
97106
// free roots before those reviewer IDs existed.
98107
'code-reviewer-lite': new Set([
99108
FREEBUFF_MINIMAX_MODEL_ID,
100109
FREEBUFF_KIMI_MODEL_ID,
101110
FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID,
111+
FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
102112
]),
103113

104114
// Legacy: kept for the standalone gemini thinker agent if invoked directly.

common/src/constants/freebuff-models.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface FreebuffModelOption {
3434
export const FREEBUFF_DEPLOYMENT_HOURS_LABEL = '9am ET-5pm PT every day'
3535
export const FREEBUFF_GEMINI_PRO_MODEL_ID = 'google/gemini-3.1-pro-preview'
3636
export const FREEBUFF_DEEPSEEK_V4_PRO_MODEL_ID = 'deepseek/deepseek-v4-pro'
37+
export const FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID = 'deepseek/deepseek-v4-flash'
3738
export const FREEBUFF_GLM_MODEL_ID = 'z-ai/glm-5.1'
3839
export const FREEBUFF_KIMI_MODEL_ID = 'moonshotai/kimi-k2.6'
3940
export const FREEBUFF_MINIMAX_MODEL_ID = 'minimax/minimax-m2.7'
@@ -86,6 +87,12 @@ export const FREEBUFF_MODELS = [
8687
tagline: 'Fastest',
8788
availability: 'always',
8889
},
90+
{
91+
id: FREEBUFF_DEEPSEEK_V4_FLASH_MODEL_ID,
92+
displayName: 'DeepSeek V4 Flash',
93+
tagline: 'Most efficient',
94+
availability: 'always',
95+
},
8996
] as const satisfies readonly FreebuffModelOption[]
9097

9198
export const LEGACY_FREEBUFF_MODELS = [

common/src/constants/model-config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ export const deepseekModels = {
6565
deepseekReasoner: 'deepseek-reasoner',
6666
deepseekV4ProDirect: 'deepseek-v4-pro',
6767
deepseekV4Pro: 'deepseek/deepseek-v4-pro',
68+
deepseekV4FlashDirect: 'deepseek-v4-flash',
69+
deepseekV4Flash: 'deepseek/deepseek-v4-flash',
6870
} as const
6971
export type DeepseekModel = (typeof deepseekModels)[keyof typeof deepseekModels]
7072

0 commit comments

Comments
 (0)