From 67457a30ffb9c816f43498cb503592c96bfdf7a5 Mon Sep 17 00:00:00 2001 From: avaritiachaos <1904382932@qq.com> Date: Thu, 30 Apr 2026 22:55:45 +0800 Subject: [PATCH] Remove legacy DeepSeek model aliases --- packages/types/src/providers/deepseek.ts | 41 +++--------- src/api/providers/__tests__/deepseek.spec.ts | 64 ++++--------------- src/api/providers/deepseek.ts | 8 +-- src/api/providers/openai.ts | 2 +- .../config/__tests__/importExport.spec.ts | 4 +- 5 files changed, 29 insertions(+), 90 deletions(-) diff --git a/packages/types/src/providers/deepseek.ts b/packages/types/src/providers/deepseek.ts index 171d2037c4..6908768a90 100644 --- a/packages/types/src/providers/deepseek.ts +++ b/packages/types/src/providers/deepseek.ts @@ -6,32 +6,9 @@ import type { ModelInfo } from "../model.js" // continuation within the same turn. See: https://api-docs.deepseek.com/guides/thinking_mode export type DeepSeekModelId = keyof typeof deepSeekModels -export const deepSeekDefaultModelId: DeepSeekModelId = "deepseek-chat" +export const deepSeekDefaultModelId: DeepSeekModelId = "deepseek-v4-flash" export const deepSeekModels = { - "deepseek-chat": { - maxTokens: 8192, // 8K max output - contextWindow: 128_000, - supportsImages: false, - supportsPromptCache: true, - inputPrice: 0.28, // $0.28 per million tokens (cache miss) - Updated Dec 9, 2025 - outputPrice: 0.42, // $0.42 per million tokens - Updated Dec 9, 2025 - cacheWritesPrice: 0.28, // $0.28 per million tokens (cache miss) - Updated Dec 9, 2025 - cacheReadsPrice: 0.028, // $0.028 per million tokens (cache hit) - Updated Dec 9, 2025 - description: `DeepSeek-V3.2 (Non-thinking Mode) achieves a significant breakthrough in inference speed over previous models. It tops the leaderboard among open-source models and rivals the most advanced closed-source models globally. Supports JSON output, tool calls, chat prefix completion (beta), and FIM completion (beta).`, - }, - "deepseek-reasoner": { - maxTokens: 8192, // 8K max output - contextWindow: 128_000, - supportsImages: false, - supportsPromptCache: true, - preserveReasoning: true, - inputPrice: 0.28, // $0.28 per million tokens (cache miss) - Updated Dec 9, 2025 - outputPrice: 0.42, // $0.42 per million tokens - Updated Dec 9, 2025 - cacheWritesPrice: 0.28, // $0.28 per million tokens (cache miss) - Updated Dec 9, 2025 - cacheReadsPrice: 0.028, // $0.028 per million tokens (cache hit) - Updated Dec 9, 2025 - description: `DeepSeek-V3.2 (Thinking Mode) achieves performance comparable to OpenAI-o1 across math, code, and reasoning tasks. Supports Chain of Thought reasoning with up to 8K output tokens. Supports JSON output, tool calls, and chat prefix completion (beta).`, - }, "deepseek-v4-flash": { maxTokens: 384_000, // 384K max output contextWindow: 1_000_000, @@ -40,10 +17,10 @@ export const deepSeekModels = { preserveReasoning: true, supportsReasoningEffort: ["disable", "high", "xhigh"], reasoningEffort: "high", - inputPrice: 0.14, // $0.14 per million tokens (cache miss) - Updated Apr 24, 2026 - outputPrice: 0.28, // $0.28 per million tokens - Updated Apr 24, 2026 - cacheWritesPrice: 0.14, // $0.14 per million tokens (cache miss) - Updated Apr 24, 2026 - cacheReadsPrice: 0.0028, // $0.0028 per million tokens (cache hit) - Updated Apr 24, 2026 + inputPrice: 0.14, // $0.14 per million tokens (cache miss) - Updated Apr 30, 2026 + outputPrice: 0.28, // $0.28 per million tokens - Updated Apr 30, 2026 + cacheWritesPrice: 0.14, // $0.14 per million tokens (cache miss) - Updated Apr 30, 2026 + cacheReadsPrice: 0.0028, // $0.0028 per million tokens (cache hit) - Updated Apr 30, 2026 description: `DeepSeek-V4 Flash supports 1M context, 384K max output, tool calls, and thinking/non-thinking modes.`, }, "deepseek-v4-pro": { @@ -54,10 +31,10 @@ export const deepSeekModels = { preserveReasoning: true, supportsReasoningEffort: ["disable", "high", "xhigh"], reasoningEffort: "high", - inputPrice: 0.435, // $0.435 per million tokens (cache miss) - Updated Apr 24, 2026 - outputPrice: 0.87, // $0.87 per million tokens - Updated Apr 24, 2026 - cacheWritesPrice: 0.435, // $0.435 per million tokens (cache miss) - Updated Apr 24, 2026 - cacheReadsPrice: 0.003625, // $0.003625 per million tokens (cache hit) - Updated Apr 24, 2026 + inputPrice: 0.435, // $0.435 per million tokens (cache miss, 75% off until May 31, 2026) - Updated Apr 30, 2026 + outputPrice: 0.87, // $0.87 per million tokens (75% off until May 31, 2026) - Updated Apr 30, 2026 + cacheWritesPrice: 0.435, // $0.435 per million tokens (cache miss, 75% off until May 31, 2026) - Updated Apr 30, 2026 + cacheReadsPrice: 0.003625, // $0.003625 per million tokens (cache hit, 75% off until May 31, 2026) - Updated Apr 30, 2026 description: `DeepSeek-V4 Pro supports 1M context, 384K max output, tool calls, and thinking/non-thinking modes.`, }, } as const satisfies Record diff --git a/src/api/providers/__tests__/deepseek.spec.ts b/src/api/providers/__tests__/deepseek.spec.ts index ea456c9976..52b9e01afb 100644 --- a/src/api/providers/__tests__/deepseek.spec.ts +++ b/src/api/providers/__tests__/deepseek.spec.ts @@ -30,8 +30,7 @@ vi.mock("openai", () => { } // Check if this is a reasoning_content test by looking at model - const isReasonerModel = - options.model?.includes("deepseek-reasoner") || options.model?.includes("deepseek-v4") + const isReasonerModel = options.model?.includes("deepseek-v4") const isToolCallTest = options.tools?.length > 0 // Return async iterator for streaming @@ -136,7 +135,7 @@ describe("DeepSeekHandler", () => { beforeEach(() => { mockOptions = { deepSeekApiKey: "test-api-key", - apiModelId: "deepseek-chat", + apiModelId: "deepseek-v4-flash", deepSeekBaseUrl: "https://api.deepseek.com", } handler = new DeepSeekHandler(mockOptions) @@ -207,22 +206,8 @@ describe("DeepSeekHandler", () => { const model = handler.getModel() expect(model.id).toBe(mockOptions.apiModelId) expect(model.info).toBeDefined() - expect(model.info.maxTokens).toBe(8192) // deepseek-chat has 8K max - expect(model.info.contextWindow).toBe(128_000) - expect(model.info.supportsImages).toBe(false) - expect(model.info.supportsPromptCache).toBe(true) // Should be true now - }) - - it("should return correct model info for deepseek-reasoner", () => { - const handlerWithReasoner = new DeepSeekHandler({ - ...mockOptions, - apiModelId: "deepseek-reasoner", - }) - const model = handlerWithReasoner.getModel() - expect(model.id).toBe("deepseek-reasoner") - expect(model.info).toBeDefined() - expect(model.info.maxTokens).toBe(8192) // deepseek-reasoner has 8K max - expect(model.info.contextWindow).toBe(128_000) + expect(model.info.maxTokens).toBe(384_000) + expect(model.info.contextWindow).toBe(1_000_000) expect(model.info.supportsImages).toBe(false) expect(model.info.supportsPromptCache).toBe(true) }) @@ -249,27 +234,20 @@ describe("DeepSeekHandler", () => { expect(model.info).toBe(expectedInfo) }) - it("should have preserveReasoning enabled for deepseek-reasoner to support interleaved thinking", () => { + it("should have preserveReasoning enabled for DeepSeek V4 models to support interleaved thinking", () => { // This is critical for DeepSeek's interleaved thinking mode with tool calls. // See: https://api-docs.deepseek.com/guides/thinking_mode // The reasoning_content needs to be passed back during tool call continuation // within the same turn for the model to continue reasoning properly. - const handlerWithReasoner = new DeepSeekHandler({ + const handlerWithV4 = new DeepSeekHandler({ ...mockOptions, - apiModelId: "deepseek-reasoner", + apiModelId: "deepseek-v4-pro", }) - const model = handlerWithReasoner.getModel() + const model = handlerWithV4.getModel() // Cast to ModelInfo to access preserveReasoning which is an optional property expect((model.info as ModelInfo).preserveReasoning).toBe(true) }) - it("should NOT have preserveReasoning enabled for deepseek-chat", () => { - // deepseek-chat doesn't use thinking mode, so no need to preserve reasoning - const model = handler.getModel() - // Cast to ModelInfo to access preserveReasoning which is an optional property - expect((model.info as ModelInfo).preserveReasoning).toBeUndefined() - }) - it("should return provided model ID with default model info if model does not exist", () => { const handlerWithInvalidModel = new DeepSeekHandler({ ...mockOptions, @@ -442,10 +420,10 @@ describe("DeepSeekHandler", () => { }, ] - it("should handle reasoning_content in streaming responses for deepseek-reasoner", async () => { + it("should handle reasoning_content in streaming responses for DeepSeek V4", async () => { const reasonerHandler = new DeepSeekHandler({ ...mockOptions, - apiModelId: "deepseek-reasoner", + apiModelId: "deepseek-v4-pro", }) const stream = reasonerHandler.createMessage(systemPrompt, messages) @@ -461,10 +439,10 @@ describe("DeepSeekHandler", () => { expect(reasoningChunks[1].text).toBe(" I'll analyze step by step.") }) - it("should pass thinking parameter for deepseek-reasoner model", async () => { + it("should pass thinking parameter for DeepSeek V4 models", async () => { const reasonerHandler = new DeepSeekHandler({ ...mockOptions, - apiModelId: "deepseek-reasoner", + apiModelId: "deepseek-v4-pro", }) const stream = reasonerHandler.createMessage(systemPrompt, messages) @@ -482,22 +460,6 @@ describe("DeepSeekHandler", () => { ) }) - it("should NOT pass thinking parameter for deepseek-chat model", async () => { - const chatHandler = new DeepSeekHandler({ - ...mockOptions, - apiModelId: "deepseek-chat", - }) - - const stream = chatHandler.createMessage(systemPrompt, messages) - for await (const _chunk of stream) { - // Consume the stream - } - - // Verify that the thinking parameter was NOT passed to the API - const callArgs = mockCreate.mock.calls[0][0] - expect(callArgs.thinking).toBeUndefined() - }) - it("should pass reasoning parameters for DeepSeek V4 models", async () => { const v4Handler = new DeepSeekHandler({ ...mockOptions, @@ -555,7 +517,7 @@ describe("DeepSeekHandler", () => { it("should handle tool calls with reasoning_content", async () => { const reasonerHandler = new DeepSeekHandler({ ...mockOptions, - apiModelId: "deepseek-reasoner", + apiModelId: "deepseek-v4-pro", }) const tools: any[] = [ diff --git a/src/api/providers/deepseek.ts b/src/api/providers/deepseek.ts index 61adabf670..706c774f79 100644 --- a/src/api/providers/deepseek.ts +++ b/src/api/providers/deepseek.ts @@ -56,7 +56,7 @@ export class DeepSeekHandler extends OpenAiHandler { const { info: modelInfo, reasoning } = this.getModel() const isDeepSeekV4Model = modelId.includes("deepseek-v4") - const isThinkingModel = modelId.includes("deepseek-reasoner") || isDeepSeekV4Model + const isThinkingModel = isDeepSeekV4Model const thinkingType = isDeepSeekV4Model && (this.options.reasoningEffort === "disable" || this.options.enableReasoningEffort === false) @@ -68,9 +68,9 @@ export class DeepSeekHandler extends OpenAiHandler { // Convert messages to R1 format (merges consecutive same-role messages) // This is required for DeepSeek which does not support successive messages with the same role - // For thinking models (deepseek-reasoner), enable mergeToolResultText to preserve reasoning_content - // during tool call sequences. Without this, environment_details text after tool_results would - // create user messages that cause DeepSeek to drop all previous reasoning_content. + // For thinking models, enable mergeToolResultText to preserve reasoning_content during tool call + // sequences. Without this, environment_details text after tool_results would create user messages + // that cause DeepSeek to drop all previous reasoning_content. // See: https://api-docs.deepseek.com/guides/thinking_mode const convertedMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages], { mergeToolResultText: isThinkingModel, diff --git a/src/api/providers/openai.ts b/src/api/providers/openai.ts index e1d8f2ccf2..77cb8a0381 100644 --- a/src/api/providers/openai.ts +++ b/src/api/providers/openai.ts @@ -106,7 +106,7 @@ export class OpenAiHandler extends BaseProvider implements SingleCompletionHandl const enabledR1Format = this.options.openAiR1FormatEnabled ?? false const isAzureAiInference = this._isAzureAiInference(modelUrl) const isDeepSeekV4Model = modelId.includes("deepseek-v4") - const usesDeepSeekThinkingParam = modelId.includes("deepseek-reasoner") || isDeepSeekV4Model + const usesDeepSeekThinkingParam = isDeepSeekV4Model const deepseekReasoner = usesDeepSeekThinkingParam || enabledR1Format const deepseekThinkingType = isDeepSeekV4Model && diff --git a/src/core/config/__tests__/importExport.spec.ts b/src/core/config/__tests__/importExport.spec.ts index 9873ffde94..95c39442c3 100644 --- a/src/core/config/__tests__/importExport.spec.ts +++ b/src/core/config/__tests__/importExport.spec.ts @@ -2197,7 +2197,7 @@ describe("importExport", () => { { testCase: "supportsReasoningBudget is false", providerName: "deepseek-provider", - modelId: "deepseek-chat", + modelId: "deepseek-v4-flash", providerId: "deepseek-id", }, { @@ -2209,7 +2209,7 @@ describe("importExport", () => { { testCase: "both supportsReasoningBudget and requiredReasoningBudget are false", providerName: "deepseek-provider-3", - modelId: "deepseek-reasoner", + modelId: "deepseek-v4-pro", providerId: "deepseek-id-3", }, ])(