Files
openclaw/src/commands/onboard-auth.config-core.ts
2026-02-18 01:34:35 +00:00

487 lines
16 KiB
TypeScript

import {
buildHuggingfaceModelDefinition,
HUGGINGFACE_BASE_URL,
HUGGINGFACE_MODEL_CATALOG,
} from "../agents/huggingface-models.js";
import {
buildQianfanProvider,
buildXiaomiProvider,
QIANFAN_DEFAULT_MODEL_ID,
XIAOMI_DEFAULT_MODEL_ID,
} from "../agents/models-config.providers.js";
import {
buildSyntheticModelDefinition,
SYNTHETIC_BASE_URL,
SYNTHETIC_DEFAULT_MODEL_REF,
SYNTHETIC_MODEL_CATALOG,
} from "../agents/synthetic-models.js";
import {
buildTogetherModelDefinition,
TOGETHER_BASE_URL,
TOGETHER_MODEL_CATALOG,
} from "../agents/together-models.js";
import {
buildVeniceModelDefinition,
VENICE_BASE_URL,
VENICE_DEFAULT_MODEL_REF,
VENICE_MODEL_CATALOG,
} from "../agents/venice-models.js";
import type { OpenClawConfig } from "../config/config.js";
import type { ModelApi } from "../config/types.models.js";
import {
HUGGINGFACE_DEFAULT_MODEL_REF,
OPENROUTER_DEFAULT_MODEL_REF,
TOGETHER_DEFAULT_MODEL_REF,
XIAOMI_DEFAULT_MODEL_REF,
ZAI_DEFAULT_MODEL_REF,
XAI_DEFAULT_MODEL_REF,
} from "./onboard-auth.credentials.js";
export {
applyCloudflareAiGatewayConfig,
applyCloudflareAiGatewayProviderConfig,
applyVercelAiGatewayConfig,
applyVercelAiGatewayProviderConfig,
} from "./onboard-auth.config-gateways.js";
export {
applyLitellmConfig,
applyLitellmProviderConfig,
LITELLM_BASE_URL,
LITELLM_DEFAULT_MODEL_ID,
} from "./onboard-auth.config-litellm.js";
import {
applyAgentDefaultModelPrimary,
applyOnboardAuthAgentModelsAndProviders,
applyProviderConfigWithDefaultModel,
applyProviderConfigWithDefaultModels,
applyProviderConfigWithModelCatalog,
} from "./onboard-auth.config-shared.js";
import {
buildZaiModelDefinition,
buildMoonshotModelDefinition,
buildXaiModelDefinition,
QIANFAN_BASE_URL,
QIANFAN_DEFAULT_MODEL_REF,
KIMI_CODING_MODEL_REF,
MOONSHOT_BASE_URL,
MOONSHOT_CN_BASE_URL,
MOONSHOT_DEFAULT_MODEL_ID,
MOONSHOT_DEFAULT_MODEL_REF,
ZAI_DEFAULT_MODEL_ID,
resolveZaiBaseUrl,
XAI_BASE_URL,
XAI_DEFAULT_MODEL_ID,
} from "./onboard-auth.models.js";
export function applyZaiProviderConfig(
cfg: OpenClawConfig,
params?: { endpoint?: string; modelId?: string },
): OpenClawConfig {
const modelId = params?.modelId?.trim() || ZAI_DEFAULT_MODEL_ID;
const modelRef = `zai/${modelId}`;
const models = { ...cfg.agents?.defaults?.models };
models[modelRef] = {
...models[modelRef],
alias: models[modelRef]?.alias ?? "GLM",
};
const providers = { ...cfg.models?.providers };
const existingProvider = providers.zai;
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
const defaultModels = [
buildZaiModelDefinition({ id: "glm-5" }),
buildZaiModelDefinition({ id: "glm-4.7" }),
buildZaiModelDefinition({ id: "glm-4.7-flash" }),
buildZaiModelDefinition({ id: "glm-4.7-flashx" }),
];
const mergedModels = [...existingModels];
const seen = new Set(existingModels.map((m) => m.id));
for (const model of defaultModels) {
if (!seen.has(model.id)) {
mergedModels.push(model);
seen.add(model.id);
}
}
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
string,
unknown
> as { apiKey?: string };
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
const normalizedApiKey = resolvedApiKey?.trim();
const baseUrl = params?.endpoint
? resolveZaiBaseUrl(params.endpoint)
: (typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl : "") ||
resolveZaiBaseUrl();
providers.zai = {
...existingProviderRest,
baseUrl,
api: "openai-completions",
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
models: mergedModels.length > 0 ? mergedModels : defaultModels,
};
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
}
export function applyZaiConfig(
cfg: OpenClawConfig,
params?: { endpoint?: string; modelId?: string },
): OpenClawConfig {
const modelId = params?.modelId?.trim() || ZAI_DEFAULT_MODEL_ID;
const modelRef = modelId === ZAI_DEFAULT_MODEL_ID ? ZAI_DEFAULT_MODEL_REF : `zai/${modelId}`;
const next = applyZaiProviderConfig(cfg, params);
return applyAgentDefaultModelPrimary(next, modelRef);
}
export function applyOpenrouterProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[OPENROUTER_DEFAULT_MODEL_REF] = {
...models[OPENROUTER_DEFAULT_MODEL_REF],
alias: models[OPENROUTER_DEFAULT_MODEL_REF]?.alias ?? "OpenRouter",
};
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
models,
},
},
};
}
export function applyOpenrouterConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyOpenrouterProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, OPENROUTER_DEFAULT_MODEL_REF);
}
export function applyMoonshotProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
return applyMoonshotProviderConfigWithBaseUrl(cfg, MOONSHOT_BASE_URL);
}
export function applyMoonshotProviderConfigCn(cfg: OpenClawConfig): OpenClawConfig {
return applyMoonshotProviderConfigWithBaseUrl(cfg, MOONSHOT_CN_BASE_URL);
}
function applyMoonshotProviderConfigWithBaseUrl(
cfg: OpenClawConfig,
baseUrl: string,
): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[MOONSHOT_DEFAULT_MODEL_REF] = {
...models[MOONSHOT_DEFAULT_MODEL_REF],
alias: models[MOONSHOT_DEFAULT_MODEL_REF]?.alias ?? "Kimi",
};
const defaultModel = buildMoonshotModelDefinition();
return applyProviderConfigWithDefaultModel(cfg, {
agentModels: models,
providerId: "moonshot",
api: "openai-completions",
baseUrl,
defaultModel,
defaultModelId: MOONSHOT_DEFAULT_MODEL_ID,
});
}
export function applyMoonshotConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyMoonshotProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, MOONSHOT_DEFAULT_MODEL_REF);
}
export function applyMoonshotConfigCn(cfg: OpenClawConfig): OpenClawConfig {
const next = applyMoonshotProviderConfigCn(cfg);
return applyAgentDefaultModelPrimary(next, MOONSHOT_DEFAULT_MODEL_REF);
}
export function applyKimiCodeProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[KIMI_CODING_MODEL_REF] = {
...models[KIMI_CODING_MODEL_REF],
alias: models[KIMI_CODING_MODEL_REF]?.alias ?? "Kimi K2.5",
};
return {
...cfg,
agents: {
...cfg.agents,
defaults: {
...cfg.agents?.defaults,
models,
},
},
};
}
export function applyKimiCodeConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyKimiCodeProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, KIMI_CODING_MODEL_REF);
}
export function applySyntheticProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[SYNTHETIC_DEFAULT_MODEL_REF] = {
...models[SYNTHETIC_DEFAULT_MODEL_REF],
alias: models[SYNTHETIC_DEFAULT_MODEL_REF]?.alias ?? "MiniMax M2.1",
};
const providers = { ...cfg.models?.providers };
const existingProvider = providers.synthetic;
const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
const syntheticModels = SYNTHETIC_MODEL_CATALOG.map(buildSyntheticModelDefinition);
const mergedModels = [
...existingModels,
...syntheticModels.filter(
(model) => !existingModels.some((existing) => existing.id === model.id),
),
];
const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
string,
unknown
> as { apiKey?: string };
const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
const normalizedApiKey = resolvedApiKey?.trim();
providers.synthetic = {
...existingProviderRest,
baseUrl: SYNTHETIC_BASE_URL,
api: "anthropic-messages",
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
models: mergedModels.length > 0 ? mergedModels : syntheticModels,
};
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
}
export function applySyntheticConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applySyntheticProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, SYNTHETIC_DEFAULT_MODEL_REF);
}
export function applyXiaomiProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[XIAOMI_DEFAULT_MODEL_REF] = {
...models[XIAOMI_DEFAULT_MODEL_REF],
alias: models[XIAOMI_DEFAULT_MODEL_REF]?.alias ?? "Xiaomi",
};
const defaultProvider = buildXiaomiProvider();
const resolvedApi = defaultProvider.api ?? "openai-completions";
return applyProviderConfigWithDefaultModels(cfg, {
agentModels: models,
providerId: "xiaomi",
api: resolvedApi,
baseUrl: defaultProvider.baseUrl,
defaultModels: defaultProvider.models ?? [],
defaultModelId: XIAOMI_DEFAULT_MODEL_ID,
});
}
export function applyXiaomiConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyXiaomiProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, XIAOMI_DEFAULT_MODEL_REF);
}
/**
* Apply Venice provider configuration without changing the default model.
* Registers Venice models and sets up the provider, but preserves existing model selection.
*/
export function applyVeniceProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[VENICE_DEFAULT_MODEL_REF] = {
...models[VENICE_DEFAULT_MODEL_REF],
alias: models[VENICE_DEFAULT_MODEL_REF]?.alias ?? "Llama 3.3 70B",
};
const veniceModels = VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "venice",
api: "openai-completions",
baseUrl: VENICE_BASE_URL,
catalogModels: veniceModels,
});
}
/**
* Apply Venice provider configuration AND set Venice as the default model.
* Use this when Venice is the primary provider choice during onboarding.
*/
export function applyVeniceConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyVeniceProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, VENICE_DEFAULT_MODEL_REF);
}
/**
* Apply Together provider configuration without changing the default model.
* Registers Together models and sets up the provider, but preserves existing model selection.
*/
export function applyTogetherProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[TOGETHER_DEFAULT_MODEL_REF] = {
...models[TOGETHER_DEFAULT_MODEL_REF],
alias: models[TOGETHER_DEFAULT_MODEL_REF]?.alias ?? "Together AI",
};
const togetherModels = TOGETHER_MODEL_CATALOG.map(buildTogetherModelDefinition);
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "together",
api: "openai-completions",
baseUrl: TOGETHER_BASE_URL,
catalogModels: togetherModels,
});
}
/**
* Apply Together provider configuration AND set Together as the default model.
* Use this when Together is the primary provider choice during onboarding.
*/
export function applyTogetherConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyTogetherProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, TOGETHER_DEFAULT_MODEL_REF);
}
/**
* Apply Hugging Face (Inference Providers) provider configuration without changing the default model.
*/
export function applyHuggingfaceProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[HUGGINGFACE_DEFAULT_MODEL_REF] = {
...models[HUGGINGFACE_DEFAULT_MODEL_REF],
alias: models[HUGGINGFACE_DEFAULT_MODEL_REF]?.alias ?? "Hugging Face",
};
const hfModels = HUGGINGFACE_MODEL_CATALOG.map(buildHuggingfaceModelDefinition);
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "huggingface",
api: "openai-completions",
baseUrl: HUGGINGFACE_BASE_URL,
catalogModels: hfModels,
});
}
/**
* Apply Hugging Face provider configuration AND set Hugging Face as the default model.
*/
export function applyHuggingfaceConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyHuggingfaceProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, HUGGINGFACE_DEFAULT_MODEL_REF);
}
export function applyXaiProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[XAI_DEFAULT_MODEL_REF] = {
...models[XAI_DEFAULT_MODEL_REF],
alias: models[XAI_DEFAULT_MODEL_REF]?.alias ?? "Grok",
};
const defaultModel = buildXaiModelDefinition();
return applyProviderConfigWithDefaultModel(cfg, {
agentModels: models,
providerId: "xai",
api: "openai-completions",
baseUrl: XAI_BASE_URL,
defaultModel,
defaultModelId: XAI_DEFAULT_MODEL_ID,
});
}
export function applyXaiConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyXaiProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, XAI_DEFAULT_MODEL_REF);
}
export function applyAuthProfileConfig(
cfg: OpenClawConfig,
params: {
profileId: string;
provider: string;
mode: "api_key" | "oauth" | "token";
email?: string;
preferProfileFirst?: boolean;
},
): OpenClawConfig {
const profiles = {
...cfg.auth?.profiles,
[params.profileId]: {
provider: params.provider,
mode: params.mode,
...(params.email ? { email: params.email } : {}),
},
};
// Only maintain `auth.order` when the user explicitly configured it.
// Default behavior: no explicit order -> resolveAuthProfileOrder can round-robin by lastUsed.
const existingProviderOrder = cfg.auth?.order?.[params.provider];
const preferProfileFirst = params.preferProfileFirst ?? true;
const reorderedProviderOrder =
existingProviderOrder && preferProfileFirst
? [
params.profileId,
...existingProviderOrder.filter((profileId) => profileId !== params.profileId),
]
: existingProviderOrder;
const order =
existingProviderOrder !== undefined
? {
...cfg.auth?.order,
[params.provider]: reorderedProviderOrder?.includes(params.profileId)
? reorderedProviderOrder
: [...(reorderedProviderOrder ?? []), params.profileId],
}
: cfg.auth?.order;
return {
...cfg,
auth: {
...cfg.auth,
profiles,
...(order ? { order } : {}),
},
};
}
export function applyQianfanProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[QIANFAN_DEFAULT_MODEL_REF] = {
...models[QIANFAN_DEFAULT_MODEL_REF],
alias: models[QIANFAN_DEFAULT_MODEL_REF]?.alias ?? "QIANFAN",
};
const defaultProvider = buildQianfanProvider();
const existingProvider = cfg.models?.providers?.qianfan as
| {
baseUrl?: unknown;
api?: unknown;
}
| undefined;
const existingBaseUrl =
typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl.trim() : "";
const resolvedBaseUrl = existingBaseUrl || QIANFAN_BASE_URL;
const resolvedApi =
typeof existingProvider?.api === "string"
? (existingProvider.api as ModelApi)
: "openai-completions";
return applyProviderConfigWithDefaultModels(cfg, {
agentModels: models,
providerId: "qianfan",
api: resolvedApi,
baseUrl: resolvedBaseUrl,
defaultModels: defaultProvider.models ?? [],
defaultModelId: QIANFAN_DEFAULT_MODEL_ID,
});
}
export function applyQianfanConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyQianfanProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, QIANFAN_DEFAULT_MODEL_REF);
}