feat(providers): add AtlasCloud as a first-class provider
AtlasCloud (https://atlascloud.ai) hosts the V4 family on its own DeepSeek-compatible endpoint at `https://api.atlascloud.ai/v1`, and several contributors had been running it through the OpenAI-compatible passthrough with manual `base_url` / model overrides. Selecting `provider = "atlascloud"` in `~/.deepseek/config.toml` (or via `DEEPSEEK_PROVIDER=atlascloud`) now wires up: - documented `DEFAULT_ATLASCLOUD_BASE_URL` / `DEFAULT_ATLASCLOUD_MODEL` defaults so a fresh install needs only the api_key - a `[providers.atlascloud]` config block with the same fields every other named provider exposes (api_key / base_url / model / http_headers) - `ATLASCLOUD_API_KEY` env var path, including the secrets test cleanup loop so per-test env hygiene continues to work - the provider-picker / `/provider` slash command entries so the provider is reachable from the runtime UI, not just config - the env-driven `*_BASE_URL` override branch so users who pin a proxy can still flip it without editing config.toml Trust-boundary pins held: AtlasCloud is opt-in (default remains DeepSeek), no API keys are hardcoded, the api_key resolution flows through the same `secrets` crate path every other provider uses, and the provider-config base_url stays settable per environment. Resolved 3-way merge conflicts in `crates/secrets/src/lib.rs` (env cleanup loop) and `crates/tui/src/config.rs` (per-provider base_url match arm + `provider_passes_model_through` predicate) so the contributor's AtlasCloud branch coexists with the v0.8.x provider expansion already on `main`. Added the missing match arm in `validate_provider_base_url` so the non-exhaustive-pattern check passes after the new variant lands. Harvested from PR #1436 by @lucaszhu-hue Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-3
@@ -26,6 +26,7 @@ enum ProviderArg {
|
||||
Deepseek,
|
||||
NvidiaNim,
|
||||
Openai,
|
||||
Atlascloud,
|
||||
Openrouter,
|
||||
Novita,
|
||||
Fireworks,
|
||||
@@ -40,6 +41,7 @@ impl From<ProviderArg> for ProviderKind {
|
||||
ProviderArg::Deepseek => ProviderKind::Deepseek,
|
||||
ProviderArg::NvidiaNim => ProviderKind::NvidiaNim,
|
||||
ProviderArg::Openai => ProviderKind::Openai,
|
||||
ProviderArg::Atlascloud => ProviderKind::Atlascloud,
|
||||
ProviderArg::Openrouter => ProviderKind::Openrouter,
|
||||
ProviderArg::Novita => ProviderKind::Novita,
|
||||
ProviderArg::Fireworks => ProviderKind::Fireworks,
|
||||
@@ -673,6 +675,7 @@ fn provider_slot(provider: ProviderKind) -> &'static str {
|
||||
ProviderKind::Deepseek => "deepseek",
|
||||
ProviderKind::NvidiaNim => "nvidia-nim",
|
||||
ProviderKind::Openai => "openai",
|
||||
ProviderKind::Atlascloud => "atlascloud",
|
||||
ProviderKind::Openrouter => "openrouter",
|
||||
ProviderKind::Novita => "novita",
|
||||
ProviderKind::Fireworks => "fireworks",
|
||||
@@ -683,16 +686,17 @@ fn provider_slot(provider: ProviderKind) -> &'static str {
|
||||
}
|
||||
|
||||
/// Provider order used by the `auth list` and `auth status` outputs.
|
||||
const PROVIDER_LIST: [ProviderKind; 9] = [
|
||||
const PROVIDER_LIST: [ProviderKind; 10] = [
|
||||
ProviderKind::Deepseek,
|
||||
ProviderKind::NvidiaNim,
|
||||
ProviderKind::Openai,
|
||||
ProviderKind::Atlascloud,
|
||||
ProviderKind::Openrouter,
|
||||
ProviderKind::Novita,
|
||||
ProviderKind::Fireworks,
|
||||
ProviderKind::Sglang,
|
||||
ProviderKind::Vllm,
|
||||
ProviderKind::Ollama,
|
||||
ProviderKind::Openai,
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -748,6 +752,7 @@ fn provider_env_vars(provider: ProviderKind) -> &'static [&'static str] {
|
||||
ProviderKind::Vllm => &["VLLM_API_KEY"],
|
||||
ProviderKind::Ollama => &["OLLAMA_API_KEY"],
|
||||
ProviderKind::Openai => &["OPENAI_API_KEY"],
|
||||
ProviderKind::Atlascloud => &["ATLASCLOUD_API_KEY"],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1390,6 +1395,7 @@ fn build_tui_command(
|
||||
ProviderKind::Deepseek
|
||||
| ProviderKind::NvidiaNim
|
||||
| ProviderKind::Openai
|
||||
| ProviderKind::Atlascloud
|
||||
| ProviderKind::Openrouter
|
||||
| ProviderKind::Novita
|
||||
| ProviderKind::Fireworks
|
||||
@@ -1398,7 +1404,7 @@ fn build_tui_command(
|
||||
| ProviderKind::Ollama
|
||||
) {
|
||||
bail!(
|
||||
"The interactive TUI supports DeepSeek, NVIDIA NIM, OpenAI-compatible, OpenRouter, Novita, Fireworks, SGLang, vLLM, and Ollama providers. Remove --provider {} or use `deepseek model ...` for provider registry inspection.",
|
||||
"The interactive TUI supports DeepSeek, NVIDIA NIM, OpenAI-compatible, AtlasCloud, OpenRouter, Novita, Fireworks, SGLang, vLLM, and Ollama providers. Remove --provider {} or use `deepseek model ...` for provider registry inspection.",
|
||||
resolved_runtime.provider.as_str()
|
||||
);
|
||||
}
|
||||
@@ -1420,6 +1426,9 @@ fn build_tui_command(
|
||||
if resolved_runtime.provider == ProviderKind::Openai {
|
||||
cmd.env("OPENAI_API_KEY", api_key);
|
||||
}
|
||||
if resolved_runtime.provider == ProviderKind::Atlascloud {
|
||||
cmd.env("ATLASCLOUD_API_KEY", api_key);
|
||||
}
|
||||
let source = resolved_runtime
|
||||
.api_key_source
|
||||
.unwrap_or(RuntimeApiKeySource::Env)
|
||||
@@ -1453,6 +1462,9 @@ fn build_tui_command(
|
||||
if resolved_runtime.provider == ProviderKind::Openai {
|
||||
cmd.env("OPENAI_API_KEY", api_key);
|
||||
}
|
||||
if resolved_runtime.provider == ProviderKind::Atlascloud {
|
||||
cmd.env("ATLASCLOUD_API_KEY", api_key);
|
||||
}
|
||||
cmd.env("DEEPSEEK_API_KEY_SOURCE", "cli");
|
||||
}
|
||||
if let Some(base_url) = cli.base_url.as_ref() {
|
||||
|
||||
Reference in New Issue
Block a user