File size: 4,731 Bytes
fcd8223 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | /** Loads capability providers through the canonical scoped plugin loader. */
import { createSubsystemLogger } from "../logging/subsystem.js";
import { withBundledPluginEnablementCompat } from "./bundled-compat.js";
import { getGatewayPluginMetadataSnapshot } from "./current-plugin-metadata-state.js";
import { discoverOpenClawPlugins, type PluginDiscoveryResult } from "./discovery.js";
import {
acquirePluginRegistryWithInternalOverrides,
loadOpenClawPluginsWithInternalOverrides,
} from "./loader-runtime-load.js";
import type { PluginLoadOptions } from "./loader.js";
import { loadPluginManifestRegistryCore } from "./manifest-registry.js";
import type { PluginRuntime } from "./runtime/types.js";
const log = createSubsystemLogger("plugins");
function createCapabilityRegistrationRuntime(
config: NonNullable<PluginLoadOptions["config"]>,
): Pick<PluginRuntime, "config"> {
return {
config: {
current: () => config,
mutateConfigFile: async () => {
throw new Error("Capability discovery cannot mutate plugin configuration.");
},
replaceConfigFile: async () => {
throw new Error("Capability discovery cannot replace plugin configuration.");
},
},
};
}
type BundledCapabilityRuntimeParams = Pick<
PluginLoadOptions,
| "env"
| "config"
| "workspaceDir"
| "installRecords"
| "manifestRegistry"
| "activationSourceConfig"
| "autoEnabledReasons"
| "preferBuiltPluginArtifacts"
| "pluginSdkResolution"
> & {
pluginIds: readonly string[];
discovery?: PluginDiscoveryResult;
};
export function loadBundledCapabilityRuntimeRegistry(params: BundledCapabilityRuntimeParams) {
const { options, overrides } = prepareBundledCapabilityRuntime(params);
return loadOpenClawPluginsWithInternalOverrides(options, overrides);
}
export function acquireBundledCapabilityRuntimeRegistry(params: BundledCapabilityRuntimeParams) {
const { options, overrides } = prepareBundledCapabilityRuntime(params);
return acquirePluginRegistryWithInternalOverrides(options, overrides);
}
function prepareBundledCapabilityRuntime(params: BundledCapabilityRuntimeParams): {
options: PluginLoadOptions & { cache: false; activate: false };
overrides: Parameters<typeof loadOpenClawPluginsWithInternalOverrides>[1];
} {
const { pluginIds: requestedPluginIds, ...loadOptions } = params;
const env = params.env ?? process.env;
// Only the speech owner may opt into legacy global-disable compatibility before capture.
const config =
params.config?.plugins?.enabled === false
? params.config
: (withBundledPluginEnablementCompat({
config: params.config,
pluginIds: params.pluginIds,
env,
}) ?? {});
const snapshot =
!params.discovery && !params.installRecords ? getGatewayPluginMetadataSnapshot() : undefined;
const preparedRegistry =
params.manifestRegistry ??
(snapshot ? (snapshot.bundledManifestRegistry ?? { plugins: [], diagnostics: [] }) : undefined);
const discovery = preparedRegistry
? undefined
: (params.discovery ??
discoverOpenClawPlugins({
env,
workspaceDir: params.workspaceDir,
installRecords: params.installRecords,
}));
const pluginIds = new Set(params.pluginIds);
const manifestRegistry =
preparedRegistry ??
loadPluginManifestRegistryCore({
config,
env,
workspaceDir: params.workspaceDir,
installRecords: params.installRecords,
candidates: discovery?.candidates,
diagnostics: discovery?.diagnostics,
});
const scopedManifestRegistry = {
plugins: manifestRegistry.plugins.filter(
(plugin) => plugin.origin === "bundled" && pluginIds.has(plugin.id),
),
diagnostics: manifestRegistry.diagnostics,
};
return {
options: {
...loadOptions,
config,
env,
onlyPluginIds: [...requestedPluginIds],
cache: false,
activate: false,
// Channel setup entries cannot register providers; keep their runtime entry in discovery mode.
channelPluginLoadIntent: "full",
manifestRegistry: scopedManifestRegistry,
logger: {
info: (message) => log.info(message),
warn: (message) => log.warn(message),
error: (message) => log.error(message),
debug: (message) => log.debug(message),
},
},
overrides: {
// Discovery needs the current config, but not the full host runtime graph. The registry
// still supplies its scoped lazy methods around this narrow base runtime.
runtime: createCapabilityRegistrationRuntime(config),
moduleLoader: {
installNativeSdkResolver: false,
loaderFilename: import.meta.url,
},
},
};
}
|