Session Management

GoClaw manages conversation context to stay within LLM token limits while preserving important information.

Overview

┌─────────────────────────────────────────────────────────────┐
│                    Context Window (200k)                     │
├─────────────────────────────────────────────────────────────┤
│ System Prompt │ Compaction Summary │ Recent Messages        │
│    (~10k)     │     (~2k)          │    (remaining)         │
└─────────────────────────────────────────────────────────────┘

As conversation grows, GoClaw:

  1. Monitors context usage (token count vs max)
  2. Checkpoints (optional) — Takes rolling snapshots at thresholds
  3. Compacts (required) — Truncates old messages when nearly full

Checkpoints

Checkpoints are rolling snapshots of conversation state. They do NOT delete messages — they just record the current state.

What’s in a Checkpoint?

Each checkpoint captures:

  • Summary — LLM-generated summary of the conversation so far
  • Token count — How many tokens were used when the checkpoint was created
  • Topics — Topics discussed in the conversation
  • Key decisions — Decisions made during the conversation
  • Open questions — Outstanding questions that haven’t been resolved

When Are Checkpoints Created?

Checkpoints are generated based on configuration:

{
  "session": {
    "summarization": {
      "checkpoint": {
        "enabled": true,
        "thresholds": [25, 50, 75],
        "turnThreshold": 15,
        "minTokensForGen": 10000
      }
    }
  }
}
TriggerDescription
thresholdsGenerate at 25%, 50%, 75% of context
turnThresholdGenerate every N user messages
minTokensForGenDon’t checkpoint if below this token count

Checkpoint Generation

Each checkpoint triggers an async LLM call using the summarization purpose chain:

[25% context] → Summarization LLM → Checkpoint saved
[50% context] → Summarization LLM → Checkpoint saved  
[75% context] → Summarization LLM → Checkpoint saved

Why Use Checkpoints?

  1. Recovery points — If something goes wrong, we have summaries
  2. Compaction optimization — Can skip LLM call at compaction time
  3. Structured data — Topics, decisions, questions are useful metadata
  4. Async/non-blocking — Don’t slow down the main agent loop

Disabling Checkpoints

If you want to minimize LLM calls:

{
  "session": {
    "summarization": {
      "checkpoint": {
        "enabled": false
      }
    }
  }
}

Compaction

Compaction truncates old messages when context approaches the limit. This is required to continue the conversation.

When Does Compaction Trigger?

Compaction triggers based on token count OR message count:

{
  "session": {
    "summarization": {
      "compaction": {
        "reserveTokens": 4000,
        "maxMessages": 500
      }
    }
  }
}
TriggerDescription
Token-basedtotalTokens >= maxTokens - reserveTokens
Message-basedmessageCount >= maxMessages (if > 0)

With reserveTokens: 30000 and maxTokens: 200000:

Compaction at: 200000 - 30000 = 170000 tokens (~85%)

What Happens During Compaction?

  1. Generate summary of messages being removed
  2. Truncate old messages (keep configurable percentage)
  3. Write compaction record to database
  4. Inject summary into future prompts

Compaction Configuration

{
  "session": {
    "summarization": {
      "compaction": {
        "reserveTokens": 4000,
        "maxMessages": 500,
        "preferCheckpoint": true,
        "keepPercent": 50,
        "minMessages": 20
      }
    }
  }
}
FieldDefaultDescription
reserveTokens4000Tokens to reserve before triggering
maxMessages500Max messages before compaction (0 = disabled)
preferCheckpointtrueUse existing checkpoint for summary if available
keepPercent50Percent of messages to keep after compaction
minMessages20Minimum messages to always keep

Summary Generation (with fallback)

GoClaw uses the LLM registry’s summarization purpose chain with automatic fallback:

1. Check for recent checkpoint (fast path)
   └─ If checkpoint covers ≥50% of context → Use its summary
   
2. Try summarization providers (in order)
   └─ Primary model → Success → Done
   └─ Fallback models → Success → Done
   
3. Emergency truncation (if all fail)
   └─ Write stub summary
   └─ Keep more messages (higher keepPercent)
   └─ Mark for background retry

Fallback Configuration

{
  "session": {
    "summarization": {
      "failureThreshold": 3,
      "resetMinutes": 30,
      "retryIntervalSeconds": 60
    }
  }
}
SettingDefaultDescription
failureThreshold3After N consecutive failures, try next provider
resetMinutes30Reset failure count after N minutes
retryIntervalSeconds60Background retry interval for pending summaries

Background Retry

If compaction had to use emergency truncation (no summary), a background goroutine retries:

  1. Checks every retryIntervalSeconds for pending retries
  2. Loads original messages from SQLite
  3. Tries summarization providers with fallback
  4. Updates compaction record with better summary

OpenClaw Session Inheritance

GoClaw can inherit conversation history from OpenClaw sessions, enabling side-by-side operation.

Configuration

{
  "session": {
    "inherit": true,
    "inheritPath": "~/.openclaw/agents/main/sessions",
    "inheritFrom": "main"
  }
}
FieldDescription
inheritEnable OpenClaw session inheritance
inheritPathPath to OpenClaw sessions directory
inheritFromSession key to inherit from

Session Watcher

When inheritance is enabled, a SessionWatcher monitors the OpenClaw session file for changes:

  • Uses fsnotify for real-time change detection
  • Reads new records as they’re written
  • Injects them into the GoClaw session
  • Enables two-way conversation flow

This allows:

  • Running GoClaw and OpenClaw simultaneously
  • Seeing messages from both in a unified timeline
  • Seamless migration between systems

Context Pressure Warnings

GoClaw shows context usage in the system prompt and warns the agent when approaching limits.

System Prompt Status

The agent always sees a context status section in the system prompt:

## Context Status

[Context: 85k/200k tokens (42%)]

At higher usage levels, warnings are added:

UsageWarning
50%+“You may want to note important decisions to memory files.”
75%+“Consider writing key decisions to memory/YYYY-MM-DD.md.”
90%+“CRITICAL: Write important context to memory files NOW before compaction.”

Memory Flush Prompts

You can also inject user messages at specific thresholds to prompt the agent more directly:

{
  "session": {
    "memoryFlush": {
      "enabled": true,
      "thresholds": [
        {
          "percent": 90,
          "prompt": "Context at 90%. Save important decisions to memory/YYYY-MM-DD.md before compaction.",
          "injectAs": "user",
          "oncePerCycle": true
        }
      ]
    }
  }
}
FieldDescription
enabledEnable memory flush prompting
thresholdsArray of threshold configurations
percentContext usage percent to trigger
promptMessage to inject
injectAs"user" or "system"
oncePerCycleOnly trigger once per compaction cycle

Use YYYY-MM-DD in the prompt — it’s automatically replaced with today’s date.


Storage

In-Memory vs Database

LocationContentsAfter Compaction
In-memoryRecent messages onlyTruncated
SQLiteFull message historyPreserved

This means:

  • Agent only sees recent messages (context window)
  • Full history is always available for auditing/retry
  • Background retry can regenerate summaries from SQLite

Database Location

Sessions are stored in ~/.goclaw/sessions.db:

-- Messages table
CREATE TABLE messages (
    id TEXT PRIMARY KEY,
    session_key TEXT,
    timestamp DATETIME,
    role TEXT,           -- user, assistant, tool_use, tool_result
    content TEXT,
    tool_name TEXT,
    tool_input BLOB,
    tool_result TEXT,
    tool_is_error BOOLEAN
);

-- Compactions table  
CREATE TABLE compactions (
    id TEXT PRIMARY KEY,
    session_key TEXT,
    timestamp DATETIME,
    summary TEXT,
    first_kept_entry_id TEXT,
    tokens_before INTEGER,
    needs_summary_retry BOOLEAN
);

-- Checkpoints table
CREATE TABLE checkpoints (
    id TEXT PRIMARY KEY,
    session_key TEXT,
    timestamp DATETIME,
    summary TEXT,
    tokens_at_checkpoint INTEGER,
    topics TEXT,
    key_decisions TEXT,
    open_questions TEXT
);

Full Configuration Example

{
  "session": {
    "store": "sqlite",
    "storePath": "~/.goclaw/sessions.db",
    
    "inherit": false,
    "inheritPath": "",
    "inheritFrom": "",
    
    "summarization": {
      "ollama": {
        "url": "http://localhost:11434",
        "model": "qwen2.5:7b",
        "timeoutSeconds": 600,
        "contextTokens": 131072
      },
      "fallbackModel": "claude-3-haiku-20240307",
      "failureThreshold": 3,
      "resetMinutes": 30,
      "retryIntervalSeconds": 60,
      
      "checkpoint": {
        "enabled": true,
        "thresholds": [25, 50, 75],
        "turnThreshold": 15,
        "minTokensForGen": 10000
      },
      
      "compaction": {
        "reserveTokens": 4000,
        "maxMessages": 500,
        "preferCheckpoint": true,
        "keepPercent": 50,
        "minMessages": 20
      }
    },
    
    "memoryFlush": {
      "enabled": true,
      "thresholds": [
        {"percent": 90, "prompt": "Context at 90%. Save key context to memory/YYYY-MM-DD.md.", "injectAs": "user", "oncePerCycle": true}
      ]
    }
  }
}

Flow Diagram

User Message
     │
     ▼
┌─────────────────┐
│ Add to Session  │
└────────┬────────┘
         │
         ▼
┌─────────────────┐     Yes    ┌─────────────────┐
│ Need Compaction?├───────────►│ Run Compaction  │
└────────┬────────┘            └────────┬────────┘
         │ No                           │
         ▼                              ▼
┌─────────────────┐            ┌─────────────────┐
│ Call LLM        │            │ Truncate + Save │
└────────┬────────┘            └────────┬────────┘
         │                              │
         ▼                              │
┌─────────────────┐                     │
│ Check Checkpoint│◄────────────────────┘
│ Trigger?        │
└────────┬────────┘
         │ Yes (async)
         ▼
┌─────────────────┐
│ Generate        │
│ Checkpoint      │
└─────────────────┘

See Also