@@ -46,7 +46,9 @@ const mockRestPatch = vi.hoisted(() => vi.fn());
4646const mockRestDelete = vi . hoisted ( ( ) => vi . fn ( ) ) ;
4747const gatewayClientStarts = vi . hoisted ( ( ) => vi . fn ( ) ) ;
4848const gatewayClientStops = vi . hoisted ( ( ) => vi . fn ( ) ) ;
49- const gatewayClientRequests = vi . hoisted ( ( ) => vi . fn ( async ( ..._args : unknown [ ] ) => ( { ok : true } ) ) ) ;
49+ const gatewayClientRequests = vi . hoisted ( ( ) =>
50+ vi . fn ( async ( ..._args : unknown [ ] ) => ( { ok : true } ) ) ,
51+ ) ;
5052const gatewayClientParams = vi . hoisted ( ( ) => [ ] as Array < Record < string , unknown > > ) ;
5153const mockGatewayClientCtor = vi . hoisted ( ( ) => vi . fn ( ) ) ;
5254const mockResolveGatewayConnectionAuth = vi . hoisted ( ( ) => vi . fn ( ) ) ;
@@ -955,9 +957,7 @@ describe("DiscordExecApprovalHandler delivery routing", () => {
955957 Routes . channelMessages ( "999888777" ) ,
956958 expect . objectContaining ( {
957959 body : expect . objectContaining ( {
958- content : expect . stringContaining (
959- "I sent approval DMs to the approvers for this account" ,
960- ) ,
960+ content : expect . stringContaining ( "I sent approval DMs to the approvers for this account" ) ,
961961 } ) ,
962962 } ) ,
963963 ) ;
@@ -988,6 +988,45 @@ describe("DiscordExecApprovalHandler delivery routing", () => {
988988 ) ;
989989 } ) ;
990990
991+ it ( "dedupes delivery when the origin route and approver DM resolve to the same Discord channel" , async ( ) => {
992+ const handler = createHandler ( {
993+ enabled : true ,
994+ approvers : [ "999" ] ,
995+ target : "both" ,
996+ } ) ;
997+
998+ mockRestPost . mockImplementation ( async ( route : string ) => {
999+ if ( route === Routes . channelMessages ( "123" ) ) {
1000+ return { id : "msg-1" , channel_id : "123" } ;
1001+ }
1002+ if ( route === Routes . userChannels ( ) ) {
1003+ return { id : "123" } ;
1004+ }
1005+ throw new Error ( `unexpected route: ${ route } ` ) ;
1006+ } ) ;
1007+
1008+ await handler . handleApprovalRequested (
1009+ createRequest ( {
1010+ sessionKey : "agent:main:discord:channel:123" ,
1011+ turnSourceChannel : "discord" ,
1012+ turnSourceTo : "123" ,
1013+ turnSourceAccountId : "default" ,
1014+ } ) ,
1015+ ) ;
1016+
1017+ expect ( mockRestPost ) . toHaveBeenCalledTimes ( 2 ) ;
1018+ expect ( mockRestPost ) . toHaveBeenNthCalledWith (
1019+ 1 ,
1020+ Routes . channelMessages ( "123" ) ,
1021+ expect . objectContaining ( {
1022+ body : expect . any ( Object ) ,
1023+ } ) ,
1024+ ) ;
1025+ expect ( mockRestPost ) . toHaveBeenNthCalledWith ( 2 , Routes . userChannels ( ) , {
1026+ body : { recipient_id : "999" } ,
1027+ } ) ;
1028+ } ) ;
1029+
9911030 it ( "delivers plugin approvals through the shared runtime flow" , async ( ) => {
9921031 const handler = createHandler ( {
9931032 enabled : true ,
0 commit comments