




























@@ -2,18 +2,24 @@ import path from "node:path";
22import { fileURLToPath, pathToFileURL } from "node:url";
33import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
44import type { OpenClawConfig } from "../../config/types.openclaw.js";
5+import { formatErrorMessage } from "../../infra/errors.js";
56import { isBlockedObjectKey } from "../../infra/prototype-keys.js";
7+import { createSubsystemLogger } from "../../logging/subsystem.js";
68import {
79hasExplicitChannelConfig,
810listConfiguredChannelIdsForReadOnlyScope,
911resolveDiscoverableScopedChannelPluginIds,
1012} from "../../plugins/channel-plugin-ids.js";
13+import {
14+channelPluginIdBelongsToManifest,
15+resolveSetupChannelRegistration,
16+} from "../../plugins/loader-channel-setup.js";
1117import type { PluginManifestRecord } from "../../plugins/manifest-registry.js";
18+import { loadPluginMetadataSnapshot } from "../../plugins/plugin-metadata-snapshot.js";
1219import {
1320getCachedPluginModuleLoader,
1421type PluginModuleLoaderCache,
1522} from "../../plugins/plugin-module-loader-cache.js";
16-import { loadPluginManifestRegistryForPluginRegistry } from "../../plugins/plugin-registry.js";
1723import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
1824import { sanitizeForLog } from "../../terminal/ansi.js";
1925import { getBundledChannelSetupPlugin } from "./bundled.js";
@@ -35,6 +41,7 @@ const BUILT_PLUGIN_LOADER_MODULE_CANDIDATES = [
3541"plugins/build-smoke-entry.js",
3642] as const;
3743const moduleLoaders: PluginModuleLoaderCache = new Map();
44+const log = createSubsystemLogger("channels");
38453946type PluginLoaderModule = {
4047loadOpenClawPlugins: (params: {
@@ -366,6 +373,44 @@ function canUseManifestChannelPlugin(record: PluginManifestRecord, channelId: st
366373367374export { resolveReadOnlyChannelCommandDefaults };
368375376+function loadSetupChannelPluginFromManifestRecord(params: {
377+record: PluginManifestRecord;
378+channelId: string;
379+}): ChannelPlugin | undefined {
380+if (!params.record.setupSource || !params.record.channels.includes(params.channelId)) {
381+return undefined;
382+}
383+try {
384+const moduleLoader = getCachedPluginModuleLoader({
385+cache: moduleLoaders,
386+modulePath: params.record.setupSource,
387+importerUrl: import.meta.url,
388+preferBuiltDist: true,
389+loaderFilename: import.meta.url,
390+tryNative: true,
391+cacheScopeKey: "read-only-setup-entry",
392+});
393+const registration = resolveSetupChannelRegistration(moduleLoader(params.record.setupSource));
394+if (!registration.plugin) {
395+return undefined;
396+}
397+if (
398+!channelPluginIdBelongsToManifest({
399+channelId: registration.plugin.id,
400+pluginId: params.record.id,
401+manifestChannels: params.record.channels,
402+})
403+) {
404+return undefined;
405+}
406+return cloneChannelPluginForChannelId(registration.plugin, params.channelId);
407+} catch (error) {
408+const detail = formatErrorMessage(error);
409+log.warn(`[channels] failed to load channel setup ${params.record.id}: ${detail}`);
410+return undefined;
411+}
412+}
413+369414function rebindChannelPluginConfig(
370415config: ChannelPlugin["config"],
371416sourceChannelId: string,
@@ -652,12 +697,11 @@ export function resolveReadOnlyChannelPluginsForConfig(
652697): ReadOnlyChannelPluginResolution {
653698const env = options.env ?? process.env;
654699const workspaceDir = resolveReadOnlyWorkspaceDir(cfg, options);
655-const manifestRecords = loadPluginManifestRegistryForPluginRegistry({
700+const manifestRecords = loadPluginMetadataSnapshot({
656701config: cfg,
657702stateDir: options.stateDir,
658703 workspaceDir,
659704 env,
660-includeDisabled: true,
661705}).plugins;
662706const bundledManifestRecords = listBundledChannelManifestRecords(manifestRecords);
663707const externalManifestRecords = listExternalChannelManifestRecords(manifestRecords);
@@ -682,7 +726,17 @@ export function resolveReadOnlyChannelPluginsForConfig(
682726if (byId.has(channelId)) {
683727continue;
684728}
685-addChannelPlugins(byId, [getBundledChannelSetupPlugin(channelId)]);
729+const bundledSetupPlugin =
730+bundledManifestRecords
731+.filter((record) => record.channels.includes(channelId))
732+.map((record) =>
733+loadSetupChannelPluginFromManifestRecord({
734+ record,
735+ channelId,
736+}),
737+)
738+.find((plugin) => plugin) ?? getBundledChannelSetupPlugin(channelId, env);
739+addChannelPlugins(byId, [bundledSetupPlugin]);
686740}
687741}
688742此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。