@@ -11,6 +11,7 @@ import * as condenseModule from "../../condense"
1111
1212import {
1313 TOKEN_BUFFER_PERCENTAGE ,
14+ MIN_TOKENS_FOR_PERCENTAGE_TRIGGER ,
1415 estimateTokenCount ,
1516 truncateConversation ,
1617 truncateConversationIfNeeded ,
@@ -821,6 +822,109 @@ describe("Sliding Window", () => {
821822 // Clean up
822823 summarizeSpy . mockRestore ( )
823824 } )
825+
826+ it ( "should not trigger percentage-based condensing when tokens are below MIN_TOKENS_FOR_PERCENTAGE_TRIGGER" , async ( ) => {
827+ // Reset any previous mock calls
828+ vi . clearAllMocks ( )
829+ const summarizeSpy = vi . spyOn ( condenseModule , "summarizeConversation" )
830+
831+ const modelInfo = createModelInfo ( 100000 , 30000 )
832+ const contextWindow = modelInfo . contextWindow
833+ // Set tokens to be below MIN_TOKENS_FOR_PERCENTAGE_TRIGGER (1000)
834+ // Even though percentage would be high (90%), it shouldn't trigger
835+ const totalTokens = 900 // Below MIN_TOKENS_FOR_PERCENTAGE_TRIGGER
836+ const messagesWithSmallContent = [
837+ ...messages . slice ( 0 , - 1 ) ,
838+ { ...messages [ messages . length - 1 ] , content : "" } ,
839+ ]
840+
841+ const result = await truncateConversationIfNeeded ( {
842+ messages : messagesWithSmallContent ,
843+ totalTokens,
844+ contextWindow,
845+ maxTokens : modelInfo . maxTokens ,
846+ apiHandler : mockApiHandler ,
847+ autoCondenseContext : true ,
848+ autoCondenseContextPercent : 5 , // Very low threshold - would normally trigger at 5%
849+ systemPrompt : "System prompt" ,
850+ taskId,
851+ profileThresholds : { } ,
852+ currentProfileId : "default" ,
853+ } )
854+
855+ // Verify summarizeConversation was not called even though percentage (0.9%) would exceed threshold (5%)
856+ // This is because totalTokens (900) < MIN_TOKENS_FOR_PERCENTAGE_TRIGGER (1000)
857+ expect ( summarizeSpy ) . not . toHaveBeenCalled ( )
858+
859+ // Verify no truncation or summarization occurred
860+ expect ( result ) . toEqual ( {
861+ messages : messagesWithSmallContent ,
862+ summary : "" ,
863+ cost : 0 ,
864+ prevContextTokens : totalTokens ,
865+ } )
866+
867+ // Clean up
868+ summarizeSpy . mockRestore ( )
869+ } )
870+
871+ it ( "should trigger percentage-based condensing when tokens exceed MIN_TOKENS_FOR_PERCENTAGE_TRIGGER and percentage threshold" , async ( ) => {
872+ // Mock the summarizeConversation function
873+ const mockSummary = "Summary after meeting minimum token requirement"
874+ const mockCost = 0.02
875+ const mockSummarizeResponse : condenseModule . SummarizeResponse = {
876+ messages : [
877+ { role : "user" , content : "First message" } ,
878+ { role : "assistant" , content : mockSummary , isSummary : true } ,
879+ { role : "user" , content : "Last message" } ,
880+ ] ,
881+ summary : mockSummary ,
882+ cost : mockCost ,
883+ newContextTokens : 150 ,
884+ }
885+
886+ const summarizeSpy = vi
887+ . spyOn ( condenseModule , "summarizeConversation" )
888+ . mockResolvedValue ( mockSummarizeResponse )
889+
890+ const modelInfo = createModelInfo ( 100000 , 30000 )
891+ const contextWindow = modelInfo . contextWindow
892+ // Set tokens to be just above MIN_TOKENS_FOR_PERCENTAGE_TRIGGER
893+ // and above the percentage threshold
894+ const totalTokens = MIN_TOKENS_FOR_PERCENTAGE_TRIGGER + 100 // 1100 tokens
895+ const messagesWithSmallContent = [
896+ ...messages . slice ( 0 , - 1 ) ,
897+ { ...messages [ messages . length - 1 ] , content : "" } ,
898+ ]
899+
900+ const result = await truncateConversationIfNeeded ( {
901+ messages : messagesWithSmallContent ,
902+ totalTokens,
903+ contextWindow,
904+ maxTokens : modelInfo . maxTokens ,
905+ apiHandler : mockApiHandler ,
906+ autoCondenseContext : true ,
907+ autoCondenseContextPercent : 1 , // Very low threshold - 1% of 100000 = 1000 tokens
908+ systemPrompt : "System prompt" ,
909+ taskId,
910+ profileThresholds : { } ,
911+ currentProfileId : "default" ,
912+ } )
913+
914+ // Should use summarization because:
915+ // 1. totalTokens (1100) >= MIN_TOKENS_FOR_PERCENTAGE_TRIGGER (1000)
916+ // 2. percentage (1.1%) >= threshold (1%)
917+ expect ( summarizeSpy ) . toHaveBeenCalled ( )
918+ expect ( result ) . toMatchObject ( {
919+ messages : mockSummarizeResponse . messages ,
920+ summary : mockSummary ,
921+ cost : mockCost ,
922+ prevContextTokens : totalTokens ,
923+ } )
924+
925+ // Clean up
926+ summarizeSpy . mockRestore ( )
927+ } )
824928 } )
825929
826930 /**
0 commit comments