Skip to content

Commit 67ee631

Browse files
committed
fix(plugins): inherit active registry workspaceDir before loading metadata snapshot
isPluginProvidersLoadInFlight and resolvePluginProviders now resolve env and workspaceDir once at the entry point (falling back to getActivePluginRegistryWorkspaceDir) and pass them into both loadPluginMetadataSnapshot and resolvePluginProviderLoadBase. Pre-fix the snapshot used params.workspaceDir raw while the load base inherited the active workspace, so workspace-scoped provider plugins could be absent from the snapshot manifest registry even though owner resolution expected them. Regression test asserts the snapshot mock receives the active workspaceDir when the caller omits it.
1 parent 75ab995 commit 67ee631

2 files changed

Lines changed: 43 additions & 10 deletions

File tree

src/plugins/providers.runtime.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,16 @@ function resolveRuntimeProviderPluginLoadState(
305305
export function isPluginProvidersLoadInFlight(
306306
params: Parameters<typeof resolvePluginProviders>[0],
307307
): boolean {
308+
const env = params.env ?? process.env;
309+
const workspaceDir = params.workspaceDir ?? getActivePluginRegistryWorkspaceDir();
308310
const snapshot =
309311
params.pluginMetadataSnapshot ??
310312
loadPluginMetadataSnapshot({
311313
config: params.config ?? {},
312-
workspaceDir: params.workspaceDir,
313-
env: params.env ?? process.env,
314+
workspaceDir,
315+
env,
314316
});
315-
const base = resolvePluginProviderLoadBase(params, snapshot);
317+
const base = resolvePluginProviderLoadBase({ ...params, workspaceDir, env }, snapshot);
316318
const loadState =
317319
params.mode === "setup"
318320
? resolveSetupProviderPluginLoadState(params, base, snapshot)
@@ -341,14 +343,16 @@ export function resolvePluginProviders(params: {
341343
includeUntrustedWorkspacePlugins?: boolean;
342344
pluginMetadataSnapshot?: PluginMetadataRegistryView;
343345
}): ProviderPlugin[] {
346+
const env = params.env ?? process.env;
347+
const workspaceDir = params.workspaceDir ?? getActivePluginRegistryWorkspaceDir();
344348
const snapshot =
345349
params.pluginMetadataSnapshot ??
346350
loadPluginMetadataSnapshot({
347351
config: params.config ?? {},
348-
workspaceDir: params.workspaceDir,
349-
env: params.env ?? process.env,
352+
workspaceDir,
353+
env,
350354
});
351-
const base = resolvePluginProviderLoadBase(params, snapshot);
355+
const base = resolvePluginProviderLoadBase({ ...params, workspaceDir, env }, snapshot);
352356
if (params.mode === "setup") {
353357
const loadState = resolveSetupProviderPluginLoadState(params, base, snapshot);
354358
if (!loadState) {

src/plugins/providers.test.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ type LoadOpenClawPlugins = typeof import("./loader.js").loadOpenClawPlugins;
1616
type IsPluginRegistryLoadInFlight = typeof import("./loader.js").isPluginRegistryLoadInFlight;
1717
type LoadPluginManifestRegistry =
1818
typeof import("./manifest-registry.js").loadPluginManifestRegistry;
19+
type LoadPluginMetadataSnapshot =
20+
typeof import("./plugin-metadata-snapshot.js").loadPluginMetadataSnapshot;
1921
type ApplyPluginAutoEnable = typeof import("../config/plugin-auto-enable.js").applyPluginAutoEnable;
2022
type SetActivePluginRegistry = typeof import("./runtime.js").setActivePluginRegistry;
2123

@@ -25,6 +27,7 @@ const resolveCompatibleRuntimePluginRegistryMock = vi.fn<ResolveCompatibleRuntim
2527
const loadOpenClawPluginsMock = vi.fn<LoadOpenClawPlugins>();
2628
const isPluginRegistryLoadInFlightMock = vi.fn<IsPluginRegistryLoadInFlight>((_) => false);
2729
const loadPluginManifestRegistryMock = vi.fn<LoadPluginManifestRegistry>();
30+
const loadPluginMetadataSnapshotMock = vi.fn<LoadPluginMetadataSnapshot>();
2831
const applyPluginAutoEnableMock = vi.fn<ApplyPluginAutoEnable>();
2932

3033
let resolveOwningPluginIdsForProvider: typeof import("./providers.js").resolveOwningPluginIdsForProvider;
@@ -483,10 +486,13 @@ describe("resolvePluginProviders", () => {
483486
loadPluginManifestRegistryMock(...args),
484487
}));
485488
vi.doMock("./plugin-metadata-snapshot.js", () => ({
486-
loadPluginMetadataSnapshot: () => ({
487-
manifestRegistry: loadPluginManifestRegistryMock(),
488-
index: createProviderRegistrySnapshotFixture(),
489-
}),
489+
loadPluginMetadataSnapshot: (params: Parameters<LoadPluginMetadataSnapshot>[0]) => {
490+
loadPluginMetadataSnapshotMock(params);
491+
return {
492+
manifestRegistry: loadPluginManifestRegistryMock(),
493+
index: createProviderRegistrySnapshotFixture(),
494+
};
495+
},
490496
}));
491497
vi.doMock("./plugin-registry.js", async () => {
492498
const actual =
@@ -566,6 +572,7 @@ describe("resolvePluginProviders", () => {
566572
loadOpenClawPluginsMock.mockReset();
567573
isPluginRegistryLoadInFlightMock.mockReset();
568574
isPluginRegistryLoadInFlightMock.mockReturnValue(false);
575+
loadPluginMetadataSnapshotMock.mockReset();
569576
const provider: ProviderPlugin = {
570577
id: "demo-provider",
571578
label: "Demo Provider",
@@ -1172,6 +1179,28 @@ describe("resolvePluginProviders", () => {
11721179
activate: false,
11731180
});
11741181
});
1182+
1183+
it("inherits workspaceDir from the active registry when loading the metadata snapshot", () => {
1184+
setActivePluginRegistry(
1185+
createEmptyPluginRegistry(),
1186+
undefined,
1187+
"default",
1188+
"/workspace/runtime",
1189+
);
1190+
1191+
resolvePluginProviders({
1192+
config: {
1193+
plugins: {
1194+
allow: ["google"],
1195+
},
1196+
},
1197+
onlyPluginIds: ["google"],
1198+
});
1199+
1200+
expect(loadPluginMetadataSnapshotMock).toHaveBeenCalled();
1201+
const snapshotCall = loadPluginMetadataSnapshotMock.mock.calls.at(-1)?.[0];
1202+
expect(snapshotCall?.workspaceDir).toBe("/workspace/runtime");
1203+
});
11751204
it("activates owning plugins for explicit provider refs", () => {
11761205
setOwningProviderManifestPlugins();
11771206

0 commit comments

Comments
 (0)