Skip to content

Commit 58f4099

Browse files
committed
refactor: share plugin runtime load context
1 parent 9568cce commit 58f4099

14 files changed

Lines changed: 507 additions & 214 deletions

src/cli/plugin-registry.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ describe("ensurePluginRegistryLoaded", () => {
142142
expect(mocks.loadOpenClawPlugins).toHaveBeenCalledTimes(2);
143143
expect(mocks.loadOpenClawPlugins).toHaveBeenNthCalledWith(
144144
1,
145-
expect.objectContaining({ onlyPluginIds: [], throwOnLoadError: true }),
145+
expect.objectContaining({ throwOnLoadError: true }),
146146
);
147147
expect(mocks.loadOpenClawPlugins).toHaveBeenNthCalledWith(
148148
2,

src/plugins/cli-registry-loader.ts

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
21
import { collectUniqueCommandDescriptors } from "../cli/program/command-descriptor-utils.js";
32
import type { OpenClawConfig } from "../config/config.js";
4-
import { loadConfig } from "../config/config.js";
5-
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
6-
import { createSubsystemLogger } from "../logging/subsystem.js";
73
import type { PluginLoadOptions } from "./loader.js";
84
import { loadOpenClawPluginCliRegistry, loadOpenClawPlugins } from "./loader.js";
95
import type { PluginRegistry } from "./registry.js";
6+
import {
7+
buildPluginRuntimeLoadOptions,
8+
createPluginRuntimeLoaderLogger,
9+
resolvePluginRuntimeLoadContext,
10+
type PluginRuntimeLoadContext,
11+
} from "./runtime/load-context.js";
1012
import type {
1113
OpenClawPluginCliCommandDescriptor,
1214
OpenClawPluginCliContext,
1315
PluginLogger,
1416
} from "./types.js";
1517

16-
const log = createSubsystemLogger("plugins");
17-
1818
export type PluginCliLoaderOptions = Pick<PluginLoadOptions, "pluginSdkResolution">;
1919

2020
export type PluginCliPublicLoadParams = {
@@ -24,13 +24,7 @@ export type PluginCliPublicLoadParams = {
2424
logger?: PluginLogger;
2525
};
2626

27-
export type PluginCliLoadContext = {
28-
rawConfig: OpenClawConfig;
29-
config: OpenClawConfig;
30-
autoEnabledReasons: Readonly<Record<string, string[]>>;
31-
workspaceDir: string | undefined;
32-
logger: PluginLogger;
33-
};
27+
export type PluginCliLoadContext = PluginRuntimeLoadContext;
3428

3529
export type PluginCliRegistryLoadResult = PluginCliLoadContext & {
3630
registry: PluginRegistry;
@@ -44,12 +38,7 @@ export type PluginCliCommandGroupEntry = {
4438
};
4539

4640
export function createPluginCliLogger(): PluginLogger {
47-
return {
48-
info: (message: string) => log.info(message),
49-
warn: (message: string) => log.warn(message),
50-
error: (message: string) => log.error(message),
51-
debug: (message: string) => log.debug(message),
52-
};
41+
return createPluginRuntimeLoaderLogger();
5342
}
5443

5544
function resolvePluginCliLogger(logger?: PluginLogger): PluginLogger {
@@ -80,59 +69,42 @@ function mergeCliRegistrars(params: {
8069

8170
function buildPluginCliLoaderParams(
8271
context: PluginCliLoadContext,
83-
env?: NodeJS.ProcessEnv,
8472
loaderOptions?: PluginCliLoaderOptions,
8573
) {
86-
return {
87-
config: context.config,
88-
activationSourceConfig: context.rawConfig,
89-
autoEnabledReasons: context.autoEnabledReasons,
90-
workspaceDir: context.workspaceDir,
91-
env,
92-
logger: context.logger,
93-
...loaderOptions,
94-
};
74+
return buildPluginRuntimeLoadOptions(context, loaderOptions);
9575
}
9676

9777
export function resolvePluginCliLoadContext(params: {
9878
cfg?: OpenClawConfig;
9979
env?: NodeJS.ProcessEnv;
10080
logger: PluginLogger;
10181
}): PluginCliLoadContext {
102-
const rawConfig = params.cfg ?? loadConfig();
103-
const autoEnabled = applyPluginAutoEnable({ config: rawConfig, env: params.env ?? process.env });
104-
const config = autoEnabled.config;
105-
const workspaceDir = resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config));
106-
return {
107-
rawConfig,
108-
config,
109-
autoEnabledReasons: autoEnabled.autoEnabledReasons,
110-
workspaceDir,
82+
return resolvePluginRuntimeLoadContext({
83+
config: params.cfg,
84+
env: params.env,
11185
logger: params.logger,
112-
};
86+
});
11387
}
11488

11589
export async function loadPluginCliMetadataRegistryWithContext(
11690
context: PluginCliLoadContext,
117-
env?: NodeJS.ProcessEnv,
11891
loaderOptions?: PluginCliLoaderOptions,
11992
): Promise<PluginCliRegistryLoadResult> {
12093
return {
12194
...context,
12295
registry: await loadOpenClawPluginCliRegistry(
123-
buildPluginCliLoaderParams(context, env, loaderOptions),
96+
buildPluginCliLoaderParams(context, loaderOptions),
12497
),
12598
};
12699
}
127100

128101
export async function loadPluginCliCommandRegistryWithContext(params: {
129102
context: PluginCliLoadContext;
130-
env?: NodeJS.ProcessEnv;
131103
loaderOptions?: PluginCliLoaderOptions;
132104
onMetadataFallbackError: (error: unknown) => void;
133105
}): Promise<PluginCliRegistryLoadResult> {
134106
const runtimeRegistry = loadOpenClawPlugins(
135-
buildPluginCliLoaderParams(params.context, params.env, params.loaderOptions),
107+
buildPluginCliLoaderParams(params.context, params.loaderOptions),
136108
);
137109

138110
if (!hasIgnoredAsyncPluginRegistration(runtimeRegistry)) {
@@ -144,7 +116,7 @@ export async function loadPluginCliCommandRegistryWithContext(params: {
144116

145117
try {
146118
const metadataRegistry = await loadOpenClawPluginCliRegistry(
147-
buildPluginCliLoaderParams(params.context, params.env, params.loaderOptions),
119+
buildPluginCliLoaderParams(params.context, params.loaderOptions),
148120
);
149121
return {
150122
...params.context,
@@ -202,7 +174,6 @@ export async function loadPluginCliDescriptors(
202174
});
203175
const { registry } = await loadPluginCliMetadataRegistryWithContext(
204176
context,
205-
params.env,
206177
params.loaderOptions,
207178
);
208179
return collectUniqueCommandDescriptors(
@@ -228,7 +199,6 @@ export async function loadPluginCliRegistrationEntries(params: {
228199
});
229200
const { config, workspaceDir, logger, registry } = await loadPluginCliCommandRegistryWithContext({
230201
context,
231-
env: params.env,
232202
loaderOptions: params.loaderOptions,
233203
onMetadataFallbackError: params.onMetadataFallbackError,
234204
});

src/plugins/memory-runtime.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
33
const resolveRuntimePluginRegistryMock = vi.fn();
44
const applyPluginAutoEnableMock = vi.fn();
55
const getMemoryRuntimeMock = vi.fn();
6+
const resolveAgentWorkspaceDirMock = vi.fn();
7+
const resolveDefaultAgentIdMock = vi.fn(() => "default");
68

79
vi.mock("../config/plugin-auto-enable.js", () => ({
810
applyPluginAutoEnable: (...args: unknown[]) => applyPluginAutoEnableMock(...args),
911
}));
1012

13+
vi.mock("../agents/agent-scope.js", () => ({
14+
resolveAgentWorkspaceDir: (...args: unknown[]) => resolveAgentWorkspaceDirMock(...args),
15+
resolveDefaultAgentId: (...args: unknown[]) => resolveDefaultAgentIdMock(...args),
16+
}));
17+
1118
vi.mock("./loader.js", () => ({
1219
resolveRuntimePluginRegistry: (...args: unknown[]) => resolveRuntimePluginRegistryMock(...args),
1320
}));
@@ -116,11 +123,14 @@ describe("memory runtime auto-enable loading", () => {
116123
resolveRuntimePluginRegistryMock.mockReset();
117124
applyPluginAutoEnableMock.mockReset();
118125
getMemoryRuntimeMock.mockReset();
126+
resolveAgentWorkspaceDirMock.mockReset();
127+
resolveDefaultAgentIdMock.mockClear();
119128
applyPluginAutoEnableMock.mockImplementation((params: { config: unknown }) => ({
120129
config: params.config,
121130
changes: [],
122131
autoEnabledReasons: {},
123132
}));
133+
resolveAgentWorkspaceDirMock.mockReturnValue(undefined);
124134
});
125135

126136
it.each([

src/plugins/memory-runtime.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import type { OpenClawConfig } from "../config/config.js";
2-
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
32
import { resolveRuntimePluginRegistry } from "./loader.js";
43
import { getMemoryRuntime } from "./memory-state.js";
4+
import {
5+
buildPluginRuntimeLoadOptions,
6+
resolvePluginRuntimeLoadContext,
7+
} from "./runtime/load-context.js";
58

69
function ensureMemoryRuntime(cfg?: OpenClawConfig) {
710
const current = getMemoryRuntime();
811
if (current || !cfg) {
912
return current;
1013
}
11-
const autoEnabled = applyPluginAutoEnable({ config: cfg, env: process.env });
12-
resolveRuntimePluginRegistry({
13-
config: autoEnabled.config,
14-
activationSourceConfig: cfg,
15-
autoEnabledReasons: autoEnabled.autoEnabledReasons,
16-
});
14+
resolveRuntimePluginRegistry(
15+
buildPluginRuntimeLoadOptions(resolvePluginRuntimeLoadContext({ config: cfg })),
16+
);
1717
return getMemoryRuntime();
1818
}
1919

src/plugins/providers.runtime.ts

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { createSubsystemLogger } from "../logging/subsystem.js";
21
import { withActivatedPluginIds } from "./activation-context.js";
32
import { resolveBundledPluginCompatibleActivationInputs } from "./activation-context.js";
43
import {
54
loadOpenClawPlugins,
65
resolveRuntimePluginRegistry,
76
type PluginLoadOptions,
87
} from "./loader.js";
9-
import { createPluginLoaderLogger } from "./logger.js";
108
import {
119
resolveDiscoveredProviderPluginIds,
1210
resolveEnabledProviderPluginIds,
@@ -16,9 +14,12 @@ import {
1614
withBundledProviderVitestCompat,
1715
} from "./providers.js";
1816
import { getActivePluginRegistryWorkspaceDir } from "./runtime.js";
17+
import {
18+
buildPluginRuntimeLoadOptionsFromValues,
19+
createPluginRuntimeLoaderLogger,
20+
} from "./runtime/load-context.js";
1921
import type { ProviderPlugin } from "./types.js";
2022

21-
const log = createSubsystemLogger("plugins");
2223
export function resolvePluginProviders(params: {
2324
config?: PluginLoadOptions["config"];
2425
workspaceDir?: string;
@@ -87,21 +88,27 @@ export function resolvePluginProviders(params: {
8788
if (providerPluginIds.length === 0) {
8889
return [];
8990
}
90-
const registry = loadOpenClawPlugins({
91-
config: withActivatedPluginIds({
92-
config: runtimeConfig,
93-
pluginIds: providerPluginIds,
94-
}),
95-
activationSourceConfig: runtimeConfig,
96-
autoEnabledReasons: {},
97-
workspaceDir,
98-
env,
99-
onlyPluginIds: providerPluginIds,
100-
pluginSdkResolution: params.pluginSdkResolution,
101-
cache: params.cache ?? false,
102-
activate: params.activate ?? false,
103-
logger: createPluginLoaderLogger(log),
104-
});
91+
const registry = loadOpenClawPlugins(
92+
buildPluginRuntimeLoadOptionsFromValues(
93+
{
94+
config: withActivatedPluginIds({
95+
config: runtimeConfig,
96+
pluginIds: providerPluginIds,
97+
}),
98+
activationSourceConfig: runtimeConfig,
99+
autoEnabledReasons: {},
100+
workspaceDir,
101+
env,
102+
logger: createPluginRuntimeLoaderLogger(),
103+
},
104+
{
105+
onlyPluginIds: providerPluginIds,
106+
pluginSdkResolution: params.pluginSdkResolution,
107+
cache: params.cache ?? false,
108+
activate: params.activate ?? false,
109+
},
110+
),
111+
);
105112
return registry.providers.map((entry) => ({
106113
...entry.provider,
107114
pluginId: entry.pluginId,
@@ -133,18 +140,24 @@ export function resolvePluginProviders(params: {
133140
env,
134141
onlyPluginIds: requestedPluginIds,
135142
});
136-
const registry = resolveRuntimePluginRegistry({
137-
config,
138-
activationSourceConfig: activation.activationSourceConfig,
139-
autoEnabledReasons: activation.autoEnabledReasons,
140-
workspaceDir,
141-
env,
142-
onlyPluginIds: providerPluginIds,
143-
pluginSdkResolution: params.pluginSdkResolution,
144-
cache: params.cache ?? false,
145-
activate: params.activate ?? false,
146-
logger: createPluginLoaderLogger(log),
147-
});
143+
const registry = resolveRuntimePluginRegistry(
144+
buildPluginRuntimeLoadOptionsFromValues(
145+
{
146+
config,
147+
activationSourceConfig: activation.activationSourceConfig,
148+
autoEnabledReasons: activation.autoEnabledReasons,
149+
workspaceDir,
150+
env,
151+
logger: createPluginRuntimeLoaderLogger(),
152+
},
153+
{
154+
onlyPluginIds: providerPluginIds,
155+
pluginSdkResolution: params.pluginSdkResolution,
156+
cache: params.cache ?? false,
157+
activate: params.activate ?? false,
158+
},
159+
),
160+
);
148161
if (!registry) {
149162
return [];
150163
}

src/plugins/providers.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ function setOwningProviderManifestPlugins() {
6363
createManifestProviderPlugin({
6464
id: "openai",
6565
providerIds: ["openai", "openai-codex"],
66+
cliBackends: ["codex-cli"],
6667
modelSupport: {
6768
modelPrefixes: ["gpt-", "o1", "o3", "o4"],
6869
},
@@ -87,6 +88,7 @@ function setOwningProviderManifestPluginsWithWorkspace() {
8788
createManifestProviderPlugin({
8889
id: "openai",
8990
providerIds: ["openai", "openai-codex"],
91+
cliBackends: ["codex-cli"],
9092
modelSupport: {
9193
modelPrefixes: ["gpt-", "o1", "o3", "o4"],
9294
},
@@ -255,6 +257,10 @@ function expectProviderRuntimeRegistryLoad(params?: { config?: unknown; env?: No
255257
describe("resolvePluginProviders", () => {
256258
beforeAll(async () => {
257259
vi.resetModules();
260+
loadPluginManifestRegistryMock.mockReturnValue({
261+
plugins: [],
262+
diagnostics: [],
263+
});
258264
vi.doMock("./loader.js", () => ({
259265
loadOpenClawPlugins: (...args: Parameters<LoadOpenClawPlugins>) =>
260266
loadOpenClawPluginsMock(...args),

0 commit comments

Comments
 (0)