mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:40:44 +00:00
fix(providers): keep setup guidance cold
This commit is contained in:
@@ -2,8 +2,6 @@ import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
|
||||
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
|
||||
import type { OpenClawConfig, GatewayAuthConfig } from "../config/config.js";
|
||||
import { isSecretRef, type SecretInput } from "../config/types.secrets.js";
|
||||
import { resolveProviderPluginChoice } from "../plugins/provider-wizard.js";
|
||||
import { resolvePluginProviders } from "../plugins/providers.runtime.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { WizardPrompter } from "../wizard/prompts.js";
|
||||
import { promptAuthChoiceGrouped } from "./auth-choice-prompt.js";
|
||||
@@ -32,18 +30,21 @@ function sanitizeTokenValue(value: unknown): string | undefined {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
function resolveProviderChoiceModelAllowlist(params: {
|
||||
async function resolveProviderChoiceModelAllowlist(params: {
|
||||
authChoice: string;
|
||||
config: OpenClawConfig;
|
||||
workspaceDir?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}):
|
||||
}): Promise<
|
||||
| {
|
||||
allowedKeys?: string[];
|
||||
initialSelections?: string[];
|
||||
message?: string;
|
||||
}
|
||||
| undefined {
|
||||
| undefined
|
||||
> {
|
||||
const { resolvePluginProviders, resolveProviderPluginChoice } =
|
||||
await import("../plugins/provider-auth-choice.runtime.js");
|
||||
const providers = resolvePluginProviders({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
@@ -162,7 +163,7 @@ export async function promptAuthConfig(
|
||||
}
|
||||
|
||||
if (authChoice !== "custom-api-key") {
|
||||
const modelAllowlist = resolveProviderChoiceModelAllowlist({
|
||||
const modelAllowlist = await resolveProviderChoiceModelAllowlist({
|
||||
authChoice,
|
||||
config: next,
|
||||
workspaceDir: resolveDefaultAgentWorkspaceDir(),
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
import { normalizeProviderId } from "../agents/model-selection.js";
|
||||
import { resolveProviderAuthAliasMap } from "../agents/provider-auth-aliases.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { resolvePluginProviders } from "../plugins/providers.runtime.js";
|
||||
import { resolveManifestProviderAuthChoices } from "../plugins/provider-auth-choices.js";
|
||||
|
||||
function matchesProviderId(
|
||||
candidate: { id: string; aliases?: string[] | readonly string[] },
|
||||
function normalizeProviderIdForAuth(
|
||||
providerId: string,
|
||||
): boolean {
|
||||
aliases: Readonly<Record<string, string>>,
|
||||
): string {
|
||||
const normalized = normalizeProviderId(providerId);
|
||||
return normalized ? (aliases[normalized] ?? normalized) : normalized;
|
||||
}
|
||||
|
||||
function matchesProviderAuthChoice(
|
||||
choice: { providerId: string },
|
||||
providerId: string,
|
||||
aliases: Readonly<Record<string, string>>,
|
||||
): boolean {
|
||||
const normalized = normalizeProviderIdForAuth(providerId, aliases);
|
||||
if (!normalized) {
|
||||
return false;
|
||||
}
|
||||
if (normalizeProviderId(candidate.id) === normalized) {
|
||||
return true;
|
||||
}
|
||||
return (candidate.aliases ?? []).some((alias) => normalizeProviderId(alias) === normalized);
|
||||
return normalizeProviderIdForAuth(choice.providerId, aliases) === normalized;
|
||||
}
|
||||
|
||||
export function resolveProviderAuthLoginCommand(params: {
|
||||
@@ -23,16 +30,14 @@ export function resolveProviderAuthLoginCommand(params: {
|
||||
workspaceDir?: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): string | undefined {
|
||||
const provider = resolvePluginProviders({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
mode: "setup",
|
||||
}).find((candidate) => matchesProviderId(candidate, params.provider));
|
||||
if (!provider || provider.auth.length === 0) {
|
||||
const aliases = resolveProviderAuthAliasMap(params);
|
||||
const choice = resolveManifestProviderAuthChoices(params).find((candidate) =>
|
||||
matchesProviderAuthChoice(candidate, params.provider, aliases),
|
||||
);
|
||||
if (!choice) {
|
||||
return undefined;
|
||||
}
|
||||
return formatCliCommand(`openclaw models auth login --provider ${provider.id}`);
|
||||
return formatCliCommand(`openclaw models auth login --provider ${choice.providerId}`);
|
||||
}
|
||||
|
||||
export function buildProviderAuthRecoveryHint(params: {
|
||||
|
||||
38
src/commands/provider-setup-cold-imports.test.ts
Normal file
38
src/commands/provider-setup-cold-imports.test.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const repoRoot = fileURLToPath(new URL("../..", import.meta.url));
|
||||
|
||||
const coldProviderSetupFiles = [
|
||||
"src/commands/auth-choice-options.ts",
|
||||
"src/commands/configure.gateway-auth.ts",
|
||||
"src/commands/provider-auth-guidance.ts",
|
||||
"src/flows/provider-flow.ts",
|
||||
"src/plugins/provider-auth-choices.ts",
|
||||
"src/plugins/provider-install-catalog.ts",
|
||||
] as const;
|
||||
|
||||
const forbiddenRuntimeImports = [
|
||||
"providers.runtime.js",
|
||||
"provider-wizard.js",
|
||||
"provider-flow.runtime.js",
|
||||
"provider-auth-choice.runtime.js",
|
||||
] as const;
|
||||
|
||||
describe("provider setup cold imports", () => {
|
||||
it("keeps auth/setup/configure metadata callers off static provider runtime imports", () => {
|
||||
for (const file of coldProviderSetupFiles) {
|
||||
const source = fs.readFileSync(path.join(repoRoot, file), "utf8");
|
||||
for (const importPath of forbiddenRuntimeImports) {
|
||||
const staticImportPattern = new RegExp(
|
||||
`\\bfrom\\s+["'][^"']*${importPath.replaceAll(".", "\\.")}["']`,
|
||||
);
|
||||
expect(source, `${file} must not statically import ${importPath}`).not.toMatch(
|
||||
staticImportPattern,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user