From c8e67348a9725d34d989322bb9f1d14d3f7a3c96 Mon Sep 17 00:00:00 2001 From: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> Date: Tue, 11 Aug 2026 10:12:35 +0800 Subject: [PATCH] feat(ai): add Atlas Cloud provider preset Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> --- .../ai/aiSettingsModalConfig.test.tsx | 18 ++++++++++++++++++ .../components/ai/aiSettingsModalConfig.tsx | 3 +++ frontend/src/utils/aiProviderPresets.test.ts | 9 +++++++++ frontend/src/utils/aiProviderPresets.ts | 2 ++ shared/i18n/de-DE.json | 2 ++ shared/i18n/en-US.json | 2 ++ shared/i18n/ja-JP.json | 2 ++ shared/i18n/ru-RU.json | 2 ++ shared/i18n/zh-CN.json | 2 ++ shared/i18n/zh-TW.json | 2 ++ 10 files changed, 44 insertions(+) diff --git a/frontend/src/components/ai/aiSettingsModalConfig.test.tsx b/frontend/src/components/ai/aiSettingsModalConfig.test.tsx index 239d5dcb..621a9962 100644 --- a/frontend/src/components/ai/aiSettingsModalConfig.test.tsx +++ b/frontend/src/components/ai/aiSettingsModalConfig.test.tsx @@ -1,6 +1,8 @@ import { describe, expect, it } from 'vitest'; import { + ATLAS_CLOUD_BASE_URL, + ATLAS_CLOUD_DEFAULT_MODEL, QWEN_CODING_PLAN_ANTHROPIC_BASE_URL, resolvePresetBaseURL, resolvePresetTransport, @@ -53,6 +55,21 @@ describe('aiSettingsModalConfig', () => { expect(preset.key).toBe('cursor'); }); + it('exposes and recognizes the Atlas Cloud preset', () => { + const preset = findPreset('atlascloud'); + + expect(preset).toMatchObject({ + label: 'Atlas Cloud', + backendType: 'openai', + defaultBaseUrl: ATLAS_CLOUD_BASE_URL, + defaultModel: ATLAS_CLOUD_DEFAULT_MODEL, + }); + expect(matchProviderPreset({ + type: 'openai', + baseUrl: ATLAS_CLOUD_BASE_URL, + }).key).toBe('atlascloud'); + }); + it('supports every configured MiniMax region and protocol endpoint', () => { const preset = findPreset('minimax'); @@ -125,6 +142,7 @@ describe('aiSettingsModalConfig', () => { }); it('keeps the provider preset list available for the settings modal', () => { + expect(PROVIDER_PRESETS.some((item) => item.key === 'atlascloud')).toBe(true); expect(PROVIDER_PRESETS.some((item) => item.key === 'codex')).toBe(true); expect(PROVIDER_PRESETS.some((item) => item.key === 'claude-subscription')).toBe(true); expect(PROVIDER_PRESETS.some((item) => item.key === 'codebuddy')).toBe(true); diff --git a/frontend/src/components/ai/aiSettingsModalConfig.tsx b/frontend/src/components/ai/aiSettingsModalConfig.tsx index 6e9820f3..d032bbc6 100644 --- a/frontend/src/components/ai/aiSettingsModalConfig.tsx +++ b/frontend/src/components/ai/aiSettingsModalConfig.tsx @@ -16,6 +16,8 @@ import type { AIUserPromptSettings, } from '../../types'; import { + ATLAS_CLOUD_BASE_URL, + ATLAS_CLOUD_DEFAULT_MODEL, QWEN_BAILIAN_ANTHROPIC_BASE_URL, QWEN_CODING_PLAN_ANTHROPIC_BASE_URL, QWEN_CODING_PLAN_MODELS, @@ -50,6 +52,7 @@ export const MINIMAX_ENDPOINTS: ProviderPresetEndpoint[] = [ export const PROVIDER_PRESETS: ProviderPreset[] = [ { key: 'openai', label: 'OpenAI', labelKey: 'ai_settings.provider_preset.openai.label', icon: , desc: 'GPT-5.4 / 5.3 series', descKey: 'ai_settings.provider_preset.openai.desc', color: '#10b981', backendType: 'openai', defaultBaseUrl: 'https://api.openai.com/v1', defaultModel: 'gpt-4o', models: [] }, + { key: 'atlascloud', label: 'Atlas Cloud', labelKey: 'ai_settings.provider_preset.atlascloud.label', icon: , desc: 'Qwen3.8 Max / OpenAI-compatible', descKey: 'ai_settings.provider_preset.atlascloud.desc', color: '#0891b2', backendType: 'openai', defaultBaseUrl: ATLAS_CLOUD_BASE_URL, defaultModel: ATLAS_CLOUD_DEFAULT_MODEL, models: [] }, { key: 'codex', label: 'Codex Subscription', labelKey: 'ai_settings.provider_preset.codex.label', icon: , desc: 'Local Codex CLI / ChatGPT subscription login', descKey: 'ai_settings.provider_preset.codex.desc', color: '#111827', backendType: 'custom', fixedApiFormat: 'codex-cli', authMode: 'local-cli', defaultBaseUrl: '', defaultModel: '', models: [] }, { key: 'deepseek', label: 'DeepSeek', labelKey: 'ai_settings.provider_preset.deepseek.label', icon: , desc: 'DeepSeek-V4 / R1', descKey: 'ai_settings.provider_preset.deepseek.desc', color: '#3b82f6', backendType: 'openai', defaultBaseUrl: 'https://api.deepseek.com/v1', defaultModel: 'deepseek-chat', models: [] }, { key: 'qwen-bailian', label: 'Qwen (Bailian General)', labelKey: 'ai_settings.provider_preset.qwen_bailian.label', icon: , desc: 'Bailian Anthropic-compatible endpoint / remote model list', descKey: 'ai_settings.provider_preset.qwen_bailian.desc', color: '#6366f1', backendType: 'anthropic', defaultBaseUrl: QWEN_BAILIAN_ANTHROPIC_BASE_URL, defaultModel: '', models: [] }, diff --git a/frontend/src/utils/aiProviderPresets.test.ts b/frontend/src/utils/aiProviderPresets.test.ts index 6eaf8cbc..6a187009 100644 --- a/frontend/src/utils/aiProviderPresets.test.ts +++ b/frontend/src/utils/aiProviderPresets.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import type { AIProviderAuthMode, AIProviderType } from '../types'; import { + ATLAS_CLOUD_BASE_URL, LEGACY_QWEN_CODING_PLAN_OPENAI_BASE_URL, QWEN_BAILIAN_ANTHROPIC_BASE_URL, QWEN_BAILIAN_MODELS_BASE_URL, @@ -24,6 +25,7 @@ type PresetMatcher = { const PRESETS: PresetMatcher[] = [ { key: 'openai', backendType: 'openai', defaultBaseUrl: 'https://api.openai.com/v1' }, + { key: 'atlascloud', backendType: 'openai', defaultBaseUrl: ATLAS_CLOUD_BASE_URL }, { key: 'qwen-bailian', backendType: 'anthropic', defaultBaseUrl: QWEN_BAILIAN_ANTHROPIC_BASE_URL }, { key: 'qwen-coding-plan', @@ -212,6 +214,13 @@ describe('ai provider preset helpers', () => { }); describe('resolveProviderPresetKey', () => { + it('recognizes Atlas Cloud by its OpenAI-compatible endpoint', () => { + expect(resolveProviderPresetKey({ + type: 'openai', + baseUrl: `${ATLAS_CLOUD_BASE_URL}/`, + }, PRESETS, 'custom')).toBe('atlascloud'); + }); + it('不会把自定义 OpenAI 端点误识别成千问 Coding Plan', () => { const key = resolveProviderPresetKey( { diff --git a/frontend/src/utils/aiProviderPresets.ts b/frontend/src/utils/aiProviderPresets.ts index d28812c5..d6a21f7f 100644 --- a/frontend/src/utils/aiProviderPresets.ts +++ b/frontend/src/utils/aiProviderPresets.ts @@ -5,6 +5,8 @@ export const LEGACY_QWEN_CODING_PLAN_OPENAI_BASE_URL = 'https://coding.dashscope export const QWEN_BAILIAN_ANTHROPIC_BASE_URL = 'https://dashscope.aliyuncs.com/apps/anthropic'; export const QWEN_CODING_PLAN_ANTHROPIC_BASE_URL = 'https://coding.dashscope.aliyuncs.com/apps/anthropic'; export const QWEN_BAILIAN_MODELS_BASE_URL = LEGACY_QWEN_BAILIAN_OPENAI_BASE_URL; +export const ATLAS_CLOUD_BASE_URL = 'https://api.atlascloud.ai/v1'; +export const ATLAS_CLOUD_DEFAULT_MODEL = 'qwen/qwen3.8-max'; export const QWEN_CODING_PLAN_MODELS = [ 'qwen3.5-plus', diff --git a/shared/i18n/de-DE.json b/shared/i18n/de-DE.json index c28e9af2..10f57729 100644 --- a/shared/i18n/de-DE.json +++ b/shared/i18n/de-DE.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "Kein Modell ausgewählt", "ai_settings.provider_preset.anthropic.desc": "Claude Opus/Sonnet Modelle", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / OpenAI-kompatibel", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "Lokale Claude Code CLI / Claude-Abonnementanmeldung", "ai_settings.provider_preset.claude_subscription.label": "Claude-Abonnement", "ai_settings.provider_preset.codex.desc": "Lokale Codex CLI / ChatGPT-Abonnementanmeldung", diff --git a/shared/i18n/en-US.json b/shared/i18n/en-US.json index 1bd82f1c..007f533f 100644 --- a/shared/i18n/en-US.json +++ b/shared/i18n/en-US.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "No model selected", "ai_settings.provider_preset.anthropic.desc": "Claude Opus/Sonnet", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / OpenAI-compatible", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "Local Claude Code CLI / Claude subscription login", "ai_settings.provider_preset.claude_subscription.label": "Claude Subscription", "ai_settings.provider_preset.codex.desc": "Local Codex CLI / ChatGPT subscription login", diff --git a/shared/i18n/ja-JP.json b/shared/i18n/ja-JP.json index 03e2beb2..2b42d04e 100644 --- a/shared/i18n/ja-JP.json +++ b/shared/i18n/ja-JP.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "モデル未選択", "ai_settings.provider_preset.anthropic.desc": "Claude Opus/Sonnet モデル", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / OpenAI 互換", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "ローカル Claude Code CLI / Claude サブスクリプションログイン", "ai_settings.provider_preset.claude_subscription.label": "Claude サブスクリプション", "ai_settings.provider_preset.codex.desc": "ローカル Codex CLI / ChatGPT サブスクリプションログイン", diff --git a/shared/i18n/ru-RU.json b/shared/i18n/ru-RU.json index abd86748..b031bacb 100644 --- a/shared/i18n/ru-RU.json +++ b/shared/i18n/ru-RU.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "Модель не выбрана", "ai_settings.provider_preset.anthropic.desc": "Модели Claude Opus/Sonnet", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / совместимо с OpenAI", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "Локальный Claude Code CLI / вход по подписке Claude", "ai_settings.provider_preset.claude_subscription.label": "Подписка Claude", "ai_settings.provider_preset.codex.desc": "Локальный Codex CLI / вход по подписке ChatGPT", diff --git a/shared/i18n/zh-CN.json b/shared/i18n/zh-CN.json index 8b3ffa4f..0261189d 100644 --- a/shared/i18n/zh-CN.json +++ b/shared/i18n/zh-CN.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "未选择模型", "ai_settings.provider_preset.anthropic.desc": "Claude Opus/Sonnet 模型", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / OpenAI 兼容", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "本机 Claude Code CLI / Claude 订阅登录态", "ai_settings.provider_preset.claude_subscription.label": "Claude 订阅", "ai_settings.provider_preset.codex.desc": "本机 Codex CLI / ChatGPT 订阅登录态", diff --git a/shared/i18n/zh-TW.json b/shared/i18n/zh-TW.json index 32ab95ee..42b3b7cd 100644 --- a/shared/i18n/zh-TW.json +++ b/shared/i18n/zh-TW.json @@ -2352,6 +2352,8 @@ "ai_settings.provider.no_model": "尚未選擇模型", "ai_settings.provider_preset.anthropic.desc": "Claude Opus/Sonnet 模型", "ai_settings.provider_preset.anthropic.label": "Claude", + "ai_settings.provider_preset.atlascloud.desc": "Qwen3.8 Max / OpenAI 相容", + "ai_settings.provider_preset.atlascloud.label": "Atlas Cloud", "ai_settings.provider_preset.claude_subscription.desc": "本機 Claude Code CLI / Claude 訂閱登入狀態", "ai_settings.provider_preset.claude_subscription.label": "Claude 訂閱", "ai_settings.provider_preset.codex.desc": "本機 Codex CLI / ChatGPT 訂閱登入狀態",