Openclaw Session Management Blueprint

Persistent conversation storage with automatic disk budgeting, transcript rotation, and session lifecycle tracking across messaging channels

   
Feature openclaw-session-management
Category Data
Version 1.0.0
Tags persistence, conversation, storage, lifecycle, maintenance
YAML Source View on GitHub
JSON API openclaw-session-management.json

Actors

ID Name Type Description
agent AI Agent system  
gateway OpenClaw Gateway system  
user End User human  
storage_engine File Storage System system  

Fields

Name Type Required Label Description
session_id text Yes Session ID  
session_key text Yes Session Key  
agent_id text Yes Agent ID  
channel text No Channel  
account_id text No Account ID  
created_at datetime Yes Created At  
updated_at datetime Yes Updated At  
last_activity datetime No Last Activity  
idle_minutes number No Idle Timeout Minutes  
message_count number Yes Message Count  
transcript_bytes number Yes Transcript Size (bytes)  
model_override text No Model Override  
provider_override text No Provider Override  
thinking_level select No Thinking Level  
input_tokens number No Input Tokens  
output_tokens number No Output Tokens  
last_channel text No Last Delivery Channel  
last_to text No Last Delivery Target  
transcript_file text Yes Transcript File Path  

States

State field: undefined

Rules

  • session_lifecycle:
    • creation: Sessions created implicitly on first inbound message. sessionKey derived from: agent_id + channel + account_id + peer. Initial entry written with createdAt, updatedAt, sessionId, empty transcript.

    • updates: Every agent response updates session:

  • Append messages to transcript
  • Increment updatedAt
  • Update last_activity, token counts
  • Record model/provider overrides Atomic write with file lock (acquireSessionWriteLock). Max concurrent writers per session: 1. Lock timeout: 30 seconds.

    • archival_on_reset: When reset trigger matches:
  • Rotate transcript: .json → .reset..json
  • Start new transcript: .json = []
  • Retention: configurable (default 30 days)

    • idle_timeout: If idleMinutes > 0:
  • Check: now - last_activity > idleMinutes * 60000
  • If true: trigger session.reset (rotate, clear context)

  • transcript_management:
    • message_append: Messages appended as objects to transcript[]: { id: string; role: “user”|”assistant”; content: string; createdAt: ISO8601; tokens?: { input, output }; metadata?: { channel, threadId, … }; }

    • message_size_limits: Individual messages capped at 128KB. Oversized: replaced with “[chat.history omitted: message too large]”. Total history display limit: 12K chars.

    • transcript_rotation: Reset triggers: cron-based or manual /reset command. Old transcript archived to reset_archives. Storage: sessions.json (index) + per-session files.

  • disk_budget_enforcement:
    • budget_limits: maxDiskBytes: total allowed storage (default 5GB). highWaterBytes: cleanup threshold (default 80% of max). Enforcement: check on every write. Exceeds max: pruneStaleEntries() removes oldest archives (FIFO).

    • pruning_strategy: When totalBytes > maxDiskBytes: 1. Sort sessions by updatedAt (oldest first) 2. Delete oldest reset_archives per session 3. If still over budget: delete oldest sessions Entries capped at max (default 500).

    • cache_invalidation: After disk budget enforcement:

  • Clear memory cache
  • Reload from disk on next access

  • concurrent_access:
    • write_locking: File-based locking via acquireSessionWriteLock():
  • One writer per sessionKey at a time
  • Queued writes wait (timeout: 30s)
  • Automatic release on completion Release: on write completion or timeout.

    • read_caching: Recent entries cached in memory. Cache valid until session updated. On write: clear cache for that sessionKey.

    • deadlock_prevention: Lock timeout: 30 seconds. Stale lock detection: >1 minute assumed crashed. Automatic cleanup: remove stale lock, retry.

SLA

Scope Max Duration Escalation
write_latency 500ms  
disk_budget_check 1s  
concurrent_writers    

Outcomes

Message_appended (Priority: 1) | Transaction: atomic

Given:

  • session exists or will be created
  • session_key (input) exists
  • new message content provided

Then:

  • set_field target: message_count value: existing + 1
  • set_field target: updated_at value: now
  • set_field target: transcript_bytes value: serialized size
  • emit_event event: session.updated

Result: Message persisted, session metadata updated

Transcript_rotated (Priority: 2) | Transaction: atomic

Given:

  • reset trigger matched OR /reset command
  • session has messages

Then:

  • create_record target: reset_archives value: archive entry with path, counts, bytes
  • set_field target: message_count value: 0
  • transition_state field: lifecycle_state from: active to: reset
  • emit_event event: session.reset

Result: Old transcript archived, new session started

Disk_budget_enforced (Priority: 3) — Error: DISK_CLEANUP_FAILED | Transaction: atomic

Given:

  • total_bytes_used (computed) gt max_disk_bytes

Then:

  • call_service
  • delete_record target: oldest reset_archives (FIFO)
  • emit_event event: disk_budget.exceeded

Result: Old transcripts deleted, disk budget enforced

Idle_session_reset (Priority: 4)

Given:

  • idle_minutes (config) gt 0
  • elapsed_time (computed) gt idle_minutes minutes

Then:

  • transition_state field: lifecycle_state from: active to: idle
  • emit_event event: session.reset

Result: Session marked idle, awaiting reset

Errors

Code Status Message Retry
SESSION_NOT_FOUND 404 Session does not exist No
DISK_QUOTA_EXCEEDED 500 Insufficient storage for new message No
WRITE_LOCK_TIMEOUT 503 Session write lock timeout No
TRANSCRIPT_CORRUPTION 500 Session transcript corrupted No
INVALID_SESSION_KEY 400 Invalid session key format No

Events

Event Description Payload
session.created   session_id, session_key, agent_id, channel, created_at
session.updated   session_id, message_count, transcript_bytes, updated_at
session.reset   session_id, reason, previous_message_count
session.archived   session_id, archived_reset_count
session.deleted   session_id, reclaimed_bytes, reason
disk_budget.exceeded   total_bytes_used, max_bytes, sessions_pruned, bytes_freed
Feature Relationship Reason
openclaw-message-routing required Route resolution provides session_key
openclaw-gateway-authentication required User auth determines session isolation scope
openclaw-llm-provider required Agent writes messages and token counts to session
Extensions (framework-specific hints) ```yaml tech_stack: language: TypeScript storage: JSON5 file-based with atomic writes patterns: - File-based session isolation - Write-lock queuing - Disk budget LRU cleanup ```