From dc8318f1cd9fad0721b1cdb269891e57823b8f43 Mon Sep 17 00:00:00 2001 From: Luca Steeb Date: Mon, 27 Apr 2026 13:51:40 +0700 Subject: [PATCH] feat(novita): add deepseek-v4-flash provider mapping Co-Authored-By: Claude Opus 4.7 --- packages/actions/src/prepare-request-body.ts | 14 +++++++++++--- packages/models/src/models/deepseek.ts | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/actions/src/prepare-request-body.ts b/packages/actions/src/prepare-request-body.ts index 2ec3765b20..b26b87727b 100644 --- a/packages/actions/src/prepare-request-body.ts +++ b/packages/actions/src/prepare-request-body.ts @@ -957,9 +957,17 @@ export async function prepareRequestBody( // `reasoning` field back to provider-style `reasoning_content`. DeepSeek // accepts an empty string, but Moonshot's newer reasoning models (kimi-k2.5, // kimi-k2.6) treat an empty string as missing — use a single space as a - // non-empty placeholder there. - if (usedProvider === "deepseek" || usedProvider === "moonshot") { - const fallback = usedProvider === "moonshot" ? " " : ""; + // non-empty placeholder there. Novita proxies DeepSeek V4 with the same + // upstream constraint, so apply the DeepSeek behavior there too. + const isNovitaDeepseekV4 = + usedProvider === "novita" && usedModel.startsWith("deepseek/deepseek-v4"); + if ( + usedProvider === "deepseek" || + usedProvider === "moonshot" || + isNovitaDeepseekV4 + ) { + const fallback = + usedProvider === "moonshot" || isNovitaDeepseekV4 ? " " : ""; processedMessages = processedMessages.map((m) => { if ( m.role !== "assistant" || diff --git a/packages/models/src/models/deepseek.ts b/packages/models/src/models/deepseek.ts index 3ee04074d8..c603af714a 100644 --- a/packages/models/src/models/deepseek.ts +++ b/packages/models/src/models/deepseek.ts @@ -328,6 +328,21 @@ export const deepseekModels = [ "tools", ], }, + { + providerId: "novita", + modelName: "deepseek/deepseek-v4-flash", + inputPrice: 0.14 / 1e6, + cachedInputPrice: 0.028 / 1e6, + outputPrice: 0.28 / 1e6, + requestPrice: 0, + contextSize: 1050000, + maxOutput: 393216, + streaming: true, + reasoning: true, + vision: false, + tools: true, + jsonOutput: true, + }, ], }, ] as const satisfies ModelDefinition[];