| name | hermes-lcm-context-management |
| description | Lossless Context Management plugin for Hermes Agent with DAG-based compression and drill-down tools |
| triggers | ["install hermes lcm plugin","configure lossless context management","use hermes lcm tools","tune lcm compaction settings","debug hermes context compression","expand lcm summary nodes","manage hermes conversation history","configure lcm for long context models"] |
Hermes LCM Context Management
Skill by ara.so — Hermes Skills collection.
Overview
Hermes-LCM is a lossless context management plugin for Hermes Agent that prevents message loss during context compression. Instead of replacing old messages with flat summaries, it:
- Stores all messages in SQLite before compaction
- Compacts old context into a hierarchical summary DAG
- Provides agent tools to drill back into compacted material
- Maintains source lineage for filtered retrieval
- Externalizes large payloads to prevent bloat
Key difference from built-in compression: LCM makes recall part of the active context engine with drill-down tools (lcm_grep, lcm_expand, lcm_expand_query) rather than relying on auxiliary cross-session search.
Installation
Standard Installation
Clone into Hermes plugins directory:
git clone https://github.com/stephenschoettler/hermes-lcm \
~/.hermes/plugins/hermes-lcm
git clone https://github.com/stephenschoettler/hermes-lcm \
~/.hermes/profiles/myprofile/plugins/hermes-lcm
Symlink Installation
From an existing checkout:
cd hermes-lcm
./scripts/install.sh
HERMES_PROFILE=myprofile ./scripts/install.sh
Configuration
Enable in Hermes config (YAML):
plugins:
enabled:
- hermes-lcm
context:
engine: lcm
compression:
enabled: true
Restart Hermes after configuration changes.
Verification
hermes plugins
Expected output includes:
- Plugin list shows
hermes-lcm
- Context engine shows
lcm
- Tools include:
lcm_grep, lcm_describe, lcm_expand, lcm_expand_query, lcm_status, lcm_doctor, lcm_load_session
Core Concepts
Message Storage
LCM stores messages in SQLite before compaction happens:
~/.hermes/profiles/<profile>/lcm.db # Default path
Summary DAG
Old messages are compacted into hierarchical summary nodes:
Raw messages → Leaf summaries → Branch summaries → Root
Each node tracks:
- Descendant message count
- Source lineage (for filtering)
- Depth in DAG
- Token counts
Bounded Recovery
Agent can page back into compacted material without flooding active context:
lcm_grep: Search raw messages and summaries
lcm_describe: Get summary metadata
lcm_expand: Retrieve child summaries or raw messages
lcm_expand_query: Synthesize answer from DAG material
Environment Configuration
Core Settings
export LCM_CONTEXT_THRESHOLD=0.75
export LCM_FRESH_TAIL_COUNT=64
export LCM_LEAF_CHUNK_TOKENS=20000
export LCM_DYNAMIC_LEAF_CHUNK_ENABLED=false
export LCM_DYNAMIC_LEAF_CHUNK_MAX=40000
Session Management
export LCM_NEW_SESSION_RETAIN_DEPTH=2
export LCM_IGNORE_SESSION_PATTERNS="test-*,debug-*"
export LCM_STATELESS_SESSION_PATTERNS="readonly-*"
export LCM_IGNORE_MESSAGE_PATTERNS="^SYSTEM:,^\[INTERNAL\]"
Large Payload Handling
export LCM_LARGE_OUTPUT_EXTERNALIZATION_ENABLED=true
export LCM_LARGE_OUTPUT_EXTERNALIZATION_THRESHOLD_CHARS=12000
export LCM_LARGE_OUTPUT_TRANSCRIPT_GC_ENABLED=false
Model Overrides
export LCM_SUMMARY_MODEL=claude-3-5-sonnet-20241022
export LCM_EXPANSION_MODEL=gpt-4-turbo
export LCM_EXPANSION_CONTEXT_TOKENS=32000
export LCM_SUMMARY_TIMEOUT_MS=60000
export LCM_EXPANSION_TIMEOUT_MS=120000
Advanced
export LCM_DATABASE_PATH=/custom/path/lcm.db
export LCM_ENABLE_SLASH_COMMAND=true
export LCM_DOCTOR_CLEAN_APPLY_ENABLED=false
export LCM_CRITICAL_BUDGET_PRESSURE_RATIO=0.0
Tuning for Long Context Models
For large context windows, tune threshold to avoid excessive prompt costs:
Calculation:
compaction_trigger = effective_context_window * LCM_CONTEXT_THRESHOLD
Examples:
| Context Window | Desired Trigger | Threshold | Use Case |
|---|
| 128K | 96K | 0.75 | Standard |
| 200K | 140K | 0.70 | Balanced |
| 400K | 240K | 0.60 | Long context |
| 1M | 250K | 0.25 | Cost-optimized |
| 1M | 400K | 0.40 | Balanced large |
| 1M | 600K | 0.60 | Max raw context |
Example configuration for 1M token model:
export LCM_CONTEXT_THRESHOLD=0.30
export LCM_CONTEXT_THRESHOLD=0.40
export LCM_CONTEXT_THRESHOLD=0.60
Agent Tools Usage
lcm_status
Get current LCM state:
{
"tool": "lcm_status",
"params": {}
}
Returns:
- Session ID
- Threshold tokens
- Current prompt tokens
- Raw message count
- Summary DAG structure
- Storage path
- Git commit (if source checkout)
lcm_grep
Search messages and summaries:
{
"tool": "lcm_grep",
"params": {
"pattern": "database schema",
"search_raw": true,
"search_summaries": false,
"max_results": 10
}
}
{
"tool": "lcm_grep",
"params": {
"pattern": "migration",
"search_raw": false,
"search_summaries": true,
"max_results": 5
}
}
{
"tool": "lcm_grep",
"params": {
"pattern": "error",
"source_filter": "src/database.py",
"search_raw": true
}
}
lcm_describe
Get summary node metadata:
{
"tool": "lcm_describe",
"params": {
"summary_id": "s_abc123"
}
}
Returns:
- Summary text
- Descendant count
- Token counts
- Depth in DAG
- Source lineage
lcm_expand
Retrieve child summaries or raw messages:
{
"tool": "lcm_expand",
"params": {
"summary_id": "s_abc123",
"max_children": 5,
"max_raw": 10
}
}
{
"tool": "lcm_expand",
"params": {
"summary_id": "s_abc123",
"source_filter": "config.py",
"max_raw": 20
}
}
lcm_expand_query
Synthesize answer from DAG material using auxiliary LLM:
{
"tool": "lcm_expand_query",
"params": {
"query": "What database migrations were discussed earlier?",
"summary_id": "s_abc123",
"max_raw": 50
}
}
This tool:
- Retrieves relevant raw messages and summaries
- Calls auxiliary LLM with query + material
- Returns synthesized answer
- Uses
LCM_EXPANSION_MODEL and LCM_EXPANSION_CONTEXT_TOKENS
lcm_load_session
Load historical session into current context:
{
"tool": "lcm_load_session",
"params": {
"session_id": "previous-session-abc123"
}
}
lcm_doctor
Diagnose and repair LCM state:
{
"tool": "lcm_doctor",
"params": {
"action": "check"
}
}
{
"tool": "lcm_doctor",
"params": {
"action": "clean_preview"
}
}
{
"tool": "lcm_doctor",
"params": {
"action": "clean_apply"
}
}
Slash Commands (Optional)
Enable with LCM_ENABLE_SLASH_COMMAND=true:
/lcm status
/lcm grep pattern search_raw=true
/lcm describe summary_id=s_abc123
/lcm expand summary_id=s_abc123 max_raw=20
/lcm query What was discussed about the API?
/lcm doctor check
/lcm doctor clean_preview
Common Patterns
Initial Setup After Installation
hermes plugins
hermes chat "Hello"
hermes chat "Can you run lcm_status?"
Recovering Lost Context
{
"tool": "lcm_grep",
"params": {
"pattern": "API authentication",
"search_raw": true,
"search_summaries": true,
"max_results": 10
}
}
{
"tool": "lcm_expand",
"params": {
"summary_id": "s_found_in_grep",
"max_raw": 20
}
}
{
"tool": "lcm_expand_query",
"params": {
"query": "What authentication method did we decide to use?",
"summary_id": "s_found_in_grep"
}
}
Debugging Compaction Issues
export LCM_ENABLE_SLASH_COMMAND=true
hermes chat "/lcm status"
hermes chat "/lcm doctor check"
hermes chat "/lcm doctor clean_preview"
Session Isolation
export LCM_IGNORE_SESSION_PATTERNS="test-*,temp-*,debug-*"
export LCM_STATELESS_SESSION_PATTERNS="readonly-*,audit-*"
hermes restart
Large Payload Management
export LCM_LARGE_OUTPUT_EXTERNALIZATION_ENABLED=true
export LCM_LARGE_OUTPUT_EXTERNALIZATION_THRESHOLD_CHARS=12000
export LCM_LARGE_OUTPUT_TRANSCRIPT_GC_ENABLED=true
hermes restart
External payloads stored in:
~/.hermes/profiles/<profile>/lcm_externalized/
Troubleshooting
Plugin Shows as Not Found
Symptom: hermes plugins shows lcm (not found) but tools exist
Solution: If tools are available, LCM is loaded. This is a host discovery mismatch, not a plugin failure.
hermes chat "Run lcm_status"
Status Shows Unbound After Restart
Symptom: /lcm status shows session_id: (unbound) or threshold_tokens: (uninitialized)
Solution: Send one normal message first:
hermes chat "Hello"
hermes chat "/lcm status"
Compaction Not Triggering
Check threshold calculation:
hermes chat "What's your context window?"
export LCM_CONTEXT_THRESHOLD=0.75
Verify compression is enabled:
compression:
enabled: true
Missing Regex Message Filtering
Symptom: Warning about disabled message-level regex filtering
Solution: Install regex package:
pip install regex
LCM uses regex with timeouts to prevent unbounded pattern matching. Without it, LCM_IGNORE_MESSAGE_PATTERNS is disabled.
High Token Costs
Tune threshold for your model:
export LCM_CONTEXT_THRESHOLD=0.25
export LCM_CONTEXT_THRESHOLD=0.40
Database Corruption
export LCM_ENABLE_SLASH_COMMAND=true
hermes chat "/lcm doctor check"
hermes chat "/lcm doctor clean_preview"
export LCM_DOCTOR_CLEAN_APPLY_ENABLED=true
hermes chat "/lcm doctor clean_apply"
Update Plugin
cd ~/.hermes/plugins/hermes-lcm
git pull --ff-only
cd /path/to/hermes-lcm
./scripts/update.sh
hermes restart
Integration Examples
Python Code Using LCM Tools
async def recover_context(topic: str, max_depth: int = 2):
"""Search LCM and expand results to recover context."""
grep_result = await hermes.call_tool("lcm_grep", {
"pattern": topic,
"search_raw": True,
"search_summaries": True,
"max_results": 5
})
if not grep_result.get("matches"):
return f"No context found for: {topic}"
first_match = grep_result["matches"][0]
if "summary_id" in first_match:
expand_result = await hermes.call_tool("lcm_expand", {
"summary_id": first_match["summary_id"],
"max_raw": 10
})
return expand_result
return first_match
async def query_history(question: str, scope_summary_id: str = None):
"""Ask a question about compacted history."""
params = {: question, : }
scope_summary_id:
params[] = scope_summary_id
result = hermes.call_tool(, params)
result.get(, )
Custom Configuration Template
#!/bin/bash
export LCM_CONTEXT_THRESHOLD=0.75
export LCM_FRESH_TAIL_COUNT=64
export LCM_LEAF_CHUNK_TOKENS=20000
export LCM_DYNAMIC_LEAF_CHUNK_ENABLED=true
export LCM_DYNAMIC_LEAF_CHUNK_MAX=40000
export LCM_NEW_SESSION_RETAIN_DEPTH=2
export LCM_IGNORE_SESSION_PATTERNS="test-*,temp-*"
export LCM_STATELESS_SESSION_PATTERNS="readonly-*"
export LCM_LARGE_OUTPUT_EXTERNALIZATION_ENABLED=true
export LCM_LARGE_OUTPUT_EXTERNALIZATION_THRESHOLD_CHARS=12000
export LCM_LARGE_OUTPUT_TRANSCRIPT_GC_ENABLED=false
export LCM_ENABLE_SLASH_COMMAND=true
export LCM_DOCTOR_CLEAN_APPLY_ENABLED=false
hermes start
Best Practices
- Start with defaults: Only tune after observing actual compaction behavior
- Monitor token usage: Use
lcm_status to track prompt size and compaction triggers
- Tune threshold for your model: Don't use 0.75 blindly on 1M token models
- Enable slash commands for debugging: Set
LCM_ENABLE_SLASH_COMMAND=true during setup
- Use source filters: When expanding, filter by relevant files/tools to reduce noise
- External payloads for large outputs: Enable externalization if tool results include large JSON/media
- Regular doctor checks: Run
/lcm doctor check periodically to catch issues early
- Session patterns for isolation: Use ignore/stateless patterns to exclude test/debug sessions
Resources