diff --git a/.changeset/stale-lizards-poke.md b/.changeset/stale-lizards-poke.md new file mode 100644 index 0000000000..40e3308e8b --- /dev/null +++ b/.changeset/stale-lizards-poke.md @@ -0,0 +1,5 @@ +--- +"claude-dev": minor +--- + +qwen platform adds deepseek-r1/v3 support diff --git a/src/api/providers/qwen.ts b/src/api/providers/qwen.ts index aa4138d09c..26ca03a898 100644 --- a/src/api/providers/qwen.ts +++ b/src/api/providers/qwen.ts @@ -4,6 +4,7 @@ import { ApiHandler } from "../" import { ApiHandlerOptions, QwenModelId, ModelInfo, qwenDefaultModelId, qwenModels } from "../../shared/api" import { convertToOpenAiMessages } from "../transform/openai-format" import { ApiStream } from "../transform/stream" +import { convertToR1Format } from "../transform/r1-format" export class QwenHandler implements ApiHandler { private options: ApiHandlerOptions @@ -34,17 +35,21 @@ export class QwenHandler implements ApiHandler { async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { const model = this.getModel() + const isDeepseekReasoner = model.id.includes("deepseek-r1") let openAiMessages: OpenAI.Chat.ChatCompletionMessageParam[] = [ { role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages), ] - + if (isDeepseekReasoner) { + openAiMessages = convertToR1Format([{ role: "user", content: systemPrompt }, ...messages]) + } const stream = await this.client.chat.completions.create({ model: model.id, max_completion_tokens: model.info.maxTokens, messages: openAiMessages, stream: true, stream_options: { include_usage: true }, + ...(model.id === "deepseek-r1" ? {} : { temperature: 0 }), }) for await (const chunk of stream) { diff --git a/src/shared/api.ts b/src/shared/api.ts index 748fb54e09..1297e6b155 100644 --- a/src/shared/api.ts +++ b/src/shared/api.ts @@ -529,6 +529,26 @@ export const qwenModels = { cacheWritesPrice: 0.0056, cacheReadsPrice: 0.0224, }, + "deepseek-v3": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, + inputPrice: 0, + outputPrice: 0.28, + cacheWritesPrice: 0.14, + cacheReadsPrice: 0.014, + }, + "deepseek-r1": { + maxTokens: 8_000, + contextWindow: 64_000, + supportsImages: false, + supportsPromptCache: true, + inputPrice: 0, + outputPrice: 2.19, + cacheWritesPrice: 0.55, + cacheReadsPrice: 0.14, + }, } as const satisfies Record // Mistral