mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 05:40:22 +00:00
fix(plugins): reuse active registry during tool resolution (#52262)
Merged via squash.
Prepared head SHA: 55982a6be6
Co-authored-by: PerfectPan <24316656+PerfectPan@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
@@ -18,7 +18,6 @@ const mocks = vi.hoisted(() => ({
|
||||
loadPluginManifestRegistry: vi.fn<() => MockManifestRegistry>(() =>
|
||||
createEmptyMockManifestRegistry(),
|
||||
),
|
||||
withBundledPluginAllowlistCompat: vi.fn(({ config }) => config),
|
||||
withBundledPluginEnablementCompat: vi.fn(({ config }) => config),
|
||||
withBundledPluginVitestCompat: vi.fn(({ config }) => config),
|
||||
}));
|
||||
@@ -32,7 +31,6 @@ vi.mock("./manifest-registry.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("./bundled-compat.js", () => ({
|
||||
withBundledPluginAllowlistCompat: mocks.withBundledPluginAllowlistCompat,
|
||||
withBundledPluginEnablementCompat: mocks.withBundledPluginEnablementCompat,
|
||||
withBundledPluginVitestCompat: mocks.withBundledPluginVitestCompat,
|
||||
}));
|
||||
@@ -49,10 +47,9 @@ function expectNoResolvedCapabilityProviders(providers: Array<{ id: string }>) {
|
||||
|
||||
function expectBundledCompatLoadPath(params: {
|
||||
cfg: OpenClawConfig;
|
||||
allowlistCompat: { plugins: { allow: string[] } };
|
||||
enablementCompat: {
|
||||
plugins: {
|
||||
allow: string[];
|
||||
allow?: string[];
|
||||
entries: { openai: { enabled: boolean } };
|
||||
};
|
||||
};
|
||||
@@ -61,12 +58,8 @@ function expectBundledCompatLoadPath(params: {
|
||||
config: params.cfg,
|
||||
env: process.env,
|
||||
});
|
||||
expect(mocks.withBundledPluginAllowlistCompat).toHaveBeenCalledWith({
|
||||
config: params.cfg,
|
||||
pluginIds: ["openai"],
|
||||
});
|
||||
expect(mocks.withBundledPluginEnablementCompat).toHaveBeenCalledWith({
|
||||
config: params.allowlistCompat,
|
||||
config: params.cfg,
|
||||
pluginIds: ["openai"],
|
||||
});
|
||||
expect(mocks.withBundledPluginVitestCompat).toHaveBeenCalledWith({
|
||||
@@ -81,14 +74,13 @@ function expectBundledCompatLoadPath(params: {
|
||||
|
||||
function createCompatChainConfig() {
|
||||
const cfg = { plugins: { allow: ["custom-plugin"] } } as OpenClawConfig;
|
||||
const allowlistCompat = { plugins: { allow: ["custom-plugin", "openai"] } };
|
||||
const enablementCompat = {
|
||||
plugins: {
|
||||
allow: ["custom-plugin", "openai"],
|
||||
allow: ["custom-plugin"],
|
||||
entries: { openai: { enabled: true } },
|
||||
},
|
||||
};
|
||||
return { cfg, allowlistCompat, enablementCompat };
|
||||
return { cfg, enablementCompat };
|
||||
}
|
||||
|
||||
function setBundledCapabilityFixture(contractKey: string) {
|
||||
@@ -113,16 +105,14 @@ function expectCompatChainApplied(params: {
|
||||
key: "speechProviders" | "mediaUnderstandingProviders" | "imageGenerationProviders";
|
||||
contractKey: string;
|
||||
cfg: OpenClawConfig;
|
||||
allowlistCompat: { plugins: { allow: string[] } };
|
||||
enablementCompat: {
|
||||
plugins: {
|
||||
allow: string[];
|
||||
allow?: string[];
|
||||
entries: { openai: { enabled: boolean } };
|
||||
};
|
||||
};
|
||||
}) {
|
||||
setBundledCapabilityFixture(params.contractKey);
|
||||
mocks.withBundledPluginAllowlistCompat.mockReturnValue(params.allowlistCompat);
|
||||
mocks.withBundledPluginEnablementCompat.mockReturnValue(params.enablementCompat);
|
||||
mocks.withBundledPluginVitestCompat.mockReturnValue(params.enablementCompat);
|
||||
expectNoResolvedCapabilityProviders(
|
||||
@@ -141,8 +131,6 @@ describe("resolvePluginCapabilityProviders", () => {
|
||||
mocks.resolveRuntimePluginRegistry.mockReturnValue(undefined);
|
||||
mocks.loadPluginManifestRegistry.mockReset();
|
||||
mocks.loadPluginManifestRegistry.mockReturnValue(createEmptyMockManifestRegistry());
|
||||
mocks.withBundledPluginAllowlistCompat.mockReset();
|
||||
mocks.withBundledPluginAllowlistCompat.mockImplementation(({ config }) => config);
|
||||
mocks.withBundledPluginEnablementCompat.mockReset();
|
||||
mocks.withBundledPluginEnablementCompat.mockImplementation(({ config }) => config);
|
||||
mocks.withBundledPluginVitestCompat.mockReset();
|
||||
@@ -216,16 +204,46 @@ describe("resolvePluginCapabilityProviders", () => {
|
||||
["mediaUnderstandingProviders", "mediaUnderstandingProviders"],
|
||||
["imageGenerationProviders", "imageGenerationProviders"],
|
||||
] as const)("applies bundled compat before fallback loading for %s", (key, contractKey) => {
|
||||
const { cfg, allowlistCompat, enablementCompat } = createCompatChainConfig();
|
||||
const { cfg, enablementCompat } = createCompatChainConfig();
|
||||
expectCompatChainApplied({
|
||||
key,
|
||||
contractKey,
|
||||
cfg,
|
||||
allowlistCompat,
|
||||
enablementCompat,
|
||||
});
|
||||
});
|
||||
|
||||
it("does not re-add bundled capability plugins excluded by an explicit allowlist", () => {
|
||||
const cfg = { plugins: { allow: ["custom-plugin"] } } as OpenClawConfig;
|
||||
const enablementCompat = {
|
||||
plugins: {
|
||||
allow: ["custom-plugin"],
|
||||
entries: { openai: { enabled: true } },
|
||||
},
|
||||
};
|
||||
|
||||
setBundledCapabilityFixture("speechProviders");
|
||||
mocks.withBundledPluginEnablementCompat.mockReturnValue(enablementCompat);
|
||||
mocks.withBundledPluginVitestCompat.mockReturnValue(enablementCompat);
|
||||
|
||||
expectNoResolvedCapabilityProviders(
|
||||
resolvePluginCapabilityProviders({ key: "speechProviders", cfg }),
|
||||
);
|
||||
|
||||
expect(mocks.withBundledPluginEnablementCompat).toHaveBeenCalledWith({
|
||||
config: cfg,
|
||||
pluginIds: ["openai"],
|
||||
});
|
||||
expect(mocks.withBundledPluginVitestCompat).toHaveBeenCalledWith({
|
||||
config: enablementCompat,
|
||||
pluginIds: ["openai"],
|
||||
env: process.env,
|
||||
});
|
||||
expect(mocks.resolveRuntimePluginRegistry).toHaveBeenCalledWith({
|
||||
config: enablementCompat,
|
||||
});
|
||||
});
|
||||
|
||||
it("reuses a compatible active registry even when the capability list is empty", () => {
|
||||
const active = createEmptyPluginRegistry();
|
||||
mocks.resolveRuntimePluginRegistry.mockReturnValue(active);
|
||||
|
||||
Reference in New Issue
Block a user