Skip to content

Commit c90e42a

Browse files
committed
fix: reuse plugin metadata during runtime loading
1 parent 20704ff commit c90e42a

5 files changed

Lines changed: 76 additions & 6 deletions

File tree

src/agents/tools/manifest-capability-availability.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ export function getCurrentCapabilityMetadataSnapshot(params: {
6868
}): PluginMetadataSnapshot | undefined {
6969
return getCurrentPluginMetadataSnapshot({
7070
config: params.config,
71-
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
71+
...(params.workspaceDir
72+
? { workspaceDir: params.workspaceDir }
73+
: { allowWorkspaceScopedSnapshot: true }),
7274
});
7375
}
7476

@@ -80,7 +82,9 @@ export function loadCapabilityMetadataSnapshot(params: {
8082
return (
8183
getCurrentPluginMetadataSnapshot({
8284
config: params.config,
83-
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
85+
...(params.workspaceDir
86+
? { workspaceDir: params.workspaceDir }
87+
: { allowWorkspaceScopedSnapshot: true }),
8488
}) ??
8589
loadManifestContractSnapshot({
8690
config: params.config,

src/plugins/manifest-model-id-normalization.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function resolveMetadataSnapshotForPolicies(
4646
const current = getCurrentPluginMetadataSnapshot({
4747
config: params.config,
4848
env,
49-
workspaceDir,
49+
...(workspaceDir !== undefined ? { workspaceDir } : { allowWorkspaceScopedSnapshot: true }),
5050
});
5151
if (current) {
5252
return { snapshot: current, cacheable: true };

src/plugins/runtime/load-context.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ const resolveAgentWorkspaceDirMock = vi.fn<
99
const resolveDefaultAgentIdMock = vi.fn<
1010
typeof import("../../agents/agent-scope.js").resolveDefaultAgentId
1111
>(() => "default");
12+
const manifestRegistry = { diagnostics: [], plugins: [] };
13+
const metadataSnapshot = {
14+
configFingerprint: "fingerprint",
15+
diagnostics: [],
16+
index: { plugins: [], policyHash: "policy" },
17+
manifestRegistry,
18+
plugins: [],
19+
policyHash: "policy",
20+
workspaceDir: "/resolved-workspace",
21+
};
22+
const loadPluginMetadataSnapshotMock = vi.fn(() => metadataSnapshot);
23+
const setCurrentPluginMetadataSnapshotMock = vi.fn();
1224

1325
let resolvePluginRuntimeLoadContext: typeof import("./load-context.js").resolvePluginRuntimeLoadContext;
1426
let buildPluginRuntimeLoadOptions: typeof import("./load-context.js").buildPluginRuntimeLoadOptions;
@@ -29,6 +41,14 @@ vi.mock("../../agents/agent-scope.js", () => ({
2941
resolveDefaultAgentId: resolveDefaultAgentIdMock,
3042
}));
3143

44+
vi.mock("../plugin-metadata-snapshot.js", () => ({
45+
loadPluginMetadataSnapshot: loadPluginMetadataSnapshotMock,
46+
}));
47+
48+
vi.mock("../current-plugin-metadata-snapshot.js", () => ({
49+
setCurrentPluginMetadataSnapshot: setCurrentPluginMetadataSnapshotMock,
50+
}));
51+
3252
describe("resolvePluginRuntimeLoadContext", () => {
3353
beforeEach(async () => {
3454
vi.resetModules();
@@ -38,6 +58,8 @@ describe("resolvePluginRuntimeLoadContext", () => {
3858
await import("./load-context.js"));
3959
loadConfigMock.mockReset();
4060
applyPluginAutoEnableMock.mockReset();
61+
loadPluginMetadataSnapshotMock.mockClear();
62+
setCurrentPluginMetadataSnapshotMock.mockClear();
4163
resolveAgentWorkspaceDirMock.mockClear();
4264
resolveDefaultAgentIdMock.mockClear();
4365

@@ -84,10 +106,23 @@ describe("resolvePluginRuntimeLoadContext", () => {
84106
workspaceDir: "/resolved-workspace",
85107
env,
86108
logger: context.logger,
109+
manifestRegistry,
110+
});
111+
expect(loadPluginMetadataSnapshotMock).toHaveBeenCalledWith({
112+
config: rawConfig,
113+
env,
114+
workspaceDir: "/resolved-workspace",
87115
});
88116
expect(applyPluginAutoEnableMock).toHaveBeenCalledWith({
89117
config: rawConfig,
90118
env,
119+
manifestRegistry,
120+
});
121+
expect(setCurrentPluginMetadataSnapshotMock).toHaveBeenCalledWith(metadataSnapshot, {
122+
config: rawConfig,
123+
compatibleConfigs: [resolvedConfig, rawConfig],
124+
env,
125+
workspaceDir: "/resolved-workspace",
91126
});
92127
expect(resolveDefaultAgentIdMock).toHaveBeenCalledWith(resolvedConfig);
93128
expect(resolveAgentWorkspaceDirMock).toHaveBeenCalledWith(resolvedConfig, "default");
@@ -111,6 +146,7 @@ describe("resolvePluginRuntimeLoadContext", () => {
111146
expect(applyPluginAutoEnableMock).toHaveBeenCalledWith({
112147
config: runtimeConfig,
113148
env: process.env,
149+
manifestRegistry,
114150
});
115151
});
116152

@@ -134,6 +170,7 @@ describe("resolvePluginRuntimeLoadContext", () => {
134170
workspaceDir: "/explicit-workspace",
135171
env: context.env,
136172
logger: context.logger,
173+
manifestRegistry,
137174
cache: false,
138175
activate: false,
139176
onlyPluginIds: ["demo"],

src/plugins/runtime/load-context.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import { applyPluginAutoEnable } from "../../config/plugin-auto-enable.js";
44
import type { OpenClawConfig } from "../../config/types.openclaw.js";
55
import { createSubsystemLogger } from "../../logging.js";
66
import { resolvePluginActivationSourceConfig } from "../activation-source-config.js";
7+
import { setCurrentPluginMetadataSnapshot } from "../current-plugin-metadata-snapshot.js";
78
import type { PluginLoadOptions } from "../loader.js";
89
import type { PluginManifestRegistry } from "../manifest-registry.js";
10+
import { loadPluginMetadataSnapshot } from "../plugin-metadata-snapshot.js";
911
import type { PluginLogger } from "../types.js";
1012

1113
const log = createSubsystemLogger("plugins");
@@ -18,11 +20,18 @@ export type PluginRuntimeLoadContext = {
1820
workspaceDir: string | undefined;
1921
env: NodeJS.ProcessEnv;
2022
logger: PluginLogger;
23+
manifestRegistry?: PluginManifestRegistry;
2124
};
2225

2326
export type PluginRuntimeResolvedLoadValues = Pick<
2427
PluginLoadOptions,
25-
"config" | "activationSourceConfig" | "autoEnabledReasons" | "workspaceDir" | "env" | "logger"
28+
| "config"
29+
| "activationSourceConfig"
30+
| "autoEnabledReasons"
31+
| "workspaceDir"
32+
| "env"
33+
| "logger"
34+
| "manifestRegistry"
2635
>;
2736

2837
export type PluginRuntimeLoadContextOptions = {
@@ -48,18 +57,36 @@ export function resolvePluginRuntimeLoadContext(
4857
): PluginRuntimeLoadContext {
4958
const env = options?.env ?? process.env;
5059
const rawConfig = options?.config ?? getRuntimeConfig();
60+
const rawWorkspaceDir =
61+
options?.workspaceDir ?? resolveAgentWorkspaceDir(rawConfig, resolveDefaultAgentId(rawConfig));
62+
const metadataSnapshot = options?.manifestRegistry
63+
? undefined
64+
: loadPluginMetadataSnapshot({
65+
config: rawConfig,
66+
env,
67+
workspaceDir: rawWorkspaceDir,
68+
});
69+
const manifestRegistry = options?.manifestRegistry ?? metadataSnapshot?.manifestRegistry;
5170
const activationSourceConfig = resolvePluginActivationSourceConfig({
5271
config: rawConfig,
5372
activationSourceConfig: options?.activationSourceConfig,
5473
});
5574
const autoEnabled = applyPluginAutoEnable({
5675
config: rawConfig,
5776
env,
58-
manifestRegistry: options?.manifestRegistry,
77+
manifestRegistry,
5978
});
6079
const config = autoEnabled.config;
6180
const workspaceDir =
6281
options?.workspaceDir ?? resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
82+
if (metadataSnapshot) {
83+
setCurrentPluginMetadataSnapshot(metadataSnapshot, {
84+
config: rawConfig,
85+
compatibleConfigs: [config, activationSourceConfig],
86+
env,
87+
workspaceDir,
88+
});
89+
}
6390
return {
6491
rawConfig,
6592
config,
@@ -68,6 +95,7 @@ export function resolvePluginRuntimeLoadContext(
6895
workspaceDir,
6996
env,
7097
logger: options?.logger ?? createPluginRuntimeLoaderLogger(),
98+
...(manifestRegistry ? { manifestRegistry } : {}),
7199
};
72100
}
73101

@@ -89,6 +117,7 @@ export function buildPluginRuntimeLoadOptionsFromValues(
89117
workspaceDir: values.workspaceDir,
90118
env: values.env,
91119
logger: values.logger,
120+
...(values.manifestRegistry ? { manifestRegistry: values.manifestRegistry } : {}),
92121
...overrides,
93122
};
94123
}

src/plugins/setup-registry.runtime.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function resolveMetadataSnapshotForSetupCliBackends(
6060
const current = getCurrentPluginMetadataSnapshot({
6161
config: params.config,
6262
env,
63-
workspaceDir,
63+
...(workspaceDir !== undefined ? { workspaceDir } : { allowWorkspaceScopedSnapshot: true }),
6464
});
6565
if (current) {
6666
return { snapshot: current, cacheable: true };

0 commit comments

Comments
 (0)