Dexter Context Management Strategy: How the AI Agent Handles Token Limits
Dexter uses an Anthropic-style sliding window approach that stores all tool results in a JSON-L scratchpad file but only feeds the most recent tool outputs to the LLM, automatically clearing older results from memory when token estimates exceed 100,000 tokens while preserving the full execution history on disk.
The virattt/dexter repository implements a sophisticated context management strategy designed to prevent token limit overflows during long-running agent executions. By combining persistent JSON-L storage with intelligent in-memory pruning, Dexter ensures that the LLM always receives relevant recent context without exceeding model constraints.
How Dexter's Context Management Strategy Works
The Scratchpad: Append-Only JSON-L Storage
At the core of Dexter's context management strategy lies the Scratchpad class in src/agent/scratchpad.ts. This component maintains an append-only log of every agent step, including initialization, thinking traces, and tool results. Each entry is stored as a JSON object in a JSON-L (JSON Lines) file, creating a complete, query-specific audit trail.
The scratchpad serves as the single source of truth for a query's execution history. It provides methods to add results, query usage statistics, and selectively clear old results from memory while leaving the underlying file untouched.
Token Estimation and Threshold Monitoring
Dexter proactively manages context size through the estimateTokens utility in src/utils/tokens.ts. This function performs a quick character-to-token conversion to approximate the current prompt size, combining the system prompt, user query, and accumulated tool results.
The system monitors against two critical constants:
CONTEXT_THRESHOLD = 100000: The safe token limit that triggers context pruningKEEP_TOOL_USES = 5: The number of recent tool results to retain in memory
After each tool execution pass, the Agent.manageContextThreshold method in src/agent/agent.ts evaluates the estimated token count and initiates cleanup if the threshold is exceeded.
Selective Memory: Clearing Old Tool Results
When token estimates surpass the 100,000 token threshold, Dexter implements an in-memory sliding window that clears the oldest tool results while preserving the five most recent entries (as defined by KEEP_TOOL_USES).
This clearing operation occurs entirely in memory. The Scratchpad.clearOldestToolResults method marks specific indices as cleared in a Set called clearedToolIndices, ensuring that subsequent calls to getToolResults() automatically omit these entries when constructing the iteration prompt.
The system emits a context_cleared event when pruning occurs, allowing monitoring tools to track when context compression happens:
if (estimatedContextTokens > CONTEXT_THRESHOLD) {
const clearedCount = ctx.scratchpad.clearOldestToolResults(KEEP_TOOL_USES);
if (clearedCount > 0) {
yield { type: 'context_cleared', clearedCount, keptCount: KEEP_TOOL_USES };
}
}
Key Implementation Details
Core Files and Components
| Component | Role | File Path |
|---|---|---|
| Scratchpad | Append-only log holding the single source of truth for query execution. Provides methods for adding results and clearing old entries. | src/agent/scratchpad.ts |
| estimateTokens | Quick character-to-token conversion for prompt size estimation. | src/utils/tokens.ts |
| Agent.manageContextThreshold | Main loop method that checks token limits and triggers context clearing. | src/agent/agent.ts |
| buildIterationPrompt | Constructs the prompt sent to the LLM, receiving filtered tool results from the scratchpad. | src/agent/agent.ts |
The Clearing Algorithm
The clearOldestToolResults method implements a precise algorithm to maintain exactly KEEP_TOOL_USES recent tool results:
clearOldestToolResults(keepCount: number): number {
const entries = this.readEntries();
const toolResultIndices: number[] = [];
let index = 0;
for (const entry of entries) {
if (entry.type === 'tool_result' && !this.clearedToolIndices.has(index)) {
toolResultIndices.push(index);
}
if (entry.type === 'tool_result') index++;
}
const toClearCount = Math.max(0, toolResultIndices.length - keepCount);
for (let i = 0; i < toClearCount; i++) {
this.clearedToolIndices.add(toolResultIndices[i]);
}
return toClearCount;
}
This approach ensures that the LLM always receives the most recent and relevant tool outputs while preventing context window overflow.
Code Examples
Running an Agent with Automatic Context Management
The following example demonstrates how Dexter automatically handles context clearing during long-running agent executions:
import { Agent } from './agent/agent.js';
async function demo() {
const agent = Agent.create(); // uses default model & tools
const query = 'What were Apple’s revenue trends and recent insider trades?';
for await (const evt of agent.run(query)) {
switch (evt.type) {
case 'thinking':
console.log('🤔', evt.message);
break;
case 'context_cleared':
console.log(`🧹 Cleared ${evt.clearedCount} old tool results (kept ${evt.keptCount})`);
break;
case 'answer_start':
console.log('📝 Generating final answer...');
break;
case 'done':
console.log('✅ Answer:', evt.answer);
console.log('🛠 Tool calls:', evt.toolCalls);
break;
}
}
}
demo();
Inspecting the Persisted Scratchpad File
Even after context clearing occurs in memory, the full execution history remains available on disk for debugging and auditing:
import { readFileSync, readdirSync } from 'fs';
import { join } from 'path';
// After a run, the file lives under .dexter/scratchpad/
const dir = '.dexter/scratchpad';
const files = readdirSync(dir);
const latest = files.sort().pop(); // newest by timestamp
const content = readFileSync(join(dir, latest), 'utf-8');
console.log(content); // each line is a JSON entry (init, thinking, tool_result)
Why This Context Management Strategy Matters
Dexter's approach to context management offers three critical advantages for production AI agent deployments:
-
Complete Auditability – The JSON-L scratchpad file preserves every tool execution, thought process, and intermediate result indefinitely. This enables post-hoc debugging, compliance auditing, and execution replay without consuming LLM context window space.
-
Dynamic Context Optimization – By estimating tokens and clearing only the oldest results, Dexter maintains the most recent and relevant tool outputs (the last 5 by default) while preventing the prompt from exceeding the 100,000 token threshold. This mirrors Anthropic's recommended approach for long-running conversations.
-
Transparent Operation – The
context_clearedevent emission allows monitoring systems to track when and how often context compression occurs, providing visibility into agent execution patterns and potential optimization opportunities.
Summary
Dexter implements an Anthropic-style sliding window context management strategy that balances complete execution history preservation with LLM token limit compliance:
- All agent steps are stored in an append-only JSON-L scratchpad file (
src/agent/scratchpad.ts) that serves as the persistent source of truth - The system estimates prompt tokens using
estimateTokensinsrc/utils/tokens.tsand monitors against a 100,000 token threshold - When limits are exceeded,
Scratchpad.clearOldestToolResultsremoves the oldest tool results from memory while keeping the 5 most recent (KEEP_TOOL_USES) - The
Agent.manageContextThresholdmethod insrc/agent/agent.tsorchestrates this process, emittingcontext_clearedevents for observability - Cleared entries are omitted from iteration prompts via
buildIterationPrompt, but remain in the disk file for debugging
Frequently Asked Questions
How does Dexter prevent losing important context when clearing old tool results?
Dexter retains the 5 most recent tool results by default (configurable via KEEP_TOOL_USES) and only clears older entries from memory. This ensures the LLM always receives the freshest, most relevant tool outputs while the full history remains safely stored in the JSON-L scratchpad file on disk. The clearing algorithm specifically targets the oldest indices first, preserving temporal relevance.
What happens to the scratchpad file when context is cleared?
Nothing is deleted from the file. Dexter's context clearing operates purely in-memory through the clearedToolIndices Set in the Scratchpad class. The JSON-L file in .dexter/scratchpad/ maintains every tool result, thought, and initialization record indefinitely. This design enables complete audit trails and debugging capabilities independent of the LLM's context window constraints.
How does Dexter estimate token counts for context management?
The system uses a simple but effective character-to-token conversion function called estimateTokens located in src/utils/tokens.ts. It calculates the combined length of the system prompt, user query, and full tool results, then applies a conversion factor to approximate token usage. When this estimate exceeds the CONTEXT_THRESHOLD of 100,000 tokens, the Agent.manageContextThreshold method triggers the clearing of oldest tool results.
Can developers adjust the context management thresholds?
Yes, the context management strategy is configurable through constants in src/utils/tokens.ts. Developers can modify CONTEXT_THRESHOLD (default 100,000) to set a different token limit for triggering context clearing, and KEEP_TOOL_USES (default 5) to change how many recent tool results remain in the prompt. These adjustments allow tuning for different model context windows or specific agent workflows requiring more or less historical context.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →