fix(providers): default DeepSeek V4 Flash to Responses - #808
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e743660fca
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| modelContextWindows: { "deepseek-v4-flash": 1_000_000, "deepseek-v4-pro": 1_000_000 }, | ||
| // DeepSeek documents V4-Flash as a native Responses API model adapted for Codex. The | ||
| // API id is `deepseek-v4-flash`; `DeepSeek-V4-Flash-0731` is a release/version label. | ||
| modelWireDefaults: { "deepseek-v4-flash": "openai-responses" }, |
There was a problem hiding this comment.
Apply the DeepSeek effort map on the Responses wire
When a user selects the advertised xhigh effort for deepseek-v4-flash, this default switches the request away from createOpenAIChatAdapter, which is the only adapter that calls mapReasoningEffort. The Responses adapter instead forwards _rawBody.reasoning.effort unchanged, so xhigh reaches DeepSeek rather than the registry-required max mapping declared in modelReasoningEffortMap; this can make an otherwise supported request fail upstream. Apply the provider effort map while constructing the Responses body, or normalize the raw reasoning effort before selecting this default wire.
Useful? React with 👍 / 👎.
| const requested = configured && MODEL_ADAPTER_OVERRIDE_ALLOWED.has(configured) | ||
| ? configured | ||
| : providerModelWireDefault(providerName, providerConfig, modelId, MODEL_ADAPTER_OVERRIDE_ALLOWED); |
There was a problem hiding this comment.
Preserve routed Responses sampling parameters
For DeepSeek Flash requests entering through /v1/messages or /v1/chat/completions, selecting this registry default makes the wrapper treat the route like the canonical ChatGPT passthrough: claude-messages.ts and chat-completions.ts then delete max_output_tokens, temperature, top_p, stop, and user solely because the effective adapter is openai-responses. Thus Claude Code's required max_tokens translation and equivalent chat-completions controls are silently discarded before calling DeepSeek, potentially removing output limits and changing sampling behavior. Restrict that ChatGPT-specific sanitization to isCanonicalOpenAiForwardProvider rather than every Responses route.
Useful? React with 👍 / 👎.
| modelContextWindows: { "deepseek-v4-flash": 1_000_000, "deepseek-v4-pro": 1_000_000 }, | ||
| // DeepSeek documents V4-Flash as a native Responses API model adapted for Codex. The | ||
| // API id is `deepseek-v4-flash`; `DeepSeek-V4-Flash-0731` is a release/version label. | ||
| modelWireDefaults: { "deepseek-v4-flash": "openai-responses" }, |
There was a problem hiding this comment.
Derive parallel-tool capability from the effective model wire
The catalog still evaluates DeepSeek's provider-wide adapter: "openai-chat", so applyProviderConfigHints advertises parallelToolCalls: true by default even though this model is now executed by openai-responses. The catalog policy deliberately requires an explicit parallelToolCalls: true for non-chat adapters, but DeepSeek has no such opt-in; Codex can therefore emit parallel_tool_calls: true to a Responses route whose support was never declared or verified. Make per-model catalog derivation use the effective wire default, or explicitly register the capability if DeepSeek Responses supports it.
AGENTS.md reference: src/AGENTS.md:L18-L19
Useful? React with 👍 / 👎.
📝 WalkthroughWalkthroughThe provider registry now supports model-specific wire defaults. DeepSeek V4 Flash uses ChangesDeepSeek wire routing
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/adapter-resolve.test.ts`:
- Around line 113-117: Add a focused test alongside the existing explicit Chat
override case in adapter-resolve.test.ts using an unsupported
modelAdapters["deepseek-v4-flash"] value such as "anthropic"; call
resolveWireProtocolOverride for the DeepSeek Flash model and assert that the
returned adapter is "openai-responses", covering the invalid-override fallback.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 9185ffc9-ee27-4cf9-a8c0-997cff07a234
📒 Files selected for processing (5)
docs-site/src/content/docs/reference/configuration.mddocs-site/src/content/docs/zh-cn/reference/configuration.mdsrc/providers/registry.tssrc/server/adapter-resolve.tstests/adapter-resolve.test.ts
| test("an explicit Chat override opts Flash back out of the default", () => { | ||
| const provider = deepseek({ modelAdapters: { "deepseek-v4-flash": "openai-chat" } }); | ||
| expect(resolveWireProtocolOverride("deepseek", "deepseek-v4-flash", provider).adapter) | ||
| .toBe("openai-chat"); | ||
| }); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Add coverage for invalid explicit overrides.
Lines 113-117 verify a valid openai-chat override. They do not verify the fallback in src/server/adapter-resolve.ts lines 29-34. Add a case where modelAdapters["deepseek-v4-flash"] is an unsupported value such as "anthropic". Assert that the resolver selects "openai-responses".
Proposed test
+ test("an invalid override falls back to the Flash registry default", () => {
+ const provider = deepseek({ modelAdapters: { "deepseek-v4-flash": "anthropic" } });
+ expect(resolveWireProtocolOverride("deepseek", "deepseek-v4-flash", provider).adapter)
+ .toBe("openai-responses");
+ });As per path instructions, shared routing changes need focused regression coverage.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| test("an explicit Chat override opts Flash back out of the default", () => { | |
| const provider = deepseek({ modelAdapters: { "deepseek-v4-flash": "openai-chat" } }); | |
| expect(resolveWireProtocolOverride("deepseek", "deepseek-v4-flash", provider).adapter) | |
| .toBe("openai-chat"); | |
| }); | |
| test("an explicit Chat override opts Flash back out of the default", () => { | |
| const provider = deepseek({ modelAdapters: { "deepseek-v4-flash": "openai-chat" } }); | |
| expect(resolveWireProtocolOverride("deepseek", "deepseek-v4-flash", provider).adapter) | |
| .toBe("openai-chat"); | |
| }); | |
| test("an invalid override falls back to the Flash registry default", () => { | |
| const provider = deepseek({ modelAdapters: { "deepseek-v4-flash": "anthropic" } }); | |
| expect(resolveWireProtocolOverride("deepseek", "deepseek-v4-flash", provider).adapter) | |
| .toBe("openai-responses"); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/adapter-resolve.test.ts` around lines 113 - 117, Add a focused test
alongside the existing explicit Chat override case in adapter-resolve.test.ts
using an unsupported modelAdapters["deepseek-v4-flash"] value such as
"anthropic"; call resolveWireProtocolOverride for the DeepSeek Flash model and
assert that the returned adapter is "openai-responses", covering the
invalid-override fallback.
Source: Path instructions
…-ids Verified locally on top of origin/dev alongside #808: typecheck clean, 214 targeted tests pass (cursor-discovery, cursor-effort-suffix, cursor-request-builder, adapter-resolve, router, config, repo-hygiene), privacy:scan green.
Closes #807
Summary
modelWireDefaultsentry fordeepseek-v4-flash→openai-responses.modelAdaptersprecedence so users can opt Flash back toopenai-chat.deepseek-v4-flashas the API id;DeepSeek-V4-Flash-0731is a release/version label, not a request model id.The upstream DeepSeek documentation says V4-Flash natively supports the Responses API and is adapted for Codex:
Verification
bun test tests/adapter-resolve.test.ts— 11 pass.adapter-resolve,provider-registry-parity,router,reasoning-effort,effort-policy) — 146 pass.bun run typecheck— pass.bun run privacy:scan— pass.bun run test— 6254 pass, 4 skipped; 2 unrelated GUI test failures/errors because this clone does not havereact/jsx-dev-runtimeinstalled (provider-workspace-rail.test.ts,quota-bars-rows.test.ts). The same two files fail unchanged when run alone.OPENCODEX_HOMEwith nomodelAdaptersentry:/v1/responsesreturned the native DeepSeek response shape, and a real Codex CLI tool loop (pwdfollowed by an exact marker) exited 0.Checklist
Summary by CodeRabbit
New Features
deepseek-v4-flashmodel now uses native Responses routing by default.Documentation
modelAdapterssettings, supported values, defaults, priority, and limitations.Bug Fixes