openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
343 lines (342 loc) • 16.8 kB
JavaScript
import { a as createLazyRuntimeSurface } from "./lazy-runtime-CgCh8H_K.js";
import { t as formatCliCommand } from "./command-format-C7YfyMTd.js";
import { t as formatErrorMessage } from "./errors-Db3Ymjlb.js";
import { u as resolveDefaultSecretProviderAlias } from "./ref-contract-D92DqQ-r.js";
import { a as resolveAgentModelPrimaryValue } from "./model-input-BuGMCNOz.js";
import { r as enablePluginWithCapabilityConsent } from "./enable-3OwjFbBV.js";
import { n as resolveManifestProviderAuthChoice, t as resolveManifestDeprecatedProviderAuthChoice } from "./provider-auth-choices-DsRM415K.js";
import { a as normalizeSecretInputModeInput } from "./provider-auth-input-B4MRIGbK.js";
import { t as applyAutoLocalModelLean } from "./local-model-lean-auto-DgTezp-6.js";
import { a as prepareAgentModelDefaults, o as projectAgentModelDefaults } from "./onboard-agent-target-CNKxVAZK.js";
import { r as resolveProviderInstallCatalogEntry, t as resolveDeprecatedProviderInstallCatalogEntry } from "./provider-install-catalog-BzkhdO6-.js";
import { r as formatAuthChoiceChoicesForCli } from "./auth-choice-options-CT4g25ir.js";
import { i as resolveDeprecatedAuthChoiceReplacement, n as isDeprecatedAuthChoice, t as formatDeprecatedNonInteractiveAuthChoiceError } from "./auth-choice-legacy-CxbJ5_3c.js";
import { t as resolvePreferredProviderForAuthChoice } from "./provider-auth-choice-preference-DxhJufZS.js";
import { t as normalizeApiKeyTokenProviderAuthChoice } from "./auth-choice.apply.api-providers-BQYIRgTb.js";
import { r as ensureModelSelectionRuntimePlugins, t as CODEX_RUNTIME_PLUGIN_ID } from "./runtime-plugin-install-C2YSxeNS.js";
import { t as createNonInteractiveLoggingPrompter } from "./non-interactive-prompter-DLCGsi38.js";
import { c as parseNonInteractiveCustomApiFlags, d as resolveCustomProviderId, n as applyCustomApiConfig, t as CustomApiError } from "./onboard-custom-config-DpIUL0Vo.js";
import { t as rejectOnboardingOption } from "./onboard-options-Tgvmf5eA.js";
import { t as resolveNonInteractiveApiKey } from "./api-keys-CNdvNbUX.js";
//#region src/commands/onboard-non-interactive/local/auth-choice.plugin-providers.ts
const PROVIDER_PLUGIN_CHOICE_PREFIX = "provider-plugin:";
async function loadPluginProviderRuntime() {
return import("./auth-choice.plugin-providers.runtime.js");
}
const loadAuthChoicePluginProvidersRuntime = createLazyRuntimeSurface(loadPluginProviderRuntime, ({ authChoicePluginProvidersRuntime }) => authChoicePluginProvidersRuntime);
/** Applies a plugin-defined auth choice, or returns undefined when it is not plugin-backed. */
async function applyNonInteractivePluginProviderChoice(params) {
const { agentDir, workspaceDir } = params.target;
const reject = (message) => {
rejectOnboardingOption(params.opts, params.runtime, message);
return null;
};
let nextConfig = params.nextConfig;
const prefixedProviderId = params.authChoice.startsWith(PROVIDER_PLUGIN_CHOICE_PREFIX) ? params.authChoice.slice(16).split(":", 1)[0]?.trim() : void 0;
if (prefixedProviderId === "") return reject(`Auth choice ${JSON.stringify(params.authChoice)} is missing a provider id. Use "${PROVIDER_PLUGIN_CHOICE_PREFIX}<provider-id>".`);
const preferredProviderId = prefixedProviderId || await resolvePreferredProviderForAuthChoice({
choice: params.authChoice,
config: nextConfig,
workspaceDir,
includeUntrustedWorkspacePlugins: false
});
const trustedManifestMatch = resolveManifestProviderAuthChoice(params.authChoice, {
config: nextConfig,
workspaceDir,
includeUntrustedWorkspacePlugins: false
});
if (trustedManifestMatch) {
const enabled = await enablePluginWithCapabilityConsent(nextConfig, trustedManifestMatch.pluginId, { workspaceDir });
if (!enabled.enabled) return reject(enabled.reason ?? "Provider plugin could not be enabled.");
nextConfig = enabled.config;
}
const { resolveOwningPluginIdsForProviderRef, resolveProviderPluginChoice, resolvePluginProviders } = await loadAuthChoicePluginProvidersRuntime();
const owningPluginIds = preferredProviderId ? resolveOwningPluginIdsForProviderRef({
provider: preferredProviderId,
config: nextConfig,
workspaceDir
}) : void 0;
let providerChoice = resolveProviderPluginChoice({
providers: resolvePluginProviders({
config: nextConfig,
workspaceDir,
onlyPluginIds: owningPluginIds,
...preferredProviderId ? { providerRefs: [preferredProviderId] } : {},
mode: "setup",
includeUntrustedWorkspacePlugins: false
}),
choice: params.authChoice
});
if (!providerChoice) {
if (prefixedProviderId) return reject([`Auth choice "${params.authChoice}" was not matched to a trusted provider plugin.`, "If this provider comes from a workspace plugin, trust/allow it first and retry."].join("\n"));
if (!trustedManifestMatch && resolveManifestProviderAuthChoice(params.authChoice, {
config: nextConfig,
workspaceDir,
includeUntrustedWorkspacePlugins: true
})) return reject([`Auth choice "${params.authChoice}" matched a provider plugin that is not trusted or enabled for setup.`, "If this provider comes from a workspace plugin, trust/allow it first and retry."].join("\n"));
const installCatalogParams = {
config: nextConfig,
workspaceDir,
includeUntrustedWorkspacePlugins: false
};
const deprecatedInstallCatalogEntry = resolveDeprecatedProviderInstallCatalogEntry(params.authChoice, installCatalogParams);
if (deprecatedInstallCatalogEntry) return reject(`${JSON.stringify(params.authChoice)} is no longer supported. Use --auth-choice ${JSON.stringify(deprecatedInstallCatalogEntry.choiceId)} instead.`);
const installCatalogEntry = resolveProviderInstallCatalogEntry(params.authChoice, installCatalogParams);
if (!installCatalogEntry) return;
const { ensureOnboardingPluginInstalled } = await import("./onboarding-plugin-install-CeahhHcF.js");
const installResult = await ensureOnboardingPluginInstalled({
cfg: nextConfig,
entry: {
pluginId: installCatalogEntry.pluginId,
label: installCatalogEntry.label,
install: installCatalogEntry.install,
...installCatalogEntry.origin === "bundled" ? { trustedSourceLinkedOfficialInstall: true } : {}
},
prompter: createNonInteractiveLoggingPrompter(params.runtime, (message) => `Non-interactive setup cannot prompt for plugin install: ${message}`),
runtime: params.runtime,
workspaceDir,
promptInstall: false
});
if (!installResult.installed) return reject(`Unable to install the ${installCatalogEntry.label} plugin for non-interactive setup.`);
nextConfig = installResult.cfg;
providerChoice = resolveProviderPluginChoice({
providers: resolvePluginProviders({
config: nextConfig,
workspaceDir,
onlyPluginIds: [installCatalogEntry.pluginId],
providerRefs: [installCatalogEntry.providerId],
mode: "setup",
includeUntrustedWorkspacePlugins: false
}),
choice: params.authChoice
});
if (!providerChoice) return reject(`Installed plugin "${installCatalogEntry.label}" did not expose auth choice "${params.authChoice}".`);
}
const enableResult = await enablePluginWithCapabilityConsent(nextConfig, providerChoice.provider.pluginId ?? providerChoice.provider.id, { workspaceDir });
if (!enableResult.enabled) return reject(`${providerChoice.provider.label} plugin is disabled (${enableResult.reason ?? "blocked"}).`);
const method = providerChoice.method;
if (!method.runNonInteractive) return reject([`Auth choice "${params.authChoice}" requires interactive mode.`, `The ${providerChoice.provider.label} provider plugin does not implement non-interactive setup.`].join("\n"));
const agentScopedModels = enableResult.config.agents?.ownership === "explicit";
const providerConfig = agentScopedModels ? prepareAgentModelDefaults(enableResult.config, params.target) : enableResult.config;
const projectProviderResult = (updated) => agentScopedModels ? projectAgentModelDefaults(enableResult.config, params.target, updated) : updated;
const result = await method.runNonInteractive({
authChoice: params.authChoice,
config: providerConfig,
baseConfig: params.baseConfig,
opts: params.opts,
runtime: params.runtime,
agentDir,
workspaceDir,
resolveApiKey: params.resolveApiKey,
toApiKeyCredential: params.toApiKeyCredential
});
if (!result) return result;
const selectedModel = resolveAgentModelPrimaryValue(result.agents?.defaults?.model);
if (!selectedModel) return projectProviderResult(result);
const runtimes = await ensureModelSelectionRuntimePlugins({
cfg: result,
model: selectedModel,
prompter: createNonInteractiveLoggingPrompter(params.runtime, (message) => message),
runtime: params.runtime,
workspaceDir,
output: "silent"
});
if (!runtimes.ok) return reject(runtimes.message);
if (runtimes.codexInstalled) {
const { offerPostInstallMigrations } = await import("./setup.post-install-migration-C3zhOodq.js");
await offerPostInstallMigrations({
config: runtimes.cfg,
runtime: params.runtime,
installedPluginIds: [CODEX_RUNTIME_PLUGIN_ID],
nonInteractive: true
});
}
const previousModel = providerConfig.agents?.defaults?.model;
const previousAutoModel = enableResult.config.wizard?.localModelLeanAutoModel;
const retainsAutoModelOwnership = previousAutoModel !== void 0 && previousAutoModel === resolveAgentModelPrimaryValue(previousModel) && previousAutoModel === runtimes.cfg.wizard?.localModelLeanAutoModel;
return projectProviderResult(applyAutoLocalModelLean({
config: runtimes.cfg,
providerId: providerChoice.provider.id,
modelRef: selectedModel,
...retainsAutoModelOwnership ? { previousModelRef: previousAutoModel } : {}
}).config);
}
//#endregion
//#region src/commands/onboard-non-interactive/local/auth-choice.ts
/** Applies a local non-interactive auth choice to the pending OpenClaw config. */
async function applyNonInteractiveAuthChoice(params) {
const { opts, runtime, baseConfig } = params;
let authChoice = normalizeApiKeyTokenProviderAuthChoice({
authChoice: params.authChoice,
tokenProvider: opts.tokenProvider,
config: params.nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
});
const nextConfig = params.nextConfig;
const requestedSecretInputMode = normalizeSecretInputModeInput(opts.secretInputMode);
if (opts.secretInputMode && !requestedSecretInputMode) {
rejectOnboardingOption(opts, runtime, `Invalid --secret-input-mode. Use "plaintext" or "ref", or run ${formatCliCommand("openclaw onboard")} for interactive setup.`);
return null;
}
const toStoredSecretInput = (paramsLocal) => {
const { resolved } = paramsLocal;
if (requestedSecretInputMode !== "ref") return resolved.key;
if (resolved.source !== "env" || !resolved.envVarName) {
const envHint = paramsLocal.envVarName ? `Set ${paramsLocal.envVarName} in env and retry` : "Set the provider API key env var and retry";
rejectOnboardingOption(opts, runtime, [`--secret-input-mode ref requires an explicit environment variable for provider "${paramsLocal.provider}".`, `${envHint}, or use --secret-input-mode plaintext.`].join("\n"));
return null;
}
return {
source: "env",
provider: resolveDefaultSecretProviderAlias(baseConfig, "env", { preferFirstProviderForSource: true }),
id: resolved.envVarName
};
};
const resolveApiKey = (input) => resolveNonInteractiveApiKey({
...input,
agentDir: params.target.agentDir,
workspaceDir: params.target.workspaceDir,
secretInputMode: requestedSecretInputMode,
json: opts.json
});
const toApiKeyCredential = (paramsLocal) => {
const stored = toStoredSecretInput({
resolved: paramsLocal.resolved,
provider: paramsLocal.provider
});
if (!stored) return null;
return {
type: "api_key",
provider: paramsLocal.provider,
...typeof stored === "string" ? { key: stored } : { keyRef: stored },
...paramsLocal.email ? { email: paramsLocal.email } : {},
...paramsLocal.metadata ? { metadata: paramsLocal.metadata } : {}
};
};
if (isDeprecatedAuthChoice(authChoice, {
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
})) {
const replacement = resolveDeprecatedAuthChoiceReplacement(authChoice, {
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
});
if (replacement) {
runtime.log(replacement.message);
authChoice = replacement.normalized;
} else {
rejectOnboardingOption(opts, runtime, formatDeprecatedNonInteractiveAuthChoiceError(authChoice, {
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
}));
return null;
}
}
const deprecatedChoice = resolveManifestDeprecatedProviderAuthChoice(authChoice, {
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
});
const deprecatedInstallChoice = deprecatedChoice ? void 0 : resolveDeprecatedProviderInstallCatalogEntry(authChoice, {
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env,
includeUntrustedWorkspacePlugins: false
});
const replacementChoiceId = deprecatedChoice?.choiceId ?? deprecatedInstallChoice?.choiceId;
if (replacementChoiceId) {
rejectOnboardingOption(opts, runtime, `${JSON.stringify(authChoice)} is no longer supported. Use --auth-choice ${JSON.stringify(replacementChoiceId)} instead.`);
return null;
}
const validAuthChoices = formatAuthChoiceChoicesForCli({
includeSkip: true,
config: nextConfig,
workspaceDir: params.target.workspaceDir,
env: process.env
}).split("|");
if (!validAuthChoices.includes(authChoice) && !authChoice.startsWith("provider-plugin:")) {
rejectOnboardingOption(opts, runtime, `Unknown --auth-choice ${JSON.stringify(authChoice)}. Valid choices: ${validAuthChoices.join(", ")}.`);
return null;
}
const pluginProviderChoice = await applyNonInteractivePluginProviderChoice({
nextConfig,
authChoice,
opts,
runtime,
baseConfig,
target: params.target,
resolveApiKey: (input) => resolveApiKey({
...input,
cfg: nextConfig,
runtime
}),
toApiKeyCredential
});
if (pluginProviderChoice !== void 0) return pluginProviderChoice;
if (authChoice === "setup-token" || authChoice === "token") {
rejectOnboardingOption(opts, runtime, [`Auth choice "${params.authChoice}" was not matched to a provider setup flow.`, "For Anthropic legacy token auth, use \"--auth-choice setup-token --token-provider anthropic --token <token>\" or pass \"--auth-choice token --token-provider anthropic\"."].join("\n"));
return null;
}
if (authChoice === "custom-api-key") try {
const customAuth = parseNonInteractiveCustomApiFlags({
baseUrl: opts.customBaseUrl,
modelId: opts.customModelId,
compatibility: opts.customCompatibility,
apiKey: opts.customApiKey,
providerId: opts.customProviderId,
supportsImageInput: opts.customImageInput
});
const resolvedProviderId = resolveCustomProviderId({
config: nextConfig,
baseUrl: customAuth.baseUrl,
providerId: customAuth.providerId
});
const resolvedCustomApiKey = await resolveApiKey({
provider: resolvedProviderId.providerId,
cfg: nextConfig,
flagValue: customAuth.apiKey,
flagName: "--custom-api-key",
envVar: "CUSTOM_API_KEY",
envVarName: "CUSTOM_API_KEY",
runtime,
required: false
});
let customApiKeyInput;
if (resolvedCustomApiKey && (requestedSecretInputMode !== "ref" || resolvedCustomApiKey.source !== "profile")) {
const stored = toStoredSecretInput({
resolved: resolvedCustomApiKey,
provider: resolvedProviderId.providerId,
envVarName: "CUSTOM_API_KEY"
});
if (!stored) return null;
customApiKeyInput = stored;
}
const result = applyCustomApiConfig({
config: nextConfig,
baseUrl: customAuth.baseUrl,
modelId: customAuth.modelId,
compatibility: customAuth.compatibility,
apiKey: customApiKeyInput,
providerId: customAuth.providerId,
supportsImageInput: customAuth.supportsImageInput,
target: params.target
});
if (result.providerIdRenamedFrom && result.providerId) runtime.log(`Custom provider ID "${result.providerIdRenamedFrom}" already exists for a different base URL. Using "${result.providerId}".`);
return result.config;
} catch (err) {
const message = err instanceof CustomApiError && (err.code === "missing_required" || err.code === "invalid_compatibility") ? err.message : `Invalid custom provider config: ${err instanceof CustomApiError ? err.message : formatErrorMessage(err)}`;
rejectOnboardingOption(opts, runtime, message);
return null;
}
if (authChoice === "chutes" || authChoice === "minimax-global-oauth" || authChoice === "minimax-cn-oauth") {
rejectOnboardingOption(opts, runtime, "OAuth requires interactive mode.");
return null;
}
return nextConfig;
}
//#endregion
export { applyNonInteractiveAuthChoice };