fix: skip runtime normalization for broad model lists

This commit is contained in:
Shakker
2026-04-27 18:37:55 +01:00
parent 8f92239fdb
commit 9682f3937e
5 changed files with 31 additions and 14 deletions

View File

@@ -35,6 +35,7 @@ type DiscoveredProviderRuntimeModelLike = Omit<ProviderRuntimeModelLike, "api">
type DiscoverModelsOptions = {
providerFilter?: string;
normalizeModels?: boolean;
};
type InMemoryAuthStorageBackendLike = {
@@ -149,17 +150,24 @@ function createOpenClawModelRegistry(
const providerFilter = options?.providerFilter ? normalizeProviderId(options.providerFilter) : "";
const matchesProviderFilter = (entry: Model<Api>) =>
!providerFilter || normalizeProviderId(entry.provider) === providerFilter;
const shouldNormalize = options?.normalizeModels !== false;
registry.getAll = () =>
getAll()
.filter((entry: Model<Api>) => matchesProviderFilter(entry))
.map((entry: Model<Api>) => normalizeDiscoveredPiModel(entry, agentDir));
registry.getAvailable = () =>
getAvailable()
.filter((entry: Model<Api>) => matchesProviderFilter(entry))
.map((entry: Model<Api>) => normalizeDiscoveredPiModel(entry, agentDir));
registry.getAll = () => {
const entries = getAll().filter((entry: Model<Api>) => matchesProviderFilter(entry));
return shouldNormalize
? entries.map((entry: Model<Api>) => normalizeDiscoveredPiModel(entry, agentDir))
: entries;
};
registry.getAvailable = () => {
const entries = getAvailable().filter((entry: Model<Api>) => matchesProviderFilter(entry));
return shouldNormalize
? entries.map((entry: Model<Api>) => normalizeDiscoveredPiModel(entry, agentDir))
: entries;
};
registry.find = (provider: string, modelId: string) =>
normalizeDiscoveredPiModel(find(provider, modelId), agentDir);
shouldNormalize
? normalizeDiscoveredPiModel(find(provider, modelId), agentDir)
: find(provider, modelId);
return registry;
}

View File

@@ -153,7 +153,7 @@ function installModelsListCommandForwardCompatMocks() {
vi.doMock("./list.registry-load.js", () => ({
loadListModelRegistry: async (
cfg: unknown,
opts?: { providerFilter?: string },
opts?: { providerFilter?: string; normalizeModels?: boolean },
): Promise<{
models: Array<{ provider: string; id: string }>;
availableKeys?: Set<string>;
@@ -173,7 +173,7 @@ function installModelsListCommandForwardCompatMocks() {
loadConfiguredListModelRegistry: (
_cfg: unknown,
_entries: unknown,
opts?: { providerFilter?: string },
opts?: { providerFilter?: string; normalizeModels?: boolean },
) => {
mocks.loadModelRegistry(mocks.resolvedConfig, opts);
return {
@@ -618,6 +618,7 @@ describe("modelsListCommand forward-compat", () => {
expect(mocks.loadModelRegistry).toHaveBeenCalledWith(mocks.resolvedConfig, {
providerFilter: undefined,
normalizeModels: false,
});
expect(mocks.loadProviderCatalogModelsForList).not.toHaveBeenCalled();
expect(mocks.resolveModelWithRegistry).not.toHaveBeenCalled();
@@ -653,6 +654,7 @@ describe("modelsListCommand forward-compat", () => {
mocks.resolvedConfig,
expect.objectContaining({
providerFilter: "openai-codex",
normalizeModels: true,
}),
);
expect(mocks.loadProviderCatalogModelsForList).toHaveBeenNthCalledWith(1, {

View File

@@ -92,7 +92,10 @@ export async function modelsListCommand(
const shouldLoadRegistry = sourcePlan?.requiresInitialRegistry ?? false;
const loadRegistryState = async () => {
const { loadListModelRegistry } = await loadRegistryLoadModule();
const loaded = await loadListModelRegistry(cfg, { providerFilter });
const loaded = await loadListModelRegistry(cfg, {
providerFilter,
normalizeModels: Boolean(providerFilter),
});
modelRegistry = loaded.registry;
discoveredKeys = loaded.discoveredKeys;
availableKeys = loaded.availableKeys;

View File

@@ -10,7 +10,7 @@ import { modelKey } from "./shared.js";
export async function loadListModelRegistry(
cfg: OpenClawConfig,
opts?: { providerFilter?: string },
opts?: { providerFilter?: string; normalizeModels?: boolean },
) {
const loaded = await loadModelRegistry(cfg, opts);
return {

View File

@@ -107,11 +107,15 @@ function loadAvailableModels(registry: ModelRegistry, cfg: OpenClawConfig): Mode
}
}
export async function loadModelRegistry(cfg: OpenClawConfig, opts?: { providerFilter?: string }) {
export async function loadModelRegistry(
cfg: OpenClawConfig,
opts?: { providerFilter?: string; normalizeModels?: boolean },
) {
const agentDir = resolveOpenClawAgentDir();
const authStorage = discoverAuthStorage(agentDir, { readOnly: true });
const registry = discoverModels(authStorage, agentDir, {
providerFilter: opts?.providerFilter,
normalizeModels: opts?.normalizeModels,
});
const models = registry.getAll().filter(
(model) =>