mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 08:01:38 +00:00
perf(agents): reuse gateway plugin preparation (#105646)
* perf(agents): reuse gateway plugin preparation * chore: keep release notes out of PR
This commit is contained in:
committed by
GitHub
parent
e3c338f664
commit
1b281de6df
@@ -1,2 +1,2 @@
|
||||
8f362012108b8b2db08e836883fac095f88e70a4c1ef66a713980e1361ec48b6 plugin-sdk-api-baseline.json
|
||||
ddbb02207930b419658209039696e8008d76c8f839d7ecde95e1c8ba91c19c7a plugin-sdk-api-baseline.jsonl
|
||||
0eb8e2e8ebfe48bbf269d6e0100e38b8c85c387651be7a3bc3d67f549a13768f plugin-sdk-api-baseline.json
|
||||
f6e5dc7474a7cb54bdcde544f135656ac8e501679e18129607f4f42fec7cd791 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -120,6 +120,23 @@ describe("bundle LSP runtime", () => {
|
||||
loadEmbeddedAgentLspConfigMock.mockReset();
|
||||
});
|
||||
|
||||
it("reuses the prepared plugin manifest registry for bundle discovery", async () => {
|
||||
loadEmbeddedAgentLspConfigMock.mockReturnValue({ lspServers: {}, diagnostics: [] });
|
||||
const manifestRegistry = { plugins: [] };
|
||||
const { createBundleLspToolRuntime } = await import("./agent-bundle-lsp-runtime.js");
|
||||
|
||||
await createBundleLspToolRuntime({
|
||||
workspaceDir: "/tmp/workspace",
|
||||
manifestRegistry,
|
||||
});
|
||||
|
||||
expect(loadEmbeddedAgentLspConfigMock).toHaveBeenCalledWith({
|
||||
workspaceDir: "/tmp/workspace",
|
||||
cfg: undefined,
|
||||
manifestRegistry,
|
||||
});
|
||||
});
|
||||
|
||||
it("starts LSP servers in a disposable process group", async () => {
|
||||
configureSingleLspServer();
|
||||
const child = new MockChildProcess();
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
materializeWindowsSpawnProgram,
|
||||
resolveWindowsSpawnProgram,
|
||||
} from "../plugin-sdk/windows-spawn.js";
|
||||
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
|
||||
import { setPluginToolMeta } from "../plugins/tools.js";
|
||||
import { killProcessTree } from "../process/kill-tree.js";
|
||||
import { loadEmbeddedAgentLspConfig } from "./embedded-agent-lsp.js";
|
||||
@@ -499,10 +500,12 @@ export async function createBundleLspToolRuntime(params: {
|
||||
workspaceDir: string;
|
||||
cfg?: OpenClawConfig;
|
||||
reservedToolNames?: Iterable<string>;
|
||||
manifestRegistry?: Pick<PluginManifestRegistry, "plugins">;
|
||||
}): Promise<BundleLspToolRuntime> {
|
||||
const loaded = loadEmbeddedAgentLspConfig({
|
||||
workspaceDir: params.workspaceDir,
|
||||
cfg: params.cfg,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
});
|
||||
for (const diagnostic of loaded.diagnostics) {
|
||||
logWarn(`bundle-lsp: ${diagnostic.pluginId}: ${diagnostic.message}`);
|
||||
|
||||
@@ -1700,8 +1700,10 @@ process.on("SIGINT", shutdown);`,
|
||||
|
||||
it("reuses repeated materialization and recreates after explicit disposal", async () => {
|
||||
const created: SessionMcpRuntime[] = [];
|
||||
const createdManifestRegistries: unknown[] = [];
|
||||
const disposed: string[] = [];
|
||||
const createRuntime: RuntimeFactory = (params) => {
|
||||
createdManifestRegistries.push(params.manifestRegistry);
|
||||
const runtime = makeRuntime([{ toolName: "bundle_probe", description: "Bundle MCP probe" }]);
|
||||
created.push(runtime);
|
||||
return {
|
||||
@@ -1716,16 +1718,19 @@ process.on("SIGINT", shutdown);`,
|
||||
};
|
||||
};
|
||||
const manager = testing.createSessionMcpRuntimeManager({ createRuntime });
|
||||
const manifestRegistry = { plugins: [] };
|
||||
|
||||
const runtimeA = await manager.getOrCreate({
|
||||
sessionId: "session-a",
|
||||
sessionKey: "agent:test:session-a",
|
||||
workspaceDir: "/workspace",
|
||||
manifestRegistry,
|
||||
});
|
||||
const runtimeB = await manager.getOrCreate({
|
||||
sessionId: "session-a",
|
||||
sessionKey: "agent:test:session-a",
|
||||
workspaceDir: "/workspace",
|
||||
manifestRegistry,
|
||||
});
|
||||
|
||||
const materializedA = await materializeBundleMcpToolsForRun({ runtime: runtimeA });
|
||||
@@ -1738,6 +1743,7 @@ process.on("SIGINT", shutdown);`,
|
||||
expect(materializedA.tools.map((tool) => tool.name)).toEqual(["bundleProbe__bundle_probe"]);
|
||||
expect(materializedB.tools.map((tool) => tool.name)).toEqual(["bundleProbe__bundle_probe"]);
|
||||
expect(created).toHaveLength(1);
|
||||
expect(createdManifestRegistries).toEqual([manifestRegistry]);
|
||||
expect(manager.listSessionIds()).toEqual(["session-a"]);
|
||||
|
||||
await manager.disposeSession("session-a");
|
||||
@@ -1747,11 +1753,13 @@ process.on("SIGINT", shutdown);`,
|
||||
sessionId: "session-a",
|
||||
sessionKey: "agent:test:session-a",
|
||||
workspaceDir: "/workspace",
|
||||
manifestRegistry,
|
||||
});
|
||||
await materializeBundleMcpToolsForRun({ runtime: runtimeC });
|
||||
|
||||
expect(runtimeC).not.toBe(runtimeA);
|
||||
expect(created).toHaveLength(2);
|
||||
expect(createdManifestRegistries).toEqual([manifestRegistry, manifestRegistry]);
|
||||
|
||||
const materializedC = await materializeBundleMcpToolsForRun({
|
||||
runtime: runtimeC,
|
||||
|
||||
@@ -1077,6 +1077,7 @@ function createSessionMcpRuntimeManager(
|
||||
workspaceDir: params.workspaceDir,
|
||||
cfg: params.cfg,
|
||||
logDiagnostics: false,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
});
|
||||
const existing = runtimesBySessionId.get(params.sessionId);
|
||||
if (existing) {
|
||||
@@ -1120,6 +1121,7 @@ function createSessionMcpRuntimeManager(
|
||||
workspaceDir: params.workspaceDir,
|
||||
agentDir: params.agentDir,
|
||||
cfg: params.cfg,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
configFingerprint: nextFingerprint,
|
||||
}),
|
||||
).then((runtime) => {
|
||||
@@ -1212,6 +1214,7 @@ export async function getOrCreateSessionMcpRuntime(params: {
|
||||
workspaceDir: string;
|
||||
agentDir?: string;
|
||||
cfg?: OpenClawConfig;
|
||||
manifestRegistry?: Pick<PluginManifestRegistry, "plugins">;
|
||||
}): Promise<SessionMcpRuntime> {
|
||||
return await getSessionMcpRuntimeManager().getOrCreate(params);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
} from "@modelcontextprotocol/sdk/types.js";
|
||||
import type { TSchema } from "typebox";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
|
||||
import type { AnyAgentTool } from "./tools/common.js";
|
||||
|
||||
/** Materialized MCP tools plus diagnostics and cleanup handle for one run. */
|
||||
@@ -113,6 +114,7 @@ export type SessionMcpRuntimeManager = {
|
||||
workspaceDir: string;
|
||||
agentDir?: string;
|
||||
cfg?: OpenClawConfig;
|
||||
manifestRegistry?: Pick<PluginManifestRegistry, "plugins">;
|
||||
}) => Promise<SessionMcpRuntime>;
|
||||
bindSessionKey: (sessionKey: string, sessionId: string) => void;
|
||||
resolveSessionId: (sessionKey: string) => string | undefined;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import type { BundleLspServerConfig } from "../plugins/bundle-lsp.js";
|
||||
import { loadEnabledBundleLspConfig } from "../plugins/bundle-lsp.js";
|
||||
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
|
||||
|
||||
type EmbeddedAgentLspConfig = {
|
||||
lspServers: Record<string, BundleLspServerConfig>;
|
||||
@@ -14,10 +15,12 @@ type EmbeddedAgentLspConfig = {
|
||||
export function loadEmbeddedAgentLspConfig(params: {
|
||||
workspaceDir: string;
|
||||
cfg?: OpenClawConfig;
|
||||
manifestRegistry?: Pick<PluginManifestRegistry, "plugins">;
|
||||
}): EmbeddedAgentLspConfig {
|
||||
const bundleLsp = loadEnabledBundleLspConfig({
|
||||
workspaceDir: params.workspaceDir,
|
||||
cfg: params.cfg,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
});
|
||||
// User-configured LSP servers could override bundle defaults here in the future.
|
||||
return {
|
||||
|
||||
@@ -1919,6 +1919,13 @@ export async function runEmbeddedAttempt(
|
||||
disableTools: params.disableTools || isRawModelRun,
|
||||
toolsAllow: params.toolsAllow,
|
||||
});
|
||||
const bundleMetadataSnapshot = getCurrentAttemptPluginMetadataSnapshot();
|
||||
// Scoped registries are partial views. Bundle discovery can skip its own scan only when
|
||||
// the attempt snapshot covers every plugin; otherwise MCP/LSP bundles can disappear.
|
||||
const bundleManifestRegistry =
|
||||
bundleMetadataSnapshot?.pluginIds === undefined
|
||||
? bundleMetadataSnapshot?.manifestRegistry
|
||||
: undefined;
|
||||
const bundleMcpSessionRuntime = bundleMcpEnabled
|
||||
? await getOrCreateSessionMcpRuntime({
|
||||
sessionId: params.sessionId,
|
||||
@@ -1926,6 +1933,7 @@ export async function runEmbeddedAttempt(
|
||||
workspaceDir: effectiveWorkspace,
|
||||
agentDir,
|
||||
cfg: params.config,
|
||||
manifestRegistry: bundleManifestRegistry,
|
||||
})
|
||||
: undefined;
|
||||
bundleMcpRuntime = bundleMcpSessionRuntime
|
||||
@@ -1948,6 +1956,7 @@ export async function runEmbeddedAttempt(
|
||||
? await createBundleLspToolRuntime({
|
||||
workspaceDir: effectiveWorkspace,
|
||||
cfg: params.config,
|
||||
manifestRegistry: bundleManifestRegistry,
|
||||
reservedToolNames: [
|
||||
...tools.map((tool) => tool.name),
|
||||
...(clientTools?.map((tool) => tool.function.name) ?? []),
|
||||
|
||||
@@ -69,6 +69,16 @@ function stableFingerprintValue(value: unknown): string {
|
||||
.join(",")}}`;
|
||||
}
|
||||
|
||||
/** Fingerprints mutable config inputs used by plugin auto-enable detection. */
|
||||
export function fingerprintPluginAutoEnableConfig(config: OpenClawConfig): string {
|
||||
return hashRuntimeConfigValue(config);
|
||||
}
|
||||
|
||||
/** Fingerprints mutable environment inputs used by plugin auto-enable detection. */
|
||||
export function fingerprintPluginAutoEnableEnv(env: NodeJS.ProcessEnv): string {
|
||||
return stableFingerprintValue(env);
|
||||
}
|
||||
|
||||
function createPluginAutoEnableCacheEntry(params: {
|
||||
config: OpenClawConfig;
|
||||
discovery: PluginDiscoveryResult;
|
||||
@@ -77,9 +87,9 @@ function createPluginAutoEnableCacheEntry(params: {
|
||||
result: PluginAutoEnableResult;
|
||||
}): PluginAutoEnableCacheEntry {
|
||||
return {
|
||||
configFingerprint: hashRuntimeConfigValue(params.config),
|
||||
configFingerprint: fingerprintPluginAutoEnableConfig(params.config),
|
||||
discoveryFingerprint: stableFingerprintValue(params.discovery.candidates),
|
||||
envFingerprint: stableFingerprintValue(params.env),
|
||||
envFingerprint: fingerprintPluginAutoEnableEnv(params.env),
|
||||
registryFingerprint: stableFingerprintValue(params.manifestRegistry.plugins),
|
||||
result: params.result,
|
||||
};
|
||||
@@ -93,9 +103,9 @@ function isPluginAutoEnableCacheEntryFresh(params: {
|
||||
manifestRegistry: PluginManifestRegistry;
|
||||
}): boolean {
|
||||
return (
|
||||
params.entry.configFingerprint === hashRuntimeConfigValue(params.config) &&
|
||||
params.entry.configFingerprint === fingerprintPluginAutoEnableConfig(params.config) &&
|
||||
params.entry.discoveryFingerprint === stableFingerprintValue(params.discovery.candidates) &&
|
||||
params.entry.envFingerprint === stableFingerprintValue(params.env) &&
|
||||
params.entry.envFingerprint === fingerprintPluginAutoEnableEnv(params.env) &&
|
||||
params.entry.registryFingerprint === stableFingerprintValue(params.manifestRegistry.plugins)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
mergeBundlePathLists,
|
||||
normalizeBundlePathList,
|
||||
} from "./bundle-manifest.js";
|
||||
import type { PluginManifestRegistry } from "./manifest-registry.js";
|
||||
import type { PluginBundleFormat } from "./manifest-types.js";
|
||||
|
||||
/** LSP server config block loaded from plugin bundle metadata. */
|
||||
@@ -150,10 +151,12 @@ export function inspectBundleLspRuntimeSupport(params: {
|
||||
export function loadEnabledBundleLspConfig(params: {
|
||||
workspaceDir: string;
|
||||
cfg?: OpenClawConfig;
|
||||
manifestRegistry?: Pick<PluginManifestRegistry, "plugins">;
|
||||
}): { config: BundleLspConfig; diagnostics: Array<{ pluginId: string; message: string }> } {
|
||||
return loadEnabledBundleConfig({
|
||||
workspaceDir: params.workspaceDir,
|
||||
cfg: params.cfg,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
createEmptyConfig: () => ({ lspServers: {} }),
|
||||
loadBundleConfig: loadBundleLspConfig,
|
||||
createDiagnostic: (pluginId, message) => ({ pluginId, message }),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Load context tests cover agent and workspace context resolution for plugin runtimes.
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
|
||||
const loadConfigMock = vi.fn<typeof import("../../config/config.js").loadConfig>();
|
||||
const applyPluginAutoEnableMock =
|
||||
@@ -20,7 +21,8 @@ const metadataSnapshot = {
|
||||
policyHash: "policy",
|
||||
workspaceDir: "/resolved-workspace",
|
||||
};
|
||||
const loadPluginMetadataSnapshotMock = vi.fn(() => metadataSnapshot);
|
||||
type MetadataSnapshotMock = typeof metadataSnapshot & { pluginIds?: readonly string[] };
|
||||
const loadPluginMetadataSnapshotMock = vi.fn((): MetadataSnapshotMock => metadataSnapshot);
|
||||
const isPluginMetadataSnapshotCompatibleMock = vi.fn(() => true);
|
||||
const getCurrentPluginMetadataSnapshotMock = vi.fn(() => undefined);
|
||||
const setCurrentPluginMetadataSnapshotMock = vi.fn();
|
||||
@@ -190,6 +192,50 @@ describe("resolvePluginRuntimeLoadContext", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("reuses auto-enable results until Gateway config or metadata changes", () => {
|
||||
const rawConfig = { plugins: {} };
|
||||
const env = process.env;
|
||||
const initialSnapshot = { ...metadataSnapshot, pluginIds: ["openai"] };
|
||||
loadPluginMetadataSnapshotMock
|
||||
.mockReturnValueOnce(initialSnapshot)
|
||||
.mockReturnValueOnce({ ...initialSnapshot, pluginIds: ["openai"] })
|
||||
.mockReturnValueOnce({ ...initialSnapshot, policyHash: "changed" })
|
||||
.mockReturnValueOnce(initialSnapshot);
|
||||
|
||||
const first = resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
const second = resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
resolvePluginRuntimeLoadContext({ config: { plugins: {} }, env });
|
||||
|
||||
expect(second.config).toBe(first.config);
|
||||
expect(applyPluginAutoEnableMock).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("invalidates auto-enable results when config or process env mutates in place", () => {
|
||||
const rawConfig: OpenClawConfig = { plugins: {} };
|
||||
const env = process.env;
|
||||
const envKey = "OPENCLAW_TEST_PLUGIN_AUTO_ENABLE_FINGERPRINT";
|
||||
const previousEnvValue = env[envKey];
|
||||
delete env[envKey];
|
||||
|
||||
try {
|
||||
resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
rawConfig.plugins = { entries: { demo: { enabled: true } } };
|
||||
resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
env[envKey] = "changed";
|
||||
resolvePluginRuntimeLoadContext({ config: rawConfig, env });
|
||||
|
||||
expect(applyPluginAutoEnableMock).toHaveBeenCalledTimes(3);
|
||||
} finally {
|
||||
if (previousEnvValue === undefined) {
|
||||
delete env[envKey];
|
||||
} else {
|
||||
env[envKey] = previousEnvValue;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("threads install records from the metadata snapshot into the context and load options", () => {
|
||||
const snapshotWithRecords = {
|
||||
...metadataSnapshot,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// Plugin runtime load context helpers resolve agent and workspace facts for runtime activation.
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
||||
import { getRuntimeConfig } from "../../config/config.js";
|
||||
import {
|
||||
fingerprintPluginAutoEnableConfig,
|
||||
fingerprintPluginAutoEnableEnv,
|
||||
} from "../../config/plugin-auto-enable.apply.js";
|
||||
import { applyPluginAutoEnable } from "../../config/plugin-auto-enable.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import type { PluginInstallRecord } from "../../config/types.plugins.js";
|
||||
@@ -14,6 +18,7 @@ import {
|
||||
import { extractPluginInstallRecordsFromInstalledPluginIndex } from "../installed-plugin-index-install-records.js";
|
||||
import type { PluginLoadOptions } from "../loader.js";
|
||||
import type { PluginManifestRegistry } from "../manifest-registry.js";
|
||||
import { registerPluginMetadataProcessMemoLifecycleClear } from "../plugin-metadata-lifecycle.js";
|
||||
import {
|
||||
isPluginMetadataSnapshotCompatible,
|
||||
resolvePluginMetadataSnapshot,
|
||||
@@ -22,6 +27,90 @@ import type { PluginLogger } from "../types.js";
|
||||
|
||||
const log = createSubsystemLogger("plugins");
|
||||
|
||||
type CurrentAutoEnableCacheEntry = {
|
||||
config: OpenClawConfig;
|
||||
env: NodeJS.ProcessEnv;
|
||||
autoEnableConfigFingerprint: string;
|
||||
autoEnableEnvFingerprint: string;
|
||||
metadataConfigFingerprint: string | undefined;
|
||||
pluginIds: readonly string[] | undefined;
|
||||
policyHash: string;
|
||||
result: ReturnType<typeof applyPluginAutoEnable>;
|
||||
workspaceDir: string | undefined;
|
||||
};
|
||||
|
||||
let currentAutoEnableCache: CurrentAutoEnableCacheEntry | undefined;
|
||||
|
||||
registerPluginMetadataProcessMemoLifecycleClear(() => {
|
||||
currentAutoEnableCache = undefined;
|
||||
});
|
||||
|
||||
function samePluginIds(
|
||||
left: readonly string[] | undefined,
|
||||
right: readonly string[] | undefined,
|
||||
): boolean {
|
||||
return (
|
||||
left === right ||
|
||||
(left !== undefined &&
|
||||
right !== undefined &&
|
||||
left.length === right.length &&
|
||||
left.every((pluginId, index) => pluginId === right[index]))
|
||||
);
|
||||
}
|
||||
|
||||
function applyCurrentPluginAutoEnable(params: {
|
||||
config: OpenClawConfig;
|
||||
env: NodeJS.ProcessEnv;
|
||||
workspaceDir?: string;
|
||||
manifestRegistry: PluginManifestRegistry | undefined;
|
||||
snapshot: ReturnType<typeof resolvePluginMetadataSnapshot> | undefined;
|
||||
}): ReturnType<typeof applyPluginAutoEnable> {
|
||||
if (!params.snapshot || !params.manifestRegistry || params.env !== process.env) {
|
||||
return applyPluginAutoEnable({
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
discovery: params.snapshot?.discovery,
|
||||
});
|
||||
}
|
||||
// Gateway plugin metadata and config are replacement snapshots. Reuse only while
|
||||
// mutable config/env content still matches; reload/close lifecycle clears the slot.
|
||||
const workspaceDir = params.snapshot.workspaceDir ?? params.workspaceDir;
|
||||
const autoEnableConfigFingerprint = fingerprintPluginAutoEnableConfig(params.config);
|
||||
const autoEnableEnvFingerprint = fingerprintPluginAutoEnableEnv(params.env);
|
||||
const cached = currentAutoEnableCache;
|
||||
if (
|
||||
cached?.config === params.config &&
|
||||
cached.env === params.env &&
|
||||
cached.autoEnableConfigFingerprint === autoEnableConfigFingerprint &&
|
||||
cached.autoEnableEnvFingerprint === autoEnableEnvFingerprint &&
|
||||
cached.metadataConfigFingerprint === params.snapshot.configFingerprint &&
|
||||
cached.policyHash === params.snapshot.policyHash &&
|
||||
cached.workspaceDir === workspaceDir &&
|
||||
samePluginIds(cached.pluginIds, params.snapshot.pluginIds)
|
||||
) {
|
||||
return cached.result;
|
||||
}
|
||||
const result = applyPluginAutoEnable({
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
manifestRegistry: params.manifestRegistry,
|
||||
discovery: params.snapshot.discovery,
|
||||
});
|
||||
currentAutoEnableCache = {
|
||||
config: params.config,
|
||||
env: params.env,
|
||||
autoEnableConfigFingerprint,
|
||||
autoEnableEnvFingerprint,
|
||||
metadataConfigFingerprint: params.snapshot.configFingerprint,
|
||||
pluginIds: params.snapshot.pluginIds,
|
||||
policyHash: params.snapshot.policyHash,
|
||||
result,
|
||||
workspaceDir,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Resolved plugin runtime load context shared by runtime loader callers. */
|
||||
export type PluginRuntimeLoadContext = {
|
||||
rawConfig: OpenClawConfig;
|
||||
@@ -90,11 +179,12 @@ export function resolvePluginRuntimeLoadContext(
|
||||
config: rawConfig,
|
||||
activationSourceConfig: options?.activationSourceConfig,
|
||||
});
|
||||
const autoEnabled = applyPluginAutoEnable({
|
||||
const autoEnabled = applyCurrentPluginAutoEnable({
|
||||
config: rawConfig,
|
||||
env,
|
||||
workspaceDir: rawWorkspaceDir,
|
||||
manifestRegistry,
|
||||
discovery: initialMetadataSnapshot?.discovery,
|
||||
snapshot: initialMetadataSnapshot,
|
||||
});
|
||||
const config = autoEnabled.config;
|
||||
const workspaceDir =
|
||||
|
||||
Reference in New Issue
Block a user