fix: use refreshable manifest rows for provider list fast paths

This commit is contained in:
Shakker
2026-04-28 01:08:03 +01:00
parent 27a8875241
commit 973a3226f0
4 changed files with 14 additions and 19 deletions

View File

@@ -53,8 +53,8 @@ Notes:
unavailable until matching auth is configured.
- Broad `models list --all` merges manifest catalog rows over registry rows
without loading provider runtime supplement hooks. Provider-filtered manifest
fast paths only use providers marked `static`, so partial `refreshable`
manifest rows do not hide registry-backed provider lists.
fast paths use `static` and `refreshable` manifest rows; providers marked
`runtime` stay on registry/runtime discovery.
- `models list` keeps native model metadata and runtime caps distinct. In table
output, `Ctx` shows `contextTokens/contextWindow` when an effective runtime
cap differs from the native context window; JSON rows include `contextTokens`

View File

@@ -50,7 +50,7 @@ const openrouterPlugin = {
};
describe("loadStaticManifestCatalogRowsForList", () => {
it("loads all static manifest catalog rows without a provider filter", async () => {
it("loads listable manifest catalog rows without a provider filter", async () => {
const { loadStaticManifestCatalogRowsForList } = await import("./list.manifest-catalog.js");
const index = { plugins: [], diagnostics: [] };
mocks.loadPluginRegistrySnapshot.mockReturnValueOnce(index);
@@ -63,7 +63,7 @@ describe("loadStaticManifestCatalogRowsForList", () => {
loadStaticManifestCatalogRowsForList({
cfg: {},
}).map((row) => row.ref),
).toEqual(["moonshot/kimi-k2.6"]);
).toEqual(["moonshot/kimi-k2.6", "openrouter/auto"]);
expect(mocks.loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledWith({
index,
config: {},

View File

@@ -37,13 +37,13 @@ function loadManifestCatalogRowsForPluginIds(params: {
if (params.staticOnly === false) {
return plan.rows;
}
const staticProviders = new Set(
plan.entries.filter((entry) => entry.discovery === "static").map((entry) => entry.provider),
const listableProviders = new Set(
plan.entries.filter((entry) => entry.discovery !== "runtime").map((entry) => entry.provider),
);
if (staticProviders.size === 0) {
if (listableProviders.size === 0) {
return [];
}
return plan.rows.filter((row) => staticProviders.has(row.provider));
return plan.rows.filter((row) => listableProviders.has(row.provider));
}
function resolveConventionModelCatalogPluginIds(params: {

View File

@@ -83,9 +83,9 @@ describe("planAllModelListSources", () => {
expect(mocks.hasProviderStaticCatalogForFilter).not.toHaveBeenCalled();
});
it("uses the registry when provider-filtered manifest rows are refreshable", async () => {
it("uses provider-filtered refreshable manifest rows without loading the registry", async () => {
const { planAllModelListSources } = await import("./list.source-plan.js");
mocks.loadManifestCatalogRowsForList.mockReturnValueOnce([]).mockReturnValueOnce([catalogRow]);
mocks.loadManifestCatalogRowsForList.mockReturnValueOnce([catalogRow]);
const plan = await planAllModelListSources({
all: true,
@@ -94,21 +94,16 @@ describe("planAllModelListSources", () => {
});
expect(plan).toMatchObject({
kind: "registry",
requiresInitialRegistry: true,
skipRuntimeModelSuppression: false,
kind: "manifest",
requiresInitialRegistry: false,
skipRuntimeModelSuppression: true,
});
expect(plan.manifestCatalogRows).toEqual([catalogRow]);
expect(mocks.loadManifestCatalogRowsForList).toHaveBeenNthCalledWith(1, {
expect(mocks.loadManifestCatalogRowsForList).toHaveBeenCalledWith({
cfg: {},
providerFilter: "openai",
staticOnly: true,
});
expect(mocks.loadManifestCatalogRowsForList).toHaveBeenNthCalledWith(2, {
cfg: {},
providerFilter: "openai",
staticOnly: false,
});
expect(mocks.loadProviderIndexCatalogRowsForList).not.toHaveBeenCalled();
});