mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:00:44 +00:00
fix(cli): resolve message channel plugin scopes
This commit is contained in:
@@ -7,6 +7,8 @@ const mocks = vi.hoisted(() => ({
|
||||
getActivePluginRegistry: vi.fn<typeof import("../runtime.js").getActivePluginRegistry>(),
|
||||
resolveConfiguredChannelPluginIds:
|
||||
vi.fn<typeof import("../channel-plugin-ids.js").resolveConfiguredChannelPluginIds>(),
|
||||
resolveDiscoverableScopedChannelPluginIds:
|
||||
vi.fn<typeof import("../channel-plugin-ids.js").resolveDiscoverableScopedChannelPluginIds>(),
|
||||
resolveChannelPluginIds:
|
||||
vi.fn<typeof import("../channel-plugin-ids.js").resolveChannelPluginIds>(),
|
||||
applyPluginAutoEnable:
|
||||
@@ -39,6 +41,9 @@ vi.mock("../channel-plugin-ids.js", () => ({
|
||||
resolveConfiguredChannelPluginIds: (
|
||||
...args: Parameters<typeof mocks.resolveConfiguredChannelPluginIds>
|
||||
) => mocks.resolveConfiguredChannelPluginIds(...args),
|
||||
resolveDiscoverableScopedChannelPluginIds: (
|
||||
...args: Parameters<typeof mocks.resolveDiscoverableScopedChannelPluginIds>
|
||||
) => mocks.resolveDiscoverableScopedChannelPluginIds(...args),
|
||||
resolveChannelPluginIds: (...args: Parameters<typeof mocks.resolveChannelPluginIds>) =>
|
||||
mocks.resolveChannelPluginIds(...args),
|
||||
}));
|
||||
@@ -67,6 +72,7 @@ describe("ensurePluginRegistryLoaded", () => {
|
||||
mocks.resolveRuntimePluginRegistry.mockReset();
|
||||
mocks.getActivePluginRegistry.mockReset();
|
||||
mocks.resolveConfiguredChannelPluginIds.mockReset();
|
||||
mocks.resolveDiscoverableScopedChannelPluginIds.mockReset();
|
||||
mocks.resolveChannelPluginIds.mockReset();
|
||||
mocks.applyPluginAutoEnable.mockReset();
|
||||
mocks.resolveAgentWorkspaceDir.mockClear();
|
||||
@@ -95,6 +101,7 @@ describe("ensurePluginRegistryLoaded", () => {
|
||||
demo: ["demo configured"],
|
||||
},
|
||||
}));
|
||||
mocks.resolveDiscoverableScopedChannelPluginIds.mockReturnValue([]);
|
||||
});
|
||||
|
||||
it("uses the shared runtime load context for configured-channel loads", () => {
|
||||
@@ -215,6 +222,54 @@ describe("ensurePluginRegistryLoaded", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("maps explicit channel scopes to owner plugin ids before loading", () => {
|
||||
const rawConfig = { channels: { "external-chat": { token: "configured" } } };
|
||||
mocks.resolveDiscoverableScopedChannelPluginIds.mockReturnValue(["external-chat-plugin"]);
|
||||
|
||||
ensurePluginRegistryLoaded({
|
||||
scope: "configured-channels",
|
||||
config: rawConfig as never,
|
||||
onlyChannelIds: ["external-chat"],
|
||||
});
|
||||
|
||||
expect(mocks.resolveDiscoverableScopedChannelPluginIds).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: expect.objectContaining({
|
||||
...rawConfig,
|
||||
plugins: expect.objectContaining({
|
||||
entries: expect.objectContaining({
|
||||
demo: { enabled: true },
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
activationSourceConfig: rawConfig,
|
||||
channelIds: ["external-chat"],
|
||||
workspaceDir: "/resolved-workspace",
|
||||
}),
|
||||
);
|
||||
expect(mocks.loadOpenClawPlugins).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
config: expect.objectContaining({
|
||||
plugins: expect.objectContaining({
|
||||
allow: ["external-chat-plugin"],
|
||||
entries: expect.objectContaining({
|
||||
"external-chat-plugin": { enabled: true },
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
activationSourceConfig: expect.objectContaining({
|
||||
plugins: expect.objectContaining({
|
||||
allow: ["external-chat-plugin"],
|
||||
entries: expect.objectContaining({
|
||||
"external-chat-plugin": { enabled: true },
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
onlyPluginIds: ["external-chat-plugin"],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("forwards explicit empty scopes without widening to channel resolution", () => {
|
||||
ensurePluginRegistryLoaded({
|
||||
scope: "configured-channels",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { withActivatedPluginIds } from "../activation-context.js";
|
||||
import {
|
||||
resolveChannelPluginIds,
|
||||
resolveConfiguredChannelPluginIds,
|
||||
resolveDiscoverableScopedChannelPluginIds,
|
||||
} from "../channel-plugin-ids.js";
|
||||
import { loadOpenClawPlugins, resolveRuntimePluginRegistry } from "../loader.js";
|
||||
import {
|
||||
@@ -90,11 +91,30 @@ export function ensurePluginRegistryLoaded(options?: {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
onlyPluginIds?: string[];
|
||||
onlyChannelIds?: string[];
|
||||
}): void {
|
||||
const scope = options?.scope ?? "all";
|
||||
const requestedPluginIds = normalizePluginIdScope(options?.onlyPluginIds);
|
||||
const scopedLoad = hasExplicitPluginIdScope(requestedPluginIds);
|
||||
const requestedPluginIdsFromOptions = normalizePluginIdScope(options?.onlyPluginIds);
|
||||
const requestedChannelIds = normalizePluginIdScope(options?.onlyChannelIds);
|
||||
const context = resolvePluginRuntimeLoadContext(options);
|
||||
const requestedChannelOwnerPluginIds =
|
||||
requestedChannelIds === undefined
|
||||
? undefined
|
||||
: resolveDiscoverableScopedChannelPluginIds({
|
||||
config: context.config,
|
||||
activationSourceConfig: context.activationSourceConfig,
|
||||
channelIds: requestedChannelIds,
|
||||
workspaceDir: context.workspaceDir,
|
||||
env: context.env,
|
||||
});
|
||||
const requestedPluginIds =
|
||||
requestedChannelOwnerPluginIds === undefined
|
||||
? requestedPluginIdsFromOptions
|
||||
: normalizePluginIdScope([
|
||||
...(requestedPluginIdsFromOptions ?? []),
|
||||
...requestedChannelOwnerPluginIds,
|
||||
]);
|
||||
const scopedLoad = hasExplicitPluginIdScope(requestedPluginIds);
|
||||
const expectedChannelPluginIds = scopedLoad
|
||||
? (requestedPluginIds ?? [])
|
||||
: scope === "configured-channels"
|
||||
@@ -129,14 +149,18 @@ export function ensurePluginRegistryLoaded(options?: {
|
||||
return;
|
||||
}
|
||||
const scopedConfig =
|
||||
!scopedLoad && scope === "configured-channels" && expectedChannelPluginIds.length > 0
|
||||
scope === "configured-channels" &&
|
||||
expectedChannelPluginIds.length > 0 &&
|
||||
(!scopedLoad || requestedChannelOwnerPluginIds !== undefined)
|
||||
? (withActivatedPluginIds({
|
||||
config: context.config,
|
||||
pluginIds: expectedChannelPluginIds,
|
||||
}) ?? context.config)
|
||||
: context.config;
|
||||
const scopedActivationSourceConfig =
|
||||
!scopedLoad && scope === "configured-channels" && expectedChannelPluginIds.length > 0
|
||||
scope === "configured-channels" &&
|
||||
expectedChannelPluginIds.length > 0 &&
|
||||
(!scopedLoad || requestedChannelOwnerPluginIds !== undefined)
|
||||
? (withActivatedPluginIds({
|
||||
config: context.activationSourceConfig,
|
||||
pluginIds: expectedChannelPluginIds,
|
||||
|
||||
Reference in New Issue
Block a user