Continual learning layer for coding agents and software projects.
Project description
The context graph layer for coding agents.
Lerim extracts the decisions, the reasoning, and the why -- so no agent starts blind.
The Problem
AI agents decide fast -- but the reasoning is lost after every session. Every decision, every "we tried X and it didn't work," every architectural choice -- gone.
And if you use multiple agents -- Claude Code at the terminal, Cursor in the IDE, Codex for reviews -- none of them know what the others learned. The why behind your project is scattered across isolated sessions, lost between agents.
Everyone stores memory. Nobody extracts the reasoning.
The Solution
Lerim is the context graph layer for coding agents -- it watches sessions, extracts the reasoning behind decisions, and builds a shared context graph across agents, projects, and teams.
- Watches your agent sessions across all supported coding agents
- Extracts the reasoning behind decisions -- the why, not just the what -- using LLM pipelines (DSPy + PydanticAI)
- Stores everything as plain markdown files in your repo (
.lerim/) - Refines knowledge continuously -- merges duplicates, archives stale entries, applies time-based decay
- Connects learnings into a context graph -- related decisions and patterns are linked
- Unifies knowledge across all your agents -- what one agent learns, every other can recall
- Answers questions about past context:
lerim ask "why did we choose Postgres?"
No proprietary format. No database lock-in. Just markdown files that both humans and agents can read. Knowledge compounds over time, not stale.
Supported Agents
Lerim works with any coding agent that produces session traces. Current adapters:
| Agent | Session Format | Status |
|---|---|---|
| Claude Code | JSONL traces | Supported |
| Codex CLI | JSONL traces | Supported |
| Cursor | SQLite to JSONL | Supported |
| OpenCode | SQLite to JSONL | Supported |
Adding a new agent adapter is straightforward -- PRs welcome! See src/lerim/adapters/ for examples.
How It Works
Lerim is file-first and primitive-first.
- Primitive folders:
decisions,learnings,summaries - Project memory:
<repo>/.lerim/ - Global fallback:
~/.lerim/ - Search: file-based (no index required)
- Orchestration:
pydantic-ailead agent + read-only explorer subagent - Extraction/summarization:
dspy.ChainOfThoughtwith transcript windowing
Sync path
The sync path processes new agent sessions: reads transcript archives, extracts decision and learning candidates via DSPy, deduplicates against existing knowledge, and writes new entries to the project's knowledge store.
Maintain path
The maintain path runs offline refinement over stored knowledge: merges duplicates, archives low-value entries, consolidates related learnings, and applies time-based decay to keep the context graph clean and relevant.
Quick start
1. Install
pip install lerim
Prerequisites: Python 3.10+, Docker (optional)
2. Set up
lerim init # interactive setup — detects your coding agents
lerim project add . # add current project (repeat for other repos)
3. Set API keys
Set keys for the providers you configure (defaults: MiniMax primary, Z.AI fallback):
export MINIMAX_API_KEY="..." # if using MiniMax (default)
export ZAI_API_KEY="..." # if using Z.AI (default fallback)
You only need keys for providers referenced in your [roles.*] config. See model roles.
4. Start Lerim
lerim up
That's it. Lerim is now running as a Docker service — syncing sessions, extracting
decisions and learnings, refining memories, and serving a dashboard at http://localhost:8765.
5. Teach your agent about Lerim
Install the Lerim skill so your agent knows how to query past context:
lerim skill install
This copies skill files (SKILL.md, cli-reference.md) into your agent's skill directory.
6. Get the most out of Lerim
At the start of a session, tell your agent:
Check lerim for any relevant memories about [topic you're working on].
Your agent will run lerim ask or lerim memory search to pull in past decisions and learnings before it starts working.
Running without Docker
If you prefer not to use Docker, Lerim works directly:
lerim connect auto # detect agent platforms
lerim serve # run HTTP server + daemon loop
Local models (Ollama)
Lerim works with local models via Ollama. Set provider = "ollama" in your role config and Lerim will automatically load models into GPU/RAM before each sync/maintain cycle and unload them after to free memory (auto_unload = true in [providers]).
ollama serve # start Ollama (runs outside Docker)
For Docker deployments, set ollama = "http://host.docker.internal:11434" in [providers] so the container can reach the host Ollama instance. See model roles for full configuration.
Dashboard
The dashboard gives you a local UI for session analytics, knowledge browsing, and runtime status.
Tabs
- Overview: high-level metrics and charts (sessions, messages, tools, errors, tokens, activity by day/hour, model usage).
- Runs: searchable session list with status and metadata; open any run in a full-screen chat viewer.
- Memories: library + editor for memory records (filter, inspect, edit title/body/kind/confidence/tags).
- Pipeline: sync/maintain status, extraction queue state, and latest extraction report.
- Settings: dashboard-editable config for server, model roles, and tracing; saves to
~/.lerim/config.toml.
CLI reference
Full command reference: skills/lerim/cli-reference.md
# Setup (host-only)
lerim init # interactive setup wizard
lerim project add ~/codes/my-app # register a project
lerim project list # list registered projects
# Docker service
lerim up # start Lerim container
lerim down # stop it
lerim logs --follow # tail logs
# Alternative: run directly without Docker
lerim serve # start HTTP server + daemon loop
# Service commands (require lerim up or lerim serve running)
lerim ask "Why did we choose this?" # query memories
lerim sync # one-shot: sync sessions + extract
lerim maintain # one-shot: merge, archive, decay
lerim status # runtime state
# Local commands (run on host, no server needed)
lerim memory search "auth pattern" # keyword search
lerim memory list # list all memories
lerim memory add --title "..." --body "..." # manual memory
lerim connect auto # detect and connect platforms
lerim skill install # install skill into agent directories
Configuration
TOML-layered config (low to high priority):
src/lerim/config/default.toml(shipped with package -- all defaults)~/.lerim/config.toml(user global)<repo>/.lerim/config.toml(project overrides)LERIM_CONFIGenv var path (explicit override, for CI/tests)
API keys come from environment variables only. Set keys for the providers you use:
| Variable | Provider | Default role |
|---|---|---|
MINIMAX_API_KEY |
MiniMax | Primary (all roles) |
ZAI_API_KEY |
Z.AI | Fallback |
OPENROUTER_API_KEY |
OpenRouter | Optional alternative |
OPENAI_API_KEY |
OpenAI | Optional alternative |
ANTHROPIC_API_KEY |
Anthropic | Optional alternative |
Default model config (from src/lerim/config/default.toml):
- All roles:
provider=minimax,model=MiniMax-M2.5 - Fallback:
zai:glm-4.7(lead/explorer),zai:glm-4.5-air(extract/summarize)
Development
uv venv && source .venv/bin/activate
uv pip install -e '.[test]'
lerim init # first-time config
lerim project add . # track this repo
lerim up # start the service
tests/run_tests.sh unit
tests/run_tests.sh all
Tracing (OpenTelemetry)
Lerim uses PydanticAI's built-in OpenTelemetry instrumentation for agent observability.
# Enable tracing
LERIM_TRACING=1 lerim sync
# or in config
# .lerim/config.toml
[tracing]
enabled = true
View traces at https://logfire.pydantic.dev.
Memory layout
Project scope:
<repo>/.lerim/
config.toml # project overrides
memory/
decisions/
learnings/
summaries/
YYYYMMDD/
HHMMSS/
{slug}.md
archived/
decisions/
learnings/
workspace/
sync-<YYYYMMDD-HHMMSS>-<shortid>/
maintain-<YYYYMMDD-HHMMSS>-<shortid>/
index/ # reserved
Global fallback scope follows the same layout under ~/.lerim/.
Contributing
Lerim is open to contributions. Whether it's a new agent adapter, a bug fix, or a documentation improvement, PRs are welcome.
- Read the Contributing Guide
- Browse open issues
- Agent adapter PRs are especially appreciated -- see
src/lerim/adapters/for examples
Docs
Full documentation: docs.lerim.dev
If your agents keep re-debating the same decisions, give Lerim a ⭐
Star on GitHub
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lerim-0.1.67.tar.gz.
File metadata
- Download URL: lerim-0.1.67.tar.gz
- Upload date:
- Size: 121.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b69a49bed7ceef1415ff05d19697c53d922ee846fbd3111240aaf554e99c5545
|
|
| MD5 |
25eeacbd710a368aac0960d7037aa17e
|
|
| BLAKE2b-256 |
ac515c01d41184c51e50f45965657aa50f58823427106d214edb3ec5477a40b0
|
Provenance
The following attestation bundles were made for lerim-0.1.67.tar.gz:
Publisher:
publish.yml on lerim-dev/lerim-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lerim-0.1.67.tar.gz -
Subject digest:
b69a49bed7ceef1415ff05d19697c53d922ee846fbd3111240aaf554e99c5545 - Sigstore transparency entry: 1124676875
- Sigstore integration time:
-
Permalink:
lerim-dev/lerim-cli@3936999ab0bd6542137b65a14958a3247f362f8f -
Branch / Tag:
refs/tags/v0.1.67 - Owner: https://github.com/lerim-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3936999ab0bd6542137b65a14958a3247f362f8f -
Trigger Event:
push
-
Statement type:
File details
Details for the file lerim-0.1.67-py3-none-any.whl.
File metadata
- Download URL: lerim-0.1.67-py3-none-any.whl
- Upload date:
- Size: 140.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a38125ec6c355293a1b510460901640fad649b9512e45874a2b94347cc901abb
|
|
| MD5 |
37be47122ac20e889c774a263d58a7b2
|
|
| BLAKE2b-256 |
634036a7e1d8a7e61734708dcede53e00c2dfe5f96f7002434219d6f4d7f5111
|
Provenance
The following attestation bundles were made for lerim-0.1.67-py3-none-any.whl:
Publisher:
publish.yml on lerim-dev/lerim-cli
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lerim-0.1.67-py3-none-any.whl -
Subject digest:
a38125ec6c355293a1b510460901640fad649b9512e45874a2b94347cc901abb - Sigstore transparency entry: 1124676993
- Sigstore integration time:
-
Permalink:
lerim-dev/lerim-cli@3936999ab0bd6542137b65a14958a3247f362f8f -
Branch / Tag:
refs/tags/v0.1.67 - Owner: https://github.com/lerim-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3936999ab0bd6542137b65a14958a3247f362f8f -
Trigger Event:
push
-
Statement type: