fix(plugins): reuse lifecycle provider metadata (#115426)

This commit is contained in:
Josh Lehman
2026-07-28 16:08:21 -07:00
committed by GitHub
parent 89bdb2d1c0
commit efde02c2a5
2 changed files with 40 additions and 8 deletions
+40 -7
View File
@@ -117,17 +117,27 @@ const providerEndpointPlugins = vi.hoisted(() => [
]);
const providerMetadataState = vi.hoisted(() => ({
compatible: true,
defaultDiscoveryCompatible: true,
pluginIdScoped: false,
snapshot: undefined as unknown,
}));
const loadPluginMetadataSnapshot = vi.hoisted(() =>
vi.fn(() => ({
owners: {
providerEndpoints: [],
providerRequests: new Map(),
},
})),
);
vi.mock("../plugins/current-plugin-metadata-snapshot.js", () => ({
getCurrentPluginMetadataSnapshot: (params?: {
config?: unknown;
allowScopedSnapshot?: boolean;
requireDefaultDiscoveryContext?: boolean;
}) =>
params?.config !== undefined ||
(params?.requireDefaultDiscoveryContext && !providerMetadataState.compatible)
(providerMetadataState.pluginIdScoped && params?.allowScopedSnapshot !== true) ||
(params?.requireDefaultDiscoveryContext === true &&
!providerMetadataState.defaultDiscoveryCompatible)
? undefined
: (providerMetadataState.snapshot ?? {
owners: {
@@ -151,6 +161,10 @@ vi.mock("../plugins/current-plugin-metadata-snapshot.js", () => ({
}),
}));
vi.mock("../plugins/plugin-metadata-snapshot.js", () => ({
loadPluginMetadataSnapshot,
}));
import {
resolveProviderEndpoint,
resolveProviderRequestCapabilities,
@@ -188,8 +202,10 @@ function listProviderAttributionPolicies(env: ProviderAttributionTestEnv) {
describe("provider attribution", () => {
afterEach(() => {
providerMetadataState.compatible = true;
providerMetadataState.defaultDiscoveryCompatible = true;
providerMetadataState.pluginIdScoped = false;
providerMetadataState.snapshot = undefined;
loadPluginMetadataSnapshot.mockClear();
});
it("uses provider facts from the replacement plugin snapshot after reload", () => {
@@ -235,8 +251,8 @@ describe("provider attribution", () => {
);
});
it("rejects provider facts from a scoped current snapshot", () => {
providerMetadataState.compatible = false;
it("rejects provider facts from a plugin-id-scoped current snapshot", () => {
providerMetadataState.pluginIdScoped = true;
providerMetadataState.snapshot = {
owners: {
providerEndpoints: [
@@ -254,6 +270,23 @@ describe("provider attribution", () => {
expect(resolveProviderEndpoint("https://scoped-only.example").endpointClass).toBe("custom");
});
it("reuses lifecycle provider facts without a default-discovery fallback", () => {
providerMetadataState.defaultDiscoveryCompatible = false;
providerMetadataState.snapshot = {
owners: {
providerEndpoints: [],
providerRequests: new Map([["custom-provider", { family: "custom" }]]),
},
};
for (let index = 0; index < 10; index += 1) {
expect(
resolveProviderRequestPolicy({ provider: "custom-provider" }).knownProviderFamily,
).toBe("custom");
}
expect(loadPluginMetadataSnapshot).not.toHaveBeenCalled();
});
it("resolves the canonical OpenClaw product and runtime version", () => {
const identity = resolveProviderAttributionIdentity({
OPENCLAW_VERSION: "2026.3.99",
-1
View File
@@ -180,7 +180,6 @@ type ProviderMetadataOwners = {
function resolveProviderMetadataOwners(): ProviderMetadataOwners {
const current = getCurrentPluginMetadataSnapshot({
allowWorkspaceScopedSnapshot: true,
requireDefaultDiscoveryContext: true,
});
if (current) {
return {