@@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
44const hoisted = vi . hoisted ( ( ) => ( {
55 getCurrentPluginMetadataSnapshot : vi . fn ( ) ,
66 ensureStandaloneRuntimePluginRegistryLoaded : vi . fn ( ) ,
7+ getLoadedRuntimePluginRegistry : vi . fn ( ) ,
78 getActivePluginRuntimeSubagentMode : vi . fn < ( ) => "default" | "explicit" | "gateway-bindable" > (
89 ( ) => "default" ,
910 ) ,
@@ -18,6 +19,10 @@ vi.mock("../plugins/runtime/standalone-runtime-registry-loader.js", () => ({
1819 ensureStandaloneRuntimePluginRegistryLoaded : hoisted . ensureStandaloneRuntimePluginRegistryLoaded ,
1920} ) ) ;
2021
22+ vi . mock ( "../plugins/active-runtime-registry.js" , ( ) => ( {
23+ getLoadedRuntimePluginRegistry : hoisted . getLoadedRuntimePluginRegistry ,
24+ } ) ) ;
25+
2126vi . mock ( "../plugins/runtime.js" , ( ) => ( {
2227 getActivePluginRuntimeSubagentMode : hoisted . getActivePluginRuntimeSubagentMode ,
2328 getActivePluginRegistryWorkspaceDir : hoisted . getActivePluginRegistryWorkspaceDir ,
@@ -32,6 +37,8 @@ describe("ensureRuntimePluginsLoaded", () => {
3237 hoisted . getCurrentPluginMetadataSnapshot . mockReturnValue ( undefined ) ;
3338 hoisted . ensureStandaloneRuntimePluginRegistryLoaded . mockReset ( ) ;
3439 hoisted . ensureStandaloneRuntimePluginRegistryLoaded . mockReturnValue ( undefined ) ;
40+ hoisted . getLoadedRuntimePluginRegistry . mockReset ( ) ;
41+ hoisted . getLoadedRuntimePluginRegistry . mockReturnValue ( undefined ) ;
3542 hoisted . getActivePluginRuntimeSubagentMode . mockReset ( ) ;
3643 hoisted . getActivePluginRuntimeSubagentMode . mockReturnValue ( "default" ) ;
3744 hoisted . getActivePluginRegistryWorkspaceDir . mockReset ( ) ;
@@ -147,6 +154,84 @@ describe("ensureRuntimePluginsLoaded", () => {
147154 } ) ;
148155 } ) ;
149156
157+ it ( "reuses the active startup registry workspace only on a compatible cache hit" , ( ) => {
158+ hoisted . getCurrentPluginMetadataSnapshot . mockReturnValue ( {
159+ startup : {
160+ pluginIds : [ "telegram" ] ,
161+ } ,
162+ } ) ;
163+ hoisted . getActivePluginRuntimeSubagentMode . mockReturnValue ( "gateway-bindable" ) ;
164+ hoisted . getActivePluginRegistryWorkspaceDir . mockReturnValue ( "/tmp/gateway-workspace" ) ;
165+ hoisted . getLoadedRuntimePluginRegistry . mockReturnValue ( { } ) ;
166+
167+ ensureRuntimePluginsLoaded ( {
168+ config : { } as never ,
169+ workspaceDir : "/tmp/agent-workspace" ,
170+ allowGatewaySubagentBinding : true ,
171+ } ) ;
172+
173+ expect ( hoisted . getCurrentPluginMetadataSnapshot ) . toHaveBeenCalledWith ( {
174+ config : { } as never ,
175+ workspaceDir : "/tmp/agent-workspace" ,
176+ } ) ;
177+ expect ( hoisted . getLoadedRuntimePluginRegistry ) . toHaveBeenCalledWith ( {
178+ requiredPluginIds : [ "telegram" ] ,
179+ workspaceDir : "/tmp/gateway-workspace" ,
180+ loadOptions : {
181+ config : { } as never ,
182+ onlyPluginIds : [ "telegram" ] ,
183+ workspaceDir : "/tmp/gateway-workspace" ,
184+ forceFullRuntimeForChannelPlugins : true ,
185+ runtimeOptions : {
186+ allowGatewaySubagentBinding : true ,
187+ } ,
188+ } ,
189+ } ) ;
190+ expect ( hoisted . ensureStandaloneRuntimePluginRegistryLoaded ) . not . toHaveBeenCalled ( ) ;
191+ } ) ;
192+
193+ it ( "loads from the requested workspace when active startup registry reuse misses" , ( ) => {
194+ hoisted . getCurrentPluginMetadataSnapshot . mockReturnValue ( {
195+ startup : {
196+ pluginIds : [ "telegram" ] ,
197+ } ,
198+ } ) ;
199+ hoisted . getActivePluginRuntimeSubagentMode . mockReturnValue ( "gateway-bindable" ) ;
200+ hoisted . getActivePluginRegistryWorkspaceDir . mockReturnValue ( "/tmp/gateway-workspace" ) ;
201+
202+ ensureRuntimePluginsLoaded ( {
203+ config : { } as never ,
204+ workspaceDir : "/tmp/agent-workspace" ,
205+ allowGatewaySubagentBinding : true ,
206+ } ) ;
207+
208+ expect ( hoisted . getLoadedRuntimePluginRegistry ) . toHaveBeenCalledWith ( {
209+ requiredPluginIds : [ "telegram" ] ,
210+ workspaceDir : "/tmp/gateway-workspace" ,
211+ loadOptions : {
212+ config : { } as never ,
213+ onlyPluginIds : [ "telegram" ] ,
214+ workspaceDir : "/tmp/gateway-workspace" ,
215+ forceFullRuntimeForChannelPlugins : true ,
216+ runtimeOptions : {
217+ allowGatewaySubagentBinding : true ,
218+ } ,
219+ } ,
220+ } ) ;
221+ expect ( hoisted . ensureStandaloneRuntimePluginRegistryLoaded ) . toHaveBeenCalledWith ( {
222+ requiredPluginIds : [ "telegram" ] ,
223+ loadOptions : {
224+ config : { } as never ,
225+ onlyPluginIds : [ "telegram" ] ,
226+ workspaceDir : "/tmp/agent-workspace" ,
227+ forceFullRuntimeForChannelPlugins : true ,
228+ runtimeOptions : {
229+ allowGatewaySubagentBinding : true ,
230+ } ,
231+ } ,
232+ } ) ;
233+ } ) ;
234+
150235 it ( "lets the loader decide when startup ids match but config changes" , ( ) => {
151236 const config = {
152237 plugins : {
0 commit comments