@@ -738,6 +738,45 @@ describe("mcp loopback server", () => {
738738 expect ( getScopedToolsCall ( 3 ) . currentInboundAudio ) . toBe ( true ) ;
739739 } ) ;
740740
741+ it ( "keeps explicit non-owner and unknown-owner loopback cache entries separate" , ( ) => {
742+ const cache = new McpLoopbackToolCache ( ) ;
743+ const baseParams = {
744+ accountId : undefined ,
745+ cfg : { session : { mainKey : "main" } } as never ,
746+ currentChannelId : "telegram:chat123" ,
747+ currentInboundAudio : undefined ,
748+ currentMessageId : "message-1" ,
749+ currentThreadTs : "thread-1" ,
750+ inboundEventKind : "room_event" ,
751+ messageProvider : "telegram" ,
752+ sessionKey : "agent:main:telegram:group:chat123" ,
753+ sourceReplyDeliveryMode : "message_tool_only" ,
754+ } satisfies Omit < Parameters < McpLoopbackToolCache [ "resolve" ] > [ 0 ] , "senderIsOwner" > ;
755+ resolveGatewayScopedToolsMock . mockImplementation ( ( input : unknown ) => {
756+ const params = input as { senderIsOwner ?: boolean } ;
757+ return {
758+ agentId : "main" ,
759+ tools :
760+ params . senderIsOwner === false
761+ ? [ makeMessageTool ( ) ]
762+ : [ makeMessageTool ( ) , makeCronTool ( ) ] ,
763+ } ;
764+ } ) ;
765+
766+ const unknownFirst = cache . resolve ( { ...baseParams , senderIsOwner : undefined } ) ;
767+ const nonOwnerSecond = cache . resolve ( { ...baseParams , senderIsOwner : false } ) ;
768+ expect ( unknownFirst . toolSchema . map ( ( tool ) => tool . name ) ) . toContain ( "cron" ) ;
769+ expect ( nonOwnerSecond . toolSchema . map ( ( tool ) => tool . name ) ) . not . toContain ( "cron" ) ;
770+
771+ const secondCache = new McpLoopbackToolCache ( ) ;
772+ const nonOwnerFirst = secondCache . resolve ( { ...baseParams , senderIsOwner : false } ) ;
773+ const unknownSecond = secondCache . resolve ( { ...baseParams , senderIsOwner : undefined } ) ;
774+ expect ( nonOwnerFirst . toolSchema . map ( ( tool ) => tool . name ) ) . not . toContain ( "cron" ) ;
775+ expect ( unknownSecond . toolSchema . map ( ( tool ) => tool . name ) ) . toContain ( "cron" ) ;
776+
777+ expect ( resolveGatewayScopedToolsMock ) . toHaveBeenCalledTimes ( 4 ) ;
778+ } ) ;
779+
741780 it ( "caps loopback tool cache cardinality by evicting oldest contexts" , ( ) => {
742781 const cache = new McpLoopbackToolCache ( ) ;
743782 const baseParams = {
0 commit comments