diff --git a/src/commands/auth-choice-options.ts b/src/commands/auth-choice-options.ts index 077fee024b9..ca55eb957c5 100644 --- a/src/commands/auth-choice-options.ts +++ b/src/commands/auth-choice-options.ts @@ -128,8 +128,13 @@ const AUTH_CHOICE_GROUP_DEFS: { { value: "modelstudio", label: "Alibaba Cloud Model Studio", - hint: "Coding Plan API key (CN / Global)", - choices: ["modelstudio-api-key-cn", "modelstudio-api-key"], + hint: "Standard / Coding Plan (CN / Global)", + choices: [ + "modelstudio-standard-api-key-cn", + "modelstudio-standard-api-key", + "modelstudio-api-key-cn", + "modelstudio-api-key", + ], }, { value: "copilot", @@ -319,6 +324,16 @@ const BASE_AUTH_CHOICE_OPTIONS: ReadonlyArray = [ hint: "Official fast tier (legacy: Lightning)", }, { value: "qianfan-api-key", label: "Qianfan API key" }, + { + value: "modelstudio-standard-api-key-cn", + label: "Standard API Key for China (pay-as-you-go)", + hint: "Endpoint: dashscope.aliyuncs.com", + }, + { + value: "modelstudio-standard-api-key", + label: "Standard API Key for Global/Intl (pay-as-you-go)", + hint: "Endpoint: dashscope-intl.aliyuncs.com", + }, { value: "modelstudio-api-key-cn", label: "Coding Plan API Key for China (subscription)", diff --git a/src/commands/auth-choice.apply.api-providers.ts b/src/commands/auth-choice.apply.api-providers.ts index 9e7419f7fda..77a037c4abd 100644 --- a/src/commands/auth-choice.apply.api-providers.ts +++ b/src/commands/auth-choice.apply.api-providers.ts @@ -84,6 +84,10 @@ import { applyModelStudioConfigCn, applyModelStudioProviderConfig, applyModelStudioProviderConfigCn, + applyModelStudioStandardConfig, + applyModelStudioStandardConfigCn, + applyModelStudioStandardProviderConfig, + applyModelStudioStandardProviderConfigCn, setModelStudioApiKey, } from "./onboard-auth.js"; import type { AuthChoice, SecretInputMode } from "./onboard-types.js"; @@ -326,6 +330,46 @@ const SIMPLE_API_KEY_PROVIDER_FLOWS: Partial String(value ?? "").trim(), + validate: (value) => (String(value ?? "").trim() ? undefined : "Required"), + }, + "modelstudio-standard-api-key": { + provider: "modelstudio", + profileId: "modelstudio:default", + expectedProviders: ["modelstudio"], + envLabel: "MODELSTUDIO_API_KEY", + promptMessage: "Enter Alibaba Cloud Model Studio API key (Global/Intl)", + setCredential: setModelStudioApiKey, + defaultModel: MODELSTUDIO_DEFAULT_MODEL_REF, + applyDefaultConfig: applyModelStudioStandardConfig, + applyProviderConfig: applyModelStudioStandardProviderConfig, + noteDefault: MODELSTUDIO_DEFAULT_MODEL_REF, + noteMessage: [ + "Get your API key at: https://modelstudio.console.alibabacloud.com/", + "Endpoint: dashscope-intl.aliyuncs.com/compatible-mode/v1", + "Models: qwen3.5-plus, qwen3.5-flash, qwen3-coder-plus, etc.", + ].join("\n"), + noteTitle: "Alibaba Cloud Model Studio (Global/Intl)", + normalize: (value) => String(value ?? "").trim(), + validate: (value) => (String(value ?? "").trim() ? undefined : "Required"), + }, "modelstudio-api-key-cn": { provider: "modelstudio", profileId: "modelstudio:default", @@ -340,7 +384,7 @@ const SIMPLE_API_KEY_PROVIDER_FLOWS: Partial String(value ?? "").trim(), @@ -360,7 +404,7 @@ const SIMPLE_API_KEY_PROVIDER_FLOWS: Partial String(value ?? "").trim(), diff --git a/src/commands/onboard-auth.config-core.ts b/src/commands/onboard-auth.config-core.ts index 4bda29df1bf..0073a93dcb0 100644 --- a/src/commands/onboard-auth.config-core.ts +++ b/src/commands/onboard-auth.config-core.ts @@ -82,6 +82,8 @@ import { XAI_DEFAULT_MODEL_ID, MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_GLOBAL_BASE_URL, + MODELSTUDIO_STANDARD_CN_BASE_URL, + MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, MODELSTUDIO_DEFAULT_MODEL_REF, } from "./onboard-auth.models.js"; @@ -666,3 +668,23 @@ export function applyModelStudioConfigCn(cfg: OpenClawConfig): OpenClawConfig { const next = applyModelStudioProviderConfigCn(cfg); return applyAgentDefaultModelPrimary(next, MODELSTUDIO_DEFAULT_MODEL_REF); } + +// Alibaba Cloud Model Studio Standard (pay-as-you-go) + +export function applyModelStudioStandardProviderConfig(cfg: OpenClawConfig): OpenClawConfig { + return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL); +} + +export function applyModelStudioStandardProviderConfigCn(cfg: OpenClawConfig): OpenClawConfig { + return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_STANDARD_CN_BASE_URL); +} + +export function applyModelStudioStandardConfig(cfg: OpenClawConfig): OpenClawConfig { + const next = applyModelStudioStandardProviderConfig(cfg); + return applyAgentDefaultModelPrimary(next, MODELSTUDIO_DEFAULT_MODEL_REF); +} + +export function applyModelStudioStandardConfigCn(cfg: OpenClawConfig): OpenClawConfig { + const next = applyModelStudioStandardProviderConfigCn(cfg); + return applyAgentDefaultModelPrimary(next, MODELSTUDIO_DEFAULT_MODEL_REF); +} diff --git a/src/commands/onboard-auth.models.ts b/src/commands/onboard-auth.models.ts index 2945e7b4461..93fa9b6edf2 100644 --- a/src/commands/onboard-auth.models.ts +++ b/src/commands/onboard-auth.models.ts @@ -225,7 +225,12 @@ export function buildKilocodeModelDefinition(): ModelDefinitionConfig { }; } -// Alibaba Cloud Model Studio Coding Plan +// Alibaba Cloud Model Studio (百炼) +// Standard (pay-as-you-go) endpoints +export const MODELSTUDIO_STANDARD_CN_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"; +export const MODELSTUDIO_STANDARD_GLOBAL_BASE_URL = + "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"; +// Coding Plan (subscription) endpoints export const MODELSTUDIO_CN_BASE_URL = "https://coding.dashscope.aliyuncs.com/v1"; export const MODELSTUDIO_GLOBAL_BASE_URL = "https://coding-intl.dashscope.aliyuncs.com/v1"; export const MODELSTUDIO_DEFAULT_MODEL_ID = "qwen3.5-plus"; diff --git a/src/commands/onboard-auth.ts b/src/commands/onboard-auth.ts index cda460b6c19..e7e1b4f9783 100644 --- a/src/commands/onboard-auth.ts +++ b/src/commands/onboard-auth.ts @@ -43,6 +43,10 @@ export { applyModelStudioConfigCn, applyModelStudioProviderConfig, applyModelStudioProviderConfigCn, + applyModelStudioStandardConfig, + applyModelStudioStandardConfigCn, + applyModelStudioStandardProviderConfig, + applyModelStudioStandardProviderConfigCn, KILOCODE_BASE_URL, } from "./onboard-auth.config-core.js"; export { diff --git a/src/commands/onboard-non-interactive/local/auth-choice-inference.ts b/src/commands/onboard-non-interactive/local/auth-choice-inference.ts index 212bb9dd890..690c86c39ba 100644 --- a/src/commands/onboard-non-interactive/local/auth-choice-inference.ts +++ b/src/commands/onboard-non-interactive/local/auth-choice-inference.ts @@ -31,6 +31,8 @@ type AuthChoiceFlagOptions = Pick< | "xaiApiKey" | "litellmApiKey" | "qianfanApiKey" + | "modelstudioStandardApiKeyCn" + | "modelstudioStandardApiKey" | "modelstudioApiKeyCn" | "modelstudioApiKey" | "volcengineApiKey" diff --git a/src/commands/onboard-non-interactive/local/auth-choice.ts b/src/commands/onboard-non-interactive/local/auth-choice.ts index af119c12efe..c9b68c3925b 100644 --- a/src/commands/onboard-non-interactive/local/auth-choice.ts +++ b/src/commands/onboard-non-interactive/local/auth-choice.ts @@ -18,6 +18,8 @@ import { applyQianfanConfig, applyModelStudioConfig, applyModelStudioConfigCn, + applyModelStudioStandardConfig, + applyModelStudioStandardConfigCn, applyKimiCodeConfig, applyMinimaxApiConfig, applyMinimaxApiConfigCn, @@ -508,6 +510,60 @@ export async function applyNonInteractiveAuthChoice(params: { return applyQianfanConfig(nextConfig); } + if (authChoice === "modelstudio-standard-api-key-cn") { + const resolved = await resolveApiKey({ + provider: "modelstudio", + cfg: baseConfig, + flagValue: opts.modelstudioStandardApiKeyCn, + flagName: "--modelstudio-standard-api-key-cn", + envVar: "MODELSTUDIO_API_KEY", + runtime, + }); + if (!resolved) { + return null; + } + if ( + !(await maybeSetResolvedApiKey(resolved, (value) => + setModelStudioApiKey(value, undefined, apiKeyStorageOptions), + )) + ) { + return null; + } + nextConfig = applyAuthProfileConfig(nextConfig, { + profileId: "modelstudio:default", + provider: "modelstudio", + mode: "api_key", + }); + return applyModelStudioStandardConfigCn(nextConfig); + } + + if (authChoice === "modelstudio-standard-api-key") { + const resolved = await resolveApiKey({ + provider: "modelstudio", + cfg: baseConfig, + flagValue: opts.modelstudioStandardApiKey, + flagName: "--modelstudio-standard-api-key", + envVar: "MODELSTUDIO_API_KEY", + runtime, + }); + if (!resolved) { + return null; + } + if ( + !(await maybeSetResolvedApiKey(resolved, (value) => + setModelStudioApiKey(value, undefined, apiKeyStorageOptions), + )) + ) { + return null; + } + nextConfig = applyAuthProfileConfig(nextConfig, { + profileId: "modelstudio:default", + provider: "modelstudio", + mode: "api_key", + }); + return applyModelStudioStandardConfig(nextConfig); + } + if (authChoice === "modelstudio-api-key-cn") { const resolved = await resolveApiKey({ provider: "modelstudio", diff --git a/src/commands/onboard-provider-auth-flags.ts b/src/commands/onboard-provider-auth-flags.ts index 7610727097f..949469d53fd 100644 --- a/src/commands/onboard-provider-auth-flags.ts +++ b/src/commands/onboard-provider-auth-flags.ts @@ -24,6 +24,8 @@ type OnboardProviderAuthOptionKey = keyof Pick< | "xaiApiKey" | "litellmApiKey" | "qianfanApiKey" + | "modelstudioStandardApiKeyCn" + | "modelstudioStandardApiKey" | "modelstudioApiKeyCn" | "modelstudioApiKey" | "volcengineApiKey" @@ -194,6 +196,20 @@ export const ONBOARD_PROVIDER_AUTH_FLAGS: ReadonlyArray cliOption: "--qianfan-api-key ", description: "QIANFAN API key", }, + { + optionKey: "modelstudioStandardApiKeyCn", + authChoice: "modelstudio-standard-api-key-cn", + cliFlag: "--modelstudio-standard-api-key-cn", + cliOption: "--modelstudio-standard-api-key-cn ", + description: "Alibaba Cloud Model Studio API key (China, pay-as-you-go)", + }, + { + optionKey: "modelstudioStandardApiKey", + authChoice: "modelstudio-standard-api-key", + cliFlag: "--modelstudio-standard-api-key", + cliOption: "--modelstudio-standard-api-key ", + description: "Alibaba Cloud Model Studio API key (Global/Intl, pay-as-you-go)", + }, { optionKey: "modelstudioApiKeyCn", authChoice: "modelstudio-api-key-cn", diff --git a/src/commands/onboard-types.ts b/src/commands/onboard-types.ts index 40a02e85c15..224166c68df 100644 --- a/src/commands/onboard-types.ts +++ b/src/commands/onboard-types.ts @@ -51,6 +51,8 @@ export type AuthChoice = | "volcengine-api-key" | "byteplus-api-key" | "qianfan-api-key" + | "modelstudio-standard-api-key-cn" + | "modelstudio-standard-api-key" | "modelstudio-api-key-cn" | "modelstudio-api-key" | "custom-api-key" @@ -142,6 +144,8 @@ export type OnboardOptions = { volcengineApiKey?: string; byteplusApiKey?: string; qianfanApiKey?: string; + modelstudioStandardApiKeyCn?: string; + modelstudioStandardApiKey?: string; modelstudioApiKeyCn?: string; modelstudioApiKey?: string; customBaseUrl?: string;