refactor: support broad static catalog reads

This commit is contained in:
Shakker
2026-04-27 17:31:48 +01:00
parent f64e4fd8cf
commit 9df9bbd243
4 changed files with 101 additions and 15 deletions

View File

@@ -0,0 +1,73 @@
import { describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
loadPluginRegistrySnapshot: vi.fn(),
resolvePluginContributionOwners: vi.fn(),
getPluginRecord: vi.fn(),
isPluginEnabled: vi.fn(),
loadPluginManifestRegistryForInstalledIndex: vi.fn(),
}));
vi.mock("../../plugins/plugin-registry.js", () => ({
loadPluginRegistrySnapshot: mocks.loadPluginRegistrySnapshot,
resolvePluginContributionOwners: mocks.resolvePluginContributionOwners,
getPluginRecord: mocks.getPluginRecord,
isPluginEnabled: mocks.isPluginEnabled,
}));
vi.mock("../../plugins/manifest-registry-installed.js", () => ({
loadPluginManifestRegistryForInstalledIndex: mocks.loadPluginManifestRegistryForInstalledIndex,
}));
const moonshotPlugin = {
id: "moonshot",
providers: ["moonshot"],
modelCatalog: {
providers: {
moonshot: {
models: [{ id: "kimi-k2.6", name: "Kimi K2.6" }],
},
},
discovery: {
moonshot: "static",
},
},
};
const openrouterPlugin = {
id: "openrouter",
providers: ["openrouter"],
modelCatalog: {
providers: {
openrouter: {
models: [{ id: "auto", name: "Auto" }],
},
},
discovery: {
openrouter: "refreshable",
},
},
};
describe("loadStaticManifestCatalogRowsForList", () => {
it("loads all static manifest catalog rows without a provider filter", async () => {
const { loadStaticManifestCatalogRowsForList } = await import("./list.manifest-catalog.js");
const index = { plugins: [], diagnostics: [] };
mocks.loadPluginRegistrySnapshot.mockReturnValueOnce(index);
mocks.loadPluginManifestRegistryForInstalledIndex.mockReturnValueOnce({
plugins: [openrouterPlugin, moonshotPlugin],
diagnostics: [],
});
expect(
loadStaticManifestCatalogRowsForList({
cfg: {},
}).map((row) => row.ref),
).toEqual(["moonshot/kimi-k2.6"]);
expect(mocks.loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledWith({
index,
config: {},
env: undefined,
});
});
});

View File

@@ -17,10 +17,10 @@ function loadStaticManifestCatalogRowsForPluginIds(params: {
cfg: OpenClawConfig;
env?: NodeJS.ProcessEnv;
index: PluginRegistrySnapshot;
pluginIds: readonly string[];
providerFilter: string;
pluginIds?: readonly string[];
providerFilter?: string;
}): readonly NormalizedModelCatalogRow[] {
if (params.pluginIds.length === 0) {
if (params.pluginIds && params.pluginIds.length === 0) {
return [];
}
const registry = loadPluginManifestRegistryForInstalledIndex({
@@ -31,7 +31,7 @@ function loadStaticManifestCatalogRowsForPluginIds(params: {
});
const plan = planManifestModelCatalogRows({
registry,
providerFilter: params.providerFilter,
...(params.providerFilter ? { providerFilter: params.providerFilter } : {}),
});
const staticProviders = new Set(
plan.entries.filter((entry) => entry.discovery === "static").map((entry) => entry.provider),
@@ -79,17 +79,23 @@ function resolveDeclaredModelCatalogPluginIds(params: {
export function loadStaticManifestCatalogRowsForList(params: {
cfg: OpenClawConfig;
providerFilter: string;
providerFilter?: string;
env?: NodeJS.ProcessEnv;
}): readonly NormalizedModelCatalogRow[] {
const providerFilter = normalizeModelCatalogProviderId(params.providerFilter);
if (!providerFilter) {
return [];
}
const providerFilter = params.providerFilter
? normalizeModelCatalogProviderId(params.providerFilter)
: undefined;
const index = loadPluginRegistrySnapshot({
config: params.cfg,
env: params.env,
});
if (!providerFilter) {
return loadStaticManifestCatalogRowsForPluginIds({
cfg: params.cfg,
env: params.env,
index,
});
}
const conventionRows = loadStaticManifestCatalogRowsForPluginIds({
cfg: params.cfg,
env: params.env,

View File

@@ -14,6 +14,14 @@ describe("loadProviderIndexCatalogRowsForList", () => {
).toContain("moonshot/kimi-k2.6");
});
it("returns all enabled provider-index preview rows without a provider filter", () => {
expect(
loadProviderIndexCatalogRowsForList({
cfg: baseConfig,
}).map((row) => row.ref),
).toEqual(expect.arrayContaining(["deepseek/deepseek-chat", "moonshot/kimi-k2.6"]));
});
it("suppresses provider-index preview rows when the provider plugin is disabled", () => {
expect(
loadProviderIndexCatalogRowsForList({

View File

@@ -8,17 +8,16 @@ import type { NormalizedModelCatalogRow } from "../../model-catalog/index.js";
import { normalizePluginsConfig, resolveEffectiveEnableState } from "../../plugins/config-state.js";
export function loadProviderIndexCatalogRowsForList(params: {
providerFilter: string;
providerFilter?: string;
cfg: OpenClawConfig;
}): readonly NormalizedModelCatalogRow[] {
const providerFilter = normalizeModelCatalogProviderId(params.providerFilter);
if (!providerFilter) {
return [];
}
const providerFilter = params.providerFilter
? normalizeModelCatalogProviderId(params.providerFilter)
: undefined;
const index = loadOpenClawProviderIndex();
return planProviderIndexModelCatalogRows({
index,
providerFilter,
...(providerFilter ? { providerFilter } : {}),
})
.entries.filter(
(entry) =>