Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/packages/opencode/src/provider/transform.ts b/packages/opencode/src/provider/transform.ts
- index 9d98815cda..3ad35e5b2a 100644
- --- a/packages/opencode/src/provider/transform.ts
- +++ b/packages/opencode/src/provider/transform.ts
- @@ -1251,6 +1251,18 @@ export function options(input: {
- result["enable_thinking"] = true
- }
- + // NVIDIA NIM's DeepSeek v4 reasoning models require `chat_template_kwargs` at the
- + // request body root on the openai-compatible transport to stream reasoning_content.
- + // Without it the request hangs indefinitely (see #24264). Keep thinking on even for
- + // the "none" effort variant — NIM hangs when enable_thinking is false.
- + if (
- + input.model.providerID === "nvidia" &&
- + input.model.api.npm === "@ai-sdk/openai-compatible" &&
- + input.model.api.id.toLowerCase().includes("deepseek-v4")
- + ) {
- + result["chat_template_kwargs"] = { thinking: true, enable_thinking: true }
- + }
- +
- if (input.providerOptions?.setCacheKey !== false) {
- if (input.model.api.npm === "@ai-sdk/deepinfra" || input.model.api.npm === "@ai-sdk/cerebras") {
- result["prompt_cache_key"] = input.sessionID
- @@ -1340,6 +1352,17 @@ export function smallOptions(model: Provider.Model) {
- return { veniceParameters: { disableThinking: true } }
- }
- + // NVIDIA NIM's DeepSeek v4 hangs on requests that disable reasoning
- + // (enable_thinking:false), so the title/summary path must keep thinking enabled
- + // even though the first variant would otherwise turn it off (see #24264).
- + if (
- + model.providerID === "nvidia" &&
- + model.api.npm === "@ai-sdk/openai-compatible" &&
- + model.api.id.toLowerCase().includes("deepseek-v4")
- + ) {
- + return { chat_template_kwargs: { thinking: true, enable_thinking: true } }
- + }
- +
- return small
- }
- @@ -1711,6 +1734,17 @@ function reasoningToggle(model: Provider.Model): NonNullable<Provider.Model["var
- }
- function reasoningEffort(model: Provider.Model, effort: string) {
- + // NVIDIA NIM's DeepSeek v4 reads `chat_template_kwargs` (with both `thinking` and
- + // `enable_thinking`) and ignores the generic `reasoningEffort` field, so translate
- + // efforts into the kwarg shape it expects. NIM hangs when thinking is disabled, so
- + // even the "none" effort keeps enable_thinking on.
- + if (
- + model.providerID === "nvidia" &&
- + model.api.npm === "@ai-sdk/openai-compatible" &&
- + model.api.id.toLowerCase().includes("deepseek-v4")
- + ) {
- + return { chat_template_kwargs: { thinking: true, enable_thinking: true } }
- + }
- switch (model.api.npm) {
- case "@openrouter/ai-sdk-provider":
- return { reasoning: { effort } }
- diff --git a/packages/opencode/test/provider/transform.test.ts b/packages/opencode/test/provider/transform.test.ts
- index 9897c543fb..948124c740 100644
- --- a/packages/opencode/test/provider/transform.test.ts
- +++ b/packages/opencode/test/provider/transform.test.ts
- @@ -387,6 +387,63 @@ describe("ProviderTransform.options - minimax m3 thinking", () => {
- })
- })
- +describe("ProviderTransform.options - nvidia deepseek-v4 chat_template_kwargs", () => {
- + const createModel = (apiID: string, reasoning = true) =>
- + ({
- + id: `nvidia/${apiID}`,
- + providerID: "nvidia",
- + api: { id: apiID, url: "https://integrate.api.nvidia.com/v1", npm: "@ai-sdk/openai-compatible" },
- + capabilities: { reasoning },
- + limit: { output: 64_000 },
- + }) as any
- +
- + test.each(["deepseek-ai/deepseek-v4-flash", "deepseek-ai/deepseek-v4-pro"])(
- + "emits default-on chat_template_kwargs for nvidia deepseek-v4 model %s",
- + (apiID) => {
- + expect(
- + ProviderTransform.options({
- + model: createModel(apiID),
- + sessionID: "test-session-123",
- + }).chat_template_kwargs,
- + ).toEqual({ thinking: true, enable_thinking: true })
- + },
- + )
- +
- + test("omits chat_template_kwargs for nvidia reasoning models that are not deepseek-v4", () => {
- + expect(
- + ProviderTransform.options({
- + model: createModel("google/gemma-4-31b-it"),
- + sessionID: "test-session-123",
- + }).chat_template_kwargs,
- + ).toBeUndefined()
- + expect(
- + ProviderTransform.options({
- + model: createModel("mistralai/mistral-medium-3.5-128b"),
- + sessionID: "test-session-123",
- + }).chat_template_kwargs,
- + ).toBeUndefined()
- + })
- +
- + test("omits chat_template_kwargs for non-reasoning nvidia models", () => {
- + expect(
- + ProviderTransform.options({
- + model: createModel("mistralai/mistral-medium-3-instruct", false),
- + sessionID: "test-session-123",
- + }).chat_template_kwargs,
- + ).toBeUndefined()
- + })
- +
- + test("omits chat_template_kwargs for non-nvidia openai-compatible deepseek-v4 models", () => {
- + const model = { ...createModel("deepseek-ai/deepseek-v4-pro"), providerID: "openrouter" }
- + expect(
- + ProviderTransform.options({
- + model,
- + sessionID: "test-session-123",
- + }).chat_template_kwargs,
- + ).toBeUndefined()
- + })
- +})
- +
- describe("ProviderTransform.options - google thinkingConfig gating", () => {
- const sessionID = "test-session-123"
- @@ -3597,6 +3654,35 @@ describe("ProviderTransform.reasoningVariants", () => {
- )
- },
- )
- +
- + test("nvidia deepseek-v4 effort models emit chat_template_kwargs variants with thinking on", () => {
- + const t = {
- + id: "deepseek-ai/deepseek-v4-pro",
- + providerID: "nvidia",
- + api: { id: "deepseek-ai/deepseek-v4-pro", url: "", npm: "@ai-sdk/openai-compatible" },
- + capabilities: { reasoning: true },
- + limit: { output: 64_000 },
- + } as any
- + expect(ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["none", "high", "max"] }]), t)).toEqual({
- + none: { chat_template_kwargs: { thinking: true, enable_thinking: true } },
- + high: { chat_template_kwargs: { thinking: true, enable_thinking: true } },
- + max: { chat_template_kwargs: { thinking: true, enable_thinking: true } },
- + })
- + })
- +
- + test("non-deepseek-v4 nvidia reasoning models keep generic effort variants", () => {
- + const t = {
- + id: "mistralai/mistral-medium-3.5-128b",
- + providerID: "nvidia",
- + api: { id: "mistralai/mistral-medium-3.5-128b", url: "", npm: "@ai-sdk/openai-compatible" },
- + capabilities: { reasoning: true },
- + limit: { output: 64_000 },
- + } as any
- + expect(ProviderTransform.reasoningVariants(model([{ type: "effort", values: ["none", "high"] }]), t)).toEqual({
- + none: { reasoningEffort: "none" },
- + high: { reasoningEffort: "high" },
- + })
- + })
- })
- describe("ProviderTransform.variants", () => {
Advertisement
Add Comment
Please, Sign In to add comment