@@ -36,6 +36,7 @@ const {
3636 resolveDiscordAllowlistConfigMock,
3737 resolveNativeCommandsEnabledMock,
3838 resolveNativeSkillsEnabledMock,
39+ voiceRuntimeModuleLoadedMock,
3940} = vi . hoisted ( ( ) => {
4041 const createdBindingManagers : Array < { stop : ReturnType < typeof vi . fn > } > = [ ] ;
4142 return {
@@ -103,6 +104,7 @@ const {
103104 } ) ) ,
104105 resolveNativeCommandsEnabledMock : vi . fn ( ( ) => true ) ,
105106 resolveNativeSkillsEnabledMock : vi . fn ( ( ) => false ) ,
107+ voiceRuntimeModuleLoadedMock : vi . fn ( ) ,
106108 } ;
107109} ) ;
108110
@@ -210,10 +212,13 @@ vi.mock("../voice/command.js", () => ({
210212 createDiscordVoiceCommand : ( ) => ( { name : "voice-command" } ) ,
211213} ) ) ;
212214
213- vi . mock ( "../voice/manager.js" , ( ) => ( {
214- DiscordVoiceManager : class DiscordVoiceManager { } ,
215- DiscordVoiceReadyListener : class DiscordVoiceReadyListener { } ,
216- } ) ) ;
215+ vi . mock ( "../voice/manager.runtime.js" , ( ) => {
216+ voiceRuntimeModuleLoadedMock ( ) ;
217+ return {
218+ DiscordVoiceManager : class DiscordVoiceManager { } ,
219+ DiscordVoiceReadyListener : class DiscordVoiceReadyListener { } ,
220+ } ;
221+ } ) ;
217222
218223vi . mock ( "./agent-components.js" , ( ) => ( {
219224 createAgentComponentButton : ( ) => ( { id : "btn" } ) ,
@@ -390,6 +395,7 @@ describe("monitorDiscordProvider", () => {
390395 } ) ;
391396 resolveNativeCommandsEnabledMock . mockClear ( ) . mockReturnValue ( true ) ;
392397 resolveNativeSkillsEnabledMock . mockClear ( ) . mockReturnValue ( false ) ;
398+ voiceRuntimeModuleLoadedMock . mockClear ( ) ;
393399 } ) ;
394400
395401 it ( "stops thread bindings when startup fails before lifecycle begins" , async ( ) => {
@@ -424,6 +430,38 @@ describe("monitorDiscordProvider", () => {
424430 expect ( reconcileAcpThreadBindingsOnStartupMock ) . toHaveBeenCalledTimes ( 1 ) ;
425431 } ) ;
426432
433+ it ( "does not load the Discord voice runtime when voice is disabled" , async ( ) => {
434+ const { monitorDiscordProvider } = await import ( "./provider.js" ) ;
435+
436+ await monitorDiscordProvider ( {
437+ config : baseConfig ( ) ,
438+ runtime : baseRuntime ( ) ,
439+ } ) ;
440+
441+ expect ( voiceRuntimeModuleLoadedMock ) . not . toHaveBeenCalled ( ) ;
442+ } ) ;
443+
444+ it ( "loads the Discord voice runtime only when voice is enabled" , async ( ) => {
445+ resolveDiscordAccountMock . mockReturnValue ( {
446+ accountId : "default" ,
447+ token : "cfg-token" ,
448+ config : {
449+ commands : { native : true , nativeSkills : false } ,
450+ voice : { enabled : true } ,
451+ agentComponents : { enabled : false } ,
452+ execApprovals : { enabled : false } ,
453+ } ,
454+ } ) ;
455+ const { monitorDiscordProvider } = await import ( "./provider.js" ) ;
456+
457+ await monitorDiscordProvider ( {
458+ config : baseConfig ( ) ,
459+ runtime : baseRuntime ( ) ,
460+ } ) ;
461+
462+ expect ( voiceRuntimeModuleLoadedMock ) . toHaveBeenCalledTimes ( 1 ) ;
463+ } ) ;
464+
427465 it ( "treats ACP error status as uncertain during startup thread-binding probes" , async ( ) => {
428466 const { monitorDiscordProvider } = await import ( "./provider.js" ) ;
429467 getAcpSessionStatusMock . mockResolvedValue ( { state : "error" } ) ;
0 commit comments