feat: add aliyun qwen backup provider
This commit is contained in:
@@ -127,7 +127,7 @@ export type LoginMethod = "password" | "code";
|
||||
export type OtaUpdateStatus = "available" | "scheduled" | "applied" | "skipped";
|
||||
export type OtaLogStatus = "checked" | "applied" | "skipped";
|
||||
export type AppLogLevel = "info" | "warn" | "error";
|
||||
export type AiProvider = "master_codex_node" | "openai_api";
|
||||
export type AiProvider = "master_codex_node" | "openai_api" | "aliyun_qwen_api";
|
||||
export type AiAccountRole = "primary" | "backup" | "api_fallback";
|
||||
export type AiAccountStatus = "ready" | "needs_login" | "needs_api_key" | "degraded" | "disabled";
|
||||
export type MasterAgentTaskStatus = "queued" | "running" | "completed" | "failed";
|
||||
@@ -2254,6 +2254,8 @@ export function aiProviderLabel(provider: AiProvider) {
|
||||
return "Master Codex Node / ChatGPT Plus 节点";
|
||||
case "openai_api":
|
||||
return "OpenAI API";
|
||||
case "aliyun_qwen_api":
|
||||
return "阿里百炼 Qwen";
|
||||
default:
|
||||
return provider;
|
||||
}
|
||||
@@ -2283,9 +2285,13 @@ function maskApiKey(value?: string) {
|
||||
return `${trimmed.slice(0, 4)}...${trimmed.slice(-4)}`;
|
||||
}
|
||||
|
||||
function isApiKeyProvider(provider: AiProvider) {
|
||||
return provider === "openai_api" || provider === "aliyun_qwen_api";
|
||||
}
|
||||
|
||||
function deriveAiAccountStatus(account: AiAccount): AiAccountStatus {
|
||||
if (!account.enabled) return "disabled";
|
||||
if (account.provider === "openai_api") {
|
||||
if (isApiKeyProvider(account.provider)) {
|
||||
if (!account.apiKey?.trim()) return "needs_api_key";
|
||||
return account.status === "disabled" ? "ready" : account.status;
|
||||
}
|
||||
@@ -2458,7 +2464,7 @@ export function getMasterIdentitySummaryFromState(state: BossState): MasterIdent
|
||||
status: "needs_api_key",
|
||||
statusLabel: aiStatusLabel("needs_api_key"),
|
||||
canGenerate: false,
|
||||
note: "请到“我的 > AI 账号”至少配置一个可用的 Master Codex Node 或 OpenAI API 账号。",
|
||||
note: "请到“我的 > AI 账号”至少配置一个可用的 Master Codex Node、OpenAI API 或阿里百炼 Qwen 账号。",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4662,6 +4668,12 @@ export async function saveAiAccount(payload: {
|
||||
existing?.accountId ??
|
||||
payload.accountId?.trim() ??
|
||||
`ai-${slugify(`${payload.label}-${payload.displayName}`)}`;
|
||||
const defaultModel =
|
||||
payload.provider === "aliyun_qwen_api"
|
||||
? "qwen3.5-plus"
|
||||
: payload.provider === "openai_api"
|
||||
? "gpt-5.4"
|
||||
: undefined;
|
||||
const next: AiAccount = normalizeAiAccount({
|
||||
accountId,
|
||||
label: payload.label.trim() || aiRoleLabel(payload.role),
|
||||
@@ -4671,21 +4683,21 @@ export async function saveAiAccount(payload: {
|
||||
accountIdentifier: payload.accountIdentifier?.trim() || undefined,
|
||||
nodeId: payload.nodeId?.trim() || undefined,
|
||||
nodeLabel: payload.nodeLabel?.trim() || undefined,
|
||||
model: payload.model?.trim() || (payload.provider === "openai_api" ? "gpt-5.4" : undefined),
|
||||
model: payload.model?.trim() || defaultModel,
|
||||
apiKey:
|
||||
payload.provider === "openai_api"
|
||||
isApiKeyProvider(payload.provider)
|
||||
? payload.apiKey?.trim()
|
||||
? payload.apiKey.trim()
|
||||
: existing?.apiKey
|
||||
: undefined,
|
||||
apiKeyMasked:
|
||||
payload.provider === "openai_api"
|
||||
isApiKeyProvider(payload.provider)
|
||||
? maskApiKey(payload.apiKey?.trim() || existing?.apiKey)
|
||||
: undefined,
|
||||
enabled: payload.enabled ?? existing?.enabled ?? true,
|
||||
isActive: existing?.isActive ?? false,
|
||||
status:
|
||||
payload.provider === "openai_api"
|
||||
isApiKeyProvider(payload.provider)
|
||||
? payload.apiKey?.trim() || existing?.apiKey
|
||||
? existing?.status === "degraded"
|
||||
? "degraded"
|
||||
|
||||
Reference in New Issue
Block a user