Skip to content

providerCompatMatrix is never applied: thinking field sent to endpoints that reject it #1337

Description

@Mike-7777777

Summary

providerCompatMatrix.ts defines a complete per-provider compatibility layer, but nothing imports it. The request path never applies it, so the fields it exists to strip are still sent.

Evidence

COMPAT_PROFILES and applyCompatRule have no consumers outside their own file:

$ grep -rn "COMPAT_PROFILES\|applyCompatRule" src packages | grep -v providerCompatMatrix
(no output)

compatRule appears only where it is declared — the four built-in providers in loader.ts and the schema in types.ts — never where a request body is built.

What this costs

isOpenAIThinkingEnabled() in requestBody.ts enables thinking from the model name alone:

return modelLower.includes('deepseek') || modelLower.includes('mimo')

That is a claim about the model, not about the endpoint serving it. Azure AI Foundry hosts DeepSeek models under names like DeepSeek-V4-Flash, and its deployment rejects the field:

API Error: 400 Unrecognized request argument supplied: thinking

COMPAT_PROFILES already encodes the right answer — strict-openai has supportsThinkingField: false, and lines 131-142 hold the stripping logic. Wiring it in would have handled this case. OPENAI_ENABLE_THINKING=0 works as a manual override, but it requires the user to first diagnose a 400 from a field they did not know was being sent.

The same gap applies to the profile's other fields: supportsStreamUsageOption and reasoningContentEcho are equally unenforced, so strict endpoints that reject unknown top-level keys will hit the same class of error.

Reproduce

CLAUDE_CODE_USE_OPENAI=1 \
OPENAI_BASE_URL=https://<resource>.openai.azure.com/openai/v1 \
OPENAI_API_KEY=<key> \
OPENAI_MODEL=DeepSeek-V4-Flash \
bun run scripts/dev.ts -p "hi"

Expected: the request succeeds. Actual: HTTP 400 on the thinking argument.

Adding OPENAI_ENABLE_THINKING=0 makes it pass, which confirms the field is the cause.

Suggestion

Call applyCompatRule on the outgoing body in the OpenAI path, resolving the profile from the active provider's compatRule and defaulting to strict-openai for user-defined providers. Auto-detecting capability from a model name cannot be right in general — the same model is served by endpoints that differ in what they accept.

Verified against v2.6.9 and current main; the file is identical in both.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions