memir 0.3.0__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.
- memir-0.3.0/CHANGELOG.md +34 -0
- memir-0.3.0/CITATION.cff +25 -0
- memir-0.3.0/LICENSE.md +116 -0
- memir-0.3.0/MANIFEST.in +8 -0
- memir-0.3.0/PKG-INFO +239 -0
- memir-0.3.0/README.md +194 -0
- memir-0.3.0/docs/BENCHMARKS.md +91 -0
- memir-0.3.0/examples/mcp.json +12 -0
- memir-0.3.0/examples/quickstart.py +47 -0
- memir-0.3.0/memir/__init__.py +22 -0
- memir-0.3.0/memir/autocapture.py +398 -0
- memir-0.3.0/memir/brain.py +1265 -0
- memir-0.3.0/memir/cli.py +297 -0
- memir-0.3.0/memir/embeddings.py +163 -0
- memir-0.3.0/memir/mcp_server.py +419 -0
- memir-0.3.0/memir/optimizer.py +150 -0
- memir-0.3.0/memir/py.typed +1 -0
- memir-0.3.0/memir/reasoner.py +110 -0
- memir-0.3.0/memir/reranker.py +156 -0
- memir-0.3.0/memir.egg-info/PKG-INFO +239 -0
- memir-0.3.0/memir.egg-info/SOURCES.txt +25 -0
- memir-0.3.0/memir.egg-info/dependency_links.txt +1 -0
- memir-0.3.0/memir.egg-info/entry_points.txt +3 -0
- memir-0.3.0/memir.egg-info/requires.txt +23 -0
- memir-0.3.0/memir.egg-info/top_level.txt +1 -0
- memir-0.3.0/pyproject.toml +81 -0
- memir-0.3.0/setup.cfg +4 -0
memir-0.3.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Memir are documented here. The format is based on
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and Memir follows
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [0.3.0] — 2026-06-08
|
|
8
|
+
|
|
9
|
+
First public release.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **First-class failure memory.** `record_failure(attempt, reason, lesson)` and a
|
|
13
|
+
`check_failure(...)` guard the agent can consult *before* acting.
|
|
14
|
+
- **Three memory kinds:** facts, decisions (with reasons), and failures, in a tiny
|
|
15
|
+
local SQLite store.
|
|
16
|
+
- **0-token, deterministic writes.** No LLM in the capture path.
|
|
17
|
+
- **Local semantic recall by default** via `model2vec` `potion-retrieval-32M`
|
|
18
|
+
(numpy-only, ~1 ms, CPU, offline) with graceful keyword fallback.
|
|
19
|
+
- **Token-budgeted `briefing(budget_tokens=...)`** that prioritises failures over
|
|
20
|
+
decisions over facts.
|
|
21
|
+
- **`recall()` with multi-hop (`hops`) and a hybrid embedding + FTS5 RRF ranker.**
|
|
22
|
+
- **Safe `consolidate()`** that merges only genuine restatements, never distinct
|
|
23
|
+
facts.
|
|
24
|
+
- **`capture_error()` / `watch()`** auto-capture that stores only non-obvious
|
|
25
|
+
failures (textbook errors are skipped to avoid bloat).
|
|
26
|
+
- **CLI** (`memir setup|start|doctor|remember|decision|failure|recall|check|briefing|stats`).
|
|
27
|
+
- **MCP server** (`memir start`) exposing the tools over stdio JSON-RPC.
|
|
28
|
+
- **Optional local CPU extras:** `memir[rerank]` (cross-encoder reranker),
|
|
29
|
+
`memir[nli]` (NLI reasoner), `memir[contextual]` (BGE encoder), `memir[ml]`.
|
|
30
|
+
|
|
31
|
+
### License
|
|
32
|
+
- Released under **PolyForm Noncommercial 1.0.0** (free for noncommercial use).
|
|
33
|
+
|
|
34
|
+
[0.3.0]: https://github.com/jabir-al-nahian/memir/releases/tag/v0.3.0
|
memir-0.3.0/CITATION.cff
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use Memir in your research, please cite it as below."
|
|
3
|
+
title: "Memir: a local-first, zero-token memory layer with first-class failure memory for coding agents"
|
|
4
|
+
abstract: >-
|
|
5
|
+
Memir is a local-first long-term memory layer for coding agents. It stores
|
|
6
|
+
facts, decisions, and a first-class failure memory in a tiny SQLite store with
|
|
7
|
+
deterministic, zero-token writes, and serves a token-budgeted briefing plus a
|
|
8
|
+
failure guard. Semantic recall runs on a local CPU static-embedding model
|
|
9
|
+
(model2vec), requiring no API keys or GPU.
|
|
10
|
+
type: software
|
|
11
|
+
authors:
|
|
12
|
+
- family-names: Nahian
|
|
13
|
+
given-names: ""
|
|
14
|
+
version: "0.3.0"
|
|
15
|
+
date-released: "2026-06-08"
|
|
16
|
+
license: "PolyForm-Noncommercial-1.0.0"
|
|
17
|
+
repository-code: "https://github.com/jabir-al-nahian/memir"
|
|
18
|
+
url: "https://github.com/jabir-al-nahian/memir"
|
|
19
|
+
keywords:
|
|
20
|
+
- coding agents
|
|
21
|
+
- long-term memory
|
|
22
|
+
- failure memory
|
|
23
|
+
- retrieval-augmented generation
|
|
24
|
+
- local-first
|
|
25
|
+
- model context protocol
|
memir-0.3.0/LICENSE.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Required Notice: Copyright (c) 2026 Nahian (https://github.com/jabir-al-nahian/memir)
|
|
2
|
+
|
|
3
|
+
# PolyForm Noncommercial License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree to them as both
|
|
10
|
+
strict obligations and conditions to all your licenses.
|
|
11
|
+
|
|
12
|
+
## Copyright License
|
|
13
|
+
|
|
14
|
+
The licensor grants you a copyright license for the software to do everything
|
|
15
|
+
you might do with the software that would otherwise infringe the licensor's
|
|
16
|
+
copyright in it for any permitted purpose. However, you may only distribute the
|
|
17
|
+
software according to [Distribution License](#distribution-license) and make
|
|
18
|
+
changes or new works based on the software according to [Changes and New Works
|
|
19
|
+
License](#changes-and-new-works-license).
|
|
20
|
+
|
|
21
|
+
## Distribution License
|
|
22
|
+
|
|
23
|
+
The licensor grants you an additional copyright license to distribute copies of
|
|
24
|
+
the software. Your license to distribute covers distributing the software with
|
|
25
|
+
changes and new works permitted by [Changes and New Works
|
|
26
|
+
License](#changes-and-new-works-license).
|
|
27
|
+
|
|
28
|
+
## Notices
|
|
29
|
+
|
|
30
|
+
You must ensure that anyone who gets a copy of any part of the software from you
|
|
31
|
+
also gets a copy of these terms or the URL for them above, as well as copies of
|
|
32
|
+
any plain-text lines beginning with `Required Notice:` that the licensor
|
|
33
|
+
provided with the software. For example:
|
|
34
|
+
|
|
35
|
+
> Required Notice: Copyright (c) 2026 Nahian (https://github.com/jabir-al-nahian/memir)
|
|
36
|
+
|
|
37
|
+
## Changes and New Works License
|
|
38
|
+
|
|
39
|
+
The licensor grants you an additional copyright license to make changes and new
|
|
40
|
+
works based on the software for any permitted purpose.
|
|
41
|
+
|
|
42
|
+
## Patent License
|
|
43
|
+
|
|
44
|
+
The licensor grants you a patent license for the software that covers patent
|
|
45
|
+
claims the licensor can license, or becomes able to license, that you would
|
|
46
|
+
infringe by using the software.
|
|
47
|
+
|
|
48
|
+
## Noncommercial Purposes
|
|
49
|
+
|
|
50
|
+
Any noncommercial purpose is a permitted purpose.
|
|
51
|
+
|
|
52
|
+
## Personal Uses
|
|
53
|
+
|
|
54
|
+
Personal use for research, experiment, and testing for the benefit of public
|
|
55
|
+
knowledge, personal study, private entertainment, hobby projects, amateur
|
|
56
|
+
pursuits, or religious observance, without any anticipated commercial
|
|
57
|
+
application, is use for a permitted purpose.
|
|
58
|
+
|
|
59
|
+
## Noncommercial Organizations
|
|
60
|
+
|
|
61
|
+
Use by any charitable organization, educational institution, public research
|
|
62
|
+
organization, public safety or health organization, environmental protection
|
|
63
|
+
organization, or government institution is use for a permitted purpose regardless
|
|
64
|
+
of the source of funding or obligations resulting from the funding.
|
|
65
|
+
|
|
66
|
+
## Fair Use
|
|
67
|
+
|
|
68
|
+
You may have "fair use" rights for the software under the law. These terms do not
|
|
69
|
+
limit them.
|
|
70
|
+
|
|
71
|
+
## No Other Rights
|
|
72
|
+
|
|
73
|
+
These terms do not allow you to sublicense or transfer any of your licenses to
|
|
74
|
+
anyone else, or prevent the licensor from granting licenses to anyone else. These
|
|
75
|
+
terms do not imply any other licenses.
|
|
76
|
+
|
|
77
|
+
## Patent Defense
|
|
78
|
+
|
|
79
|
+
If you make any written claim that the software infringes or contributes to
|
|
80
|
+
infringement of any patent, your patent license for the software granted under
|
|
81
|
+
these terms ends immediately. If your company makes such a claim, your patent
|
|
82
|
+
license ends immediately for work on behalf of your company.
|
|
83
|
+
|
|
84
|
+
## Violations
|
|
85
|
+
|
|
86
|
+
The first time you are notified in writing that you have violated any of these
|
|
87
|
+
terms, or done anything with the software not covered by your licenses, your
|
|
88
|
+
licenses can nonetheless continue if you come into full compliance with these
|
|
89
|
+
terms, and take practical steps to correct past violations, within 32 days of
|
|
90
|
+
receiving notice. Otherwise, all your licenses end immediately.
|
|
91
|
+
|
|
92
|
+
## No Liability
|
|
93
|
+
|
|
94
|
+
*As far as the law allows, the software comes as is, without any warranty or
|
|
95
|
+
condition, and the licensor will not be liable to you for any damages arising out
|
|
96
|
+
of these terms or the use or nature of the software, under any kind of legal
|
|
97
|
+
claim.*
|
|
98
|
+
|
|
99
|
+
## Definitions
|
|
100
|
+
|
|
101
|
+
The **licensor** is the individual or entity offering these terms, and the
|
|
102
|
+
**software** is the software the licensor makes available under these terms.
|
|
103
|
+
|
|
104
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
105
|
+
|
|
106
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of
|
|
107
|
+
organization that you work for, plus all organizations that have control over, are
|
|
108
|
+
under the control of, or are under common control with that organization.
|
|
109
|
+
**Control** means ownership of substantially all the assets of an entity, or the
|
|
110
|
+
power to direct its management and policies by vote, contract, or otherwise.
|
|
111
|
+
Control can be direct or indirect.
|
|
112
|
+
|
|
113
|
+
**Your licenses** are all the licenses granted to you for the software under these
|
|
114
|
+
terms.
|
|
115
|
+
|
|
116
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
memir-0.3.0/MANIFEST.in
ADDED
memir-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memir
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Local memory for coding agents: deterministic zero-token writes, a first-class failure guard (never repeat a mistake), and a token-efficient briefing. Local CPU semantic recall — no API keys, no cloud.
|
|
5
|
+
Author: Nahian
|
|
6
|
+
License: PolyForm-Noncommercial-1.0.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/jabir-al-nahian/memir
|
|
8
|
+
Project-URL: Repository, https://github.com/jabir-al-nahian/memir
|
|
9
|
+
Project-URL: Issues, https://github.com/jabir-al-nahian/memir/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/jabir-al-nahian/memir/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: agent,memory,llm,coding-agent,mcp,model-context-protocol,failure-memory,context-window,local-first,rag,sqlite,embeddings,model2vec
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: Other/Proprietary License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE.md
|
|
26
|
+
Requires-Dist: model2vec>=0.3
|
|
27
|
+
Requires-Dist: numpy>=1.21
|
|
28
|
+
Provides-Extra: nli
|
|
29
|
+
Requires-Dist: torch>=2.2; extra == "nli"
|
|
30
|
+
Requires-Dist: transformers>=4.40; extra == "nli"
|
|
31
|
+
Provides-Extra: rerank
|
|
32
|
+
Requires-Dist: torch>=2.2; extra == "rerank"
|
|
33
|
+
Requires-Dist: transformers>=4.40; extra == "rerank"
|
|
34
|
+
Provides-Extra: contextual
|
|
35
|
+
Requires-Dist: torch>=2.2; extra == "contextual"
|
|
36
|
+
Requires-Dist: transformers>=4.40; extra == "contextual"
|
|
37
|
+
Provides-Extra: ml
|
|
38
|
+
Requires-Dist: torch>=2.2; extra == "ml"
|
|
39
|
+
Requires-Dist: transformers>=4.40; extra == "ml"
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
42
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
43
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# 🧠 Memir
|
|
47
|
+
|
|
48
|
+
**The memoir your coding agent writes for itself.**
|
|
49
|
+
Long-term memory for coding agents that *doesn't* eat your context window.
|
|
50
|
+
Local-first. Zero API keys. And it **never lets the agent repeat a mistake.**
|
|
51
|
+
|
|
52
|
+
[](https://github.com/jabir-al-nahian/memir/actions/workflows/ci.yml)
|
|
53
|
+

|
|
54
|
+

|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
> *Memir* = **mem**ory + **memoir** + **Mímir**, the Norse keeper of memory and
|
|
58
|
+
> wisdom. Your agent keeps a memoir; Memir is where it lives.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## The problem
|
|
63
|
+
|
|
64
|
+
Every coding agent forgets. Switch chats, hit the context limit, start a new
|
|
65
|
+
session — and it re-asks what it already knew, re-decides what you already
|
|
66
|
+
decided, and **repeats the exact mistake it made an hour ago.**
|
|
67
|
+
|
|
68
|
+
The common "fix" is to stuff the whole history back into the prompt every turn.
|
|
69
|
+
That burns thousands of tokens per request and *still* overflows as the project
|
|
70
|
+
grows.
|
|
71
|
+
|
|
72
|
+
## The idea
|
|
73
|
+
|
|
74
|
+
Memir stores three kinds of memory in a tiny local SQLite file:
|
|
75
|
+
|
|
76
|
+
| kind | what it captures |
|
|
77
|
+
|------|------------------|
|
|
78
|
+
| **fact** | durable truths about the project (endpoints, conventions, constraints) |
|
|
79
|
+
| **decision** | a choice **and the reason** for it, so it isn't relitigated |
|
|
80
|
+
| **failure** | what was **tried**, **why it failed**, and the **lesson** — a first-class memory |
|
|
81
|
+
|
|
82
|
+
Then it hands the agent a **token-budgeted briefing** at the start of a session
|
|
83
|
+
and a **failure guard** it can check *before* trying something.
|
|
84
|
+
|
|
85
|
+
> **Writing a memory costs 0 tokens and 0 API calls** — it's a local insert, sub-
|
|
86
|
+
> millisecond. Compare that to memory frameworks that run an LLM extraction call
|
|
87
|
+
> on *every* `add`.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Why it's different
|
|
92
|
+
|
|
93
|
+
- **First-class FAILURE memory.** Most memory tools remember facts. Memir
|
|
94
|
+
remembers *mistakes* — what failed, why, and what to do instead — and blocks
|
|
95
|
+
the repeat. That's the load-bearing feature for a coding agent.
|
|
96
|
+
- **0-token, deterministic writes.** No LLM in the capture path. Nothing to bill,
|
|
97
|
+
nothing to rate-limit, nothing to go down.
|
|
98
|
+
- **Local semantic recall by default.** Ships with a retrieval-tuned, numpy-only
|
|
99
|
+
embedding model ([model2vec](https://github.com/MinishLab/model2vec)
|
|
100
|
+
`potion-retrieval-32M`) that runs in ~1 ms on a **CPU** — no GPU, no torch, no
|
|
101
|
+
API. Paraphrase matching works out of the box, and gracefully falls back to
|
|
102
|
+
keyword recall if the model can't be loaded.
|
|
103
|
+
- **Anti-bloat.** Write-time dedup plus a *safe* `consolidate()` that only merges
|
|
104
|
+
genuine restatements — it will **never** collapse two distinct facts.
|
|
105
|
+
- **Bounded context cost.** A naive "replay everything" agent grows without
|
|
106
|
+
bound; the briefing here stays inside a token budget you set.
|
|
107
|
+
- **Plugs into any agent via MCP.** One stdio server works with Cursor, Claude
|
|
108
|
+
Desktop, Cline, VS Code, Windsurf, …
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Install
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
pip install memir
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The base install is light — `model2vec` + `numpy` only (no torch, no GPU, no
|
|
119
|
+
API key). Optional **local CPU** accuracy features are opt-in extras:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install "memir[rerank]" # cross-encoder reranker (precision second stage)
|
|
123
|
+
pip install "memir[nli]" # NLI reasoner (contradiction detection)
|
|
124
|
+
pip install "memir[contextual]" # contextual BGE encoder (stronger multi-hop)
|
|
125
|
+
pip install "memir[ml]" # all of the above
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Warm the model cache once so later runs work fully offline:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
memir setup # downloads the CPU model, initialises the store
|
|
132
|
+
memir start # starts the MCP server (stdio) for your editor/agent
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Quickstart (Python)
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from memir import Memir
|
|
141
|
+
|
|
142
|
+
brain = Memir("my-project") # local model loads automatically (CPU)
|
|
143
|
+
|
|
144
|
+
# remember things (0 tokens, sub-ms, no API)
|
|
145
|
+
brain.remember_fact("The billing job MUST run in UTC; our partner reports in UTC.")
|
|
146
|
+
brain.record_decision("Use SQLite FTS5 for recall.", reason="100x faster than scanning.")
|
|
147
|
+
|
|
148
|
+
# record a failure so it's never repeated
|
|
149
|
+
brain.record_failure(
|
|
150
|
+
attempt="POSTed the whole batch to /v1/ingest in one request.",
|
|
151
|
+
reason="The gateway silently drops bodies >256KB and returns an empty 200.",
|
|
152
|
+
lesson="Chunk uploads under 256KB and verify each ack id.",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# BEFORE trying something, check the failure guard
|
|
156
|
+
if hits := brain.check_failure("send the full batch to /v1/ingest at once"):
|
|
157
|
+
print("⛔", hits[0].lesson) # -> Chunk uploads under 256KB and verify each ack id.
|
|
158
|
+
|
|
159
|
+
# start a fresh session fully informed, within a token budget
|
|
160
|
+
print(brain.briefing(budget_tokens=300))
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Auto-capture from real errors
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
# parses the traceback, decides it's non-obvious, stores it as a failure:
|
|
167
|
+
brain.capture_error("RuntimeError: gateway returned 200 with empty body — silently dropped")
|
|
168
|
+
|
|
169
|
+
# a textbook typo is judged self-evident and skipped (no bloat):
|
|
170
|
+
brain.capture_error("NameError: name 'foo' is not defined") # -> None
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Command line
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
memir remember "Deploys go out via the blue/green pipeline only."
|
|
179
|
+
memir decision "Adopt SQLite WAL" --why "concurrent reads during writes"
|
|
180
|
+
memir failure "Dropped the prod table" --why "ran migration w/o backup" \
|
|
181
|
+
--lesson "snapshot before every migration"
|
|
182
|
+
memir recall "how do we deploy?"
|
|
183
|
+
memir check "run the migration now" # failure guard
|
|
184
|
+
memir briefing --budget 300
|
|
185
|
+
memir stats
|
|
186
|
+
memir doctor # environment + MCP config check
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Use it from your editor (MCP)
|
|
192
|
+
|
|
193
|
+
Memir ships a Model Context Protocol server (stdio JSON-RPC).
|
|
194
|
+
|
|
195
|
+
**Cursor / Windsurf / Claude Desktop** — add to your MCP config:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"mcpServers": {
|
|
200
|
+
"memir": {
|
|
201
|
+
"command": "memir",
|
|
202
|
+
"args": ["start"],
|
|
203
|
+
"env": { "MEMIR_PROJECT": "my-project", "MEMIR_DB": ".memir/memir.db" }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**VS Code** (`.vscode/mcp.json`):
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{ "servers": { "memir": { "command": "memir", "args": ["start"] } } }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Tools exposed: `remember_fact`, `record_decision`, `record_failure`, `recall`,
|
|
216
|
+
`check_failure`, `briefing`, `capture_error`, `stats`, `consolidate`.
|
|
217
|
+
|
|
218
|
+
Set `MEMIR_EMBED=0` to force keyword-only mode (skips the model entirely).
|
|
219
|
+
Override the model with `MEMIR_MODEL=minishlab/potion-base-8M` (30 MB, faster).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Benchmarks
|
|
224
|
+
|
|
225
|
+
Memir is measured against real memory backends (mem0, cognee, graphiti, letta)
|
|
226
|
+
and an oracle upper bound under a single uniform LLM judge. The honest headline:
|
|
227
|
+
**Memir matches the top accuracy tier while injecting ~10× fewer memory tokens
|
|
228
|
+
per turn**, locally and with zero-token writes. See
|
|
229
|
+
[docs/BENCHMARKS.md](docs/BENCHMARKS.md) for the full tables, the competitor
|
|
230
|
+
head-to-heads, and the documented limits (relational multi-hop at large scale).
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
[PolyForm Noncommercial 1.0.0](LICENSE.md) — **free for research, personal,
|
|
237
|
+
educational, and other noncommercial use.** Commercial use is reserved; for a
|
|
238
|
+
commercial license, open an issue. (The author holds the copyright and may
|
|
239
|
+
relicense more permissively in the future.)
|
memir-0.3.0/README.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# 🧠 Memir
|
|
2
|
+
|
|
3
|
+
**The memoir your coding agent writes for itself.**
|
|
4
|
+
Long-term memory for coding agents that *doesn't* eat your context window.
|
|
5
|
+
Local-first. Zero API keys. And it **never lets the agent repeat a mistake.**
|
|
6
|
+
|
|
7
|
+
[](https://github.com/jabir-al-nahian/memir/actions/workflows/ci.yml)
|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
> *Memir* = **mem**ory + **memoir** + **Mímir**, the Norse keeper of memory and
|
|
13
|
+
> wisdom. Your agent keeps a memoir; Memir is where it lives.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## The problem
|
|
18
|
+
|
|
19
|
+
Every coding agent forgets. Switch chats, hit the context limit, start a new
|
|
20
|
+
session — and it re-asks what it already knew, re-decides what you already
|
|
21
|
+
decided, and **repeats the exact mistake it made an hour ago.**
|
|
22
|
+
|
|
23
|
+
The common "fix" is to stuff the whole history back into the prompt every turn.
|
|
24
|
+
That burns thousands of tokens per request and *still* overflows as the project
|
|
25
|
+
grows.
|
|
26
|
+
|
|
27
|
+
## The idea
|
|
28
|
+
|
|
29
|
+
Memir stores three kinds of memory in a tiny local SQLite file:
|
|
30
|
+
|
|
31
|
+
| kind | what it captures |
|
|
32
|
+
|------|------------------|
|
|
33
|
+
| **fact** | durable truths about the project (endpoints, conventions, constraints) |
|
|
34
|
+
| **decision** | a choice **and the reason** for it, so it isn't relitigated |
|
|
35
|
+
| **failure** | what was **tried**, **why it failed**, and the **lesson** — a first-class memory |
|
|
36
|
+
|
|
37
|
+
Then it hands the agent a **token-budgeted briefing** at the start of a session
|
|
38
|
+
and a **failure guard** it can check *before* trying something.
|
|
39
|
+
|
|
40
|
+
> **Writing a memory costs 0 tokens and 0 API calls** — it's a local insert, sub-
|
|
41
|
+
> millisecond. Compare that to memory frameworks that run an LLM extraction call
|
|
42
|
+
> on *every* `add`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Why it's different
|
|
47
|
+
|
|
48
|
+
- **First-class FAILURE memory.** Most memory tools remember facts. Memir
|
|
49
|
+
remembers *mistakes* — what failed, why, and what to do instead — and blocks
|
|
50
|
+
the repeat. That's the load-bearing feature for a coding agent.
|
|
51
|
+
- **0-token, deterministic writes.** No LLM in the capture path. Nothing to bill,
|
|
52
|
+
nothing to rate-limit, nothing to go down.
|
|
53
|
+
- **Local semantic recall by default.** Ships with a retrieval-tuned, numpy-only
|
|
54
|
+
embedding model ([model2vec](https://github.com/MinishLab/model2vec)
|
|
55
|
+
`potion-retrieval-32M`) that runs in ~1 ms on a **CPU** — no GPU, no torch, no
|
|
56
|
+
API. Paraphrase matching works out of the box, and gracefully falls back to
|
|
57
|
+
keyword recall if the model can't be loaded.
|
|
58
|
+
- **Anti-bloat.** Write-time dedup plus a *safe* `consolidate()` that only merges
|
|
59
|
+
genuine restatements — it will **never** collapse two distinct facts.
|
|
60
|
+
- **Bounded context cost.** A naive "replay everything" agent grows without
|
|
61
|
+
bound; the briefing here stays inside a token budget you set.
|
|
62
|
+
- **Plugs into any agent via MCP.** One stdio server works with Cursor, Claude
|
|
63
|
+
Desktop, Cline, VS Code, Windsurf, …
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Install
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install memir
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The base install is light — `model2vec` + `numpy` only (no torch, no GPU, no
|
|
74
|
+
API key). Optional **local CPU** accuracy features are opt-in extras:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install "memir[rerank]" # cross-encoder reranker (precision second stage)
|
|
78
|
+
pip install "memir[nli]" # NLI reasoner (contradiction detection)
|
|
79
|
+
pip install "memir[contextual]" # contextual BGE encoder (stronger multi-hop)
|
|
80
|
+
pip install "memir[ml]" # all of the above
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Warm the model cache once so later runs work fully offline:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
memir setup # downloads the CPU model, initialises the store
|
|
87
|
+
memir start # starts the MCP server (stdio) for your editor/agent
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Quickstart (Python)
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from memir import Memir
|
|
96
|
+
|
|
97
|
+
brain = Memir("my-project") # local model loads automatically (CPU)
|
|
98
|
+
|
|
99
|
+
# remember things (0 tokens, sub-ms, no API)
|
|
100
|
+
brain.remember_fact("The billing job MUST run in UTC; our partner reports in UTC.")
|
|
101
|
+
brain.record_decision("Use SQLite FTS5 for recall.", reason="100x faster than scanning.")
|
|
102
|
+
|
|
103
|
+
# record a failure so it's never repeated
|
|
104
|
+
brain.record_failure(
|
|
105
|
+
attempt="POSTed the whole batch to /v1/ingest in one request.",
|
|
106
|
+
reason="The gateway silently drops bodies >256KB and returns an empty 200.",
|
|
107
|
+
lesson="Chunk uploads under 256KB and verify each ack id.",
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# BEFORE trying something, check the failure guard
|
|
111
|
+
if hits := brain.check_failure("send the full batch to /v1/ingest at once"):
|
|
112
|
+
print("⛔", hits[0].lesson) # -> Chunk uploads under 256KB and verify each ack id.
|
|
113
|
+
|
|
114
|
+
# start a fresh session fully informed, within a token budget
|
|
115
|
+
print(brain.briefing(budget_tokens=300))
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Auto-capture from real errors
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# parses the traceback, decides it's non-obvious, stores it as a failure:
|
|
122
|
+
brain.capture_error("RuntimeError: gateway returned 200 with empty body — silently dropped")
|
|
123
|
+
|
|
124
|
+
# a textbook typo is judged self-evident and skipped (no bloat):
|
|
125
|
+
brain.capture_error("NameError: name 'foo' is not defined") # -> None
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Command line
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
memir remember "Deploys go out via the blue/green pipeline only."
|
|
134
|
+
memir decision "Adopt SQLite WAL" --why "concurrent reads during writes"
|
|
135
|
+
memir failure "Dropped the prod table" --why "ran migration w/o backup" \
|
|
136
|
+
--lesson "snapshot before every migration"
|
|
137
|
+
memir recall "how do we deploy?"
|
|
138
|
+
memir check "run the migration now" # failure guard
|
|
139
|
+
memir briefing --budget 300
|
|
140
|
+
memir stats
|
|
141
|
+
memir doctor # environment + MCP config check
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Use it from your editor (MCP)
|
|
147
|
+
|
|
148
|
+
Memir ships a Model Context Protocol server (stdio JSON-RPC).
|
|
149
|
+
|
|
150
|
+
**Cursor / Windsurf / Claude Desktop** — add to your MCP config:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"mcpServers": {
|
|
155
|
+
"memir": {
|
|
156
|
+
"command": "memir",
|
|
157
|
+
"args": ["start"],
|
|
158
|
+
"env": { "MEMIR_PROJECT": "my-project", "MEMIR_DB": ".memir/memir.db" }
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**VS Code** (`.vscode/mcp.json`):
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{ "servers": { "memir": { "command": "memir", "args": ["start"] } } }
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Tools exposed: `remember_fact`, `record_decision`, `record_failure`, `recall`,
|
|
171
|
+
`check_failure`, `briefing`, `capture_error`, `stats`, `consolidate`.
|
|
172
|
+
|
|
173
|
+
Set `MEMIR_EMBED=0` to force keyword-only mode (skips the model entirely).
|
|
174
|
+
Override the model with `MEMIR_MODEL=minishlab/potion-base-8M` (30 MB, faster).
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Benchmarks
|
|
179
|
+
|
|
180
|
+
Memir is measured against real memory backends (mem0, cognee, graphiti, letta)
|
|
181
|
+
and an oracle upper bound under a single uniform LLM judge. The honest headline:
|
|
182
|
+
**Memir matches the top accuracy tier while injecting ~10× fewer memory tokens
|
|
183
|
+
per turn**, locally and with zero-token writes. See
|
|
184
|
+
[docs/BENCHMARKS.md](docs/BENCHMARKS.md) for the full tables, the competitor
|
|
185
|
+
head-to-heads, and the documented limits (relational multi-hop at large scale).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
[PolyForm Noncommercial 1.0.0](LICENSE.md) — **free for research, personal,
|
|
192
|
+
educational, and other noncommercial use.** Commercial use is reserved; for a
|
|
193
|
+
commercial license, open an issue. (The author holds the copyright and may
|
|
194
|
+
relicense more permissively in the future.)
|