Skip to main content

Continual learning layer for coding agents and software projects.

Project description

Lerim Logo

Your coding agents forget everything after each session.
Lerim remembers — across all of them.

PyPI version Python versions License Tests GitHub stars

Lerim network animation

lerim.dev · docs · pypi

The Problem

You spend 20 minutes explaining context to your coding agent. It writes great code. Next session? It's forgotten everything. Every decision, every pattern, every "we tried X and it didn't work" -- 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. Your project knowledge is scattered across isolated sessions with no shared memory.

This is agent context amnesia, and it's the biggest productivity drain in AI-assisted development.

The Solution

Lerim is a continual learning layer that gives coding agents persistent, shared memory across sessions and platforms. Use Claude Code, Cursor, Codex, and OpenCode on the same project — Lerim unifies their knowledge into one memory store that every agent can query.

  • Watches your agent sessions across Claude Code, Codex CLI, Cursor, and OpenCode
  • Extracts decisions and learnings automatically using LLM pipelines
  • Stores everything as plain markdown files in your repo (.lerim/)
  • Refines memories continuously -- merges duplicates, archives stale entries, applies time-based decay
  • Unifies knowledge across all your agents -- what Cursor learns, Claude Code 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. Memories get smarter over time, not stale.

Supported Agents

Agent Session Format Status
Claude Code JSONL traces Supported
Codex CLI JSONL traces Supported
Cursor SQLite to JSONL Supported
OpenCode SQLite to JSONL Supported

More agents coming soon -- PRs welcome!

How It Works

Lerim is file-first and primitive-first.

  • Primitive folders: decisions, learnings, summaries
  • Project memory first: <repo>/.lerim/
  • Global fallback memory: ~/.lerim/
  • Search default: files (no index required)
  • Orchestration runtime: pydantic-ai lead agent + read-only explorer subagent
  • Extraction/summarization: dspy.RLM role-configured models (default OpenRouter x-ai/grok-4.1-fast)
  • Graph source of truth: explicit id/slug references (and related when present)

This keeps memory readable by humans and easy for agents to traverse.

Lead flow:

  1. Extract candidates from transcript archive.
  2. Lead agent orchestrates with runtime tools and delegates a read-only explorer subagent.
  3. Lead runs deterministic decision policy for add|update|no-op.
  4. Lead writes memory only through boundary-enforced runtime write/edit tools.
  5. sync stays lightweight; maintain runs offline memory refinement (merge duplicates, archive low-value entries, consolidate related memories, apply time-based decay).

Sync path

Sync path

The sync path processes new agent sessions: reads transcript archives, extracts decision and learning candidates via DSPy, deduplicates against existing memories, and writes new primitives to the memory folder.

Maintain path

Maintain path

The maintain path runs offline refinement over stored memories: merges duplicates, archives low-value entries, consolidates related memories, and applies time-based decay to keep the memory store clean and relevant.

Quick start

1. Install

pip install lerim

Prerequisites: Python 3.10+, Docker

2. Set up

lerim init                     # interactive setup — detects your coding agents
lerim project add .            # add current project (repeat for other repos)

3. 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.

4. Teach your agent about Lerim

Install the Lerim skill so your agent knows how to query past context:

npx skills add lerim-dev/lerim-cli

This works with Claude Code, Codex, Cursor, Copilot, Cline, Windsurf, OpenCode, and other agents that support skills.

5. 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:

brew install deno              # required for extraction
lerim connect auto             # detect agent platforms
lerim daemon                   # run sync + maintain in terminal

Dashboard

The dashboard gives you a local UI for session analytics, memory browsing, and runtime status.

Lerim dashboard

Run it locally

# simple
lerim dashboard

# explicit host/port
python -m lerim dashboard --host 127.0.0.1 --port 8765

Then open http://127.0.0.1:8765.

Tabs

  • Overview: high-level metrics and charts (sessions, messages, tools, errors, tokens, activity by day/hour, model usage).
  • Runs: searchable session list (50/page) 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.

Notes

  • Top bar filters (Agent, Scope) update dashboard metrics and run listings.
  • Graph Explorer code is kept in the project but currently hidden in the UI.

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
lerim dashboard                             # show dashboard URL

# 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

Development

uv venv && source .venv/bin/activate
uv pip install -e .
lerim init                    # first-time config
lerim project add .           # track this repo
docker build -t lerim .       # build Docker image locally
lerim up                      # start the service
tests/run_tests.sh unit
tests/run_tests.sh all

Configuration

TOML-layered config (low to high priority):

  1. src/lerim/config/default.toml (shipped with package -- all defaults)
  2. ~/.lerim/config.toml (user global)
  3. <repo>/.lerim/config.toml (project overrides)
  4. LERIM_CONFIG env var path (explicit override, for CI/tests)

API keys come from environment variables only (ZAI_API_KEY, OPENROUTER_API_KEY, OPENAI_API_KEY, optional ANTHROPIC_API_KEY).

Default role model config (from src/lerim/config/default.toml):

  • lead: provider=openrouter, model=x-ai/grok-4.1-fast
  • explorer: provider=openrouter, model=x-ai/grok-4.1-fast
  • extract: provider=openrouter, model=x-ai/grok-4.1-fast, sub_model=x-ai/grok-4.1-fast
  • summarize: provider=openrouter, model=x-ai/grok-4.1-fast, sub_model=x-ai/grok-4.1-fast

Tracing (OpenTelemetry)

Lerim uses PydanticAI's built-in OpenTelemetry instrumentation for agent observability. Stderr logs are kept minimal; detailed traces (model calls, tool calls, tokens, timing) go through OTel spans instead.

One-time setup:

uv pip install logfire
logfire auth
logfire projects new

Enable tracing:

# env var (quick toggle)
LERIM_TRACING=1 lerim sync

# or in config
# .lerim/config.toml
[tracing]
enabled = true

View traces at https://logfire.pydantic.dev.

Config options ([tracing] in TOML):

Key Default Description
enabled false Enable tracing (or set LERIM_TRACING=1)
include_httpx false Capture raw HTTP request/response bodies
include_content true Include prompt/completion text in spans

Connecting coding agents

Lerim ingests session transcripts from your coding agents to extract decisions and learnings. The lerim connect command registers an agent platform so Lerim knows where to find its sessions.

Supported agents

Platform Session store Format
claude ~/.claude/projects/ JSONL files
codex ~/.codex/sessions/ JSONL files
cursor ~/Library/Application Support/Cursor/User/globalStorage/ (macOS) SQLite state.vscdb, exported to JSONL cache
opencode ~/.local/share/opencode/ SQLite opencode.db, exported to JSONL cache

How to connect

Auto-detect and connect all supported platforms at once:

lerim connect auto

Or connect a specific platform:

lerim connect claude
lerim connect codex
lerim connect cursor
lerim connect opencode

List currently connected platforms:

lerim connect list

Disconnect a platform:

lerim connect remove claude

Custom session path

If your agent stores sessions in a non-default location, use --path to point Lerim to the correct folder:

lerim connect claude --path /custom/path/to/claude/sessions
lerim connect cursor --path ~/my-cursor-data/globalStorage

The path is expanded (~ is resolved) and must exist on disk. This overrides the auto-detected default for that platform.

Search

Retrieval is file-first: scan markdown memory files directly. No index required.

Memory layout

Project scope:

<repo>/.lerim/
  config.toml              # project overrides
  memory/
    decisions/
    learnings/
    summaries/
      YYYYMMDD/
        HHMMSS/
          {slug}.md
    archived/
      decisions/
      learnings/
  meta/
    traces/
      sessions/
  workspace/
    sync-<YYYYMMDD-HHMMSS>-<shortid>/
      extract.json
      summary.json
      memory_actions.json
      agent.log
      subagents.log
      session.log
    maintain-<YYYYMMDD-HHMMSS>-<shortid>/
      maintain_actions.json
      agent.log
      subagents.log
  index/   # reserved

Global fallback scope follows the same layout under ~/.lerim/.

Primitive frontmatter (lean)

  • decision: id,title,created,updated,source,confidence,tags
  • learning: id,title,created,updated,source,confidence,tags,kind
  • summary: id,title,description,date,time,coding_agent,raw_trace_path,run_id,repo_name,created,source,tags

All metadata lives in frontmatter — no sidecars.

Reset policy

Memory reset is explicit and destructive.

  • lerim memory reset --scope project|global|both --yes
  • Deletes memory/, workspace/, and index/ under selected root(s), then recreates canonical folders.
  • --scope project: resets <repo>/.lerim/ only.
  • --scope global: resets ~/.lerim/ only (includes sessions DB).
  • --scope both (default): resets both.
  • Sessions DB lives in global index/, so --scope project alone does not reset sessions.

Fresh start:

lerim memory reset --yes        # wipe everything
lerim sync --max-sessions 5     # re-sync newest conversations

Contributing

Lerim is open to contributions. Whether it's a new agent adapter, a bug fix, or a documentation improvement, PRs are welcome.

Docs

Full documentation: docs.lerim.dev


If lerim saves you from re-explaining context to your agent, give it a ⭐
Star on GitHub

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

lerim-0.1.4.tar.gz (108.1 kB view details)

Uploaded Source

Built Distribution

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

lerim-0.1.4-py3-none-any.whl (124.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: lerim-0.1.4.tar.gz
  • Upload date:
  • Size: 108.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lerim-0.1.4.tar.gz
Algorithm Hash digest
SHA256 ac11087b2bc48476f63d26bf748d1fb056bf615c4d6ac6d7377e3fcf2d6f1902
MD5 bc6d530e6ca9f0061b1915fb3af3fccd
BLAKE2b-256 5f40584b9f58a8dce8dd1dbe4d7e824d1b4dd7c8a6524664bae58b06b216f267

See more details on using hashes here.

Provenance

The following attestation bundles were made for lerim-0.1.4.tar.gz:

Publisher: publish.yml on lerim-dev/lerim-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: lerim-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 124.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lerim-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 40f2b859638c109447d3399fe3c21a37f0d8829b27b1a06615cfb770bef14c31
MD5 2f57d9d08c702afe4f58cc51238c2269
BLAKE2b-256 35b4b2581d88f50add0e084e4b9681880ce38ab61ab9624fc6060a4dff8a04df

See more details on using hashes here.

Provenance

The following attestation bundles were made for lerim-0.1.4-py3-none-any.whl:

Publisher: publish.yml on lerim-dev/lerim-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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