# Dexter Context Management Strategy: How the AI Agent Handles Token Limits

> Discover Dexter's context management strategy. Learn how this AI agent efficiently handles token limits using a sliding window and JSON-L scratchpad for optimal LLM performance.

- Repository: [Virat Singh/dexter](https://github.com/virattt/dexter)
- Tags: how-to-guide
- Published: 2026-02-16

---

**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`](https://github.com/virattt/dexter/blob/main/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`](https://github.com/virattt/dexter/blob/main/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 pruning
- **`KEEP_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`](https://github.com/virattt/dexter/blob/main/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:

```typescript
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`](https://github.com/virattt/dexter/blob/main/src/agent/scratchpad.ts) |
| **estimateTokens** | Quick character-to-token conversion for prompt size estimation. | [`src/utils/tokens.ts`](https://github.com/virattt/dexter/blob/main/src/utils/tokens.ts) |
| **Agent.manageContextThreshold** | Main loop method that checks token limits and triggers context clearing. | [`src/agent/agent.ts`](https://github.com/virattt/dexter/blob/main/src/agent/agent.ts) |
| **buildIterationPrompt** | Constructs the prompt sent to the LLM, receiving filtered tool results from the scratchpad. | [`src/agent/agent.ts`](https://github.com/virattt/dexter/blob/main/src/agent/agent.ts) |

### The Clearing Algorithm

The **`clearOldestToolResults`** method implements a precise algorithm to maintain exactly `KEEP_TOOL_USES` recent tool results:

```typescript
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:

```typescript
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:

```typescript
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:

1. **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.

2. **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.

3. **Transparent Operation** – The `context_cleared` event 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`](https://github.com/virattt/dexter/blob/main/src/agent/scratchpad.ts)) that serves as the persistent source of truth
- The system estimates prompt tokens using `estimateTokens` in [`src/utils/tokens.ts`](https://github.com/virattt/dexter/blob/main/src/utils/tokens.ts) and monitors against a **100,000 token threshold**
- When limits are exceeded, **`Scratchpad.clearOldestToolResults`** removes the oldest tool results from memory while keeping the **5 most recent** (`KEEP_TOOL_USES`)
- The **`Agent.manageContextThreshold`** method in [`src/agent/agent.ts`](https://github.com/virattt/dexter/blob/main/src/agent/agent.ts) orchestrates this process, emitting `context_cleared` events 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`](https://github.com/virattt/dexter/blob/main/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`](https://github.com/virattt/dexter/blob/main/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.