





















@@ -1,13 +1,28 @@
11import type { OpenClawConfig } from "../config/types.openclaw.js";
22import {
33externalCliDiscoveryForProviderAuth,
4+externalCliDiscoveryForProviders,
45ensureAuthProfileStore,
56ensureAuthProfileStoreWithoutExternalProfiles,
67listProfilesForProvider,
78type AuthProfileStore,
89} from "./auth-profiles.js";
910import { hasRuntimeAvailableProviderAuth } from "./model-auth.js";
11+import { loadModelCatalog } from "./model-catalog.js";
1012import { normalizeProviderId } from "./model-selection.js";
13+import { resolveDefaultAgentWorkspaceDir } from "./workspace.js";
14+15+// Prepared runtime fact: which providers have available auth given the
16+// current cfg + env. Populated explicitly at gateway startup and on config
17+// reload; consulted by hasAuthForModelProvider so every model-listing call
18+// (pickers, /models, status commands, CLI) skips the per-provider plugin
19+// discovery and external-CLI probing on the hot path.
20+21+let currentProviderAuthState: ReadonlyMap<string, boolean> | null = null;
22+23+export function clearCurrentProviderAuthState(): void {
24+currentProviderAuthState = null;
25+}
11261227export function hasAuthForModelProvider(params: {
1328provider: string;
@@ -20,6 +35,10 @@ export function hasAuthForModelProvider(params: {
2035discoverExternalCliAuth?: boolean;
2136}): boolean {
2237const provider = normalizeProviderId(params.provider);
38+const preparedAnswer = currentProviderAuthState?.get(provider);
39+if (preparedAnswer !== undefined) {
40+return preparedAnswer;
41+}
2342if (
2443hasRuntimeAvailableProviderAuth({
2544 provider,
@@ -74,3 +93,32 @@ export function createProviderAuthChecker(params: {
7493return value;
7594};
7695}
96+97+export async function warmCurrentProviderAuthState(cfg: OpenClawConfig): Promise<void> {
98+const catalog = await loadModelCatalog({ config: cfg });
99+const providers = new Set<string>();
100+for (const entry of catalog) {
101+providers.add(normalizeProviderId(entry.provider));
102+}
103+const workspaceDir = resolveDefaultAgentWorkspaceDir();
104+// One AuthProfileStore scoped to every candidate provider; without this the
105+// per-provider externalCli discovery rebuilds the store ~N times.
106+const store = ensureAuthProfileStore(undefined, {
107+config: cfg,
108+externalCli: externalCliDiscoveryForProviders({
109+ cfg,
110+providers: [...providers],
111+}),
112+});
113+const state = new Map<string, boolean>();
114+for (const provider of providers) {
115+const value = hasAuthForModelProvider({
116+ provider,
117+ cfg,
118+ workspaceDir,
119+ store,
120+});
121+state.set(provider, value);
122+}
123+currentProviderAuthState = state;
124+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。