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.4.tar.gz (201.3 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.4-py3-none-any.whl (233.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: openlcm-0.1.4.tar.gz
  • Upload date:
  • Size: 201.3 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.4.tar.gz
Algorithm Hash digest
SHA256 b22820caeb9fe0f3d7d1916f190d70d6dd2a8fbf16ef339bfcb06f573fb9eea3
MD5 bae6f5ab62d3ff022498966a5e152425
BLAKE2b-256 ba2fcc48403f2e5b711bcca104d5507cc4cbc1ad8380b15c424cec121aa39ae4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: openlcm-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 233.4 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 56cb425d707d09d5e97f1146e3432d1c7cb434d0aad0ddd37722555da60514e5
MD5 c83d22c6521316bfa0a7530d655cbbd3
BLAKE2b-256 a440811f4e24db57a399c70f0f10d775f54ce895d5844fad8687a6e82cd15581

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