Skip to content

Commit 37914b8

Browse files
committed
Add another context pruner test for good measure
1 parent 1de4a9d commit 37914b8

File tree

2 files changed

+34857
-0
lines changed

2 files changed

+34857
-0
lines changed

.agents/__tests__/context-pruner.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ describe('context-pruner saved run state overflow', () => {
824824
// Run context-pruner with 100k limit
825825
const mockAgentState = {
826826
messageHistory: initialMessages,
827+
systemPrompt: savedRunState.sessionState?.mainAgentState?.systemPrompt,
827828
} as AgentState
828829
const mockLogger = {
829830
debug: () => {},
@@ -870,6 +871,90 @@ describe('context-pruner saved run state overflow', () => {
870871
expect(finalTokens).toBeLessThan(maxAllowedTokens)
871872
})
872873

874+
test('prunes message history from saved run state with large token count including system prompt', () => {
875+
// Load the saved run state file - message tokens (~183k) + system prompt tokens (~22k) = ~205k total
876+
// This exceeds the 200k limit when system prompt is included
877+
const runStatePath = join(
878+
__dirname,
879+
'data',
880+
'run-state-context-overflow2.json',
881+
)
882+
const savedRunState = JSON.parse(readFileSync(runStatePath, 'utf-8'))
883+
const initialMessages =
884+
savedRunState.sessionState?.mainAgentState?.messageHistory
885+
const systemPrompt =
886+
savedRunState.sessionState?.mainAgentState?.systemPrompt
887+
888+
// Calculate initial token count
889+
const countTokens = (msgs: any[]) => {
890+
return msgs.reduce(
891+
(sum, msg) => sum + Math.ceil(JSON.stringify(msg).length / 3),
892+
0,
893+
)
894+
}
895+
const initialMessageTokens = countTokens(initialMessages)
896+
const systemPromptTokens = Math.ceil(JSON.stringify(systemPrompt).length / 3)
897+
console.log('Initial message count:', initialMessages.length)
898+
console.log('Initial message tokens (approx):', initialMessageTokens)
899+
console.log('System prompt tokens (approx):', systemPromptTokens)
900+
console.log('Total initial tokens (approx):', initialMessageTokens + systemPromptTokens)
901+
902+
// Run context-pruner with 200k limit - must include systemPrompt in agentState
903+
// so the pruner knows about the extra tokens from the system prompt
904+
const mockAgentState = {
905+
messageHistory: initialMessages,
906+
systemPrompt: systemPrompt,
907+
} as AgentState
908+
const mockLogger = {
909+
debug: () => {},
910+
info: () => {},
911+
warn: () => {},
912+
error: () => {},
913+
}
914+
915+
const maxContextLength = 200_000
916+
917+
// Override maxMessageTokens via params
918+
const generator = contextPruner.handleSteps!({
919+
agentState: mockAgentState,
920+
logger: mockLogger,
921+
params: { maxContextLength },
922+
})
923+
924+
const results: any[] = []
925+
let result = generator.next()
926+
while (!result.done) {
927+
if (typeof result.value === 'object') {
928+
results.push(result.value)
929+
}
930+
result = generator.next()
931+
}
932+
933+
expect(results).toHaveLength(1)
934+
const prunedMessages = results[0].input.messages
935+
const finalMessageTokens = countTokens(prunedMessages)
936+
const finalTotalTokens = finalMessageTokens + systemPromptTokens
937+
938+
console.log('Final message count:', prunedMessages.length)
939+
console.log('Final message tokens (approx):', finalMessageTokens)
940+
console.log('Final total tokens (approx):', finalTotalTokens)
941+
console.log('Message token reduction:', initialMessageTokens - finalMessageTokens)
942+
943+
// The context-pruner calculates effective message budget as:
944+
// maxMessageTokens = maxContextLength - systemPromptTokens - toolDefinitionTokens
945+
// maxMessageTokens = 200k - ~22k - 0 = ~178k
946+
// Then it targets shortenedMessageTokenFactor (0.5) of that budget:
947+
// targetMessageTokens = 178k * 0.5 = ~89k
948+
// So final message tokens should be around 89k
949+
const effectiveMessageBudget = maxContextLength - systemPromptTokens
950+
const shortenedMessageTokenFactor = 0.5
951+
const targetMessageTokens = effectiveMessageBudget * shortenedMessageTokenFactor
952+
// Allow some overhead for the pruning not being exact
953+
const maxAllowedMessageTokens = targetMessageTokens + 5000
954+
955+
expect(finalMessageTokens).toBeLessThan(maxAllowedMessageTokens)
956+
})
957+
873958
test('accounts for system prompt and tool definitions when pruning with default 200k limit', () => {
874959
// Load the saved run state file with ~194k tokens in message history
875960
const runStatePath = join(

0 commit comments

Comments
 (0)