How Cache-Aware Context Maintenance Prunes Stale Tool Output in DeepSeek-Reasonix

Reasonix eliminates automatic pruning of stale tool output, replacing destructive marker insertion with summary checkpoints that preserve full history in durable cache while keeping model-visible tokens compact.

Cache-aware context maintenance in Reasonix represents a fundamental architectural shift in how long-running sessions handle accumulated tool results. Instead of mutating the conversation history to save tokens, the system separates the canonical transcript—an immutable, fully-preserved record—from the model-visible context projection sent to the LLM. This split enables efficient "cold-resume" and "warm-resume" behavior without data loss, as implemented in the esengine/DeepSeek-Reasonix repository.

Why Automatic Pruning Was Removed

The previous architecture in internal/agent/prune.go automatically inserted prune or snip markers into the model-visible projection when tool results exceeded configurable size thresholds. This approach had significant drawbacks: pruned data could be lost permanently, placeholder markers polluted the model's context window, and the system required complex state tracking for partially-rewritten histories.

The new cache-aware design removes automatic prune/snip projections entirely. The public APIs PruneStaleToolResults and SnipStaleToolResults now return PruneStats with Mode populated but perform no mutation:

// internal/agent/prune.go
// Automatic prune/snip projections are gone; the public APIs are no‑ops.
func (a *Agent) PruneStaleToolResults() (PruneStats, error) {
    return PruneStats{Mode: toolResultPrune}, nil
}

func (a *Agent) SnipStaleToolResults() (PruneStats, error) {
    return PruneStats{Mode: toolResultSnip}, nil
}

This no-op implementation preserves backward compatibility for callers while signaling the architectural transition through documentation comments.

The Compact-Ratio Threshold for Summary Checkpoints

With automatic pruning eliminated, Reasonix now relies on a single compact-ratio threshold (compact_ratio, default 0.85) to trigger context maintenance. The behavior differs substantially from the old system:

  • Below threshold: No rewriting occurs; the model receives the full context projection.
  • At or above threshold: A single summary checkpoint is generated, replacing multiple tool results with one synthetic summary message.

The original tool results remain intact in the canonical transcript stored in ArchiveDir. Only the model-visible projection is compacted, and crucially, no placeholder markers like [elided tool result — …] are emitted.

How Context Maintenance Events Report Pruning

The ContextMaintenanceEvent defined in internal/event/event.go (lines 57-70) still signals context maintenance activity, but the Action field now reflects the new behavior:

Action Meaning Typical Scenario
"summary" A checkpoint summary was installed Compact-ratio threshold crossed
"noop" No maintenance performed Threshold not met, or call was no-op
"blocked" Maintenance was prevented Cache validity check failed
"prune" (Legacy) Destructive pruning occurred Only on explicit forced prune

When a prune would have occurred under the old system, the event now reports Action: "noop" with SavedTokens: 0, making the behavior transparent to telemetry pipelines.

Snapshot Logic and Cache Validation

internal/agent/context_status.go builds ContextMaintenanceSnapshot to expose the current maintenance state. The snapshot interprets the last maintenance receipt:

func (a *Agent) ContextMaintenanceSnapshot() ContextMaintenanceSnapshot {
    // ... builds projection validity check ...
    receipt := a.lastMaintenanceReceipt()
    if receipt.Status == "applied" && (receipt.Action == "prune" || receipt.Action == "summary") {
        snapshot.LastSavedTokens = receipt.SavedTokens
    }
    // ...
}

The projectionValid boolean ensures the cached projection matches both the current canonical transcript and cache key. This validation prevents stale projections from being reused after resume operations.

Verifying No Prune Markers in Tests

The test file internal/agent/context_maintenance_issue7935_test.go explicitly asserts the new behavior:

func TestCacheAwareNoAutomaticPrune(t *testing.T) {
    a := setupAgentWithCompactRatio(0.85)
    // ... run turns until threshold crossed ...
    
    if got := countToolResultsWithPrefix(a.modelVisibleMessages(), prunedMarker); got != 0 {
        t.Fatalf("automatic prune markers installed = %d, want 0", got)
    }
    
    // Verify exactly one summary checkpoint exists
    summaries := countSummaryCheckpoints(a.modelVisibleMessages())
    if summaries != 1 {
        t.Fatalf("summary checkpoints = %d, want 1", summaries)
    }
}

This test codifies the core guarantee: cache-aware context maintenance never emits automatic prune markers.

Working with Context Maintenance APIs

Checking Current Maintenance State

snap := agent.ContextMaintenanceSnapshot()
fmt.Printf("Projection version: %d, valid: %v\n", snap.ProjectionVersion, snap.ProjectionValid)

if snap.LastReceipt != nil {
    fmt.Printf("Last action: %s, saved: %d tokens\n",
        snap.LastReceipt.Action, snap.LastSavedTokens)
}

Handling Maintenance Events in Custom Sinks

type maintenanceLogger struct{ event.Sink }

func (l *maintenanceLogger) Emit(e event.Event) {
    if e.Kind == event.ContextMaintenanceEvent && e.Maintenance != nil {
        m := e.Maintenance
        if m.Action == "summary" {
            log.Printf("Installed summary checkpoint, saved %d tokens", m.SavedTokens)
        } else if m.Action == "noop" && m.CacheBreak {
            log.Printf("Cache break detected, projection invalidated")
        }
    }
    l.Sink.Emit(e) // Forward to underlying sink
}

Detecting Legacy Prune Markers for Migration

func hasLegacyPruneMarkers(messages []provider.Message) bool {
    const legacyMarker = "[elided tool result — "
    for _, m := range messages {
        if m.Role == provider.RoleTool && strings.HasPrefix(m.Content, legacyMarker) {
            return true
        }
    }
    return false
}

Key Files in the Reasonix Repository

Summary

  • Automatic pruning is eliminated — PruneStaleToolResults and SnipStaleToolResults are no-ops
  • Compact-ratio threshold (0.85 default) triggers single summary checkpoints, not destructive edits
  • Canonical transcript remains immutable in durable cache; only model-visible projection compacts
  • No placeholder markers are ever emitted in the new architecture
  • Context maintenance events report "summary", "noop", or "blocked" — rarely "prune"

Frequently Asked Questions

What happens to existing code that calls PruneStaleToolResults?

Existing code continues to compile and run without errors. The function returns PruneStats{Mode: toolResultPrune} with zeroed savings fields, making the no-op behavior detectable if callers inspect results. Migration involves removing explicit prune calls and relying on automatic summary checkpoint generation.

How does Reasonix handle extremely long sessions without pruning?

The compact-ratio threshold ensures summaries install automatically when context growth would inefficiently consume tokens. Each summary checkpoint collapses preceding tool results into a single message. For pathological cases, the durable cache supports pagination and the ContextMaintenanceSnapshot exposes ProjectionVersion to detect when resynchronization is needed.

Can I force destructive pruning for compatibility with external systems?

The public APIs no longer support forced pruning through standard methods. The architecture intentionally prevents destructive history mutation to preserve reproducibility and resume capabilities. Custom projection layers can implement filtering, but the canonical transcript in ArchiveDir always retains complete tool output.

How do I verify my agent is using cache-aware maintenance?

Check ContextMaintenanceSnapshot.LastReceipt.Action after running a turn that exceeds your configured compact_ratio. It should read "summary" rather than "prune". Additionally, inspect modelVisibleMessages() for absence of the [elided tool result — prefix using strings.HasPrefix checks.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →