diff --git a/src/models.ts b/src/models.ts index 89d6712..e6f8417 100644 --- a/src/models.ts +++ b/src/models.ts @@ -41,7 +41,13 @@ type Protocol = "openai" | "anthropic"; const PROVIDERS = new Map([ ["openai", { protocol: "openai", npm: "@ai-sdk/openai" }], ["anthropic", { protocol: "anthropic", npm: "@ai-sdk/anthropic" }], - ["deepseek", { protocol: "anthropic", npm: "@ai-sdk/anthropic" }], + // DeepSeek must use Chat Completions, not the Anthropic protocol: the + // Anthropic message format drops reasoning blocks that carry no signature, + // and DeepSeek never issues one. A reasoning-only assistant turn then lowers + // to `content: []` and the API rejects the whole request with "all messages + // must have non-empty content", while `reasoning_content` never survives the + // round-trip that DeepSeek's thinking mode requires. + ["deepseek", { protocol: "openai", npm: "@ai-sdk/openai-compatible" }], ["zai", { protocol: "openai", npm: "@ai-sdk/openai-compatible" }], ["moonshotai", { protocol: "openai", npm: "@ai-sdk/openai-compatible" }], ]); diff --git a/test/index.test.ts b/test/index.test.ts index 6e57118..f14c757 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -80,6 +80,7 @@ const MODELS_DEV_DATA = { output: ["text"], }, cost: { input: 1.5, output: 6, cache_read: 0.15, cache_write: 1.5 }, + interleaved: { field: "reasoning_content" }, }, "deepseek-v4-flash": { id: "deepseek-v4-flash", @@ -99,6 +100,7 @@ const MODELS_DEV_DATA = { cache_read: 0.015, cache_write: 0.15, }, + interleaved: { field: "reasoning_content" }, }, }, }, @@ -217,8 +219,8 @@ describe("config hook", () => { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", provider: { - api: "https://hub.coreinfra.ai/anthropic/api/v1", - npm: "@ai-sdk/anthropic", + api: "https://hub.coreinfra.ai/openai/api/v1", + npm: "@ai-sdk/openai-compatible", }, attachment: false, reasoning: true, @@ -228,18 +230,15 @@ describe("config hook", () => { cost: { input: 1.5, output: 6, cache_read: 0.15, cache_write: 1.5 }, limit: { context: 1000000, output: 384000 }, interleaved: { field: "reasoning_content" }, - headers: { - "anthropic-beta": - "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14", - }, + headers: {}, }); expect(models["deepseek-v4-flash"]).toEqual({ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", provider: { - api: "https://hub.coreinfra.ai/anthropic/api/v1", - npm: "@ai-sdk/anthropic", + api: "https://hub.coreinfra.ai/openai/api/v1", + npm: "@ai-sdk/openai-compatible", }, attachment: false, reasoning: true, @@ -249,10 +248,7 @@ describe("config hook", () => { cost: { input: 0.15, output: 0.6, cache_read: 0.015, cache_write: 0.15 }, limit: { context: 1000000, output: 384000 }, interleaved: { field: "reasoning_content" }, - headers: { - "anthropic-beta": - "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14", - }, + headers: {}, }); }); diff --git a/test/models.test.ts b/test/models.test.ts index 55262c0..388d8d1 100644 --- a/test/models.test.ts +++ b/test/models.test.ts @@ -67,6 +67,7 @@ const MODELS_DEV_FIXTURE = { output: ["text"], }, cost: { input: 1.5, output: 6, cache_read: 0.15, cache_write: 1.5 }, + interleaved: { field: "reasoning_content" }, }, "deepseek-v4-flash": { id: "deepseek-v4-flash", @@ -86,6 +87,7 @@ const MODELS_DEV_FIXTURE = { cache_read: 0.015, cache_write: 0.15, }, + interleaved: { field: "reasoning_content" }, }, }, }, @@ -174,8 +176,8 @@ describe("buildConfigModels", () => { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", provider: { - api: "https://hub.coreinfra.ai/anthropic/api/v1", - npm: "@ai-sdk/anthropic", + api: "https://hub.coreinfra.ai/openai/api/v1", + npm: "@ai-sdk/openai-compatible", }, attachment: false, reasoning: true, @@ -188,10 +190,7 @@ describe("buildConfigModels", () => { cost: { input: 1.5, output: 6, cache_read: 0.15, cache_write: 1.5 }, limit: { context: 1000000, output: 384000 }, interleaved: { field: "reasoning_content" }, - headers: { - "anthropic-beta": - "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14", - }, + headers: {}, }); const dsFlash = models["deepseek-v4-flash"]; @@ -199,8 +198,8 @@ describe("buildConfigModels", () => { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", provider: { - api: "https://hub.coreinfra.ai/anthropic/api/v1", - npm: "@ai-sdk/anthropic", + api: "https://hub.coreinfra.ai/openai/api/v1", + npm: "@ai-sdk/openai-compatible", }, attachment: false, reasoning: true, @@ -213,10 +212,7 @@ describe("buildConfigModels", () => { cost: { input: 0.15, output: 0.6, cache_read: 0.015, cache_write: 0.15 }, limit: { context: 1000000, output: 384000 }, interleaved: { field: "reasoning_content" }, - headers: { - "anthropic-beta": - "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14", - }, + headers: {}, }); });