Remove legacy DeepSeek model aliases

This commit is contained in:
avaritiachaos 2026-04-30 22:55:45 +08:00
parent e882b9ddcc
commit 67457a30ff
5 changed files with 29 additions and 90 deletions

View file

@ -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<string, ModelInfo>

View file

@ -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[] = [

View file

@ -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,

View file

@ -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 &&

View file

@ -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",
},
])(