diff --git a/.env.example b/.env.example index eb28de82..d059e02b 100644 --- a/.env.example +++ b/.env.example @@ -25,6 +25,12 @@ # NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1 # NVIDIA_NIM_MODEL=deepseek-ai/deepseek-v4-pro +# AtlasCloud OpenAI-compatible endpoint +# DEEPSEEK_PROVIDER=atlascloud +# ATLASCLOUD_API_KEY= +# ATLASCLOUD_BASE_URL=https://api.atlascloud.ai/v1 +# ATLASCLOUD_MODEL=deepseek-ai/deepseek-v4-flash + # Logging # `DEEPSEEK_LOG_LEVEL` is forwarded by the facade; `RUST_LOG` enables the # TUI's lightweight verbose logs for info/debug/trace directives. diff --git a/crates/agent/src/lib.rs b/crates/agent/src/lib.rs index ece17305..8d93d65b 100644 --- a/crates/agent/src/lib.rs +++ b/crates/agent/src/lib.rs @@ -87,6 +87,26 @@ impl Default for ModelRegistry { supports_tools: true, supports_reasoning: true, }, + ModelInfo { + id: "deepseek-ai/deepseek-v4-flash".to_string(), + provider: ProviderKind::Atlascloud, + aliases: vec![ + "deepseek-v4-flash".to_string(), + "atlascloud-deepseek-v4-flash".to_string(), + ], + supports_tools: true, + supports_reasoning: true, + }, + ModelInfo { + id: "deepseek-ai/deepseek-v4-pro".to_string(), + provider: ProviderKind::Atlascloud, + aliases: vec![ + "deepseek-v4-pro".to_string(), + "atlascloud-deepseek-v4-pro".to_string(), + ], + supports_tools: true, + supports_reasoning: true, + }, ModelInfo { id: "deepseek-reasoner".to_string(), provider: ProviderKind::WanjieArk, @@ -434,6 +454,34 @@ mod tests { assert_eq!(resolved.resolved.id, "deepseek-ai/deepseek-v4-flash"); } + #[test] + fn atlascloud_default_uses_namespaced_model_id() { + let registry = ModelRegistry::default(); + let resolved = registry.resolve(None, Some(ProviderKind::Atlascloud)); + + assert_eq!(resolved.resolved.provider, ProviderKind::Atlascloud); + assert_eq!(resolved.resolved.id, "deepseek-ai/deepseek-v4-flash"); + assert!(resolved.resolved.supports_reasoning); + } + + #[test] + fn deepseek_v4_flash_alias_resolves_to_atlascloud_when_provider_hinted() { + let registry = ModelRegistry::default(); + let resolved = registry.resolve(Some("deepseek-v4-flash"), Some(ProviderKind::Atlascloud)); + + assert_eq!(resolved.resolved.provider, ProviderKind::Atlascloud); + assert_eq!(resolved.resolved.id, "deepseek-ai/deepseek-v4-flash"); + } + + #[test] + fn deepseek_v4_pro_alias_resolves_to_atlascloud_when_provider_hinted() { + let registry = ModelRegistry::default(); + let resolved = registry.resolve(Some("deepseek-v4-pro"), Some(ProviderKind::Atlascloud)); + + assert_eq!(resolved.resolved.provider, ProviderKind::Atlascloud); + assert_eq!(resolved.resolved.id, "deepseek-ai/deepseek-v4-pro"); + } + #[test] fn openrouter_default_uses_namespaced_model_id() { let registry = ModelRegistry::default(); diff --git a/docs/PROVIDERS.md b/docs/PROVIDERS.md index 425155d4..abfa1bbe 100644 --- a/docs/PROVIDERS.md +++ b/docs/PROVIDERS.md @@ -114,7 +114,7 @@ endpoint. | `deepseek` | `[providers.deepseek]` | `DEEPSEEK_API_KEY` | `CODEWHALE_BASE_URL` / `DEEPSEEK_BASE_URL`; default `https://api.deepseek.com/beta` | `deepseek-v4-pro`, `deepseek-v4-flash`; compatibility aliases `deepseek-chat`, `deepseek-reasoner` | First-class default. Beta URL enables strict tool mode, chat prefix completion, and FIM completion. Set `https://api.deepseek.com` or `/v1` explicitly to opt out of beta-only features. | | `nvidia-nim` | `[providers.nvidia_nim]` | `NVIDIA_API_KEY`, `NVIDIA_NIM_API_KEY`, fallback `DEEPSEEK_API_KEY` | `NVIDIA_NIM_BASE_URL`, `NIM_BASE_URL`, `NVIDIA_BASE_URL`; default `https://integrate.api.nvidia.com/v1` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | Hosted DeepSeek V4 through NVIDIA NIM. `NVIDIA_NIM_MODEL` is accepted by the TUI config path. | | `openai` | `[providers.openai]` | `OPENAI_API_KEY` | `OPENAI_BASE_URL`; default `https://api.openai.com/v1` | Registry entries: `deepseek-v4-pro`, `deepseek-v4-flash`; default config model `deepseek-v4-pro` | Generic OpenAI-compatible route for gateways and custom endpoints. Use this for explicit third-party OpenAI-compatible routes instead of inventing a new provider ID. `OPENAI_MODEL` is accepted. | -| `atlascloud` | `[providers.atlascloud]` | `ATLASCLOUD_API_KEY` | `ATLASCLOUD_BASE_URL`; default `https://api.atlascloud.ai/v1` | Default config model `deepseek-ai/deepseek-v4-flash` | OpenAI-compatible hosted route. `ATLASCLOUD_MODEL` is accepted by the TUI config path. The static `ModelRegistry` does not currently list AtlasCloud rows. | +| `atlascloud` | `[providers.atlascloud]` | `ATLASCLOUD_API_KEY` | `ATLASCLOUD_BASE_URL`; default `https://api.atlascloud.ai/v1` | `deepseek-ai/deepseek-v4-flash`, `deepseek-ai/deepseek-v4-pro` | OpenAI-compatible hosted route. `ATLASCLOUD_MODEL` is accepted by the TUI config path, and the static `ModelRegistry` includes AtlasCloud fallback rows for CLI model resolution. | | `wanjie-ark` | `[providers.wanjie_ark]` | `WANJIE_ARK_API_KEY`, `WANJIE_API_KEY`, `WANJIE_MAAS_API_KEY` | `WANJIE_ARK_BASE_URL`, `WANJIE_BASE_URL`, `WANJIE_MAAS_BASE_URL`; default `https://maas-openapi.wanjiedata.com/api/v1` | `deepseek-reasoner` | OpenAI-compatible hosted route. `WANJIE_ARK_MODEL`, `WANJIE_MODEL`, and `WANJIE_MAAS_MODEL` are accepted. | | `volcengine` | `[providers.volcengine]` | `VOLCENGINE_API_KEY`, `VOLCENGINE_ARK_API_KEY`, `ARK_API_KEY` | `VOLCENGINE_BASE_URL`, `VOLCENGINE_ARK_BASE_URL`, `ARK_BASE_URL`; default `https://ark.cn-beijing.volces.com/api/coding/v3` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | Volcengine/Volcano Engine Ark OpenAI-compatible coding endpoint. `VOLCENGINE_MODEL` and `VOLCENGINE_ARK_MODEL` are accepted. | | `openrouter` | `[providers.openrouter]` | `OPENROUTER_API_KEY` | `OPENROUTER_BASE_URL`; default `https://openrouter.ai/api/v1` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | Additive open-model routing layer. It does not replace DeepSeek; it lets users route supported model IDs through OpenRouter when they choose it. | @@ -148,6 +148,7 @@ endpoint when the endpoint supports model listing. | `deepseek` | `deepseek-v4-pro`, `deepseek-v4-flash` | yes | yes | | `nvidia-nim` | `deepseek-ai/deepseek-v4-pro`, `deepseek-ai/deepseek-v4-flash` | yes | yes | | `openai` | `deepseek-v4-pro`, `deepseek-v4-flash` | yes | yes | +| `atlascloud` | `deepseek-ai/deepseek-v4-flash`, `deepseek-ai/deepseek-v4-pro` | yes | yes | | `wanjie-ark` | `deepseek-reasoner` | yes | yes | | `volcengine` | `DeepSeek-V4-Pro`, `DeepSeek-V4-Flash` | yes | yes | | `openrouter` | `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash` | yes | yes | @@ -160,9 +161,10 @@ endpoint when the endpoint supports model listing. | `vllm` | `deepseek-ai/DeepSeek-V4-Pro`, `deepseek-ai/DeepSeek-V4-Flash` | yes | yes | | `ollama` | `deepseek-coder:1.3b`; custom tags pass through when provider hint is `ollama` | yes | no | -The registry currently has no AtlasCloud entry even though AtlasCloud is a -supported provider in config and TUI selection. AtlasCloud should use the -configured model or live model listing. +AtlasCloud keeps the same default model as the config layer and adds +provider-scoped aliases for the Pro and Flash rows. Other AtlasCloud model IDs +should still be selected through `ATLASCLOUD_MODEL`, config, or live model +listing when available. ## Capability Metadata