fix(#37): make NIM a peer provider in config.example.toml + setup status

A user couldn't find an `NVIDIA_API_KEY` block in `~/.deepseek/config.toml`
because the example file only mentioned NIM as commented-out alternates
to the top-level keys. Two fixes:

- `config.example.toml` now has explicit `[providers.deepseek]` and
  `[providers.nvidia_nim]` sections (placed after all top-level keys so
  the TOML still parses cleanly), each documenting `api_key` /
  `base_url` / `model` plus the env vars that override them. Both
  providers can be stored at once and toggled via `/provider` or
  `--provider` without re-entering keys.
- `setup --status` "missing api_key" message is now provider-aware: on
  `nvidia-nim` it points at `NVIDIA_API_KEY` + `[providers.nvidia_nim]`
  + `deepseek auth set --provider nvidia-nim`, instead of the
  DeepSeek-only hint.

Audit verified: the v0.5.0 multi-turn replay fix path
(`should_replay_reasoning_content` → `requires_reasoning_content` in
`crates/tui/src/client.rs:1796`) keys off the model name (matches
`deepseek-v4`), not the provider, so NIM-hosted V4 models get the
replay automatically. No NIM-specific 400-class regression there.

Closes #37 (docs/UX); the live multi-turn-against-NIM verification
remains a manual smoke step listed in the issue (no NIM creds in CI).
This commit is contained in:
Hunter Bown
2026-04-25 13:52:44 -05:00
parent 24b8945010
commit f7fe5e09a5
2 changed files with 48 additions and 13 deletions
+29 -9
View File
@@ -7,21 +7,19 @@
# See `docs/CONFIGURATION.md` for how config is loaded (profiles, env overrides, etc.).
# ─────────────────────────────────────────────────────────────────────────────────
# API Keys
# Active provider + DeepSeek defaults
# ─────────────────────────────────────────────────────────────────────────────────
# Choose which provider to use by default. Per-provider credentials live in the
# `[providers.deepseek]` and `[providers.nvidia_nim]` sections near the bottom of
# this file — keeping both stored at once means `/provider deepseek` and
# `/provider nvidia-nim` (or `--provider nvidia-nim`) toggle without having to
# re-enter keys. Top-level `api_key` / `base_url` are still read as DeepSeek
# defaults when `[providers.deepseek]` is absent (backward compatibility).
provider = "deepseek" # deepseek | nvidia-nim
api_key = "YOUR_DEEPSEEK_API_KEY" # must be non-empty
# ─────────────────────────────────────────────────────────────────────────────────
# Base URLs
# ─────────────────────────────────────────────────────────────────────────────────
base_url = "https://api.deepseek.com"
# base_url = "https://api.deepseeki.com" # China users
# base_url = "https://api.deepseek.com/beta" # DeepSeek beta features such as strict tool mode
# For NVIDIA NIM-hosted DeepSeek:
# provider = "nvidia-nim"
# api_key = "YOUR_NVIDIA_API_KEY"
# base_url = "https://integrate.api.nvidia.com/v1"
# ─────────────────────────────────────────────────────────────────────────────────
# Default Models
@@ -70,6 +68,28 @@ max_subagents = 5 # optional (1-20)
# managed_config_path = "/etc/deepseek/managed_config.toml"
# requirements_path = "/etc/deepseek/requirements.toml"
# ─────────────────────────────────────────────────────────────────────────────────
# Per-provider credentials (peer providers — NIM is first-class, not a flag)
# ─────────────────────────────────────────────────────────────────────────────────
# Both providers can be stored at once; `provider = "..."` (top of file) or
# `/provider deepseek` / `/provider nvidia-nim` switches between them without
# having to re-enter keys. Env vars override anything set here:
# DeepSeek: DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, DEEPSEEK_MODEL
# NIM: NVIDIA_API_KEY (or NVIDIA_NIM_API_KEY), NIM_BASE_URL
# (or NVIDIA_NIM_BASE_URL / NVIDIA_BASE_URL), NVIDIA_NIM_MODEL
# DeepSeek Platform (https://platform.deepseek.com)
[providers.deepseek]
# api_key = "YOUR_DEEPSEEK_API_KEY"
# base_url = "https://api.deepseek.com"
# model = "deepseek-v4-pro"
# NVIDIA NIM-hosted DeepSeek V4 (https://build.nvidia.com)
[providers.nvidia_nim]
# api_key = "YOUR_NVIDIA_API_KEY"
# base_url = "https://integrate.api.nvidia.com/v1"
# model = "deepseek-ai/deepseek-v4-pro" # or deepseek-ai/deepseek-v4-flash
# ─────────────────────────────────────────────────────────────────────────────────
# TUI
# ─────────────────────────────────────────────────────────────────────────────────
+19 -4
View File
@@ -1118,10 +1118,25 @@ fn run_setup_status(config: &Config, workspace: &Path) -> Result<()> {
" {} api_key: set via config",
"".truecolor(aqua_r, aqua_g, aqua_b)
),
ApiKeySource::Missing => println!(
" {} api_key: missing (set DEEPSEEK_API_KEY or run `deepseek login`)",
"".truecolor(red_r, red_g, red_b)
),
ApiKeySource::Missing => {
let (env_var, login_hint) = match config.api_provider() {
crate::config::ApiProvider::NvidiaNim => (
"NVIDIA_API_KEY",
"deepseek auth set --provider nvidia-nim --api-key \"...\"",
),
crate::config::ApiProvider::Deepseek => {
("DEEPSEEK_API_KEY", "deepseek login --api-key \"...\"")
}
};
println!(
" {} api_key: missing (set {env_var} or `[providers.{}].api_key` in ~/.deepseek/config.toml; or run `{login_hint}`)",
"".truecolor(red_r, red_g, red_b),
match config.api_provider() {
crate::config::ApiProvider::NvidiaNim => "nvidia_nim",
crate::config::ApiProvider::Deepseek => "deepseek",
}
);
}
}
println!(
" · base_url: {}",