@@ -602,6 +602,79 @@ public async Task InvokedAsync_CustomStorageInputFilter_OverridesDefaultAsync()
602602
603603 #region Recent Message Memory Tests
604604
605+ [ Theory ]
606+ [ InlineData ( false , false , false , 0 ) ]
607+ [ InlineData ( false , false , false , 2 ) ]
608+ [ InlineData ( false , false , true , 0 ) ]
609+ [ InlineData ( false , false , true , 2 ) ]
610+ [ InlineData ( false , true , false , 0 ) ]
611+ [ InlineData ( false , true , false , 2 ) ]
612+ [ InlineData ( false , true , true , 0 ) ]
613+ [ InlineData ( false , true , true , 2 ) ]
614+ [ InlineData ( true , false , false , 0 ) ]
615+ [ InlineData ( true , false , false , 2 ) ]
616+ [ InlineData ( true , false , true , 0 ) ]
617+ [ InlineData ( true , false , true , 2 ) ]
618+ [ InlineData ( true , true , false , 0 ) ]
619+ [ InlineData ( true , true , false , 2 ) ]
620+ [ InlineData ( true , true , true , 0 ) ]
621+ [ InlineData ( true , true , true , 2 ) ]
622+ public async Task InvokingAsync_WithConfiguredMemoryLimit_HonorsSavedStateAsync ( bool restore , bool messageOnly , bool populated , int limit )
623+ {
624+ // Arrange
625+ var session = new TestAgentSession ( ) ;
626+ string ? capturedInput = null ;
627+ Task < IEnumerable < TextSearchProvider . TextSearchResult > > SearchAsync ( string input , CancellationToken ct )
628+ {
629+ capturedInput = input ;
630+ return Task . FromResult < IEnumerable < TextSearchProvider . TextSearchResult > > ( [ ] ) ;
631+ }
632+
633+ if ( populated )
634+ {
635+ var originalProvider = new TextSearchProvider ( SearchAsync , new TextSearchProviderOptions { RecentMessageMemoryLimit = 2 } ) ;
636+ await originalProvider . InvokedAsync ( new ( s_mockAgent , session , [ new ChatMessage ( ChatRole . User , "Previous" ) ] , [ ] ) ) ;
637+ }
638+
639+ if ( restore )
640+ {
641+ session = new TestAgentSession ( AgentSessionStateBag . Deserialize ( session . StateBag . Serialize ( ) ) ) ;
642+ }
643+
644+ string originalState = session . StateBag . Serialize ( ) . GetRawText ( ) ;
645+ var provider = new TextSearchProvider ( SearchAsync , new TextSearchProviderOptions { RecentMessageMemoryLimit = limit } ) ;
646+
647+ // Act
648+ await InvokeSearchAsync ( provider , "Current" ) ;
649+
650+ // Assert
651+ Assert . Equal ( populated && limit > 0 ? "Previous\n Current" : "Current" , capturedInput ) ;
652+
653+ if ( limit == 0 )
654+ {
655+ await provider . InvokedAsync ( new ( s_mockAgent , session , [ new ChatMessage ( ChatRole . User , "Disabled turn" ) ] , [ ] ) ) ;
656+ Assert . Equal ( originalState , session . StateBag . Serialize ( ) . GetRawText ( ) ) ;
657+
658+ var enabledProvider = new TextSearchProvider ( SearchAsync , new TextSearchProviderOptions { RecentMessageMemoryLimit = 2 } ) ;
659+ await InvokeSearchAsync ( enabledProvider , "Reenabled" ) ;
660+ Assert . Equal ( populated ? "Previous\n Reenabled" : "Reenabled" , capturedInput ) ;
661+ }
662+
663+ async Task InvokeSearchAsync ( TextSearchProvider instance , string text )
664+ {
665+ ChatMessage [ ] messages = [ new ( ChatRole . User , text ) ] ;
666+ if ( messageOnly )
667+ {
668+ await instance . InvokingAsync ( new MessageAIContextProvider . InvokingContext ( s_mockAgent , session , messages ) ) ;
669+ }
670+ else
671+ {
672+ await instance . InvokingAsync ( new AIContextProvider . InvokingContext ( s_mockAgent , session , new AIContext { Messages = messages } ) ) ;
673+ }
674+ }
675+ }
676+
677+
605678 [ Fact ]
606679 public async Task InvokingAsync_WithPreviousFailedRequest_ShouldNotIncludeFailedRequestInputInSearchInputAsync ( )
607680 {
0 commit comments