Skip to content

fix(providers): default DeepSeek V4 Flash to Responses - #808

Merged
lidge-jun merged 1 commit into
lidge-jun:devfrom
estelledc:codex/deepseek-v4-flash-responses
Jul 31, 2026
Merged

fix(providers): default DeepSeek V4 Flash to Responses#808
lidge-jun merged 1 commit into
lidge-jun:devfrom
estelledc:codex/deepseek-v4-flash-responses

Conversation

@estelledc

@estelledc estelledc commented Jul 31, 2026

Copy link
Copy Markdown

Closes #807

Summary

  • Add a registry-only modelWireDefaults entry for deepseek-v4-flashopenai-responses.
  • Keep DeepSeek Pro, legacy models, and providers without a default on their existing adapter.
  • Preserve explicit modelAdapters precedence so users can opt Flash back to openai-chat.
  • Document the automatic route in the English and Simplified Chinese configuration references.
  • Treat deepseek-v4-flash as the API id; DeepSeek-V4-Flash-0731 is 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.
  • Focused routing set (adapter-resolve, provider-registry-parity, router, reasoning-effort, effort-policy) — 146 pass.
  • bun run typecheck — pass.
  • bun run privacy:scan — pass.
  • Full bun run test — 6254 pass, 4 skipped; 2 unrelated GUI test failures/errors because this clone does not have react/jsx-dev-runtime installed (provider-workspace-rail.test.ts, quota-bars-rows.test.ts). The same two files fail unchanged when run alone.
  • Candidate default mapping was verified against a live DeepSeek key in an isolated OPENCODEX_HOME with no modelAdapters entry: /v1/responses returned the native DeepSeek response shape, and a real Codex CLI tool loop (pwd followed by an exact marker) exited 0.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs were updated for the user-visible routing default.
  • No credentials, request bodies, or personal data are included; the change does not alter authentication or external destinations.

Summary by CodeRabbit

  • New Features

    • Added support for model-specific wire adapter defaults.
    • DeepSeek’s deepseek-v4-flash model now uses native Responses routing by default.
    • Explicit per-model adapter overrides continue to take precedence.
  • Documentation

    • Updated English and Chinese configuration guides with modelAdapters settings, supported values, defaults, priority, and limitations.
  • Bug Fixes

    • Invalid adapter overrides now safely fall back to the appropriate model default.

@github-actions github-actions Bot added the bug Something isn't working label Jul 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/providers/registry.ts
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" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines +32 to +34
const requested = configured && MODEL_ADAPTER_OVERRIDE_ALLOWED.has(configured)
? configured
: providerModelWireDefault(providerName, providerConfig, modelId, MODEL_ADAPTER_OVERRIDE_ALLOWED);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment thread src/providers/registry.ts
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" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The provider registry now supports model-specific wire defaults. DeepSeek V4 Flash uses openai-responses by default. Explicit valid modelAdapters overrides remain authoritative. Tests and English and Chinese configuration documentation describe the behavior.

Changes

DeepSeek wire routing

Layer / File(s) Summary
Registry wire defaults
src/providers/registry.ts
ProviderRegistryEntry adds modelWireDefaults at lines 126-131. The DeepSeek entry maps deepseek-v4-flash to openai-responses at lines 822-824. providerModelWireDefault validates provider transport, registry destination, allowed wires, and case-insensitive model IDs at lines 1247-1265.
Adapter resolution and validation
src/server/adapter-resolve.ts, tests/adapter-resolve.test.ts
resolveWireProtocolOverride uses valid explicit adapters first and registry defaults otherwise at lines 12-17 and 29-34. Tests cover DeepSeek Flash, dated aliases, explicit overrides, non-Chat adapters, credentials, and destinations at lines 93-131.
Configuration documentation
docs-site/src/content/docs/reference/configuration.md, docs-site/src/content/docs/zh-cn/reference/configuration.md
The documentation describes model-level adapter selection, registry defaults, override precedence, and unsupported fixed-wire cases at English line 328 and Chinese line 175.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: lidge-jun, wibias, ingwannu

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: routing DeepSeek V4 Flash to the Responses adapter by default.
Linked Issues check ✅ Passed The implementation maps deepseek-v4-flash to openai-responses, preserves overrides and existing routes, documents the behavior, and adds focused tests.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue, including registry logic, resolution behavior, documentation, and focused tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between e03bf35 and e743660.

📒 Files selected for processing (5)
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/providers/registry.ts
  • src/server/adapter-resolve.ts
  • tests/adapter-resolve.test.ts

Comment on lines +113 to +117
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");
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 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.

Suggested change
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

@lidge-jun
lidge-jun merged commit 4d495e9 into lidge-jun:dev Jul 31, 2026
5 checks passed
lidge-jun added a commit that referenced this pull request Jul 31, 2026
…-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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants