@@ -31,16 +31,21 @@ import {
3131 capturePluginToolDescriptor ,
3232 createPluginToolDescriptorConfigCacheKeyMemo ,
3333 readCachedPluginToolDescriptors ,
34+ resetPluginToolDescriptorCache as resetCachedPluginToolDescriptors ,
3435 type CachedPluginToolDescriptor ,
3536 type PluginToolDescriptorConfigCacheKeyMemo ,
3637 writeCachedPluginToolDescriptors ,
3738} from "./tool-descriptor-cache.js" ;
3839import type { OpenClawPluginToolContext } from "./types.js" ;
3940
40- export {
41- resetPluginToolDescriptorCache ,
42- resetPluginToolDescriptorCache as resetPluginToolFactoryCache ,
43- } from "./tool-descriptor-cache.js" ;
41+ let cachedDescriptorRuntimeRegistries = new WeakMap < CachedPluginToolDescriptor , PluginRegistry > ( ) ;
42+
43+ export function resetPluginToolDescriptorCache ( ) : void {
44+ resetCachedPluginToolDescriptors ( ) ;
45+ cachedDescriptorRuntimeRegistries = new WeakMap ( ) ;
46+ }
47+
48+ export { resetPluginToolDescriptorCache as resetPluginToolFactoryCache } ;
4449
4550/** MCP bridge metadata attached to plugin tools surfaced through agent tool lists. */
4651export type PluginToolMcpMeta = {
@@ -692,6 +697,10 @@ function createCachedDescriptorPluginTool(params: {
692697 const registry = resolvePluginToolRegistry ( {
693698 loadOptions,
694699 onlyPluginIds : [ pluginId ] ,
700+ retainedRegistry : cachedDescriptorRuntimeRegistries . get ( params . descriptor ) ,
701+ onRetainRegistry : ( retainedRegistry ) => {
702+ cachedDescriptorRuntimeRegistries . set ( params . descriptor , retainedRegistry ) ;
703+ } ,
695704 } ) ;
696705 const candidates = registry ?. tools . filter ( ( candidate ) => candidate . pluginId === pluginId ) ;
697706 if ( ! candidates || candidates . length === 0 ) {
@@ -899,6 +908,8 @@ function resolveCachedPluginTools(params: {
899908function resolvePluginToolRegistry ( params : {
900909 loadOptions : PluginLoadOptions ;
901910 onlyPluginIds ?: readonly string [ ] ;
911+ retainedRegistry ?: PluginRegistry ;
912+ onRetainRegistry ?: ( registry : PluginRegistry ) => void ;
902913} ) {
903914 const lookup = {
904915 env : params . loadOptions . env ,
@@ -924,7 +935,16 @@ function resolvePluginToolRegistry(params: {
924935 return activeRegistry ;
925936 }
926937
938+ if ( registryHasScopedPluginTools ( params . retainedRegistry , params . onlyPluginIds ) ) {
939+ return params . retainedRegistry ;
940+ }
941+
927942 const forceStandaloneLoad = Boolean ( channelRegistry || activeRegistry ) ;
943+ const shouldRetainColdLoadedToolRegistry =
944+ forceStandaloneLoad &&
945+ params . loadOptions . activate === false &&
946+ params . loadOptions . toolDiscovery === true &&
947+ params . onRetainRegistry !== undefined ;
928948 const standaloneRegistry = ensureStandaloneRuntimePluginRegistryLoaded ( {
929949 surface : "active" ,
930950 forceLoad : forceStandaloneLoad ,
@@ -933,6 +953,9 @@ function resolvePluginToolRegistry(params: {
933953 loadOptions : params . loadOptions ,
934954 } ) ;
935955 if ( registryHasScopedPluginTools ( standaloneRegistry , params . onlyPluginIds ) ) {
956+ if ( shouldRetainColdLoadedToolRegistry ) {
957+ params . onRetainRegistry ?.( standaloneRegistry ) ;
958+ }
936959 return standaloneRegistry ;
937960 }
938961 return standaloneRegistry ?? channelRegistry ?? activeRegistry ;
0 commit comments