loop-memory 0.4.0__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {loop_memory-0.4.0 → loop_memory-0.4.2}/PKG-INFO +182 -43
- {loop_memory-0.4.0 → loop_memory-0.4.2}/README.md +181 -42
- loop_memory-0.4.2/loop_memory/cli/main.py +184 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/static/index.html +1 -1
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/PKG-INFO +182 -43
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/SOURCES.txt +2 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/pyproject.toml +1 -1
- loop_memory-0.4.2/tests/test_cli_version.py +130 -0
- loop_memory-0.4.2/tests/test_repo_framing.py +287 -0
- loop_memory-0.4.0/loop_memory/cli/main.py +0 -115
- {loop_memory-0.4.0 → loop_memory-0.4.2}/LICENSE +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/backends/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/backends/embedding.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/backends/sentence_embedder.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/backends/vector_store.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/_common.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/cognitive.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/diag.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/graph.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/hooks.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/read.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/serve.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/cli/commands/write.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/engine/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/engine/loop.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/engine/reflect.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/examples/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/examples/demo.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/export/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/export/memory_md.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/graph/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/graph/build.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/graph/extract.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/ingest/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/ingest/loader.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/ingest/pipeline.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/cognitive.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/compact.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/consolidate.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/contradiction.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/evolution.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/graph.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/llm_compact_pass.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/llm_consolidate.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/jobs/scheduler.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/llm/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/llm/base.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/llm/openai_adapter.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/llm/providers.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/mcp/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/memory/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/memory/types.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/privacy/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/privacy/private.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/privacy/redact.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/py.typed +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/sdk.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/sdk_extensions.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/security/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/security/secrets.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/app.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/handlers.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/_shared.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/admin.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/cognitive.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/export.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/graph.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/insights.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/memories.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/sessions.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/system.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/routes/wiki.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/static/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/serve/watcher.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/storage/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/storage/retrieval.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/storage/sqlite_store.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/wiki/__init__.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/wiki/backfill.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/wiki/classifier.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/wiki/prompts.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory/wiki/scope.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/dependency_links.txt +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/entry_points.txt +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/requires.txt +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/loop_memory.egg-info/top_level.txt +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/setup.cfg +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_admin_ingest_route.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_agent_memory_api.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_agent_memory_sdk.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_auth_token_rotate.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_cli_v7.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_contradictions.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_evolution.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_evolution_quality.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_expanduser.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_export_ask.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_graph.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_ingest.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_llm_consolidator.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_llm_fingerprint_not_persisted.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_llm_providers.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_llm_test_endpoint.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_loop.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_mcp.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_memories_pagination.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_openclaw_loader.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_reflection.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_score_api.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_scoring_v2.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_secrets.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_serve_app.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_serve_handlers.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_session_order.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_store.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_summarization.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_universal_memory.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_vector_store.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_watcher.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_wiki_classifier.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_wiki_export_escape.py +0 -0
- {loop_memory-0.4.0 → loop_memory-0.4.2}/tests/test_wiki_prompts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loop-memory
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: A general-purpose, local memory system for every AI agent you run. Loop Memory auto-captures conversations from Codex / Claude / Hermes / OpenClaw, scores them by importance × recency × usage × feedback, distils them into a curated wiki, and serves everything from a single web UI.
|
|
5
5
|
Author: Loop Memory contributors <loop-memory@users.noreply.github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -48,11 +48,14 @@ Dynamic: license-file
|
|
|
48
48
|
|
|
49
49
|
# Loop Memory
|
|
50
50
|
|
|
51
|
-
> **A general-purpose memory system for every AI agent you run
|
|
51
|
+
> **A general-purpose, local-first memory system that closes the agent loop for every AI agent you run.**
|
|
52
52
|
>
|
|
53
|
-
>
|
|
54
|
-
>
|
|
55
|
-
>
|
|
53
|
+
> Point Loop Memory at any agent's transcript directory and it
|
|
54
|
+
> quietly catches every conversation, scores it, distils the long
|
|
55
|
+
> tail into a tight wiki of stable knowledge, and re-injects the
|
|
56
|
+
> relevant pieces into the next session. Out of the box: hooks for
|
|
57
|
+
> Codex, Claude, Hermes, and OpenClaw; an SDK + generic watcher
|
|
58
|
+
> CLI cover everything else.
|
|
56
59
|
|
|
57
60
|
[](https://github.com/smartfind/loop-memory/actions)
|
|
58
61
|
[](https://pypi.org/project/loop-memory/)
|
|
@@ -63,14 +66,51 @@ Dynamic: license-file
|
|
|
63
66
|
|
|
64
67
|
---
|
|
65
68
|
|
|
69
|
+
> **What's new in 0.4.1** — CLI dispatch hardened so every subcommand's
|
|
70
|
+
> `--help` / `--version` exits 0 cleanly (no more `ValueError: unknown
|
|
71
|
+
> source: '--help'` on a zero-deps install). Added a static
|
|
72
|
+
> `COMMAND_HELP` table guarded by 10 new regression cases in
|
|
73
|
+
> `tests/test_cli_version.py`, plus GitHub `About` / README lead now
|
|
74
|
+
> surface for "agent loop" searches.
|
|
75
|
+
> [Full changelog →](CHANGELOG.md)
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Table of contents
|
|
80
|
+
|
|
81
|
+
- [What it does](#what-it-does)
|
|
82
|
+
- [Install](#install)
|
|
83
|
+
- [Quickstart](#quickstart)
|
|
84
|
+
- [Why Loop Memory vs. every other agent-memory project](#why-loop-memory-vs-every-other-agent-memory-project)
|
|
85
|
+
- [Architecture & docs](#architecture--docs)
|
|
86
|
+
- [After install: 30-second setup](#after-install-30-second-setup)
|
|
87
|
+
- [Auto-capture (after every conversation)](#auto-capture-after-every-conversation)
|
|
88
|
+
- [Dashboard + Evolution consolidator](#dashboard--evolution-consolidator-看板--进化式蒸馏)
|
|
89
|
+
- [Auto-feedback into every LLM client](#auto-feedback-into-every-llm-client-反哺)
|
|
90
|
+
- [Web UI](#web-ui)
|
|
91
|
+
- [Programmatic use](#programmatic-use)
|
|
92
|
+
- [The four-stage loop](#the-four-stage-loop)
|
|
93
|
+
- [Project layout](#project-layout)
|
|
94
|
+
- [Security & auth token](#security--auth-token)
|
|
95
|
+
- [Wiki scope auto-classification](#wiki-scope-auto-classification)
|
|
96
|
+
- [FAQ & troubleshooting](#faq--troubleshooting)
|
|
97
|
+
- [Run the tests](#run-the-tests)
|
|
98
|
+
- [Using distilled knowledge in your clients](#using-distilled-knowledge-in-your-clients)
|
|
99
|
+
- [License](#license)
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
66
103
|
## What it does
|
|
67
104
|
|
|
68
105
|
**Loop Memory** gives every agent you use a single, persistent brain
|
|
69
|
-
that outlives any one conversation.
|
|
70
|
-
Code, Hermes, OpenClaw / clawx,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
106
|
+
that outlives any one conversation. Any agent that drops transcripts
|
|
107
|
+
on disk — Codex CLI, Claude Code, Hermes, OpenClaw / clawx, Aider,
|
|
108
|
+
Cursor, … — works; the shipped hooks cover the popular ones and a
|
|
109
|
+
generic watcher CLI (`loop-memory hook --source <name> --watch <dir>`)
|
|
110
|
+
accepts anything else. Loop Memory quietly catches every fragment,
|
|
111
|
+
scores it by *importance × recency × usage × feedback*, distils the
|
|
112
|
+
long tail into a curated wiki, and re-injects the relevant pieces
|
|
113
|
+
into the next session.
|
|
74
114
|
|
|
75
115
|
```mermaid
|
|
76
116
|
flowchart LR
|
|
@@ -102,6 +142,21 @@ via MCP / hooks]
|
|
|
102
142
|
|
|
103
143
|
*One loop, many agents, one evolving wiki.*
|
|
104
144
|
|
|
145
|
+
**Supported agents:**
|
|
146
|
+
|
|
147
|
+
| Agent | Capture path | Hook shipped? | Notes |
|
|
148
|
+
| -------------- | ----------------------------------- | :-----------: | ----- |
|
|
149
|
+
| Codex CLI | `~/.codex/sessions/*.json` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
150
|
+
| Claude Code | `~/.claude/**/*.jsonl` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
151
|
+
| Hermes | `~/.hermes/**/*.jsonl` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
152
|
+
| OpenClaw/clawx | `~/.openclaw/agents/main/sessions` + `workspace/memory/*.md` | ✅ | watcher only (no MCP yet); `openclaw-setup` enables launchd |
|
|
153
|
+
| Anything else | any on-disk transcript dir | — | use `loop-memory hook --source <name> --watch <dir>` (see [docs/auto-capture.md](docs/auto-capture.md)) |
|
|
154
|
+
|
|
155
|
+
The shipped hooks are the four popular agents we maintain in-tree.
|
|
156
|
+
The generic watcher CLI is the supported extension point for every
|
|
157
|
+
other agent — Aider, Cursor, Copilot, Cline, Continue, Goose, your
|
|
158
|
+
own home-grown CLI, anything that drops JSON/JSONL on disk.
|
|
159
|
+
|
|
105
160
|
---
|
|
106
161
|
|
|
107
162
|
## Install
|
|
@@ -142,7 +197,7 @@ following — every other project we looked at lacks at least one:
|
|
|
142
197
|
|
|
143
198
|
| Capability | **Loop Memory** | Mem0 v3 | Hindsight | OpenViking | A-MEM |
|
|
144
199
|
| --- | --- | --- | --- | --- | --- |
|
|
145
|
-
| Multi-source capture (Codex / Claude / Hermes / OpenClaw
|
|
200
|
+
| Multi-source capture (any agent with on-disk transcripts) | ✅ generic watcher CLI; hooks shipped for Codex / Claude / Hermes / OpenClaw | ⚠ requires plugin per client | ⚠ hosted only | ⚠ SDK + companion app | ❌ |
|
|
146
201
|
| Local-first SQLite (zero external services) | ✅ | ❌ Postgres + Qdrant | ❌ Postgres + Qdrant | ⚠ file-system + cloud | ⚠ ChromaDB |
|
|
147
202
|
| Hybrid recall: BM25 + semantic + entity (RRF) | ✅ | ✅ | ✅ | ✅ | ⚠ entity-only |
|
|
148
203
|
| Temporal reasoning in retrieval (boost / suppress by date intent) | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
@@ -223,6 +278,7 @@ flavors:
|
|
|
223
278
|
| Claude Code | `loop-memory hook --source claude --watch ~/.claude` |
|
|
224
279
|
| Hermes | `loop-memory hook --source hermes --watch ~/.hermes` |
|
|
225
280
|
| OpenClaw (clawx) | `loop-memory hook --source openclaw --watch ~/.openclaw/agents/main/sessions` — also ingests `workspace/memory/*.md` daily logs |
|
|
281
|
+
| Anything else (Aider, Cursor, Copilot, Cline, Continue, Goose, …) | `loop-memory hook --source <name> --watch <path/to/transcripts>` — see [docs/auto-capture.md](docs/auto-capture.md) for loader requirements |
|
|
226
282
|
|
|
227
283
|
Three of these in a `tmux` session, or persisted via launchd, keeps
|
|
228
284
|
your memory store fresh without any clicks. Run `loop-memory
|
|
@@ -329,6 +385,34 @@ User signals close the loop:
|
|
|
329
385
|
- Every `recall()` / search bumps `recall_count` on the returned
|
|
330
386
|
rows so the next Stage-1 ranks them higher.
|
|
331
387
|
|
|
388
|
+
### Cognitive sleep (v7)
|
|
389
|
+
|
|
390
|
+
`loop-memory cognitive-sleep [--apply]` runs an **auditable cleanup
|
|
391
|
+
pass** over the store:
|
|
392
|
+
|
|
393
|
+
- Surfaces contradictions between memories (e.g. "user prefers X"
|
|
394
|
+
vs. "user prefers Y") so you can resolve them in one click rather
|
|
395
|
+
than chasing them across sessions.
|
|
396
|
+
- Drops items that are below the configurable floor (`min_score`) and
|
|
397
|
+
older than the floor age.
|
|
398
|
+
- Merges near-duplicate memories (cosine ≥ 0.95 with `MergeableBy` rules).
|
|
399
|
+
- Emits a full audit row per action — visible in the Dashboard →
|
|
400
|
+
**Audit** tab and reachable via the MCP `audit` tool, so every
|
|
401
|
+
byte the consolidator ever touches is traceable.
|
|
402
|
+
|
|
403
|
+
Dry-run by default; pass `--apply` to commit.
|
|
404
|
+
|
|
405
|
+
### Knowledge graph
|
|
406
|
+
|
|
407
|
+
`loop-memory graph-rebuild` extracts entities from every distilled
|
|
408
|
+
wiki page and every long-term memory, then materialises a typed
|
|
409
|
+
relation graph:
|
|
410
|
+
|
|
411
|
+
- Visible as the **Knowledge graph** globe tab in the web UI.
|
|
412
|
+
- Queryable via the MCP `subgraph` and `remember_edge` tools.
|
|
413
|
+
- Re-built by the Evolution Consolidator's Stage-5 evolution memo, so
|
|
414
|
+
the graph evolves alongside the wiki.
|
|
415
|
+
|
|
332
416
|
## Auto-feedback into every LLM client (反哺)
|
|
333
417
|
|
|
334
418
|
Distilled knowledge is only useful if your LLM tools can actually
|
|
@@ -385,21 +469,6 @@ configuration, scheduling, language switching, and light/dark themes.
|
|
|
385
469
|
|
|
386
470
|
---
|
|
387
471
|
|
|
388
|
-
## Time-weighted scoring
|
|
389
|
-
|
|
390
|
-
Every memory carries a `score ∈ [0, 1]` recomputed from:
|
|
391
|
-
|
|
392
|
-
```
|
|
393
|
-
score = 0.35 · importance + 0.65 · recency
|
|
394
|
-
recency = ½ ^ (age / half_life)
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
`half_life` defaults to 30 days, configurable via
|
|
398
|
-
`consolidate(half_life_days=...)`. The UI shows the score as a
|
|
399
|
-
percentage; use `?min_score=0.85` to see only high-relevance memories.
|
|
400
|
-
|
|
401
|
-
---
|
|
402
|
-
|
|
403
472
|
## Programmatic use
|
|
404
473
|
|
|
405
474
|
```python
|
|
@@ -453,26 +522,35 @@ Even though v0.2 is built around local storage, the original
|
|
|
453
522
|
```
|
|
454
523
|
loop_memory/
|
|
455
524
|
loop_memory/
|
|
525
|
+
cli/main.py # CLI entrypoint + COMMAND_HELP table + `--version`
|
|
526
|
+
ingest/ # Codex / Claude / Hermes / OpenClaw / generic loaders
|
|
527
|
+
wiki/ # distillation, classifier, scope auto-promotion
|
|
528
|
+
graph/ # entity extraction + knowledge-graph build
|
|
529
|
+
jobs/ # consolidate / evolve / cognitive-sleep / scheduler / contradiction / graph
|
|
530
|
+
llm/ # provider protocol + OpenAI / Anthropic / Ollama / rule-based
|
|
531
|
+
backends/ # embedding (hashing / sentence-transformers) + vector store (memory / chroma)
|
|
532
|
+
storage/ # SQLite-backed MemoryStore + migrations
|
|
533
|
+
privacy/ # <private> stripping + regex redaction
|
|
534
|
+
security/ # Keychain / 0600-file secrets wrapper
|
|
535
|
+
mcp/ # stdio JSON-RPC MCP server
|
|
536
|
+
serve/ # FastAPI app, watcher, web UI (Timeline / Dashboard / Wiki / Graph)
|
|
537
|
+
export/ # markdown + v7 portable bundle export/import
|
|
538
|
+
sdk.py # four-verb stable API: remember / recall / forget / feedback
|
|
539
|
+
sdk_extensions.py # optional high-level helpers (graph edges, wiki pages)
|
|
540
|
+
engine/loop.py # Retrieve → Generate → Reflect → Store loop
|
|
456
541
|
memory/types.py # MemoryItem + 4 tiers
|
|
457
|
-
backends/embedding.py # BaseEmbedder, HashingEmbedder, IdentityEmbedder
|
|
458
|
-
backends/vector_store.py # VectorStore protocol + InMemory / Chroma
|
|
459
|
-
backends/sentence_embedder.py # optional sentence-transformers
|
|
460
|
-
llm/base.py # LLMClient protocol + EchoLLM + helpers
|
|
461
|
-
llm/openai_adapter.py # optional OpenAI client
|
|
462
|
-
engine/loop.py # the Retrieve → Generate → Reflect → Store loop
|
|
463
|
-
engine/reflect.py # reflection & summarization passes
|
|
464
|
-
storage/sqlite_store.py # persistent SQLite-backed MemoryStore
|
|
465
|
-
ingest/loader.py # CodexLoader, ClaudeLoader, HermesLoader
|
|
466
|
-
ingest/pipeline.py # session → MemoryStore
|
|
467
|
-
jobs/consolidate.py # background rescore + GC + dedupe
|
|
468
|
-
serve/app.py # FastAPI app for the local web UI
|
|
469
|
-
serve/static/index.html # the page
|
|
470
|
-
serve/watcher.py # filesystem watcher for auto-capture
|
|
471
|
-
cli/main.py # CLI entrypoint (chat / stats / ingest / consolidate / serve / hook)
|
|
472
542
|
examples/demo.py # runnable, zero-API-key demo
|
|
473
543
|
py.typed
|
|
474
|
-
tests/ #
|
|
475
|
-
docs/
|
|
544
|
+
tests/ # 475 unit tests across memory / SDK / serve / CLI / scripts
|
|
545
|
+
docs/
|
|
546
|
+
auto-capture.md # launchd / systemd / cron recipes
|
|
547
|
+
architecture.md # layered view + 5-stage evolution pipeline
|
|
548
|
+
api.md # HTTP API reference
|
|
549
|
+
agent-memory-api.md # four-verb SDK / HTTP / MCP contract
|
|
550
|
+
universal-agent-memory.md # v7 graph memory + cognitive sleep + bundles
|
|
551
|
+
providers.md # LLM provider reference
|
|
552
|
+
settings.md # settings table + secrets file
|
|
553
|
+
weekly-research-automation.md # how the project auto-evolves from upstream research
|
|
476
554
|
```
|
|
477
555
|
|
|
478
556
|
---
|
|
@@ -554,6 +632,67 @@ classifier is local and makes no model or network request on a wiki write.
|
|
|
554
632
|
|
|
555
633
|
---
|
|
556
634
|
|
|
635
|
+
## FAQ & troubleshooting
|
|
636
|
+
|
|
637
|
+
**Q: `pip install loop-memory` succeeds but `loop-memory serve` says `ModuleNotFoundError: No module named 'fastapi'`.**
|
|
638
|
+
A: `fastapi` is the optional `[serve]` extra. Install it explicitly:
|
|
639
|
+
`pip install 'loop-memory[serve]'` (or `'loop-memory[all]'` for everything).
|
|
640
|
+
|
|
641
|
+
**Q: My `~/.codex/sessions/` is empty / nothing appears in the UI.**
|
|
642
|
+
A: Run `loop-memory doctor` — it prints per-source paths, last-seen
|
|
643
|
+
mtime, and whether the watcher is running. Then check
|
|
644
|
+
`loop-memory hook --source codex --watch ~/.codex/sessions` is alive
|
|
645
|
+
in another shell (or via launchd — see [docs/auto-capture.md](docs/auto-capture.md)).
|
|
646
|
+
|
|
647
|
+
**Q: Distillation never finishes / wiki stays empty.**
|
|
648
|
+
A: You need an LLM provider configured. Open the web UI → ⚙ Model,
|
|
649
|
+
pick a provider, paste an API key, and click **Save**. Then either
|
|
650
|
+
wait for the scheduler or hit **� Run now**. Zero-deps installs ship
|
|
651
|
+
with a rule-based provider as a placeholder so the loop never blocks
|
|
652
|
+
on a missing key.
|
|
653
|
+
|
|
654
|
+
**Q: `loop-memory install-hooks` warns that the token file already exists.**
|
|
655
|
+
A: That's expected — it's idempotent. To force a rewrite, delete the
|
|
656
|
+
target files (`~/.codex/config.toml`, `~/.claude/mcp.json`,
|
|
657
|
+
`~/.hermes/mcp.json`) and re-run. The tool also refuses to touch
|
|
658
|
+
non-loop-memory config keys.
|
|
659
|
+
|
|
660
|
+
**Q: How big can the SQLite store get before I should worry?**
|
|
661
|
+
A: Practical floor: 100k memories / 10k wiki pages stays under ~80 MB
|
|
662
|
+
and `recall()` returns in <100 ms. The Evolution Consolidator is
|
|
663
|
+
designed to keep the wiki tight (~hundreds of pages) rather than let
|
|
664
|
+
it grow unbounded. Run `loop-memory cognitive-sleep --apply` weekly
|
|
665
|
+
to drop the long tail.
|
|
666
|
+
|
|
667
|
+
**Q: Can I sync the store across machines?**
|
|
668
|
+
A: The SQLite file is git-friendly and copy-friendly. The `MEMORY.md`
|
|
669
|
+
+ graph + memories + metadata **bundle** (`loop-memory export
|
|
670
|
+
<dir>`) is a portable v7 artefact you can commit, share, or
|
|
671
|
+
back-up. There is no first-class sync daemon — by design — so the
|
|
672
|
+
local-first guarantee is never violated.
|
|
673
|
+
|
|
674
|
+
**Q: Is there a hosted / cloud version?**
|
|
675
|
+
A: No. Loop Memory is MIT-licensed and 100% local; the SQLite file
|
|
676
|
+
lives under `~/.loop_memory/`. The web UI is bound to loopback by
|
|
677
|
+
default; binding to `0.0.0.0` prints a security warning and requires
|
|
678
|
+
an auth token.
|
|
679
|
+
|
|
680
|
+
**Q: Where do secrets / API keys live?**
|
|
681
|
+
A: Two places. Provider keys you set in the **⚙ Model** UI are
|
|
682
|
+
written to `~/.loop_memory/secrets.json` (mode 0600) via the
|
|
683
|
+
`loop_memory.security.secrets` wrapper, which prefers the macOS
|
|
684
|
+
Keychain on Darwin and falls back to the encrypted file on Linux.
|
|
685
|
+
The auth token used by the web UI is hashed in the SQLite settings
|
|
686
|
+
table — never stored in plaintext.
|
|
687
|
+
|
|
688
|
+
**Q: I see "no version" / "package not found" on the PyPI badge.**
|
|
689
|
+
A: shields.io pulls from a separate data source that lags PyPI by a
|
|
690
|
+
few minutes after a new release. Re-publish the badge warmer step
|
|
691
|
+
in `.github/workflows/publish.yml` to force a refresh, or wait ~30
|
|
692
|
+
minutes for shields.io to catch up.
|
|
693
|
+
|
|
694
|
+
---
|
|
695
|
+
|
|
557
696
|
## Run the tests
|
|
558
697
|
|
|
559
698
|
```bash
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
# Loop Memory
|
|
6
6
|
|
|
7
|
-
> **A general-purpose memory system for every AI agent you run
|
|
7
|
+
> **A general-purpose, local-first memory system that closes the agent loop for every AI agent you run.**
|
|
8
8
|
>
|
|
9
|
-
>
|
|
10
|
-
>
|
|
11
|
-
>
|
|
9
|
+
> Point Loop Memory at any agent's transcript directory and it
|
|
10
|
+
> quietly catches every conversation, scores it, distils the long
|
|
11
|
+
> tail into a tight wiki of stable knowledge, and re-injects the
|
|
12
|
+
> relevant pieces into the next session. Out of the box: hooks for
|
|
13
|
+
> Codex, Claude, Hermes, and OpenClaw; an SDK + generic watcher
|
|
14
|
+
> CLI cover everything else.
|
|
12
15
|
|
|
13
16
|
[](https://github.com/smartfind/loop-memory/actions)
|
|
14
17
|
[](https://pypi.org/project/loop-memory/)
|
|
@@ -19,14 +22,51 @@
|
|
|
19
22
|
|
|
20
23
|
---
|
|
21
24
|
|
|
25
|
+
> **What's new in 0.4.1** — CLI dispatch hardened so every subcommand's
|
|
26
|
+
> `--help` / `--version` exits 0 cleanly (no more `ValueError: unknown
|
|
27
|
+
> source: '--help'` on a zero-deps install). Added a static
|
|
28
|
+
> `COMMAND_HELP` table guarded by 10 new regression cases in
|
|
29
|
+
> `tests/test_cli_version.py`, plus GitHub `About` / README lead now
|
|
30
|
+
> surface for "agent loop" searches.
|
|
31
|
+
> [Full changelog →](CHANGELOG.md)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Table of contents
|
|
36
|
+
|
|
37
|
+
- [What it does](#what-it-does)
|
|
38
|
+
- [Install](#install)
|
|
39
|
+
- [Quickstart](#quickstart)
|
|
40
|
+
- [Why Loop Memory vs. every other agent-memory project](#why-loop-memory-vs-every-other-agent-memory-project)
|
|
41
|
+
- [Architecture & docs](#architecture--docs)
|
|
42
|
+
- [After install: 30-second setup](#after-install-30-second-setup)
|
|
43
|
+
- [Auto-capture (after every conversation)](#auto-capture-after-every-conversation)
|
|
44
|
+
- [Dashboard + Evolution consolidator](#dashboard--evolution-consolidator-看板--进化式蒸馏)
|
|
45
|
+
- [Auto-feedback into every LLM client](#auto-feedback-into-every-llm-client-反哺)
|
|
46
|
+
- [Web UI](#web-ui)
|
|
47
|
+
- [Programmatic use](#programmatic-use)
|
|
48
|
+
- [The four-stage loop](#the-four-stage-loop)
|
|
49
|
+
- [Project layout](#project-layout)
|
|
50
|
+
- [Security & auth token](#security--auth-token)
|
|
51
|
+
- [Wiki scope auto-classification](#wiki-scope-auto-classification)
|
|
52
|
+
- [FAQ & troubleshooting](#faq--troubleshooting)
|
|
53
|
+
- [Run the tests](#run-the-tests)
|
|
54
|
+
- [Using distilled knowledge in your clients](#using-distilled-knowledge-in-your-clients)
|
|
55
|
+
- [License](#license)
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
22
59
|
## What it does
|
|
23
60
|
|
|
24
61
|
**Loop Memory** gives every agent you use a single, persistent brain
|
|
25
|
-
that outlives any one conversation.
|
|
26
|
-
Code, Hermes, OpenClaw / clawx,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
that outlives any one conversation. Any agent that drops transcripts
|
|
63
|
+
on disk — Codex CLI, Claude Code, Hermes, OpenClaw / clawx, Aider,
|
|
64
|
+
Cursor, … — works; the shipped hooks cover the popular ones and a
|
|
65
|
+
generic watcher CLI (`loop-memory hook --source <name> --watch <dir>`)
|
|
66
|
+
accepts anything else. Loop Memory quietly catches every fragment,
|
|
67
|
+
scores it by *importance × recency × usage × feedback*, distils the
|
|
68
|
+
long tail into a curated wiki, and re-injects the relevant pieces
|
|
69
|
+
into the next session.
|
|
30
70
|
|
|
31
71
|
```mermaid
|
|
32
72
|
flowchart LR
|
|
@@ -58,6 +98,21 @@ via MCP / hooks]
|
|
|
58
98
|
|
|
59
99
|
*One loop, many agents, one evolving wiki.*
|
|
60
100
|
|
|
101
|
+
**Supported agents:**
|
|
102
|
+
|
|
103
|
+
| Agent | Capture path | Hook shipped? | Notes |
|
|
104
|
+
| -------------- | ----------------------------------- | :-----------: | ----- |
|
|
105
|
+
| Codex CLI | `~/.codex/sessions/*.json` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
106
|
+
| Claude Code | `~/.claude/**/*.jsonl` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
107
|
+
| Hermes | `~/.hermes/**/*.jsonl` | ✅ | MCP + SessionStart auto-wired by `install-hooks` |
|
|
108
|
+
| OpenClaw/clawx | `~/.openclaw/agents/main/sessions` + `workspace/memory/*.md` | ✅ | watcher only (no MCP yet); `openclaw-setup` enables launchd |
|
|
109
|
+
| Anything else | any on-disk transcript dir | — | use `loop-memory hook --source <name> --watch <dir>` (see [docs/auto-capture.md](docs/auto-capture.md)) |
|
|
110
|
+
|
|
111
|
+
The shipped hooks are the four popular agents we maintain in-tree.
|
|
112
|
+
The generic watcher CLI is the supported extension point for every
|
|
113
|
+
other agent — Aider, Cursor, Copilot, Cline, Continue, Goose, your
|
|
114
|
+
own home-grown CLI, anything that drops JSON/JSONL on disk.
|
|
115
|
+
|
|
61
116
|
---
|
|
62
117
|
|
|
63
118
|
## Install
|
|
@@ -98,7 +153,7 @@ following — every other project we looked at lacks at least one:
|
|
|
98
153
|
|
|
99
154
|
| Capability | **Loop Memory** | Mem0 v3 | Hindsight | OpenViking | A-MEM |
|
|
100
155
|
| --- | --- | --- | --- | --- | --- |
|
|
101
|
-
| Multi-source capture (Codex / Claude / Hermes / OpenClaw
|
|
156
|
+
| Multi-source capture (any agent with on-disk transcripts) | ✅ generic watcher CLI; hooks shipped for Codex / Claude / Hermes / OpenClaw | ⚠ requires plugin per client | ⚠ hosted only | ⚠ SDK + companion app | ❌ |
|
|
102
157
|
| Local-first SQLite (zero external services) | ✅ | ❌ Postgres + Qdrant | ❌ Postgres + Qdrant | ⚠ file-system + cloud | ⚠ ChromaDB |
|
|
103
158
|
| Hybrid recall: BM25 + semantic + entity (RRF) | ✅ | ✅ | ✅ | ✅ | ⚠ entity-only |
|
|
104
159
|
| Temporal reasoning in retrieval (boost / suppress by date intent) | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
@@ -179,6 +234,7 @@ flavors:
|
|
|
179
234
|
| Claude Code | `loop-memory hook --source claude --watch ~/.claude` |
|
|
180
235
|
| Hermes | `loop-memory hook --source hermes --watch ~/.hermes` |
|
|
181
236
|
| OpenClaw (clawx) | `loop-memory hook --source openclaw --watch ~/.openclaw/agents/main/sessions` — also ingests `workspace/memory/*.md` daily logs |
|
|
237
|
+
| Anything else (Aider, Cursor, Copilot, Cline, Continue, Goose, …) | `loop-memory hook --source <name> --watch <path/to/transcripts>` — see [docs/auto-capture.md](docs/auto-capture.md) for loader requirements |
|
|
182
238
|
|
|
183
239
|
Three of these in a `tmux` session, or persisted via launchd, keeps
|
|
184
240
|
your memory store fresh without any clicks. Run `loop-memory
|
|
@@ -285,6 +341,34 @@ User signals close the loop:
|
|
|
285
341
|
- Every `recall()` / search bumps `recall_count` on the returned
|
|
286
342
|
rows so the next Stage-1 ranks them higher.
|
|
287
343
|
|
|
344
|
+
### Cognitive sleep (v7)
|
|
345
|
+
|
|
346
|
+
`loop-memory cognitive-sleep [--apply]` runs an **auditable cleanup
|
|
347
|
+
pass** over the store:
|
|
348
|
+
|
|
349
|
+
- Surfaces contradictions between memories (e.g. "user prefers X"
|
|
350
|
+
vs. "user prefers Y") so you can resolve them in one click rather
|
|
351
|
+
than chasing them across sessions.
|
|
352
|
+
- Drops items that are below the configurable floor (`min_score`) and
|
|
353
|
+
older than the floor age.
|
|
354
|
+
- Merges near-duplicate memories (cosine ≥ 0.95 with `MergeableBy` rules).
|
|
355
|
+
- Emits a full audit row per action — visible in the Dashboard →
|
|
356
|
+
**Audit** tab and reachable via the MCP `audit` tool, so every
|
|
357
|
+
byte the consolidator ever touches is traceable.
|
|
358
|
+
|
|
359
|
+
Dry-run by default; pass `--apply` to commit.
|
|
360
|
+
|
|
361
|
+
### Knowledge graph
|
|
362
|
+
|
|
363
|
+
`loop-memory graph-rebuild` extracts entities from every distilled
|
|
364
|
+
wiki page and every long-term memory, then materialises a typed
|
|
365
|
+
relation graph:
|
|
366
|
+
|
|
367
|
+
- Visible as the **Knowledge graph** globe tab in the web UI.
|
|
368
|
+
- Queryable via the MCP `subgraph` and `remember_edge` tools.
|
|
369
|
+
- Re-built by the Evolution Consolidator's Stage-5 evolution memo, so
|
|
370
|
+
the graph evolves alongside the wiki.
|
|
371
|
+
|
|
288
372
|
## Auto-feedback into every LLM client (反哺)
|
|
289
373
|
|
|
290
374
|
Distilled knowledge is only useful if your LLM tools can actually
|
|
@@ -341,21 +425,6 @@ configuration, scheduling, language switching, and light/dark themes.
|
|
|
341
425
|
|
|
342
426
|
---
|
|
343
427
|
|
|
344
|
-
## Time-weighted scoring
|
|
345
|
-
|
|
346
|
-
Every memory carries a `score ∈ [0, 1]` recomputed from:
|
|
347
|
-
|
|
348
|
-
```
|
|
349
|
-
score = 0.35 · importance + 0.65 · recency
|
|
350
|
-
recency = ½ ^ (age / half_life)
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
`half_life` defaults to 30 days, configurable via
|
|
354
|
-
`consolidate(half_life_days=...)`. The UI shows the score as a
|
|
355
|
-
percentage; use `?min_score=0.85` to see only high-relevance memories.
|
|
356
|
-
|
|
357
|
-
---
|
|
358
|
-
|
|
359
428
|
## Programmatic use
|
|
360
429
|
|
|
361
430
|
```python
|
|
@@ -409,26 +478,35 @@ Even though v0.2 is built around local storage, the original
|
|
|
409
478
|
```
|
|
410
479
|
loop_memory/
|
|
411
480
|
loop_memory/
|
|
481
|
+
cli/main.py # CLI entrypoint + COMMAND_HELP table + `--version`
|
|
482
|
+
ingest/ # Codex / Claude / Hermes / OpenClaw / generic loaders
|
|
483
|
+
wiki/ # distillation, classifier, scope auto-promotion
|
|
484
|
+
graph/ # entity extraction + knowledge-graph build
|
|
485
|
+
jobs/ # consolidate / evolve / cognitive-sleep / scheduler / contradiction / graph
|
|
486
|
+
llm/ # provider protocol + OpenAI / Anthropic / Ollama / rule-based
|
|
487
|
+
backends/ # embedding (hashing / sentence-transformers) + vector store (memory / chroma)
|
|
488
|
+
storage/ # SQLite-backed MemoryStore + migrations
|
|
489
|
+
privacy/ # <private> stripping + regex redaction
|
|
490
|
+
security/ # Keychain / 0600-file secrets wrapper
|
|
491
|
+
mcp/ # stdio JSON-RPC MCP server
|
|
492
|
+
serve/ # FastAPI app, watcher, web UI (Timeline / Dashboard / Wiki / Graph)
|
|
493
|
+
export/ # markdown + v7 portable bundle export/import
|
|
494
|
+
sdk.py # four-verb stable API: remember / recall / forget / feedback
|
|
495
|
+
sdk_extensions.py # optional high-level helpers (graph edges, wiki pages)
|
|
496
|
+
engine/loop.py # Retrieve → Generate → Reflect → Store loop
|
|
412
497
|
memory/types.py # MemoryItem + 4 tiers
|
|
413
|
-
backends/embedding.py # BaseEmbedder, HashingEmbedder, IdentityEmbedder
|
|
414
|
-
backends/vector_store.py # VectorStore protocol + InMemory / Chroma
|
|
415
|
-
backends/sentence_embedder.py # optional sentence-transformers
|
|
416
|
-
llm/base.py # LLMClient protocol + EchoLLM + helpers
|
|
417
|
-
llm/openai_adapter.py # optional OpenAI client
|
|
418
|
-
engine/loop.py # the Retrieve → Generate → Reflect → Store loop
|
|
419
|
-
engine/reflect.py # reflection & summarization passes
|
|
420
|
-
storage/sqlite_store.py # persistent SQLite-backed MemoryStore
|
|
421
|
-
ingest/loader.py # CodexLoader, ClaudeLoader, HermesLoader
|
|
422
|
-
ingest/pipeline.py # session → MemoryStore
|
|
423
|
-
jobs/consolidate.py # background rescore + GC + dedupe
|
|
424
|
-
serve/app.py # FastAPI app for the local web UI
|
|
425
|
-
serve/static/index.html # the page
|
|
426
|
-
serve/watcher.py # filesystem watcher for auto-capture
|
|
427
|
-
cli/main.py # CLI entrypoint (chat / stats / ingest / consolidate / serve / hook)
|
|
428
498
|
examples/demo.py # runnable, zero-API-key demo
|
|
429
499
|
py.typed
|
|
430
|
-
tests/ #
|
|
431
|
-
docs/
|
|
500
|
+
tests/ # 475 unit tests across memory / SDK / serve / CLI / scripts
|
|
501
|
+
docs/
|
|
502
|
+
auto-capture.md # launchd / systemd / cron recipes
|
|
503
|
+
architecture.md # layered view + 5-stage evolution pipeline
|
|
504
|
+
api.md # HTTP API reference
|
|
505
|
+
agent-memory-api.md # four-verb SDK / HTTP / MCP contract
|
|
506
|
+
universal-agent-memory.md # v7 graph memory + cognitive sleep + bundles
|
|
507
|
+
providers.md # LLM provider reference
|
|
508
|
+
settings.md # settings table + secrets file
|
|
509
|
+
weekly-research-automation.md # how the project auto-evolves from upstream research
|
|
432
510
|
```
|
|
433
511
|
|
|
434
512
|
---
|
|
@@ -510,6 +588,67 @@ classifier is local and makes no model or network request on a wiki write.
|
|
|
510
588
|
|
|
511
589
|
---
|
|
512
590
|
|
|
591
|
+
## FAQ & troubleshooting
|
|
592
|
+
|
|
593
|
+
**Q: `pip install loop-memory` succeeds but `loop-memory serve` says `ModuleNotFoundError: No module named 'fastapi'`.**
|
|
594
|
+
A: `fastapi` is the optional `[serve]` extra. Install it explicitly:
|
|
595
|
+
`pip install 'loop-memory[serve]'` (or `'loop-memory[all]'` for everything).
|
|
596
|
+
|
|
597
|
+
**Q: My `~/.codex/sessions/` is empty / nothing appears in the UI.**
|
|
598
|
+
A: Run `loop-memory doctor` — it prints per-source paths, last-seen
|
|
599
|
+
mtime, and whether the watcher is running. Then check
|
|
600
|
+
`loop-memory hook --source codex --watch ~/.codex/sessions` is alive
|
|
601
|
+
in another shell (or via launchd — see [docs/auto-capture.md](docs/auto-capture.md)).
|
|
602
|
+
|
|
603
|
+
**Q: Distillation never finishes / wiki stays empty.**
|
|
604
|
+
A: You need an LLM provider configured. Open the web UI → ⚙ Model,
|
|
605
|
+
pick a provider, paste an API key, and click **Save**. Then either
|
|
606
|
+
wait for the scheduler or hit **� Run now**. Zero-deps installs ship
|
|
607
|
+
with a rule-based provider as a placeholder so the loop never blocks
|
|
608
|
+
on a missing key.
|
|
609
|
+
|
|
610
|
+
**Q: `loop-memory install-hooks` warns that the token file already exists.**
|
|
611
|
+
A: That's expected — it's idempotent. To force a rewrite, delete the
|
|
612
|
+
target files (`~/.codex/config.toml`, `~/.claude/mcp.json`,
|
|
613
|
+
`~/.hermes/mcp.json`) and re-run. The tool also refuses to touch
|
|
614
|
+
non-loop-memory config keys.
|
|
615
|
+
|
|
616
|
+
**Q: How big can the SQLite store get before I should worry?**
|
|
617
|
+
A: Practical floor: 100k memories / 10k wiki pages stays under ~80 MB
|
|
618
|
+
and `recall()` returns in <100 ms. The Evolution Consolidator is
|
|
619
|
+
designed to keep the wiki tight (~hundreds of pages) rather than let
|
|
620
|
+
it grow unbounded. Run `loop-memory cognitive-sleep --apply` weekly
|
|
621
|
+
to drop the long tail.
|
|
622
|
+
|
|
623
|
+
**Q: Can I sync the store across machines?**
|
|
624
|
+
A: The SQLite file is git-friendly and copy-friendly. The `MEMORY.md`
|
|
625
|
+
+ graph + memories + metadata **bundle** (`loop-memory export
|
|
626
|
+
<dir>`) is a portable v7 artefact you can commit, share, or
|
|
627
|
+
back-up. There is no first-class sync daemon — by design — so the
|
|
628
|
+
local-first guarantee is never violated.
|
|
629
|
+
|
|
630
|
+
**Q: Is there a hosted / cloud version?**
|
|
631
|
+
A: No. Loop Memory is MIT-licensed and 100% local; the SQLite file
|
|
632
|
+
lives under `~/.loop_memory/`. The web UI is bound to loopback by
|
|
633
|
+
default; binding to `0.0.0.0` prints a security warning and requires
|
|
634
|
+
an auth token.
|
|
635
|
+
|
|
636
|
+
**Q: Where do secrets / API keys live?**
|
|
637
|
+
A: Two places. Provider keys you set in the **⚙ Model** UI are
|
|
638
|
+
written to `~/.loop_memory/secrets.json` (mode 0600) via the
|
|
639
|
+
`loop_memory.security.secrets` wrapper, which prefers the macOS
|
|
640
|
+
Keychain on Darwin and falls back to the encrypted file on Linux.
|
|
641
|
+
The auth token used by the web UI is hashed in the SQLite settings
|
|
642
|
+
table — never stored in plaintext.
|
|
643
|
+
|
|
644
|
+
**Q: I see "no version" / "package not found" on the PyPI badge.**
|
|
645
|
+
A: shields.io pulls from a separate data source that lags PyPI by a
|
|
646
|
+
few minutes after a new release. Re-publish the badge warmer step
|
|
647
|
+
in `.github/workflows/publish.yml` to force a refresh, or wait ~30
|
|
648
|
+
minutes for shields.io to catch up.
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
513
652
|
## Run the tests
|
|
514
653
|
|
|
515
654
|
```bash
|