From a6a2516cd8d74b5448f58d2018ddc9aa183cabda Mon Sep 17 00:00:00 2001 From: Shakker Date: Fri, 24 Apr 2026 02:59:49 +0100 Subject: [PATCH] perf: narrow default models list registry loading --- src/commands/models/list.list-command.ts | 11 +++-- src/commands/models/list.registry-load.ts | 59 +++++++++++++++++++++++ src/commands/models/list.row-sources.ts | 5 +- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/commands/models/list.list-command.ts b/src/commands/models/list.list-command.ts index 9395ed18bf1..2ee17c2881e 100644 --- a/src/commands/models/list.list-command.ts +++ b/src/commands/models/list.list-command.ts @@ -4,7 +4,7 @@ import type { RuntimeEnv } from "../../runtime.js"; import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js"; import { resolveConfiguredEntries } from "./list.configured.js"; import { formatErrorWithStack } from "./list.errors.js"; -import { loadListModelRegistry } from "./list.registry-load.js"; +import { loadConfiguredListModelRegistry, loadListModelRegistry } from "./list.registry-load.js"; import { appendAllModelRowSources, appendConfiguredModelRowSources, @@ -59,6 +59,8 @@ export async function modelsListCommand( let availableKeys: Set | undefined; let availabilityErrorMessage: string | undefined; const useProviderCatalogFastPath = Boolean(opts.all && providerFilter === "codex"); + const { entries } = resolveConfiguredEntries(cfg); + const configuredByKey = new Map(entries.map((entry) => [entry.key, entry])); const shouldLoadRegistry = modelRowSourcesRequireRegistry({ all: opts.all, useProviderCatalogFastPath, @@ -70,6 +72,11 @@ export async function modelsListCommand( discoveredKeys = loaded.discoveredKeys; availableKeys = loaded.availableKeys; availabilityErrorMessage = loaded.availabilityErrorMessage; + } else if (!opts.all) { + const loaded = loadConfiguredListModelRegistry(cfg, entries, { providerFilter }); + modelRegistry = loaded.registry; + discoveredKeys = loaded.discoveredKeys; + availableKeys = loaded.availableKeys; } } catch (err) { runtime.error(`Model registry unavailable:\n${formatErrorWithStack(err)}`); @@ -81,8 +88,6 @@ export async function modelsListCommand( `Model availability lookup failed; falling back to auth heuristics for discovered models: ${availabilityErrorMessage}`, ); } - const { entries } = resolveConfiguredEntries(cfg); - const configuredByKey = new Map(entries.map((entry) => [entry.key, entry])); const rows: ModelRow[] = []; const rowContext = { diff --git a/src/commands/models/list.registry-load.ts b/src/commands/models/list.registry-load.ts index f85def817b7..e4114be6a04 100644 --- a/src/commands/models/list.registry-load.ts +++ b/src/commands/models/list.registry-load.ts @@ -1,5 +1,10 @@ +import type { Api, Model } from "@mariozechner/pi-ai"; +import type { ModelRegistry } from "@mariozechner/pi-coding-agent"; +import { shouldSuppressBuiltInModel } from "../../agents/model-suppression.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { loadModelRegistry } from "./list.registry.js"; +import { discoverAuthStorage, discoverModels, resolveOpenClawAgentDir } from "./list.runtime.js"; +import type { ConfiguredEntry } from "./list.types.js"; import { modelKey } from "./shared.js"; export async function loadListModelRegistry( @@ -12,3 +17,57 @@ export async function loadListModelRegistry( discoveredKeys: new Set(loaded.models.map((model) => modelKey(model.provider, model.id))), }; } + +function findConfiguredRegistryModel(params: { + registry: ModelRegistry; + entry: ConfiguredEntry; + cfg: OpenClawConfig; +}): Model | undefined { + const model = params.registry.find(params.entry.ref.provider, params.entry.ref.model); + if (!model) { + return undefined; + } + if ( + shouldSuppressBuiltInModel({ + provider: model.provider, + id: model.id, + baseUrl: model.baseUrl, + config: params.cfg, + }) + ) { + return undefined; + } + return model; +} + +export function loadConfiguredListModelRegistry( + cfg: OpenClawConfig, + entries: ConfiguredEntry[], + opts?: { providerFilter?: string }, +) { + const agentDir = resolveOpenClawAgentDir(); + const authStorage = discoverAuthStorage(agentDir, { readOnly: true }); + const registry = discoverModels(authStorage, agentDir, { + providerFilter: opts?.providerFilter, + }); + const discoveredKeys = new Set(); + const availableKeys = new Set(); + + for (const entry of entries) { + const model = findConfiguredRegistryModel({ registry, entry, cfg }); + if (!model) { + continue; + } + const key = modelKey(model.provider, model.id); + discoveredKeys.add(key); + if (registry.hasConfiguredAuth(model)) { + availableKeys.add(key); + } + } + + return { + registry, + discoveredKeys, + availableKeys, + }; +} diff --git a/src/commands/models/list.row-sources.ts b/src/commands/models/list.row-sources.ts index 9ced8a300b8..39f360d3fbb 100644 --- a/src/commands/models/list.row-sources.ts +++ b/src/commands/models/list.row-sources.ts @@ -20,7 +20,10 @@ export function modelRowSourcesRequireRegistry(params: { all?: boolean; useProviderCatalogFastPath: boolean; }): boolean { - return !(params.all && params.useProviderCatalogFastPath); + if (!params.all) { + return false; + } + return !params.useProviderCatalogFastPath; } export async function appendAllModelRowSources(params: AllModelRowSources): Promise {