Skip to content

WIP: Add DeepSeek Anthropic-compatible route#3449

Open
Hmbown wants to merge 1 commit into
mainfrom
issue/2963-deepseek-anthropic-route
Open

WIP: Add DeepSeek Anthropic-compatible route#3449
Hmbown wants to merge 1 commit into
mainfrom
issue/2963-deepseek-anthropic-route

Conversation

@Hmbown

@Hmbown Hmbown commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Goal

Add a first-class opt-in route for DeepSeek's Anthropic-compatible API without changing the existing DeepSeek Chat Completions path.

Refs #2963.

Changes

  • Adds deepseek-anthropic / deepseek_anthropic provider metadata, config tables, aliases, defaults, and env var wiring.
  • Defaults the route to https://api.deepseek.com/anthropic with deepseek-v4-pro.
  • Routes the provider through the existing Anthropic Messages adapter and x-api-key / anthropic-version header dialect.
  • Marks runtime capability metadata as AnthropicMessages, while keeping DeepSeek-native cache telemetry scoped to the existing DeepSeek routes.
  • Updates provider docs, provider registry drift checks, and generated web facts maps for the new manual provider.
  • Adds focused config, URL, header, capability, and metadata parity tests.

Upstream Docs Checked

Verification

  • cargo fmt --all -- --check
  • cargo test -p codewhale-config --locked provider_metadata_defaults_match_runtime_helpers
  • cargo test -p codewhale-config --locked deepseek_anthropic_route_defaults_to_anthropic_endpoint
  • cargo test -p codewhale-tui --bin codewhale-tui --locked messages_url_tolerates_v1_suffix
  • cargo test -p codewhale-tui --bin codewhale-tui --locked deepseek_anthropic_uses_anthropic_header_dialect
  • cargo test -p codewhale-tui --bin codewhale-tui --locked provider_capability_deepseek_anthropic_uses_messages_payload
  • cargo test -p codewhale-tui --bin codewhale-tui --locked body_maps_reasoning_effort_to_adaptive_thinking_and_effort
  • cargo test -p codewhale-tui --bin codewhale-tui --locked sse_fixture_decodes_text_thinking_signature_and_tool_use
  • cargo test -p codewhale-tui --bin codewhale-tui --locked parse_usage_reads_deepseek_cache_and_reasoning_tokens
  • cargo test -p codewhale-tui --bin codewhale-tui --locked api_provider_metadata_helpers_follow_config_provider_metadata
  • cargo test -p codewhale-tui --bin codewhale-tui --locked provider_config_key_follows_config_provider_metadata
  • node web/scripts/derive-facts.mjs
  • python3 scripts/check-provider-registry.py
  • ./scripts/release/check-versions.sh
  • ./scripts/release/check-ohos-deps.sh
  • git diff --check

Remaining Risk

This wires the documented API shape and adapter path, but does not prove account-specific server-tool behavior against a live DeepSeek key. That should stay as a follow-up manual probe before marking #2963 fully done.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new DeepseekAnthropic provider variant, allowing users to opt-in to a DeepSeek route that communicates via the Anthropic Messages wire protocol. The changes span configuration structures, provider registries, and TUI client implementations to support the new endpoint, authentication headers, and aliases. The review feedback highlights three key areas for improvement: a security risk where ANTHROPIC_API_KEY could be leaked to DeepSeek servers if configured as a fallback, missing hyphenated aliases in the subagent provider key matching logic, and an inconsistency in EnvRuntimeOverrides that prevents overriding the base URL for the new provider via environment variables.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +161 to +163
fn env_vars(&self) -> &'static [&'static str] {
&["DEEPSEEK_API_KEY", "ANTHROPIC_API_KEY"]
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

security-high high

Including ANTHROPIC_API_KEY in the list of environment variables for DeepseekAnthropic poses a security risk. If a user has ANTHROPIC_API_KEY set in their environment (which is common for Anthropic users) but has not set DEEPSEEK_API_KEY, the application will fall back to using the Anthropic API key and send it to DeepSeek's servers (https://api.deepseek.com/anthropic). This results in credential exposure to a third party. Since DeepSeek's Anthropic-compatible endpoint requires a DeepSeek API key and cannot authenticate with an Anthropic key, ANTHROPIC_API_KEY should be removed from this list.

Suggested change
fn env_vars(&self) -> &'static [&'static str] {
&["DEEPSEEK_API_KEY", "ANTHROPIC_API_KEY"]
}
fn env_vars(&self) -> &'static [&'static str] {
&["DEEPSEEK_API_KEY"]
}

Comment thread crates/tui/src/config.rs
Comment on lines +469 to +472
ApiProvider::DeepseekAnthropic => matches!(
normalized.as_str(),
"deepseek_anthropic" | "deepseek_claude" | "deepseek_anthropic_api"
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The subagent provider key matching is missing the hyphenated aliases (deepseek-anthropic and deepseek-claude), which are supported elsewhere in the configuration (e.g., in Serde aliases). If a user configures a subagent using the hyphenated format, it will fail to match. We should include the hyphenated versions to ensure consistency and robustness.

Suggested change
ApiProvider::DeepseekAnthropic => matches!(
normalized.as_str(),
"deepseek_anthropic" | "deepseek_claude" | "deepseek_anthropic_api"
),
ApiProvider::DeepseekAnthropic => matches!(
normalized.as_str(),
"deepseek_anthropic" | "deepseek-anthropic" | "deepseek_claude" | "deepseek-claude" | "deepseek_anthropic_api"
),

Comment thread crates/config/src/lib.rs
// values (`providers.<name>.base_url`) still win when env is unset.
match provider {
ProviderKind::Deepseek => self.deepseek_base_url.clone(),
ProviderKind::DeepseekAnthropic => None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Returning None here means that EnvRuntimeOverrides does not support overriding the base URL for the deepseek-anthropic provider via environment variables, unlike other providers (e.g., Deepseek uses self.deepseek_base_url.clone()). This creates an inconsistency between crates/config and crates/tui (where DEEPSEEK_ANTHROPIC_BASE_URL or similar is handled). Consider adding a deepseek_anthropic_base_url field to EnvRuntimeOverrides to support environment-based base URL overrides consistently.

@Hmbown Hmbown force-pushed the issue/2963-deepseek-anthropic-route branch from c63864c to 69d198f Compare June 23, 2026 05:07

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Add an opt-in deepseek-anthropic provider that resolves to DeepSeek's Anthropic-compatible endpoint and model defaults while leaving the existing DeepSeek chat-completions route unchanged.

Route the provider through the existing Anthropic Messages adapter, x-api-key header dialect, and TUI provider config table, with runtime capability metadata marking it as AnthropicMessages.

Update the provider docs, provider registry drift checker, and web facts maps so the manual provider implementation stays covered by generated guards.

Verified with: cargo fmt --all -- --check; cargo test -p codewhale-config --locked provider_metadata_defaults_match_runtime_helpers; cargo test -p codewhale-config --locked deepseek_anthropic_route_defaults_to_anthropic_endpoint; cargo test -p codewhale-tui --bin codewhale-tui --locked messages_url_tolerates_v1_suffix; cargo test -p codewhale-tui --bin codewhale-tui --locked deepseek_anthropic_uses_anthropic_header_dialect; cargo test -p codewhale-tui --bin codewhale-tui --locked provider_capability_deepseek_anthropic_uses_messages_payload; cargo test -p codewhale-tui --bin codewhale-tui --locked body_maps_reasoning_effort_to_adaptive_thinking_and_effort; cargo test -p codewhale-tui --bin codewhale-tui --locked sse_fixture_decodes_text_thinking_signature_and_tool_use; cargo test -p codewhale-tui --bin codewhale-tui --locked parse_usage_reads_deepseek_cache_and_reasoning_tokens; cargo test -p codewhale-tui --bin codewhale-tui --locked api_provider_metadata_helpers_follow_config_provider_metadata; cargo test -p codewhale-tui --bin codewhale-tui --locked provider_config_key_follows_config_provider_metadata; node web/scripts/derive-facts.mjs; python3 scripts/check-provider-registry.py; ./scripts/release/check-versions.sh; ./scripts/release/check-ohos-deps.sh; git diff --check
@Hmbown Hmbown force-pushed the issue/2963-deepseek-anthropic-route branch from 69d198f to e93cc8f Compare June 23, 2026 05:12

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@Hmbown Hmbown marked this pull request as ready for review June 23, 2026 05:55

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant