mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-16 23:20:43 +00:00
perf: scope reply runtime plugin startup
This commit is contained in:
@@ -25,6 +25,7 @@ vi.mock("../config/plugin-auto-enable.js", () => ({
|
||||
|
||||
let resolvePluginTools: typeof import("./tools.js").resolvePluginTools;
|
||||
let buildPluginToolMetadataKey: typeof import("./tools.js").buildPluginToolMetadataKey;
|
||||
let pinActivePluginChannelRegistry: typeof import("./runtime.js").pinActivePluginChannelRegistry;
|
||||
let resetPluginRuntimeStateForTest: typeof import("./runtime.js").resetPluginRuntimeStateForTest;
|
||||
let setActivePluginRegistry: typeof import("./runtime.js").setActivePluginRegistry;
|
||||
|
||||
@@ -226,7 +227,8 @@ function expectConflictingCoreNameResolution(params: {
|
||||
describe("resolvePluginTools optional tools", () => {
|
||||
beforeAll(async () => {
|
||||
({ buildPluginToolMetadataKey, resolvePluginTools } = await import("./tools.js"));
|
||||
({ resetPluginRuntimeStateForTest, setActivePluginRegistry } = await import("./runtime.js"));
|
||||
({ pinActivePluginChannelRegistry, resetPluginRuntimeStateForTest, setActivePluginRegistry } =
|
||||
await import("./runtime.js"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -544,7 +546,7 @@ describe("resolvePluginTools optional tools", () => {
|
||||
expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("routes gateway-bindable tool loads through scoped runtime compatibility", () => {
|
||||
it("reuses the gateway-bindable registry when it covers the tool runtime scope", () => {
|
||||
const activeRegistry = createOptionalDemoActiveRegistry();
|
||||
setActivePluginRegistry(activeRegistry as never, "gateway-startup", "gateway-bindable");
|
||||
resolveRuntimePluginRegistryMock.mockReturnValue(activeRegistry);
|
||||
@@ -557,14 +559,7 @@ describe("resolvePluginTools optional tools", () => {
|
||||
);
|
||||
|
||||
expectResolvedToolNames(tools, ["optional_tool"]);
|
||||
expect(resolveRuntimePluginRegistryMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
onlyPluginIds: ["optional-demo"],
|
||||
runtimeOptions: {
|
||||
allowGatewaySubagentBinding: true,
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(resolveRuntimePluginRegistryMock).not.toHaveBeenCalled();
|
||||
expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -597,6 +592,55 @@ describe("resolvePluginTools optional tools", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("reuses the pinned gateway channel registry after provider runtime loads replace active registry", () => {
|
||||
const gatewayRegistry = createOptionalDemoActiveRegistry();
|
||||
pinActivePluginChannelRegistry(gatewayRegistry as never);
|
||||
setActivePluginRegistry(
|
||||
{
|
||||
tools: [],
|
||||
diagnostics: [],
|
||||
} as never,
|
||||
"provider-runtime",
|
||||
"default",
|
||||
);
|
||||
resolveRuntimePluginRegistryMock.mockReturnValue(undefined);
|
||||
|
||||
const tools = resolvePluginTools(
|
||||
createResolveToolsParams({
|
||||
toolAllowlist: ["optional_tool"],
|
||||
allowGatewaySubagentBinding: true,
|
||||
}),
|
||||
);
|
||||
|
||||
expectResolvedToolNames(tools, ["optional_tool"]);
|
||||
expect(resolveRuntimePluginRegistryMock).not.toHaveBeenCalled();
|
||||
expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reuses the pinned gateway channel registry even when the caller omits gateway binding", () => {
|
||||
const gatewayRegistry = createOptionalDemoActiveRegistry();
|
||||
pinActivePluginChannelRegistry(gatewayRegistry as never);
|
||||
setActivePluginRegistry(
|
||||
{
|
||||
tools: [],
|
||||
diagnostics: [],
|
||||
} as never,
|
||||
"provider-runtime",
|
||||
"default",
|
||||
);
|
||||
resolveRuntimePluginRegistryMock.mockReturnValue(undefined);
|
||||
|
||||
const tools = resolvePluginTools(
|
||||
createResolveToolsParams({
|
||||
toolAllowlist: ["optional_tool"],
|
||||
}),
|
||||
);
|
||||
|
||||
expectResolvedToolNames(tools, ["optional_tool"]);
|
||||
expect(resolveRuntimePluginRegistryMock).not.toHaveBeenCalled();
|
||||
expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("loads plugin tools when gateway-bindable tool loads have no active registry", () => {
|
||||
setOptionalDemoRegistry();
|
||||
|
||||
|
||||
@@ -5,7 +5,12 @@ import { applyTestPluginDefaults, normalizePluginsConfig } from "./config-state.
|
||||
import { listEnabledInstalledPluginRecords } from "./installed-plugin-index.js";
|
||||
import { resolveRuntimePluginRegistry, type PluginLoadOptions } from "./loader.js";
|
||||
import { loadPluginRegistrySnapshot } from "./plugin-registry-snapshot.js";
|
||||
import { getActivePluginRegistry } from "./runtime.js";
|
||||
import {
|
||||
getActivePluginChannelRegistry,
|
||||
getActivePluginRegistry,
|
||||
getActivePluginRegistryKey,
|
||||
getActivePluginRuntimeSubagentMode,
|
||||
} from "./runtime.js";
|
||||
import {
|
||||
buildPluginRuntimeLoadOptions,
|
||||
resolvePluginRuntimeLoadContext,
|
||||
@@ -194,18 +199,25 @@ function describeMalformedPluginTool(tool: unknown): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addLoadedPluginIdsFromRegistry(
|
||||
registry: ReturnType<typeof getActivePluginRegistry>,
|
||||
pluginIds: Set<string>,
|
||||
): void {
|
||||
for (const plugin of registry?.plugins ?? []) {
|
||||
if (plugin.status === undefined || plugin.status === "loaded") {
|
||||
pluginIds.add(plugin.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resolvePluginToolRuntimePluginIds(params: {
|
||||
config: PluginLoadOptions["config"];
|
||||
workspaceDir?: string;
|
||||
env: NodeJS.ProcessEnv;
|
||||
}): string[] | undefined {
|
||||
const pluginIds = new Set<string>();
|
||||
const activeRegistry = getActivePluginRegistry();
|
||||
for (const plugin of activeRegistry?.plugins ?? []) {
|
||||
if (plugin.status === undefined || plugin.status === "loaded") {
|
||||
pluginIds.add(plugin.id);
|
||||
}
|
||||
}
|
||||
addLoadedPluginIdsFromRegistry(getActivePluginChannelRegistry(), pluginIds);
|
||||
addLoadedPluginIdsFromRegistry(getActivePluginRegistry(), pluginIds);
|
||||
const index = loadPluginRegistrySnapshot({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
@@ -219,6 +231,37 @@ function resolvePluginToolRuntimePluginIds(params: {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function registryContainsPluginIds(
|
||||
registry: ReturnType<typeof getActivePluginRegistry>,
|
||||
pluginIds?: readonly string[],
|
||||
): boolean {
|
||||
if (!registry || pluginIds === undefined) {
|
||||
return false;
|
||||
}
|
||||
const loadedPluginIds = new Set<string>();
|
||||
addLoadedPluginIdsFromRegistry(registry, loadedPluginIds);
|
||||
return pluginIds.every((pluginId) => loadedPluginIds.has(pluginId));
|
||||
}
|
||||
|
||||
function resolvePluginToolRegistry(params: {
|
||||
loadOptions: PluginLoadOptions;
|
||||
onlyPluginIds?: readonly string[];
|
||||
}) {
|
||||
const activeRegistry = getActivePluginRegistry();
|
||||
const channelRegistry = getActivePluginChannelRegistry();
|
||||
const activeRegistryIsGatewayBindable =
|
||||
getActivePluginRegistryKey() && getActivePluginRuntimeSubagentMode() === "gateway-bindable";
|
||||
const hasPinnedGatewayRegistry = Boolean(channelRegistry && channelRegistry !== activeRegistry);
|
||||
if (
|
||||
channelRegistry &&
|
||||
(activeRegistryIsGatewayBindable || hasPinnedGatewayRegistry) &&
|
||||
registryContainsPluginIds(channelRegistry, params.onlyPluginIds)
|
||||
) {
|
||||
return channelRegistry;
|
||||
}
|
||||
return resolveRuntimePluginRegistry(params.loadOptions);
|
||||
}
|
||||
|
||||
export function resolvePluginTools(params: {
|
||||
context: OpenClawPluginToolContext;
|
||||
existingToolNames?: Set<string>;
|
||||
@@ -255,7 +298,10 @@ export function resolvePluginTools(params: {
|
||||
...(onlyPluginIds !== undefined ? { onlyPluginIds } : {}),
|
||||
runtimeOptions,
|
||||
});
|
||||
const registry = resolveRuntimePluginRegistry(loadOptions);
|
||||
const registry = resolvePluginToolRegistry({
|
||||
loadOptions,
|
||||
onlyPluginIds,
|
||||
});
|
||||
if (!registry) {
|
||||
return [];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user