Repository navigation
Description
fix(ai): DeepSeek models behind multi-family gateways get the wrong max-tokens field and a store flag — #1731's family classifier omits deepseek
Follow-up to #1706 (closed by PR #1731). #1706's own survey named DeepSeek as one of the families fronted by the multi-family gateways (cline-pass, opendesign, opencode-go), but the family classifier PR #1731 added covers only GLM / Kimi / Gemini, so DeepSeek models behind those gateways still get the generic defaults instead of the direct-DeepSeek decisions.
Evidence (main 736273e, PR #1731 merge)
packages/ai/src/protocols/openai-chat.ts:
detectModelFamily(:696-704) —type ModelFamily = "glm" | "kimi" | "gemini"; no deepseek.detectMaxTokensField(:710-717) — family glm/kimi short-circuit tomax_tokens; DeepSeek reachesmax_tokensonly viap === "deepseek"or adeepseek.combaseURL, neither of which holds behind a gateway. The function's own comment (:706-709) states DeepSeek "still require[s]max_tokens".detectSupportsStore(:747-764) — the direct-DeepSeek case is in the non-standard set (isDeepSeek, :764) so direct requests omitstore; the family short-circuit (:751) covers only the three recognized families, so a gateway DeepSeek model getssupportsStore = true.- Precedent in the same file:
requireReasoning(:571-575) already detects DeepSeek by model id (modelID.includes("deepseek")), because the direct/gateway distinction was already known to matter there.
Reproduction (laptop probe, this run)
Probe test through the same compileRequest harness PR #1731's tests use (packages/ai/test/provider/openai-chat.test.ts), comparing the direct deepseek provider (https://api.deepseek.com/v1) against cline-pass / opendesign / opencode-go (gateway baseURL), generation maxTokens: 20, one tool:
| model id | direct deepseek | behind each of the 3 gateways |
|---|---|---|
deepseek-chat |
max_tokens, no store |
max_completion_tokens, store present |
deepseek/deepseek-chat |
max_tokens, no store |
max_completion_tokens, store present |
deepseek-v3.2 |
max_tokens, no store |
max_completion_tokens, store present |
deepseek-reasoner |
max_tokens, no store |
max_completion_tokens, store present |
All 12 gateway combinations diverge from direct on both fields; strict already matches (true both ways).
Why it matters
A DeepSeek model seated behind opencode-go / cline-pass / opendesign is sent max_completion_tokens — the field the codebase itself says DeepSeek does not use in place of max_tokens — so the caller's token cap can be silently ignored or rejected upstream, and it carries a store flag the direct route deliberately withholds from a non-standard endpoint. This is exactly the #1706 failure mode ("the same model gets different wire behavior depending on which door it entered through"), left for one of the families #1706 enumerated.
Acceptance criteria
detectModelFamilyrecognizes DeepSeek model ids with the same anchoring discipline as the existing families (whole id segment: start of id or the segment after a/vendor prefix; case-insensitive; ids merely embedding the name inside a larger segment, e.g.not-deepseek-chat, are not the family).- Behind cline-pass / opendesign / opencode-go, DeepSeek ids compile to the direct-DeepSeek body for the affected fields:
max_tokens, nostore; explicitcompatibilityoverrides still win, including explicit values that contradict the family default. - Regression tests extend PR fix(ai): detect OpenAI Chat compatibility by model family behind gateways #1731's gateway-parity test in
packages/ai/test/provider/openai-chat.test.tswith DeepSeek ids (bare, vendor-prefixed, versioned, reasoner) asserting gateway bodies equal the direct body on the pinned fields. - No behavior change for the direct
deepseekprovider or for non-DeepSeek models behind gateways (existing openai-chat / openai-compatible-chat suites green).
Activity
dezren39 commentedon Nov 5, 2026
🤖 Agent note · state: filed
dezren39 commentedon Nov 5, 2026
🤖 Agent note · state: picked up
dezren39 commentedon Nov 5, 2026
🤖 Agent note · state: done