mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-30 19:33:31 +00:00
fix(plugins): treat refreshable catalogs as requiring runtime discovery (#93786)
Treat refreshable manifest catalog rows as non-authoritative and load the owning plugin for runtime/cache-backed discovery. Adds focused regression coverage for entries-only and full discovery paths.
This commit is contained in:
@@ -67,7 +67,7 @@ function createManifestPlugin(id: string): PluginManifestRecord {
|
||||
|
||||
function createManifestPluginWithModelCatalog(
|
||||
id: string,
|
||||
discovery: "static" | "runtime" = "static",
|
||||
discovery: "static" | "refreshable" | "runtime" = "static",
|
||||
): PluginManifestRecord {
|
||||
return {
|
||||
...createManifestPluginWithoutDiscovery({ id }),
|
||||
@@ -263,6 +263,38 @@ describe("resolvePluginDiscoveryProvidersRuntime", () => {
|
||||
expect(mocks.resolvePluginProviders).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not synthesize manifest entry providers for refreshable catalogs", () => {
|
||||
mocks.resolveDiscoveredProviderPluginIds.mockReturnValue(["token-plan"]);
|
||||
mocks.loadPluginMetadataSnapshot.mockReturnValue({
|
||||
index: { plugins: [] },
|
||||
manifestRegistry: {
|
||||
plugins: [createManifestPluginWithModelCatalog("token-plan", "refreshable")],
|
||||
diagnostics: [],
|
||||
},
|
||||
});
|
||||
|
||||
expect(resolvePluginDiscoveryProvidersRuntime({ discoveryEntriesOnly: true })).toStrictEqual(
|
||||
[],
|
||||
);
|
||||
expect(mocks.resolvePluginProviders).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("loads the full plugin for refreshable manifest catalog rows", () => {
|
||||
const refreshableProvider = createProvider({ id: "token-plan", mode: "catalog" });
|
||||
mocks.resolveDiscoveredProviderPluginIds.mockReturnValue(["token-plan"]);
|
||||
mocks.resolvePluginProviders.mockReturnValue([refreshableProvider]);
|
||||
mocks.loadPluginMetadataSnapshot.mockReturnValue({
|
||||
index: { plugins: [] },
|
||||
manifestRegistry: {
|
||||
plugins: [createManifestPluginWithModelCatalog("token-plan", "refreshable")],
|
||||
diagnostics: [],
|
||||
},
|
||||
});
|
||||
|
||||
expect(resolvePluginDiscoveryProvidersRuntime({})).toStrictEqual([refreshableProvider]);
|
||||
expect(requireResolvePluginProvidersParams().onlyPluginIds).toEqual(["token-plan"]);
|
||||
});
|
||||
|
||||
it("loads the full plugin when one manifest catalog provider is runtime-owned", () => {
|
||||
const runtimeProvider = createProvider({ id: "xiaomi-token-plan", mode: "catalog" });
|
||||
mocks.resolveDiscoveredProviderPluginIds.mockReturnValue(["xiaomi"]);
|
||||
|
||||
@@ -217,7 +217,7 @@ function resolveManifestModelCatalogProviders(
|
||||
}
|
||||
const plan = planManifestModelCatalogRows({ registry: { plugins: [plugin] } });
|
||||
for (const entry of plan.entries) {
|
||||
if (entry.rows.length === 0 || entry.discovery === "runtime") {
|
||||
if (entry.rows.length === 0 || entry.discovery === "runtime" || entry.discovery === "refreshable") {
|
||||
continue;
|
||||
}
|
||||
const providerConfig = providerConfigFromManifestRows(entry.rows);
|
||||
@@ -249,7 +249,7 @@ function resolveRuntimeManifestCatalogPluginIds(
|
||||
);
|
||||
const ownsRuntimeDiscovery = Object.entries(plugin.modelCatalog?.discovery ?? {}).some(
|
||||
([provider, discovery]) =>
|
||||
discovery === "runtime" && ownedProviders.has(normalizeProviderId(provider)),
|
||||
(discovery === "runtime" || discovery === "refreshable") && ownedProviders.has(normalizeProviderId(provider)),
|
||||
);
|
||||
if (ownsRuntimeDiscovery) {
|
||||
pluginIds.add(plugin.id);
|
||||
@@ -259,7 +259,7 @@ function resolveRuntimeManifestCatalogPluginIds(
|
||||
continue;
|
||||
}
|
||||
const plan = planManifestModelCatalogRows({ registry: { plugins: [plugin] } });
|
||||
if (plan.entries.some((entry) => entry.discovery === "runtime")) {
|
||||
if (plan.entries.some((entry) => entry.discovery === "runtime" || entry.discovery === "refreshable")) {
|
||||
pluginIds.add(plugin.id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user