refactor: move remaining provider onboarding into extensions

This commit is contained in:
Peter Steinberger
2026-03-16 19:56:19 -07:00
parent 7df0ced8ac
commit f6d3aaa442
8 changed files with 183 additions and 229 deletions

View File

@@ -3,11 +3,8 @@ import {
createKilocodeWrapper,
isProxyReasoningUnsupported,
} from "../../src/agents/pi-embedded-runner/proxy-stream-wrappers.js";
import {
applyKilocodeConfig,
KILOCODE_DEFAULT_MODEL_REF,
} from "../../src/commands/onboard-auth.js";
import { createProviderApiKeyAuthMethod } from "../../src/plugins/provider-api-key-auth.js";
import { applyKilocodeConfig, KILOCODE_DEFAULT_MODEL_REF } from "./onboard.js";
import { buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
const PROVIDER_ID = "kilocode";

View File

@@ -0,0 +1,35 @@
import {
applyAgentDefaultModelPrimary,
applyProviderConfigWithModelCatalog,
} from "../../src/commands/onboard-auth.config-shared.js";
import type { OpenClawConfig } from "../../src/config/config.js";
import {
KILOCODE_BASE_URL,
KILOCODE_DEFAULT_MODEL_REF,
} from "../../src/providers/kilocode-shared.js";
import { buildKilocodeProvider } from "./provider-catalog.js";
export { KILOCODE_BASE_URL, KILOCODE_DEFAULT_MODEL_REF };
export function applyKilocodeProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[KILOCODE_DEFAULT_MODEL_REF] = {
...models[KILOCODE_DEFAULT_MODEL_REF],
alias: models[KILOCODE_DEFAULT_MODEL_REF]?.alias ?? "Kilo Gateway",
};
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "kilocode",
api: "openai-completions",
baseUrl: KILOCODE_BASE_URL,
catalogModels: buildKilocodeProvider().models ?? [],
});
}
export function applyKilocodeConfig(cfg: OpenClawConfig): OpenClawConfig {
return applyAgentDefaultModelPrimary(
applyKilocodeProviderConfig(cfg),
KILOCODE_DEFAULT_MODEL_REF,
);
}

View File

@@ -1,10 +1,10 @@
import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { createProviderApiKeyAuthMethod } from "../../src/plugins/provider-api-key-auth.js";
import {
applyModelStudioConfig,
applyModelStudioConfigCn,
MODELSTUDIO_DEFAULT_MODEL_REF,
} from "../../src/commands/onboard-auth.js";
import { createProviderApiKeyAuthMethod } from "../../src/plugins/provider-api-key-auth.js";
} from "./onboard.js";
import { buildModelStudioProvider } from "./provider-catalog.js";
const PROVIDER_ID = "modelstudio";

View File

@@ -0,0 +1,61 @@
import {
applyAgentDefaultModelPrimary,
applyProviderConfigWithModelCatalog,
} from "../../src/commands/onboard-auth.config-shared.js";
import {
MODELSTUDIO_CN_BASE_URL,
MODELSTUDIO_DEFAULT_MODEL_REF,
MODELSTUDIO_GLOBAL_BASE_URL,
} from "../../src/commands/onboard-auth.models.js";
import type { OpenClawConfig } from "../../src/config/config.js";
import { buildModelStudioProvider } from "./provider-catalog.js";
export { MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL };
function applyModelStudioProviderConfigWithBaseUrl(
cfg: OpenClawConfig,
baseUrl: string,
): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
const provider = buildModelStudioProvider();
for (const model of provider.models ?? []) {
const modelRef = `modelstudio/${model.id}`;
if (!models[modelRef]) {
models[modelRef] = {};
}
}
models[MODELSTUDIO_DEFAULT_MODEL_REF] = {
...models[MODELSTUDIO_DEFAULT_MODEL_REF],
alias: models[MODELSTUDIO_DEFAULT_MODEL_REF]?.alias ?? "Qwen",
};
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "modelstudio",
api: provider.api ?? "openai-completions",
baseUrl,
catalogModels: provider.models ?? [],
});
}
export function applyModelStudioProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_GLOBAL_BASE_URL);
}
export function applyModelStudioProviderConfigCn(cfg: OpenClawConfig): OpenClawConfig {
return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_CN_BASE_URL);
}
export function applyModelStudioConfig(cfg: OpenClawConfig): OpenClawConfig {
return applyAgentDefaultModelPrimary(
applyModelStudioProviderConfig(cfg),
MODELSTUDIO_DEFAULT_MODEL_REF,
);
}
export function applyModelStudioConfigCn(cfg: OpenClawConfig): OpenClawConfig {
return applyAgentDefaultModelPrimary(
applyModelStudioProviderConfigCn(cfg),
MODELSTUDIO_DEFAULT_MODEL_REF,
);
}

View File

@@ -20,17 +20,13 @@ import {
} from "../../src/commands/auth-choice.api-key.js";
import { ensureApiKeyFromOptionEnvOrPrompt } from "../../src/commands/auth-choice.apply-helpers.js";
import { buildApiKeyCredential } from "../../src/commands/onboard-auth.credentials.js";
import {
applyAuthProfileConfig,
applyZaiConfig,
applyZaiProviderConfig,
ZAI_DEFAULT_MODEL_REF,
} from "../../src/commands/onboard-auth.js";
import { applyAuthProfileConfig } from "../../src/commands/onboard-auth.js";
import type { SecretInput } from "../../src/config/types.secrets.js";
import { resolveRequiredHomeDir } from "../../src/infra/home-dir.js";
import { fetchZaiUsage } from "../../src/infra/provider-usage.fetch.js";
import { normalizeOptionalSecretInput } from "../../src/utils/normalize-secret-input.js";
import { detectZaiEndpoint, type ZaiEndpointId } from "./detect.js";
import { applyZaiConfig, applyZaiProviderConfig, ZAI_DEFAULT_MODEL_REF } from "./onboard.js";
const PROVIDER_ID = "zai";
const GLM5_MODEL_ID = "glm-5";

57
extensions/zai/onboard.ts Normal file
View File

@@ -0,0 +1,57 @@
import {
applyAgentDefaultModelPrimary,
applyProviderConfigWithModelCatalog,
} from "../../src/commands/onboard-auth.config-shared.js";
import {
buildZaiModelDefinition,
resolveZaiBaseUrl,
ZAI_DEFAULT_MODEL_ID,
} from "../../src/commands/onboard-auth.models.js";
import type { OpenClawConfig } from "../../src/config/config.js";
export const ZAI_DEFAULT_MODEL_REF = `zai/${ZAI_DEFAULT_MODEL_ID}`;
const ZAI_DEFAULT_MODELS = [
buildZaiModelDefinition({ id: "glm-5" }),
buildZaiModelDefinition({ id: "glm-5-turbo" }),
buildZaiModelDefinition({ id: "glm-4.7" }),
buildZaiModelDefinition({ id: "glm-4.7-flash" }),
buildZaiModelDefinition({ id: "glm-4.7-flashx" }),
];
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 existingProvider = cfg.models?.providers?.zai;
const models = { ...cfg.agents?.defaults?.models };
models[modelRef] = {
...models[modelRef],
alias: models[modelRef]?.alias ?? "GLM",
};
const existingBaseUrl =
typeof existingProvider?.baseUrl === "string" ? existingProvider.baseUrl.trim() : "";
const baseUrl = params?.endpoint
? resolveZaiBaseUrl(params.endpoint)
: existingBaseUrl || resolveZaiBaseUrl();
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "zai",
api: "openai-completions",
baseUrl,
catalogModels: ZAI_DEFAULT_MODELS,
});
}
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}`;
return applyAgentDefaultModelPrimary(applyZaiProviderConfig(cfg, params), modelRef);
}

View File

@@ -1,7 +1,3 @@
import { buildKilocodeProvider } from "../../extensions/kilocode/provider-catalog.js";
import type { OpenClawConfig } from "../config/config.js";
import { KILOCODE_BASE_URL } from "../providers/kilocode-shared.js";
import { KILOCODE_DEFAULT_MODEL_REF, ZAI_DEFAULT_MODEL_REF } from "./onboard-auth.credentials.js";
export {
applyCloudflareAiGatewayConfig,
applyCloudflareAiGatewayProviderConfig,
@@ -14,20 +10,7 @@ export {
LITELLM_BASE_URL,
LITELLM_DEFAULT_MODEL_ID,
} from "./onboard-auth.config-litellm.js";
import {
applyAgentDefaultModelPrimary,
applyOnboardAuthAgentModelsAndProviders,
applyProviderConfigWithModelCatalog,
} from "./onboard-auth.config-shared.js";
import {
buildZaiModelDefinition,
buildModelStudioModelDefinition,
ZAI_DEFAULT_MODEL_ID,
resolveZaiBaseUrl,
MODELSTUDIO_CN_BASE_URL,
MODELSTUDIO_GLOBAL_BASE_URL,
MODELSTUDIO_DEFAULT_MODEL_REF,
} from "./onboard-auth.models.js";
export { applyAuthProfileConfig } from "./auth-profile-config.js";
export {
applyHuggingfaceConfig,
applyHuggingfaceProviderConfig,
@@ -37,11 +20,26 @@ export {
applyKimiCodeConfig,
applyKimiCodeProviderConfig,
} from "../../extensions/kimi-coding/onboard.js";
export {
applyKilocodeConfig,
applyKilocodeProviderConfig,
KILOCODE_BASE_URL,
KILOCODE_DEFAULT_MODEL_REF,
} from "../../extensions/kilocode/onboard.js";
export {
applyMistralConfig,
applyMistralProviderConfig,
MISTRAL_DEFAULT_MODEL_REF,
} from "../../extensions/mistral/onboard.js";
export {
applyModelStudioConfig,
applyModelStudioConfigCn,
applyModelStudioProviderConfig,
applyModelStudioProviderConfigCn,
MODELSTUDIO_CN_BASE_URL,
MODELSTUDIO_DEFAULT_MODEL_REF,
MODELSTUDIO_GLOBAL_BASE_URL,
} from "../../extensions/modelstudio/onboard.js";
export {
applyMoonshotConfig,
applyMoonshotConfigCn,
@@ -71,204 +69,14 @@ export {
applyVeniceProviderConfig,
VENICE_DEFAULT_MODEL_REF,
} from "../../extensions/venice/onboard.js";
export { applyXiaomiConfig, applyXiaomiProviderConfig } from "../../extensions/xiaomi/onboard.js";
export {
applyXaiConfig,
applyXaiProviderConfig,
XAI_DEFAULT_MODEL_REF,
} from "../../extensions/xai/onboard.js";
export { applyAuthProfileConfig } from "./auth-profile-config.js";
function mergeProviderModels<T extends { id: string }>(
existingProvider: Record<string, unknown> | undefined,
defaultModels: T[],
): T[] {
const existingModels = Array.isArray(existingProvider?.models)
? (existingProvider.models as T[])
: [];
const mergedModels = [...existingModels];
const seen = new Set(existingModels.map((model) => model.id));
for (const model of defaultModels) {
if (!seen.has(model.id)) {
mergedModels.push(model);
seen.add(model.id);
}
}
return mergedModels;
}
function getNormalizedProviderApiKey(existingProvider: Record<string, unknown> | undefined) {
const { apiKey } = (existingProvider ?? {}) as { apiKey?: string };
return typeof apiKey === "string" ? apiKey.trim() || undefined : undefined;
}
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 defaultModels = [
buildZaiModelDefinition({ id: "glm-5" }),
buildZaiModelDefinition({ id: "glm-5-turbo" }),
buildZaiModelDefinition({ id: "glm-4.7" }),
buildZaiModelDefinition({ id: "glm-4.7-flash" }),
buildZaiModelDefinition({ id: "glm-4.7-flashx" }),
];
const mergedModels = mergeProviderModels(existingProvider, defaultModels);
const { apiKey: _existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
string,
unknown
> as { apiKey?: string };
const normalizedApiKey = getNormalizedProviderApiKey(existingProvider);
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 { KILOCODE_BASE_URL };
/**
* Apply Kilo Gateway provider configuration without changing the default model.
* Registers Kilo Gateway and sets up the provider, but preserves existing model selection.
*/
export function applyKilocodeProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
models[KILOCODE_DEFAULT_MODEL_REF] = {
...models[KILOCODE_DEFAULT_MODEL_REF],
alias: models[KILOCODE_DEFAULT_MODEL_REF]?.alias ?? "Kilo Gateway",
};
const kilocodeModels = buildKilocodeProvider().models ?? [];
return applyProviderConfigWithModelCatalog(cfg, {
agentModels: models,
providerId: "kilocode",
api: "openai-completions",
baseUrl: KILOCODE_BASE_URL,
catalogModels: kilocodeModels,
});
}
/**
* Apply Kilo Gateway provider configuration AND set Kilo Gateway as the default model.
* Use this when Kilo Gateway is the primary provider choice during setup.
*/
export function applyKilocodeConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyKilocodeProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, KILOCODE_DEFAULT_MODEL_REF);
}
// Alibaba Cloud Model Studio Coding Plan
function applyModelStudioProviderConfigWithBaseUrl(
cfg: OpenClawConfig,
baseUrl: string,
): OpenClawConfig {
const models = { ...cfg.agents?.defaults?.models };
const modelStudioModelIds = [
"qwen3.5-plus",
"qwen3-max-2026-01-23",
"qwen3-coder-next",
"qwen3-coder-plus",
"MiniMax-M2.5",
"glm-5",
"glm-4.7",
"kimi-k2.5",
];
for (const modelId of modelStudioModelIds) {
const modelRef = `modelstudio/${modelId}`;
if (!models[modelRef]) {
models[modelRef] = {};
}
}
models[MODELSTUDIO_DEFAULT_MODEL_REF] = {
...models[MODELSTUDIO_DEFAULT_MODEL_REF],
alias: models[MODELSTUDIO_DEFAULT_MODEL_REF]?.alias ?? "Qwen",
};
const providers = { ...cfg.models?.providers };
const existingProvider = providers.modelstudio;
const defaultModels = [
buildModelStudioModelDefinition({ id: "qwen3.5-plus" }),
buildModelStudioModelDefinition({ id: "qwen3-max-2026-01-23" }),
buildModelStudioModelDefinition({ id: "qwen3-coder-next" }),
buildModelStudioModelDefinition({ id: "qwen3-coder-plus" }),
buildModelStudioModelDefinition({ id: "MiniMax-M2.5" }),
buildModelStudioModelDefinition({ id: "glm-5" }),
buildModelStudioModelDefinition({ id: "glm-4.7" }),
buildModelStudioModelDefinition({ id: "kimi-k2.5" }),
];
const mergedModels = mergeProviderModels(existingProvider, defaultModels);
const { apiKey: _existingApiKey, ...existingProviderRest } = (existingProvider ?? {}) as Record<
string,
unknown
> as { apiKey?: string };
const normalizedApiKey = getNormalizedProviderApiKey(existingProvider);
providers.modelstudio = {
...existingProviderRest,
baseUrl,
api: "openai-completions",
...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
models: mergedModels.length > 0 ? mergedModels : defaultModels,
};
return applyOnboardAuthAgentModelsAndProviders(cfg, { agentModels: models, providers });
}
export function applyModelStudioProviderConfig(cfg: OpenClawConfig): OpenClawConfig {
return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_GLOBAL_BASE_URL);
}
export function applyModelStudioProviderConfigCn(cfg: OpenClawConfig): OpenClawConfig {
return applyModelStudioProviderConfigWithBaseUrl(cfg, MODELSTUDIO_CN_BASE_URL);
}
export function applyModelStudioConfig(cfg: OpenClawConfig): OpenClawConfig {
const next = applyModelStudioProviderConfig(cfg);
return applyAgentDefaultModelPrimary(next, MODELSTUDIO_DEFAULT_MODEL_REF);
}
export function applyModelStudioConfigCn(cfg: OpenClawConfig): OpenClawConfig {
const next = applyModelStudioProviderConfigCn(cfg);
return applyAgentDefaultModelPrimary(next, MODELSTUDIO_DEFAULT_MODEL_REF);
}
export { applyXiaomiConfig, applyXiaomiProviderConfig } from "../../extensions/xiaomi/onboard.js";
export {
applyZaiConfig,
applyZaiProviderConfig,
ZAI_DEFAULT_MODEL_REF,
} from "../../extensions/zai/onboard.js";

View File

@@ -59,7 +59,6 @@ export {
} from "./onboard-auth.config-opencode-go.js";
export {
CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,
KILOCODE_DEFAULT_MODEL_REF,
LITELLM_DEFAULT_MODEL_REF,
OPENROUTER_DEFAULT_MODEL_REF,
setOpenaiApiKey,
@@ -90,15 +89,16 @@ export {
writeOAuthCredentials,
VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
XIAOMI_DEFAULT_MODEL_REF,
ZAI_DEFAULT_MODEL_REF,
MODELSTUDIO_DEFAULT_MODEL_REF,
} from "./onboard-auth.credentials.js";
export { HUGGINGFACE_DEFAULT_MODEL_REF } from "../../extensions/huggingface/onboard.js";
export { KILOCODE_DEFAULT_MODEL_REF } from "../../extensions/kilocode/onboard.js";
export { MISTRAL_DEFAULT_MODEL_REF } from "../../extensions/mistral/onboard.js";
export { MODELSTUDIO_DEFAULT_MODEL_REF } from "../../extensions/modelstudio/onboard.js";
export { SYNTHETIC_DEFAULT_MODEL_REF } from "../../extensions/synthetic/onboard.js";
export { TOGETHER_DEFAULT_MODEL_REF } from "../../extensions/together/onboard.js";
export { VENICE_DEFAULT_MODEL_REF } from "../../extensions/venice/onboard.js";
export { XAI_DEFAULT_MODEL_REF } from "../../extensions/xai/onboard.js";
export { ZAI_DEFAULT_MODEL_REF } from "../../extensions/zai/onboard.js";
export {
buildKilocodeModelDefinition,
buildMinimaxApiModelDefinition,