Skip to content

[Bug]: requiresReasoningContentOnAssistantMessages missing from ModelCompatSchema — can't replicate native DeepSeek behavior on custom providers #89660

@kyKKK

Description

@kyKKK

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

requiresReasoningContentOnAssistantMessages is used at runtime in detectCompat() / getCompat() to control whether reasoning_content: "" is injected on assistant messages (required by DeepSeek's API). However, this field is not in the Zod ModelCompatSchema, so setting it in user config triggers a .strict() validation error on gateway startup.

This makes it impossible to fully replicate native DeepSeek provider behavior on a custom OpenAI-compatible proxy.

Steps to reproduce

Configure a custom provider pointing to a DeepSeek-compatible proxy:

{
  "models": {
    "providers": {
      "my-proxy": {
        "baseUrl": "https://my-proxy.example.com/v1",
        "models": [
          {
            "id": "deepseek-v4-pro",
            "reasoning": true,
            "compat": {
              "thinkingFormat": "deepseek",
              "requiresReasoningContentOnAssistantMessages": true
            }
          }
        ]
      }
    }
  }
}

Expected: Config accepted, runtime behavior matches native deepseek provider.

Actual: Gateway rejects with Unrecognized key(s) in object: 'requiresReasoningContentOnAssistantMessages' because ModelCompatSchema is .strict() and doesn't include this field.

Setting thinkingFormat: "deepseek" works (it IS in the schema) and correctly triggers the thinking block + reasoning_effort. But the requiresReasoningContentOnAssistantMessages flag, which controls this behavior in convertMessages(), cannot be toggled by users:

// openai-completions.ts

if (compat.requiresReasoningContentOnAssistantMessages && model.reasoning
    && assistantMsg.reasoning_content === undefined) {
    assistantMsg.reasoning_content = "";
}

Currently this flag is only true when detectCompat sees provider === "deepseek" || baseUrl.includes("deepseek.com"). Custom providers never match.


Root Cause

ModelCompatSchema in zod-schema.core.ts doesn't include requiresReasoningContentOnAssistantMessages. The .strict() modifier rejects any unrecognized key.


Suggested Fix

 const ModelCompatSchema = object({
     // ... existing fields ...
+    requiresReasoningContentOnAssistantMessages: boolean().optional(),
 }).strict().optional();

Additional missing fields (minor)

While here, these compat fields also exist in getCompat() but are missing from the schema:

cacheControlFormat (string | undefined)
sendSessionAffinityHeaders (boolean)
supportsLongCacheRetention (boolean)
zaiToolStream (boolean)
openRouterRouting (object)
vercelGatewayRouting (object)

Expected behavior

Configuring a custom OpenAI-compatible provider with:
"compat": { "requiresReasoningContentOnAssistantMessages": true }
should be accepted and cause assistant messages to include reasoning_content: ""

Actual behavior

Gateway startup fails with:
Unrecognized key(s) in object: 'requiresReasoningContentOnAssistantMessages'
because ModelCompatSchema is .strict() and does not include this field.

OpenClaw version

2026.5.28

Operating system

Linux (Ubuntu)

Install method

npm global

Model

deepseek-v4-pro

Provider / routing chain

Custom provider (e.g. Tencent TokenHub / tencentmaas-deepseek) → DeepSeek-compatible API

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Impact and severity

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.bugSomething isn't workingbug:behaviorIncorrect behavior without a crashclawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions