Extension host: establish host-owned plugin runtime foundations

This commit is contained in:
Gustavo Madeira Santana
2026-03-16 00:39:23 +00:00
parent 963237a18f
commit 9ab7fdfd03
145 changed files with 17632 additions and 2727 deletions

View File

@@ -0,0 +1,67 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createEmptyPluginRegistry } from "../plugins/registry.js";
const loadOpenClawPluginsMock = vi.hoisted(() => vi.fn());
const getActivePluginRegistryMock = vi.hoisted(() => vi.fn());
vi.mock("../agents/agent-scope.js", () => ({
resolveAgentWorkspaceDir: () => "/tmp/workspace",
resolveDefaultAgentId: () => "default-agent",
}));
vi.mock("../config/config.js", () => ({
loadConfig: () => ({}),
}));
vi.mock("../logging.js", () => ({
createSubsystemLogger: () => ({
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
debug: vi.fn(),
}),
}));
vi.mock("../plugins/loader.js", () => ({
loadOpenClawPlugins: loadOpenClawPluginsMock,
}));
vi.mock("../plugins/runtime.js", () => ({
getActivePluginRegistry: getActivePluginRegistryMock,
}));
describe("ensurePluginRegistryLoaded", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.resetModules();
});
it("skips plugin loading when a provider-only registry is already active", async () => {
const registry = createEmptyPluginRegistry();
registry.providers.push({
pluginId: "provider-demo",
source: "test",
provider: {
id: "provider-demo",
label: "Provider Demo",
auth: [],
},
});
getActivePluginRegistryMock.mockReturnValue(registry);
const { ensurePluginRegistryLoaded } = await import("./plugin-registry.js");
ensurePluginRegistryLoaded();
expect(loadOpenClawPluginsMock).not.toHaveBeenCalled();
});
it("loads plugins once when the active registry is empty", async () => {
getActivePluginRegistryMock.mockReturnValue(createEmptyPluginRegistry());
const { ensurePluginRegistryLoaded } = await import("./plugin-registry.js");
ensurePluginRegistryLoaded();
ensurePluginRegistryLoaded();
expect(loadOpenClawPluginsMock).toHaveBeenCalledTimes(1);
});
});

View File

@@ -1,5 +1,6 @@
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
import { loadConfig } from "../config/config.js";
import { hasExtensionHostRuntimeEntries } from "../extension-host/contributions/runtime-registry.js";
import { createSubsystemLogger } from "../logging.js";
import { loadOpenClawPlugins } from "../plugins/loader.js";
import { getActivePluginRegistry } from "../plugins/runtime.js";
@@ -14,11 +15,8 @@ export function ensurePluginRegistryLoaded(): void {
}
const active = getActivePluginRegistry();
// Tests (and callers) can pre-seed a registry (e.g. `test/setup.ts`); avoid
// doing an expensive load when we already have plugins/channels/tools.
if (
active &&
(active.plugins.length > 0 || active.channels.length > 0 || active.tools.length > 0)
) {
// doing an expensive load when we already have runtime entries.
if (hasExtensionHostRuntimeEntries(active)) {
pluginRegistryLoaded = true;
return;
}