Skip to content

Commit 4e11d1d

Browse files
authored
fix: updaet deepseek models (#3082)
1 parent 5e8c661 commit 4e11d1d

4 files changed

Lines changed: 101 additions & 74 deletions

File tree

src/backend/drivers/ai-chat/providers/deepseek/DeepSeekProvider.test.ts

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ describe('DeepSeekProvider construction', () => {
145145
// ── Model catalog ───────────────────────────────────────────────────
146146

147147
describe('DeepSeekProvider model catalog', () => {
148-
it('returns deepseek-chat as the default', () => {
148+
it('returns deepseek-v4-flash as the default', () => {
149149
const { provider } = makeProvider();
150-
expect(provider.getDefaultModel()).toBe('deepseek-chat');
150+
expect(provider.getDefaultModel()).toBe('deepseek-v4-flash');
151151
});
152152

153153
it('exposes the static DEEPSEEK_MODELS list verbatim from models()', () => {
@@ -164,8 +164,10 @@ describe('DeepSeekProvider model catalog', () => {
164164
expect(ids).toContain(a);
165165
}
166166
}
167+
expect(ids).toContain('deepseek-v4-flash');
168+
expect(ids).toContain('deepseek-v4-pro');
167169
expect(ids).toContain('deepseek-chat');
168-
expect(ids).toContain('deepseek/deepseek-chat');
170+
expect(ids).toContain('deepseek/deepseek-v4-pro');
169171
});
170172
});
171173

@@ -188,13 +190,13 @@ describe('DeepSeekProvider.complete request shape', () => {
188190

189191
await withTestActor(() =>
190192
provider.complete({
191-
model: 'deepseek-chat',
193+
model: 'deepseek-v4-flash',
192194
messages: [{ role: 'user', content: 'hello' }],
193195
}),
194196
);
195197

196198
const [args] = createMock.mock.calls[0]!;
197-
expect(args.model).toBe('deepseek-chat');
199+
expect(args.model).toBe('deepseek-v4-flash');
198200
expect(args.messages).toEqual([{ role: 'user', content: 'hello' }]);
199201
expect(args.max_tokens).toBe(1000);
200202
});
@@ -205,7 +207,7 @@ describe('DeepSeekProvider.complete request shape', () => {
205207

206208
await withTestActor(() =>
207209
provider.complete({
208-
model: 'deepseek-chat',
210+
model: 'deepseek-v4-flash',
209211
messages: [{ role: 'user', content: 'hi' }],
210212
max_tokens: 256,
211213
}),
@@ -220,7 +222,7 @@ describe('DeepSeekProvider.complete request shape', () => {
220222

221223
await withTestActor(() =>
222224
provider.complete({
223-
model: 'deepseek-chat',
225+
model: 'deepseek-v4-flash',
224226
messages: [{ role: 'user', content: 'hi' }],
225227
}),
226228
);
@@ -244,7 +246,7 @@ describe('DeepSeekProvider.complete request shape', () => {
244246
];
245247
await withTestActor(() =>
246248
provider.complete({
247-
model: 'deepseek-chat',
249+
model: 'deepseek-v4-flash',
248250
messages: [{ role: 'user', content: 'hi' }],
249251
tools,
250252
}),
@@ -258,7 +260,7 @@ describe('DeepSeekProvider.complete request shape', () => {
258260
createMock.mockResolvedValueOnce(baseCompletion);
259261
await withTestActor(() =>
260262
provider.complete({
261-
model: 'deepseek-chat',
263+
model: 'deepseek-v4-flash',
262264
messages: [{ role: 'user', content: 'hi' }],
263265
stream: false,
264266
}),
@@ -270,7 +272,7 @@ describe('DeepSeekProvider.complete request shape', () => {
270272
createMock.mockReturnValueOnce(asAsyncIterable([]));
271273
await withTestActor(() =>
272274
provider.complete({
273-
model: 'deepseek-chat',
275+
model: 'deepseek-v4-flash',
274276
messages: [{ role: 'user', content: 'hi' }],
275277
stream: true,
276278
}),
@@ -286,7 +288,7 @@ describe('DeepSeekProvider.complete request shape', () => {
286288

287289
await withTestActor(() =>
288290
provider.complete({
289-
model: 'deepseek-chat',
291+
model: 'deepseek-v4-flash',
290292
messages: [
291293
{
292294
role: 'assistant',
@@ -327,7 +329,7 @@ describe('DeepSeekProvider.complete request shape', () => {
327329

328330
await withTestActor(() =>
329331
provider.complete({
330-
model: 'deepseek-chat',
332+
model: 'deepseek-v4-flash',
331333
messages: [
332334
{
333335
role: 'assistant',
@@ -364,7 +366,7 @@ describe('DeepSeekProvider.complete request shape', () => {
364366

365367
await withTestActor(() =>
366368
provider.complete({
367-
model: 'deepseek-chat',
369+
model: 'deepseek-v4-flash',
368370
messages: [
369371
{ role: 'user', content: 'do tool call' },
370372
{
@@ -412,16 +414,16 @@ describe('DeepSeekProvider model resolution', () => {
412414

413415
await withTestActor(() =>
414416
provider.complete({
415-
model: 'deepseek-reasoner',
417+
model: 'deepseek-v4-flash',
416418
messages: [{ role: 'user', content: 'hi' }],
417419
}),
418420
);
419421

420-
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-reasoner');
422+
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-v4-flash');
421423
expect(recordSpy).toHaveBeenCalledWith(
422424
expect.any(Object),
423425
expect.anything(),
424-
'deepseek:deepseek-reasoner',
426+
'deepseek:deepseek-v4-flash',
425427
expect.any(Object),
426428
);
427429
});
@@ -432,17 +434,17 @@ describe('DeepSeekProvider model resolution', () => {
432434

433435
await withTestActor(() =>
434436
provider.complete({
435-
// `deepseek/deepseek-chat` is an alias of `deepseek-chat`.
436-
model: 'deepseek/deepseek-chat',
437+
// `deepseek/deepseek-v4-flash` is an alias of `deepseek-v4-flash`.
438+
model: 'deepseek/deepseek-v4-flash',
437439
messages: [{ role: 'user', content: 'hi' }],
438440
}),
439441
);
440442

441-
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-chat');
443+
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-v4-flash');
442444
expect(recordSpy).toHaveBeenCalledWith(
443445
expect.any(Object),
444446
expect.anything(),
445-
'deepseek:deepseek-chat',
447+
'deepseek:deepseek-v4-flash',
446448
expect.any(Object),
447449
);
448450
});
@@ -458,11 +460,41 @@ describe('DeepSeekProvider model resolution', () => {
458460
}),
459461
);
460462

461-
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-chat');
463+
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-v4-flash');
462464
expect(recordSpy).toHaveBeenCalledWith(
463465
expect.any(Object),
464466
expect.anything(),
465-
'deepseek:deepseek-chat',
467+
'deepseek:deepseek-v4-flash',
468+
expect.any(Object),
469+
);
470+
});
471+
472+
// The legacy DeepSeek chat/reasoner ids (and their `deepseek/…` and
473+
// `deepseek:deepseek/…` variants) are aliased onto deepseek-v4-flash
474+
// so callers using the old names get transparently upgraded — and
475+
// metered against the v4-flash canonical prefix.
476+
it.each([
477+
'deepseek-chat',
478+
'deepseek/deepseek-chat',
479+
'deepseek:deepseek/deepseek-chat',
480+
'deepseek/deepseek-reasoner',
481+
'deepseek:deepseek/deepseek-reasoner',
482+
])('maps legacy alias %s onto deepseek-v4-flash', async (alias) => {
483+
const { provider } = makeProvider();
484+
createMock.mockResolvedValueOnce(baseCompletion);
485+
486+
await withTestActor(() =>
487+
provider.complete({
488+
model: alias,
489+
messages: [{ role: 'user', content: 'hi' }],
490+
}),
491+
);
492+
493+
expect(createMock.mock.calls[0]![0].model).toBe('deepseek-v4-flash');
494+
expect(recordSpy).toHaveBeenCalledWith(
495+
expect.any(Object),
496+
expect.anything(),
497+
'deepseek:deepseek-v4-flash',
466498
expect.any(Object),
467499
);
468500
});
@@ -489,7 +521,7 @@ describe('DeepSeekProvider.complete non-stream output', () => {
489521

490522
const result = await withTestActor(() =>
491523
provider.complete({
492-
model: 'deepseek-chat',
524+
model: 'deepseek-v4-flash',
493525
messages: [{ role: 'user', content: 'hi' }],
494526
}),
495527
);
@@ -504,8 +536,8 @@ describe('DeepSeekProvider.complete non-stream output', () => {
504536
cached_tokens: 10,
505537
});
506538

507-
// deepseek-chat costs: prompt=56, completion=168, cached=0.
508-
const chat = DEEPSEEK_MODELS.find((m) => m.id === 'deepseek-chat')!;
539+
// deepseek-v4-flash costs: prompt=14, completion=28, cached=0.28
540+
const chat = DEEPSEEK_MODELS.find((m) => m.id === 'deepseek-v4-flash')!;
509541
expect(recordSpy).toHaveBeenCalledTimes(1);
510542
const [usage, actor, prefix, overrides] = recordSpy.mock.calls[0]!;
511543
expect(usage).toEqual({
@@ -514,7 +546,7 @@ describe('DeepSeekProvider.complete non-stream output', () => {
514546
cached_tokens: 10,
515547
});
516548
expect(actor).toBe(SYSTEM_ACTOR);
517-
expect(prefix).toBe('deepseek:deepseek-chat');
549+
expect(prefix).toBe('deepseek:deepseek-v4-flash');
518550
expect(overrides).toEqual({
519551
prompt_tokens: 100 * Number(chat.costs.prompt_tokens),
520552
completion_tokens: 50 * Number(chat.costs.completion_tokens),
@@ -549,7 +581,7 @@ describe('DeepSeekProvider.complete non-stream output', () => {
549581

550582
const result = (await withTestActor(() =>
551583
provider.complete({
552-
model: 'deepseek-chat',
584+
model: 'deepseek-v4-flash',
553585
messages: [{ role: 'user', content: 'do a tool call' }],
554586
tools: [
555587
{
@@ -584,7 +616,7 @@ describe('DeepSeekProvider.complete non-stream output', () => {
584616

585617
await withTestActor(() =>
586618
provider.complete({
587-
model: 'deepseek-chat',
619+
model: 'deepseek-v4-flash',
588620
messages: [{ role: 'user', content: 'hi' }],
589621
}),
590622
);
@@ -617,7 +649,7 @@ describe('DeepSeekProvider.complete streaming', () => {
617649

618650
const result = await withTestActor(() =>
619651
provider.complete({
620-
model: 'deepseek-chat',
652+
model: 'deepseek-v4-flash',
621653
messages: [{ role: 'user', content: 'say hi' }],
622654
stream: true,
623655
}),
@@ -642,10 +674,10 @@ describe('DeepSeekProvider.complete streaming', () => {
642674
cached_tokens: 1,
643675
});
644676

645-
const chat = DEEPSEEK_MODELS.find((m) => m.id === 'deepseek-chat')!;
677+
const chat = DEEPSEEK_MODELS.find((m) => m.id === 'deepseek-v4-flash')!;
646678
expect(recordSpy).toHaveBeenCalledTimes(1);
647679
const [, , prefix, overrides] = recordSpy.mock.calls[0]!;
648-
expect(prefix).toBe('deepseek:deepseek-chat');
680+
expect(prefix).toBe('deepseek:deepseek-v4-flash');
649681
expect(overrides).toEqual({
650682
prompt_tokens: 4 * Number(chat.costs.prompt_tokens),
651683
completion_tokens: 2 * Number(chat.costs.completion_tokens),
@@ -698,7 +730,7 @@ describe('DeepSeekProvider.complete streaming', () => {
698730

699731
const result = await withTestActor(() =>
700732
provider.complete({
701-
model: 'deepseek-chat',
733+
model: 'deepseek-v4-flash',
702734
messages: [{ role: 'user', content: 'do tool call' }],
703735
tools: [
704736
{
@@ -737,7 +769,7 @@ describe('DeepSeekProvider.complete error mapping', () => {
737769
await expect(
738770
withTestActor(() =>
739771
provider.complete({
740-
model: 'deepseek-chat',
772+
model: 'deepseek-v4-flash',
741773
messages: [{ role: 'user', content: 'boom' }],
742774
}),
743775
),

src/backend/drivers/ai-chat/providers/deepseek/DeepSeekProvider.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class DeepSeekProvider implements IChatProvider {
4040
}
4141

4242
getDefaultModel() {
43-
return 'deepseek-chat';
43+
return 'deepseek-v4-flash';
4444
}
4545

4646
models() {
@@ -137,20 +137,18 @@ export class DeepSeekProvider implements IChatProvider {
137137
);
138138
this.#meteringService.utilRecordUsageObject(
139139
trackedUsage,
140-
actor,
140+
actor!,
141141
`deepseek:${modelUsed.id}`,
142142
costsOverrideFromModel,
143143
);
144144
return trackedUsage;
145145
},
146-
stream,
146+
stream: stream,
147147
completion,
148148
});
149149
}
150150

151-
checkModeration(
152-
_text: string,
153-
): ReturnType<IChatProvider['checkModeration']> {
151+
checkModeration(_text: string) {
154152
throw new Error('Method not implemented.');
155153
}
156154
}

src/backend/drivers/ai-chat/providers/deepseek/models.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,47 +22,54 @@ import type { IChatModel } from '../../types.js';
2222
// Hardcoded from https://models.dev/api.json
2323
export const DEEPSEEK_MODELS: IChatModel[] = [
2424
{
25-
puterId: 'deepseek:deepseek/deepseek-chat',
26-
id: 'deepseek-chat',
25+
puterId: 'deepseek:deepseek/deepseek-v4-flash',
26+
id: 'deepseek-v4-flash',
2727
modalities: { input: ['text'], output: ['text'] },
2828
open_weights: false,
2929
tool_call: true,
30-
knowledge: '2024-07',
31-
release_date: '2024-12-26',
30+
knowledge: '2026-04',
31+
release_date: '2026-04-24',
3232
name: 'DeepSeek Chat',
33-
aliases: ['deepseek/deepseek-chat'],
34-
context: 128000,
33+
aliases: [
34+
'deepseek-v4-flash',
35+
'deepseek-chat',
36+
'deepseek/deepseek-chat',
37+
'deepseek/deepseek-reasoner',
38+
'deepseek:deepseek/deepseek-reasoner',
39+
'deepseek:deepseek/deepseek-chat',
40+
],
41+
context: 1_000_000,
3542
costs_currency: 'usd-cents',
3643
input_cost_key: 'prompt_tokens',
3744
output_cost_key: 'completion_tokens',
3845
costs: {
3946
tokens: 1_000_000,
40-
prompt_tokens: 56,
41-
completion_tokens: 168,
42-
cached_tokens: 0,
47+
prompt_tokens: 14,
48+
completion_tokens: 28,
49+
cached_tokens: 0.28,
4350
},
44-
max_tokens: 8000,
51+
max_tokens: 384_000,
4552
},
4653
{
47-
puterId: 'deepseek:deepseek/deepseek-reasoner',
48-
id: 'deepseek-reasoner',
54+
puterId: 'deepseek:deepseek/deepseek-v4-pro',
55+
id: 'deepseek-v4-pro',
4956
modalities: { input: ['text'], output: ['text'] },
5057
open_weights: false,
5158
tool_call: true,
52-
knowledge: '2024-07',
53-
release_date: '2025-01-20',
54-
name: 'DeepSeek Reasoner',
55-
aliases: ['deepseek/deepseek-reasoner'],
56-
context: 128000,
59+
knowledge: '2026-04',
60+
release_date: '2026-04-24',
61+
name: 'DeepSeek Chat',
62+
aliases: ['deepseek/deepseek-v4-pro', 'deepseek-v4-pro'],
63+
context: 1_000_000,
5764
costs_currency: 'usd-cents',
5865
input_cost_key: 'prompt_tokens',
5966
output_cost_key: 'completion_tokens',
6067
costs: {
6168
tokens: 1_000_000,
62-
prompt_tokens: 56,
63-
completion_tokens: 168,
64-
cached_tokens: 0,
69+
prompt_tokens: 174,
70+
completion_tokens: 348,
71+
cached_tokens: 1.45,
6572
},
66-
max_tokens: 64000,
73+
max_tokens: 384_000,
6774
},
6875
];

0 commit comments

Comments
 (0)