





















@@ -4,7 +4,11 @@ import {
44withBundledPluginEnablementCompat,
55withBundledPluginVitestCompat,
66} from "./bundled-compat.js";
7-import { resolveRuntimePluginRegistry, type PluginLoadOptions } from "./loader.js";
7+import {
8+resolvePluginRegistryLoadCacheKey,
9+resolveRuntimePluginRegistry,
10+type PluginLoadOptions,
11+} from "./loader.js";
812import { loadPluginManifestRegistryForPluginRegistry } from "./plugin-registry.js";
913import type { PluginRegistry } from "./registry-types.js";
1014@@ -30,6 +34,12 @@ type CapabilityContractKey =
30343135type CapabilityProviderForKey<K extends CapabilityProviderRegistryKey> =
3236PluginRegistry[K][number] extends { provider: infer T } ? T : never;
37+type CapabilityProviderEntries = PluginRegistry[CapabilityProviderRegistryKey];
38+39+const capabilityProviderSnapshotCache = new WeakMap<
40+OpenClawConfig,
41+Map<string, CapabilityProviderEntries>
42+>();
33433444const CAPABILITY_CONTRACT_KEY: Record<CapabilityProviderRegistryKey, CapabilityContractKey> = {
3545memoryEmbeddingProviders: "memoryEmbeddingProviders",
@@ -64,6 +74,25 @@ function resolveBundledCapabilityCompatPluginIds(params: {
6474.toSorted((left, right) => left.localeCompare(right));
6575}
667677+export function resolveBundledCapabilityProviderIds(params: {
78+key: CapabilityProviderRegistryKey;
79+cfg?: OpenClawConfig;
80+}): string[] {
81+const env = process.env;
82+const contractKey = CAPABILITY_CONTRACT_KEY[params.key];
83+return [
84+ ...new Set(
85+loadPluginManifestRegistryForPluginRegistry({
86+config: params.cfg,
87+ env,
88+includeDisabled: true,
89+}).plugins.flatMap((plugin) =>
90+plugin.origin === "bundled" ? (plugin.contracts?.[contractKey] ?? []) : [],
91+),
92+),
93+].toSorted((left, right) => left.localeCompare(right));
94+}
95+6796function resolveCapabilityProviderConfig(params: {
6897key: CapabilityProviderRegistryKey;
6998cfg?: OpenClawConfig;
@@ -101,6 +130,30 @@ function createCapabilityProviderFallbackLoadOptions(params: {
101130return loadOptions;
102131}
103132133+function resolveCapabilityProviderSnapshotCache(
134+cfg: OpenClawConfig | undefined,
135+): Map<string, CapabilityProviderEntries> | undefined {
136+if (!cfg) {
137+return undefined;
138+}
139+let cache = capabilityProviderSnapshotCache.get(cfg);
140+if (!cache) {
141+cache = new Map();
142+capabilityProviderSnapshotCache.set(cfg, cache);
143+}
144+return cache;
145+}
146+147+function resolveCapabilityProviderSnapshotCacheKey(params: {
148+key: CapabilityProviderRegistryKey;
149+loadOptions: PluginLoadOptions;
150+}): string {
151+return JSON.stringify({
152+key: params.key,
153+load: resolvePluginRegistryLoadCacheKey(params.loadOptions),
154+});
155+}
156+104157function findProviderById<K extends CapabilityProviderRegistryKey>(
105158entries: PluginRegistry[K],
106159providerId: string,
@@ -246,8 +299,17 @@ export function resolvePluginCapabilityProvider<K extends CapabilityProviderRegi
246299 pluginIds,
247300installBundledRuntimeDeps: params.installBundledRuntimeDeps,
248301});
249-const registry = resolveRuntimePluginRegistry(loadOptions);
250-return findProviderById(registry?.[params.key] ?? [], params.providerId);
302+const cache = resolveCapabilityProviderSnapshotCache(params.cfg);
303+const cacheKey = cache
304+ ? resolveCapabilityProviderSnapshotCacheKey({ key: params.key, loadOptions })
305+ : "";
306+let loadedProviders = cache?.get(cacheKey) as PluginRegistry[K] | undefined;
307+if (!loadedProviders) {
308+const registry = resolveRuntimePluginRegistry(loadOptions);
309+loadedProviders = registry?.[params.key] ?? [];
310+cache?.set(cacheKey, loadedProviders as CapabilityProviderEntries);
311+}
312+return findProviderById(loadedProviders, params.providerId);
251313}
252314253315export function resolvePluginCapabilityProviders<K extends CapabilityProviderRegistryKey>(params: {
@@ -291,8 +353,16 @@ export function resolvePluginCapabilityProviders<K extends CapabilityProviderReg
291353 pluginIds,
292354installBundledRuntimeDeps: params.installBundledRuntimeDeps,
293355});
294-const registry = resolveRuntimePluginRegistry(loadOptions);
295-const loadedProviders = registry?.[params.key] ?? [];
356+const cache = resolveCapabilityProviderSnapshotCache(params.cfg);
357+const cacheKey = cache
358+ ? resolveCapabilityProviderSnapshotCacheKey({ key: params.key, loadOptions })
359+ : "";
360+let loadedProviders = cache?.get(cacheKey) as PluginRegistry[K] | undefined;
361+if (!loadedProviders) {
362+const registry = resolveRuntimePluginRegistry(loadOptions);
363+loadedProviders = registry?.[params.key] ?? [];
364+cache?.set(cacheKey, loadedProviders as CapabilityProviderEntries);
365+}
296366if (params.key !== "memoryEmbeddingProviders") {
297367const mergeLoadedProviders =
298368activeProviders.length > 0
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。