Skip to content

feat(providers): add DeepSeek and Kimi support#208

Merged
qhkm merged 2 commits intomainfrom
feat/deepseek-kimi-providers
Mar 1, 2026
Merged

feat(providers): add DeepSeek and Kimi support#208
qhkm merged 2 commits intomainfrom
feat/deepseek-kimi-providers

Conversation

@qhkm
Copy link
Copy Markdown
Owner

@qhkm qhkm commented Mar 1, 2026

Summary

  • Add DeepSeek (https://api.deepseek.com/v1) and Kimi/Moonshot AI (https://api.moonshot.cn/v1) as OpenAI-compatible providers
  • Both route through OpenAIProvider with custom base URLs — no new provider code needed
  • Add known models for /model list: DeepSeek V3, DeepSeek R1, Kimi 128K, Kimi 32K

Changes

  • src/providers/registry.rs — Add ProviderSpec entries + provider_config_by_name arms
  • src/providers/mod.rs — Add to RUNTIME_SUPPORTED_PROVIDERS
  • src/config/types.rs — Add deepseek and kimi fields to ProvidersConfig
  • src/channels/model_switch.rs — Add known models + update valid providers list in tests
  • CLAUDE.md — Update provider docs

Configuration

{
  "providers": {
    "deepseek": {
      "api_key": "sk-xxx",
      "model": "deepseek-chat"
    },
    "kimi": {
      "api_key": "sk-xxx",
      "model": "moonshot-v1-128k"
    }
  }
}

Or via env vars:

ZEPTOCLAW_PROVIDERS_DEEPSEEK_API_KEY=sk-xxx
ZEPTOCLAW_PROVIDERS_KIMI_API_KEY=sk-xxx

Test plan

  • cargo fmt -- --check passes
  • cargo clippy -- -D warnings passes
  • cargo test --lib — 2670 tests pass (including registry sync test)

Closes #207

🤖 Generated with Claude Code

Summary by CodeRabbit

Documentation

  • Updated provider docs to note support for additional endpoints via custom api_base configuration.

New Features

  • Added DeepSeek provider with DeepSeek V3 and DeepSeek R1 model options.
  • Added Kimi/Moonshot provider with Kimi 128K and Kimi 32K model options.
  • Added runtime configuration and environment-variable support for per-provider API keys, base URLs, and model overrides.

Both providers use OpenAI-compatible APIs and route through
OpenAIProvider with custom base URLs. No new code needed beyond
registry wiring.

Closes #207

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 1, 2026

📝 Walkthrough

Walkthrough

Adds DeepSeek and Kimi/Moonshot as runtime-supported providers: registers them in the provider registry, exposes their models in the model list, wires optional provider config and env vars, and updates documentation to mention availability via configurable api_base.

Changes

Cohort / File(s) Summary
Provider config & env wiring
src/config/types.rs, src/config/mod.rs
Added optional deepseek and kimi fields to ProvidersConfig and wired environment variables for API_KEY, API_BASE, and per-provider MODEL overrides. Tests updated to include these env overrides.
Provider registry & runtime list
src/providers/registry.rs, src/providers/mod.rs
Registered deepseek and kimi in PROVIDER_REGISTRY with metadata (model keywords, default_base_url, backend=openai) and added them to RUNTIME_SUPPORTED_PROVIDERS. Updated provider_config_by_name to return their configs.
Model listing & tests
src/channels/model_switch.rs
Added four KnownModel entries (DeepSeek V3, DeepSeek R1, Kimi 128K, Kimi 32K) to KNOWN_MODELS and updated tests to accept deepseek and kimi as valid providers.
Docs
CLAUDE.md
Expanded OpenAIProvider description to mention additional endpoints/providers accessible via api_base (DeepSeek, Kimi/Moonshot).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hop, hop — two new names in the field,
DeepSeek and Kimi, with keys now revealed,
Models registered, envs set just right,
I nibble a carrot and celebrate tonight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding DeepSeek and Kimi as new provider support.
Linked Issues check ✅ Passed The pull request fully addresses issue #207 requirements: adds DeepSeek and Kimi support via OpenAI-compatible routing, exposes configuration options, and includes known models with test updates.
Out of Scope Changes check ✅ Passed All changes are directly within scope: provider registry updates, configuration wiring, model listings, and test updates for the two new providers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/deepseek-kimi-providers

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/config/types.rs`:
- Around line 1134-1137: The ProvidersConfig struct was extended with deepseek
and kimi fields but apply_provider_env_overrides() in src/config/mod.rs lacks
handling for their environment overrides; update apply_provider_env_overrides()
to mirror the existing provider pattern (as used for anthropic/openai/groq) by
checking ProvidersConfig.deepseek and ProvidersConfig.kimi Option values and,
when present, overwrite their ProviderConfig.api_key, api_base, and model from
env vars ZEPTOCLAW_PROVIDERS_DEEPSEEK_API_KEY,
ZEPTOCLAW_PROVIDERS_DEEPSEEK_API_BASE, ZEPTOCLAW_PROVIDERS_DEEPSEEK_MODEL and
ZEPTOCLAW_PROVIDERS_KIMI_API_KEY, ZEPTOCLAW_PROVIDERS_KIMI_API_BASE,
ZEPTOCLAW_PROVIDERS_KIMI_MODEL respectively (only set if the env var is
defined), using the same helper/get-env logic used for the other providers.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc11936 and a0872ef.

📒 Files selected for processing (5)
  • CLAUDE.md
  • src/channels/model_switch.rs
  • src/config/types.rs
  • src/providers/mod.rs
  • src/providers/registry.rs

Comment thread src/config/types.rs
Add ZEPTOCLAW_PROVIDERS_DEEPSEEK_{API_KEY,API_BASE,MODEL} and
ZEPTOCLAW_PROVIDERS_KIMI_{API_KEY,API_BASE,MODEL} environment variable
overrides in apply_provider_env_overrides(), following the existing
pattern for other providers. Updates the test to cover both new
providers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@src/config/mod.rs`:
- Around line 427-457: The helper functions get_api_key() and get_api_base() are
missing DeepSeek and Kimi entries and their docstrings are out of date; update
the helper implementations and their docstrings to include DeepSeek and Kimi
(matching the provider names used in provider_config_by_name()), or
alternatively add a clear comment in the helpers stating they are only used for
unit tests and not for runtime provider selection; ensure you reference the
exact helper function names get_api_key() and get_api_base() and align their
returned/handled provider names with the registry implementation
(provider_config_by_name()) so tests and docs are consistent.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a0872ef and efa5a0d.

📒 Files selected for processing (1)
  • src/config/mod.rs

Comment thread src/config/mod.rs
Comment on lines +427 to +457
// DeepSeek
if let Ok(val) = std::env::var("ZEPTOCLAW_PROVIDERS_DEEPSEEK_API_KEY") {
let provider = self
.providers
.deepseek
.get_or_insert_with(ProviderConfig::default);
provider.api_key = Some(val);
}
if let Ok(val) = std::env::var("ZEPTOCLAW_PROVIDERS_DEEPSEEK_API_BASE") {
let provider = self
.providers
.deepseek
.get_or_insert_with(ProviderConfig::default);
provider.api_base = Some(val);
}

// Kimi (Moonshot AI)
if let Ok(val) = std::env::var("ZEPTOCLAW_PROVIDERS_KIMI_API_KEY") {
let provider = self
.providers
.kimi
.get_or_insert_with(ProviderConfig::default);
provider.api_key = Some(val);
}
if let Ok(val) = std::env::var("ZEPTOCLAW_PROVIDERS_KIMI_API_BASE") {
let provider = self
.providers
.kimi
.get_or_insert_with(ProviderConfig::default);
provider.api_base = Some(val);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Helper definitions =="
rg -n --type=rust -C5 'fn get_api_key|fn get_api_base' src/config/mod.rs

echo
echo "== Call sites relying on helpers =="
rg -nP --type=rust -C3 '\bget_api_key\s*\(|\bget_api_base\s*\(' src

echo
echo "== DeepSeek/Kimi references in config module =="
rg -n --type=rust -C2 'providers\.(deepseek|kimi)' src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 3368


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Full get_api_key implementation =="
rg -n --type=rust -A20 'pub fn get_api_key' src/config/mod.rs | head -40

echo
echo "== Full get_api_base implementation =="
rg -n --type=rust -A30 'pub fn get_api_base' src/config/mod.rs | head -50

echo
echo "== Calls to get_api_key outside tests =="
rg -n --type=rust 'get_api_key' src --glob='!**/*test*' --glob='!**/tests/**'

echo
echo "== Calls to get_api_base outside tests =="
rg -n --type=rust 'get_api_base' src --glob='!**/*test*' --glob='!**/tests/**'

echo
echo "== Providers struct definition =="
rg -n --type=rust -A50 'struct Providers' src/config/mod.rs | head -70

Repository: qhkm/zeptoclaw

Length of output: 2484


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Providers struct definition =="
rg -n --type=rust -B2 -A30 'pub struct Providers' src/config/mod.rs

echo
echo "== Check actual usage of helpers in codebase =="
git grep -n 'get_api_key\|get_api_base' src/ || echo "Not found in source (only in tests)"

echo
echo "== Check if deepseek/kimi wiring is complete =="
echo "Checking environment variable env overrides..."
rg -n --type=rust 'ZEPTOCLAW_PROVIDERS_DEEPSEEK|ZEPTOCLAW_PROVIDERS_KIMI' src/config/mod.rs

echo
echo "=== Provider Config model field support ==="
rg -n --type=rust -B2 -A2 'pub model:' src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 91


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find Providers struct =="
rg -n 'struct Providers' src/config/mod.rs -A 40

echo
echo "== Check all provider fields =="
rg -n 'pub (openrouter|anthropic|openai|gemini|zhipu|groq|deepseek|kimi|vllm):' src/config/mod.rs

echo
echo "== Search for actual usage patterns outside tests =="
rg -n 'get_api_key|get_api_base' src --type=rust | grep -v test | grep -v '#\['

echo
echo "== Check if these helpers are used in onboarding/cli =="
rg -rn 'get_api_key\|get_api_base' src/cli/ src/onboard/

echo
echo "== Verify the complete get_api_base to see all providers =="
sed -n '1158,1220p' src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 85


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Direct file read: Providers struct and fields =="
sed -n '1,150p' src/config/mod.rs | grep -A 50 'struct Providers'

echo
echo "== Complete get_api_base function =="
sed -n '1158,1230p' src/config/mod.rs

echo
echo "== Line count and structure =="
wc -l src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 109


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check file exists and size =="
ls -lh src/config/mod.rs

echo
echo "== Read full file to understand structure =="
cat src/config/mod.rs | head -100

echo
echo "=== Search for Providers struct ==="
cat src/config/mod.rs | grep -n "struct Providers" -A 30 || true

Repository: qhkm/zeptoclaw

Length of output: 3754


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search for all provider fields =="
grep -n "deepseek\|kimi\|openrouter\|anthropic" src/config/mod.rs | head -30

echo
echo "== Context around line 1136 (get_api_key) =="
sed -n '1130,1160p' src/config/mod.rs

echo
echo "== Context around line 1158 (get_api_base) =="
sed -n '1158,1210p' src/config/mod.rs

echo
echo "== Check what uses these helper functions =="
grep -n "\.get_api_key()\|\.get_api_base()" src/config/mod.rs src/**/*.rs 2>/dev/null || true

Repository: qhkm/zeptoclaw

Length of output: 4894


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Verify: ANY usage of get_api_key or get_api_base across entire codebase =="
git grep -n 'get_api_key\|get_api_base' 2>/dev/null || echo "None found outside src/config/mod.rs tests"

echo
echo "== Check if DeepSeek/Kimi wiring is otherwise complete =="
echo "Model override env vars:"
grep -n 'ZEPTOCLAW_PROVIDERS_DEEPSEEK_MODEL\|ZEPTOCLAW_PROVIDERS_KIMI_MODEL' src/config/mod.rs

echo
echo "== Confirm test coverage for model overrides =="
sed -n '1745,1760p' src/config/mod.rs

echo
echo "== Check comment/docstring accuracy =="
sed -n '1133,1136p' src/config/mod.rs
sed -n '1157,1158p' src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 1883


🏁 Script executed:

#!/bin/bash
set -euo pipefemporal

echo "== Check if these helpers are exported/part of public API =="
rg -n 'pub fn get_api_key|pub fn get_api_base' src/config/mod.rs

echo
echo "== Check if they might be used transitively through imports =="
grep -n 'use.*Config' src/**/*.rs | head -20

echo
echo "== Verify no runtime usage by checking provider selection logic =="
rg -n 'get_or_insert_with.*ProviderConfig' src/config/mod.rs | head -10

echo
echo "== Look for actual runtime provider selection logic =="
rg -n 'providers\.(deepseek|kimi)' src --type=rust | grep -v test | grep -v 'get_or_insert'

Repository: qhkm/zeptoclaw

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if these helpers are exported/part of public API =="
rg -n 'pub fn get_api_key|pub fn get_api_base' src/config/mod.rs

echo
echo "== Check if they might be used transitively through imports =="
grep -n 'use.*Config' src/**/*.rs 2>/dev/null | head -20 || true

echo
echo "== Verify no runtime usage by checking provider selection logic =="
rg -n 'get_or_insert_with.*ProviderConfig' src/config/mod.rs | head -10

echo
echo "== Look for actual runtime provider selection logic =="
rg -n 'providers\.(deepseek|kimi)' src --type=rust | grep -v test | grep -v 'get_or_insert'

Repository: qhkm/zeptoclaw

Length of output: 2857


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check src/providers/registry.rs to understand actual provider selection =="
sed -n '130,145p' src/providers/registry.rs

echo
echo "== Context around provider registry =="
sed -n '120,150p' src/providers/registry.rs

echo
echo "== Verify complete docstring for get_api_key =="
sed -n '1133,1156p' src/config/mod.rs

Repository: qhkm/zeptoclaw

Length of output: 2740


Helpers get_api_key() and get_api_base() are outdated, but this does not impact runtime provider selection.

The docstring at line 1135 and the helper implementation omit DeepSeek and Kimi, but these functions are only used in unit tests and never called in production code. Actual provider selection at runtime uses provider_config_by_name() in src/providers/registry.rs, which correctly includes both new providers. Consider updating the helpers' docstrings and implementation to include DeepSeek and Kimi for consistency with the registered provider list, or clarify their intended scope in comments.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config/mod.rs` around lines 427 - 457, The helper functions get_api_key()
and get_api_base() are missing DeepSeek and Kimi entries and their docstrings
are out of date; update the helper implementations and their docstrings to
include DeepSeek and Kimi (matching the provider names used in
provider_config_by_name()), or alternatively add a clear comment in the helpers
stating they are only used for unit tests and not for runtime provider
selection; ensure you reference the exact helper function names get_api_key()
and get_api_base() and align their returned/handled provider names with the
registry implementation (provider_config_by_name()) so tests and docs are
consistent.

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.

support deepseek and kimi

1 participant