@@ -562,4 +562,139 @@ describe("ToolRepetitionDetector", () => {
562562 expect ( result . askUser ) . toBeDefined ( )
563563 } )
564564 } )
565+
566+ // ===== Native Protocol (nativeArgs) tests =====
567+ describe ( "native protocol with nativeArgs" , ( ) => {
568+ it ( "should differentiate read_file calls with different files in nativeArgs" , ( ) => {
569+ const detector = new ToolRepetitionDetector ( 2 )
570+
571+ // Create read_file tool use with nativeArgs (like native protocol does)
572+ const readFile1 : ToolUse = {
573+ type : "tool_use" ,
574+ name : "read_file" as ToolName ,
575+ params : { } , // Empty for native protocol
576+ partial : false ,
577+ nativeArgs : {
578+ files : [ { path : "file1.ts" } ] ,
579+ } ,
580+ }
581+
582+ const readFile2 : ToolUse = {
583+ type : "tool_use" ,
584+ name : "read_file" as ToolName ,
585+ params : { } , // Empty for native protocol
586+ partial : false ,
587+ nativeArgs : {
588+ files : [ { path : "file2.ts" } ] ,
589+ } ,
590+ }
591+
592+ // First call with file1
593+ expect ( detector . check ( readFile1 ) . allowExecution ) . toBe ( true )
594+
595+ // Second call with file2 - should be treated as different
596+ expect ( detector . check ( readFile2 ) . allowExecution ) . toBe ( true )
597+
598+ // Third call with file1 again - should reset counter
599+ expect ( detector . check ( readFile1 ) . allowExecution ) . toBe ( true )
600+ } )
601+
602+ it ( "should detect repetition when same files are read multiple times with nativeArgs" , ( ) => {
603+ const detector = new ToolRepetitionDetector ( 2 )
604+
605+ // Create identical read_file tool uses
606+ const readFile : ToolUse = {
607+ type : "tool_use" ,
608+ name : "read_file" as ToolName ,
609+ params : { } , // Empty for native protocol
610+ partial : false ,
611+ nativeArgs : {
612+ files : [ { path : "same-file.ts" } ] ,
613+ } ,
614+ }
615+
616+ // First call allowed
617+ expect ( detector . check ( readFile ) . allowExecution ) . toBe ( true )
618+
619+ // Second call allowed
620+ expect ( detector . check ( readFile ) . allowExecution ) . toBe ( true )
621+
622+ // Third identical call should be blocked (limit is 2)
623+ const result = detector . check ( readFile )
624+ expect ( result . allowExecution ) . toBe ( false )
625+ expect ( result . askUser ) . toBeDefined ( )
626+ } )
627+
628+ it ( "should differentiate read_file calls with multiple files in different orders" , ( ) => {
629+ const detector = new ToolRepetitionDetector ( 2 )
630+
631+ const readFile1 : ToolUse = {
632+ type : "tool_use" ,
633+ name : "read_file" as ToolName ,
634+ params : { } ,
635+ partial : false ,
636+ nativeArgs : {
637+ files : [ { path : "a.ts" } , { path : "b.ts" } ] ,
638+ } ,
639+ }
640+
641+ const readFile2 : ToolUse = {
642+ type : "tool_use" ,
643+ name : "read_file" as ToolName ,
644+ params : { } ,
645+ partial : false ,
646+ nativeArgs : {
647+ files : [ { path : "b.ts" } , { path : "a.ts" } ] ,
648+ } ,
649+ }
650+
651+ // Different order should be treated as different calls
652+ expect ( detector . check ( readFile1 ) . allowExecution ) . toBe ( true )
653+ expect ( detector . check ( readFile2 ) . allowExecution ) . toBe ( true )
654+ } )
655+
656+ it ( "should handle tools with both params and nativeArgs" , ( ) => {
657+ const detector = new ToolRepetitionDetector ( 2 )
658+
659+ const tool1 : ToolUse = {
660+ type : "tool_use" ,
661+ name : "execute_command" as ToolName ,
662+ params : { command : "ls" } ,
663+ partial : false ,
664+ nativeArgs : {
665+ command : "ls" ,
666+ cwd : "/home/user" ,
667+ } ,
668+ }
669+
670+ const tool2 : ToolUse = {
671+ type : "tool_use" ,
672+ name : "execute_command" as ToolName ,
673+ params : { command : "ls" } ,
674+ partial : false ,
675+ nativeArgs : {
676+ command : "ls" ,
677+ cwd : "/home/admin" ,
678+ } ,
679+ }
680+
681+ // Different cwd in nativeArgs should make these different
682+ expect ( detector . check ( tool1 ) . allowExecution ) . toBe ( true )
683+ expect ( detector . check ( tool2 ) . allowExecution ) . toBe ( true )
684+ } )
685+
686+ it ( "should handle tools with only params (no nativeArgs)" , ( ) => {
687+ const detector = new ToolRepetitionDetector ( 2 )
688+
689+ const legacyTool = createToolUse ( "read_file" , "read_file" , { path : "test.txt" } )
690+
691+ // Should work the same as before
692+ expect ( detector . check ( legacyTool ) . allowExecution ) . toBe ( true )
693+ expect ( detector . check ( legacyTool ) . allowExecution ) . toBe ( true )
694+
695+ const result = detector . check ( legacyTool )
696+ expect ( result . allowExecution ) . toBe ( false )
697+ expect ( result . askUser ) . toBeDefined ( )
698+ } )
699+ } )
565700} )
0 commit comments