Skip to main content

Framework-agnostic Lossless Context Management SDK for LLM agents

Project description

OpenLCM — Lossless Context Management for LLM Agents

Unbounded memory. Bounded context.

OpenLCM is a framework-agnostic Python SDK that gives your AI agents a permanent, lossless memory — without ever hitting the context limit. Every message is persisted verbatim in SQLite and compressed into a hierarchical DAG of summaries. Nothing is ever lost. Any past moment is recoverable.

pip install openlcm

The problem

LLMs have a hard token limit. As conversations grow, agents either crash or replace old turns with a flat, irreversible summary. Details fall out permanently — decisions, constraints, file paths, tool results.

How LCM works

OpenLCM maintains two layers:

  1. Immutable message store — every message written verbatim to SQLite with a stable store_id. FTS5-indexed. Never modified.
  2. Summary DAG — older messages are compressed into D0 leaf nodes → D1 session arcs → D2 durable history. Each node points back to its source messages for exact recovery.

The model always sees: system + highest DAG node + recent D0 nodes + fresh tail (last N raw messages).


Quick start

from openlcm import LCMEngine

engine = LCMEngine(model="anthropic/claude-haiku-4-5-20251001")
engine.bind_session("my-session", context_length=200_000)

# Call before every LLM turn — compresses only when needed
messages = await engine.compress(messages)

Pass any LiteLLM model string: openai/gpt-4o, gemini/gemini-2.0-flash, azure/gpt-4o, bedrock/..., ollama/llama3, etc.


Framework adapters

All adapters are included — one install, no extras needed.

LangGraph

from openlcm.adapters.langgraph import LCMCheckpointer

graph = StateGraph(MyState).compile(
    checkpointer=LCMCheckpointer(llm=my_llm)
)

Google ADK

from openlcm.adapters.google_adk import LCMSessionService, lcm_compress_callback

agent = LlmAgent(
    name="assistant",
    model="gemini-2.0-flash",
    tools=[...],
    before_model_callback=lcm_compress_callback(engine),
)
runner = Runner(agent=agent, session_service=LCMSessionService(engine))

AutoGen

from openlcm.adapters.autogen import LCMContext

agent = AssistantAgent(
    "assistant",
    model_client=client,
    model_context=LCMContext(llm=client),
)

CrewAI

from openlcm.adapters.crewai import LCMStorage

crew = Crew(
    memory=True,
    long_term_memory=LongTermMemory(storage=LCMStorage(engine))
)

OpenAI / Groq / Mistral / Ollama

from openlcm.adapters.openai import OpenAIMessages

lcm = OpenAIMessages.to_lcm(messages)
if engine.should_compress_preflight(lcm):
    lcm      = await engine.compress(lcm)
    messages = OpenAIMessages.from_lcm(lcm)

Anthropic

from openlcm.adapters.anthropic import AnthropicMessages

lcm = AnthropicMessages.to_lcm(messages, system=system_prompt)
lcm = await engine.compress(lcm)
system_out, anthropic_msgs = AnthropicMessages.from_lcm(lcm)

LlamaIndex / Haystack / Gemini

from openlcm.adapters.llamaindex import LlamaIndexMessages
from openlcm.adapters.haystack   import HaystackMessages
from openlcm.adapters.gemini     import GeminiMessages

All follow the same to_lcm() / from_lcm() interface.


Configuration

from openlcm.core.config import LCMConfig

config = LCMConfig.from_env()
config.context_threshold  = 0.75   # compress at 75% of context window
config.fresh_tail_count   = 64     # protect last 64 messages from compression
config.leaf_chunk_tokens  = 20_000 # tokens per D0 leaf summary
config.condensation_fanin = 4      # D0 nodes before a D1 arc is created

engine = LCMEngine(model="...", config=config)
Env var Default Description
LCM_CONTEXT_THRESHOLD 0.75 Compression trigger as fraction of context window
LCM_FRESH_TAIL_COUNT 64 Messages protected from compression at tail
LCM_LEAF_CHUNK_TOKENS 20000 Tokens per D0 summary chunk
LCM_CONDENSATION_FANIN 4 D0 nodes required before D1 arc is created

Live dashboard

import threading
from openlcm.viz.server import create_app, serve as viz_serve

threading.Thread(
    target=lambda: viz_serve(create_app(engine), port=7842, open_browser=True),
    daemon=True
).start()

Or from the CLI:

openlcm viz          # opens http://localhost:7842
openlcm grep "query" # full-text search across all sessions
openlcm status       # session stats

The dashboard shows token pressure, DAG graph, SQLite message store, and a live event log — all updating in real time.


Guarantees

  • Lossless — every message persisted with stable store_id. Recoverable even after 100 compactions.
  • Deterministic — summarization always terminates. L1 → L2 → L3 escalation with circuit breaker.
  • Zero-cost — compression fires only when the threshold is exceeded. Short conversations pay zero overhead.

License

MIT — see LICENSE.

Built on the LCM paper by Ehrlich & Blackman (Voltropy, 2026).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openlcm-0.1.0.tar.gz (144.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

openlcm-0.1.0-py3-none-any.whl (172.1 kB view details)

Uploaded Python 3

File details

Details for the file openlcm-0.1.0.tar.gz.

File metadata

  • Download URL: openlcm-0.1.0.tar.gz
  • Upload date:
  • Size: 144.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for openlcm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fc6815fe74aefa557b03be596beac603e50462334f4e5201e1c75740b43d3645
MD5 ed3e988a33886835b242d2c6e2af4e14
BLAKE2b-256 0603dadb0549204523a7c0cef260c47802f5d99654ca996c4cf142cff6179c95

See more details on using hashes here.

File details

Details for the file openlcm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: openlcm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 172.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for openlcm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5599ba18b04a4f584e1e192b8f887859576388d1a727837aa2ad8078ddaee2b
MD5 475de5ff84701353e366f86aadf213fe
BLAKE2b-256 d5f4f495e435721b7bfcf645aaf2146745d00bc75fe6f07a7e0a96ac06a230b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page