memstash 0.15.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.
- memstash-0.15.0/.github/workflows/ci.yml +26 -0
- memstash-0.15.0/.github/workflows/publish.yml +47 -0
- memstash-0.15.0/.gitignore +25 -0
- memstash-0.15.0/CHANGELOG.md +293 -0
- memstash-0.15.0/LICENSE +21 -0
- memstash-0.15.0/PKG-INFO +471 -0
- memstash-0.15.0/README.md +418 -0
- memstash-0.15.0/ROADMAP.md +118 -0
- memstash-0.15.0/examples/basic.py +22 -0
- memstash-0.15.0/memstash/__init__.py +18 -0
- memstash-0.15.0/memstash/adapters/__init__.py +165 -0
- memstash-0.15.0/memstash/adapters/anthropic_adapter.py +75 -0
- memstash-0.15.0/memstash/adapters/base.py +61 -0
- memstash-0.15.0/memstash/adapters/gemini_adapter.py +77 -0
- memstash-0.15.0/memstash/adapters/openai_adapter.py +90 -0
- memstash-0.15.0/memstash/bench.py +150 -0
- memstash-0.15.0/memstash/cli.py +998 -0
- memstash-0.15.0/memstash/config.py +80 -0
- memstash-0.15.0/memstash/core.py +594 -0
- memstash-0.15.0/memstash/dashboard/__init__.py +1 -0
- memstash-0.15.0/memstash/dashboard/server.py +143 -0
- memstash-0.15.0/memstash/evals.py +98 -0
- memstash-0.15.0/memstash/extract.py +53 -0
- memstash-0.15.0/memstash/extract_llm.py +90 -0
- memstash-0.15.0/memstash/graph_extract.py +77 -0
- memstash-0.15.0/memstash/ingest.py +57 -0
- memstash-0.15.0/memstash/instrument.py +121 -0
- memstash-0.15.0/memstash/mcp_server.py +108 -0
- memstash-0.15.0/memstash/memory.py +388 -0
- memstash-0.15.0/memstash/otel_export.py +92 -0
- memstash-0.15.0/memstash/pricing.py +140 -0
- memstash-0.15.0/memstash/prompts.py +39 -0
- memstash-0.15.0/memstash/reconcile.py +109 -0
- memstash-0.15.0/memstash/store.py +738 -0
- memstash-0.15.0/pyproject.toml +70 -0
- memstash-0.15.0/tests/test_bench.py +52 -0
- memstash-0.15.0/tests/test_bitemporal.py +66 -0
- memstash-0.15.0/tests/test_core.py +103 -0
- memstash-0.15.0/tests/test_embeddings.py +87 -0
- memstash-0.15.0/tests/test_eval_suites.py +92 -0
- memstash-0.15.0/tests/test_evals.py +84 -0
- memstash-0.15.0/tests/test_features.py +118 -0
- memstash-0.15.0/tests/test_graph.py +66 -0
- memstash-0.15.0/tests/test_graph_retrieval.py +57 -0
- memstash-0.15.0/tests/test_ingest.py +87 -0
- memstash-0.15.0/tests/test_instrument.py +88 -0
- memstash-0.15.0/tests/test_lifecycle.py +113 -0
- memstash-0.15.0/tests/test_memory_ops.py +112 -0
- memstash-0.15.0/tests/test_multiturn.py +64 -0
- memstash-0.15.0/tests/test_otel.py +32 -0
- memstash-0.15.0/tests/test_plugins.py +44 -0
- memstash-0.15.0/tests/test_pricing_map.py +47 -0
- memstash-0.15.0/tests/test_prompts.py +50 -0
- memstash-0.15.0/tests/test_provenance.py +54 -0
- memstash-0.15.0/tests/test_reconcile.py +105 -0
- memstash-0.15.0/tests/test_retrieval_budget.py +127 -0
- memstash-0.15.0/tests/test_robustness.py +83 -0
- memstash-0.15.0/tests/test_trace_tree.py +76 -0
- memstash-0.15.0/tests/test_v3.py +114 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- name: Install
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
pip install -e '.[dev]'
|
|
23
|
+
- name: Lint
|
|
24
|
+
run: ruff check memstash
|
|
25
|
+
- name: Test
|
|
26
|
+
run: pytest -q
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publishes memstash to PyPI when a version tag is pushed (e.g. v0.3.0).
|
|
4
|
+
# Uses PyPI Trusted Publishing (OIDC) — no API token stored in the repo.
|
|
5
|
+
#
|
|
6
|
+
# One-time setup on PyPI:
|
|
7
|
+
# 1. Create the project `memstash` (or let the first manual upload create it).
|
|
8
|
+
# 2. PyPI → project → Publishing → add a trusted publisher:
|
|
9
|
+
# owner: zionLyl repo: recall workflow: publish.yml environment: pypi
|
|
10
|
+
#
|
|
11
|
+
# Then releasing is just: git tag v0.3.0 && git push origin v0.3.0
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags:
|
|
16
|
+
- "v*"
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
- name: Build sdist + wheel
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade build
|
|
29
|
+
python -m build
|
|
30
|
+
- uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment: pypi
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # required for trusted publishing
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/download-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: dist
|
|
45
|
+
path: dist/
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
env/
|
|
11
|
+
|
|
12
|
+
# recall local data
|
|
13
|
+
.recall/
|
|
14
|
+
*.db
|
|
15
|
+
*.sqlite
|
|
16
|
+
|
|
17
|
+
# tooling
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
|
|
22
|
+
# OS / editor
|
|
23
|
+
.DS_Store
|
|
24
|
+
.vscode/
|
|
25
|
+
.idea/
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.15.0]
|
|
4
|
+
|
|
5
|
+
Renamed to **memstash** (the PyPI name `engram-ai` collided with the existing
|
|
6
|
+
`engram` project). Brand, CLI command, and import are all `memstash` now.
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- PyPI package + CLI + import are now **`memstash`** (`pip install memstash`,
|
|
10
|
+
`memstash ...`, `import memstash`). The `Memstash` class is exported (the
|
|
11
|
+
`Recall` class name still works as an alias).
|
|
12
|
+
- Env vars are `MEMSTASH_*`; the default store is `~/.memstash/memstash.db`;
|
|
13
|
+
the adapter entry-point group is `memstash.adapters`.
|
|
14
|
+
- (The unreleased `engram-ai` 0.14.0 was never published; this supersedes it.)
|
|
15
|
+
|
|
16
|
+
## [0.14.0]
|
|
17
|
+
|
|
18
|
+
Rebrand to **Engram**.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Project renamed from `zion-recall-ai` to **`engram-ai`** (PyPI) with the
|
|
22
|
+
**`engram`** CLI command and `import engram`. The `Engram` class is exported
|
|
23
|
+
(the old `Recall` class name still works as an alias).
|
|
24
|
+
- Env vars are now `ENGRAM_*` (was `RECALL_*`); the default store moved to
|
|
25
|
+
`~/.engram/engram.db`; the adapter entry-point group is `engram.adapters`.
|
|
26
|
+
- README reworked with a sharper pitch, a comparison table, and CI/PyPI badges.
|
|
27
|
+
|
|
28
|
+
## [0.13.0]
|
|
29
|
+
|
|
30
|
+
New capability (3/3): capture other libraries' LLM calls.
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- **`recall.instrument()`**: makes recall a *local* OpenInference/OpenTelemetry
|
|
34
|
+
span sink — LLM calls made by LangChain, LlamaIndex, the OpenAI SDK, etc.
|
|
35
|
+
(instrumented via OpenInference) get written to `~/.engram/recall.db` as
|
|
36
|
+
traces (model, tokens, cost, latency, `kind="instrumented"`), visible in
|
|
37
|
+
`engram recent` / `stats` / `trace`. No server, no cloud — the local
|
|
38
|
+
counterpart to Phoenix/Langfuse auto-instrumentation. Best-effort enables the
|
|
39
|
+
OpenAI/LangChain instrumentors if installed. New `recall/instrument.py`
|
|
40
|
+
(`span_to_trace`, `instrument`). Requires `[otel]`.
|
|
41
|
+
|
|
42
|
+
## [0.12.0]
|
|
43
|
+
|
|
44
|
+
New capability (2/3): document ingestion.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- **`engram ingest <file>`**: read a `.txt` / `.md` (or `.pdf` with the `[pdf]`
|
|
48
|
+
extra), split it into reasonably-sized chunks, and store each as a searchable
|
|
49
|
+
memory tagged with the filename — so `engram search` and chat memory-injection
|
|
50
|
+
cover your notes/docs. 100% local and deterministic (no LLM). Dedupes on
|
|
51
|
+
re-ingest. `recall/ingest.py` (`chunk_text`, `read_file`) + `Recall.ingest`.
|
|
52
|
+
|
|
53
|
+
## [0.11.0]
|
|
54
|
+
|
|
55
|
+
New capability (1/3): bi-temporal memory.
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- **Point-in-time queries**: `engram list --at <when>` shows the memories that
|
|
59
|
+
were valid at a past time — `YYYY-MM-DD`, a relative `30d`/`12h`/`45m` ago, or
|
|
60
|
+
an epoch. Includes since-forgotten memories whose validity window covers that
|
|
61
|
+
moment. `Store.memories_as_of()` / `Recall.as_of()`.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
- **Conflict-resolution UPDATE now supersedes instead of overwriting**: the old
|
|
65
|
+
fact's validity window is closed (kept as history, deactivated) and the new
|
|
66
|
+
fact is added — so "what did I know on date X?" stays answerable.
|
|
67
|
+
|
|
68
|
+
## [0.10.0]
|
|
69
|
+
|
|
70
|
+
Credibility — reproducible quality numbers.
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
- **Benchmark harness** (`engram benchmark`): deterministic, key-free. Seeds a
|
|
74
|
+
fixed, hand-labeled memory set into a throwaway store and reports retrieval
|
|
75
|
+
quality — **recall@1, recall@k, precision@k, MRR** — plus a heuristic
|
|
76
|
+
extraction fact-recall / false-capture check. Honestly labels whether the run
|
|
77
|
+
used the semantic or keyword/BM25 backend, so numbers are comparable and not
|
|
78
|
+
overstated. New `recall/bench.py` (`run_retrieval_benchmark`,
|
|
79
|
+
`run_extraction_benchmark`, `run_all`). Baseline (keyword): recall@1 ≈ 0.50,
|
|
80
|
+
MRR ≈ 0.69, extraction fact-recall 1.00 with 0 false captures; semantic
|
|
81
|
+
embeddings score higher.
|
|
82
|
+
|
|
83
|
+
## [0.9.0]
|
|
84
|
+
|
|
85
|
+
Robustness & scale.
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
- **Vectorized retrieval**: semantic ranking now uses numpy (when present) to
|
|
89
|
+
cosine-score all memories in one matrix op, with a pure-Python fallback —
|
|
90
|
+
keeping recall fast as the store grows to thousands of memories. No new
|
|
91
|
+
required dependency.
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
- **Embedding dimension safety**: stored vectors whose dimension differs from
|
|
95
|
+
the query (e.g. after switching embedding models/backends) are now skipped
|
|
96
|
+
instead of producing silently-wrong cosine scores. `_cosine` returns 0 on
|
|
97
|
+
mismatch, protecting search, near-dup suppression, and dedupe.
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
- SQLite now opens in **WAL** mode (`synchronous=NORMAL`) for safer concurrent
|
|
101
|
+
reads/writes (e.g. the dashboard reading while the CLI writes).
|
|
102
|
+
|
|
103
|
+
## [0.8.0]
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
- **Pluggable embedding backend**: semantic search can now use any
|
|
107
|
+
OpenAI-compatible `/embeddings` endpoint instead of the local
|
|
108
|
+
sentence-transformers model — point at a local Ollama / LM Studio (no PyTorch
|
|
109
|
+
download) or a cloud provider. Config: `embedding_backend = api`,
|
|
110
|
+
`embedding_model`, `embedding_base_url`, `embedding_api_key_env`. Falls back to
|
|
111
|
+
keyword/BM25 search if the endpoint is unreachable. Default stays `local`.
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
- Published to PyPI as **`engram-ai`** (`pip install engram-ai`); the
|
|
115
|
+
import package and `recall` CLI command are unchanged. README gains a PyPI
|
|
116
|
+
badge + prominent install line.
|
|
117
|
+
|
|
118
|
+
## [0.7.0]
|
|
119
|
+
|
|
120
|
+
Usability & onboarding polish — informed by a competitive scan of how peers
|
|
121
|
+
(simonw/llm, Jan, Phoenix, mem0, …) handle ease-of-adoption.
|
|
122
|
+
|
|
123
|
+
### Added
|
|
124
|
+
- **Interactive chat REPL**: bare `engram chat` (no prompt) drops into a
|
|
125
|
+
multi-turn conversation loop — memory injected + auto-captured each turn,
|
|
126
|
+
cost traced, `/exit` or Ctrl-D to quit. Matches `llm chat`'s ergonomics.
|
|
127
|
+
- **Multi-turn conversation history**: adapters and `Recall.chat/stream` accept
|
|
128
|
+
a `history` of prior turns, so chats are no longer single-shot. OpenAI,
|
|
129
|
+
Anthropic, and Gemini adapters all thread it natively.
|
|
130
|
+
- **Zero-key local default**: `engram init` now detects a running Ollama
|
|
131
|
+
(localhost:11434) and offers it as the default provider — no API key needed.
|
|
132
|
+
|
|
133
|
+
### Changed
|
|
134
|
+
- **Onboarding**: README leads with `pipx install 'engram-ai[all]'` (and `uv tool
|
|
135
|
+
install`); the quickstart's first chat command now installs a working provider
|
|
136
|
+
extra instead of failing on the base install.
|
|
137
|
+
- First semantic search prints a one-time "loading embedding model (~80MB)"
|
|
138
|
+
notice to stderr instead of hanging silently.
|
|
139
|
+
|
|
140
|
+
## [0.6.0]
|
|
141
|
+
|
|
142
|
+
The rest of the roadmap — extensibility, interop, auditing, and eval workflow.
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
- **Provenance**: auto-captured memories record the chat trace they came from
|
|
146
|
+
(`source_trace`); `engram show <id>` prints a memory's detail plus the source
|
|
147
|
+
call's model and prompt snippet for end-to-end auditing.
|
|
148
|
+
- **Plugin hooks**: `recall.register_adapter(...)` for runtime custom providers,
|
|
149
|
+
and auto-discovery of adapters published under the `recall.adapters`
|
|
150
|
+
entry-point group. *(simonw/llm-style.)*
|
|
151
|
+
- **OpenTelemetry export** (opt-in): `config otel_export true` mirrors calls as
|
|
152
|
+
OpenInference LLM spans to an OTLP backend (Phoenix/Langfuse) or the console —
|
|
153
|
+
no server dependency. `pip install 'engram-ai[otel]'`.
|
|
154
|
+
- **Eval ergonomics**: saved eval suites (`engram eval-suite save/list/rm`,
|
|
155
|
+
`engram eval <id> --suite NAME`), an eval pass-rate/score summary in
|
|
156
|
+
`engram stats`, and opt-in **auto-eval after chat** (`config auto_eval_suite`).
|
|
157
|
+
|
|
158
|
+
## [0.5.0]
|
|
159
|
+
|
|
160
|
+
Retrieval, cost accuracy, and quality — the next batch from the roadmap.
|
|
161
|
+
|
|
162
|
+
### Added
|
|
163
|
+
- **Graph-aware retrieval**: with `graph_weight > 0`, recall finds entities
|
|
164
|
+
named in the query, expands to their neighbors via the graph-lite relations,
|
|
165
|
+
and pulls in memories about those neighbors as an extra RRF signal — surfacing
|
|
166
|
+
connected memories the query never mentions. *(mem0/Zep-style.)*
|
|
167
|
+
- **Maintained pricing map**: provider-prefixed ids resolve
|
|
168
|
+
(`openrouter/openai/gpt-4o` → `gpt-4o`); override without editing the package
|
|
169
|
+
via `ENGRAM_PRICING_FILE` (JSON file) layered under `ENGRAM_PRICING` (inline);
|
|
170
|
+
more current models added; `engram pricing [model]` to inspect. *(LiteLLM-style.)*
|
|
171
|
+
- **Quality evals**: attach checks to a traced reply — local rules
|
|
172
|
+
(`--contains` / `--not-contains` / `--regex` / `--max-tokens`, free &
|
|
173
|
+
deterministic) and an opt-in `--judge "criterion"` LLM score (1–5 → 0–1).
|
|
174
|
+
`engram eval <trace_id> ...` and `engram evals` list results; `engram recent`
|
|
175
|
+
now shows trace IDs and kind. *(Langfuse/Phoenix-style, local.)*
|
|
176
|
+
|
|
177
|
+
## [0.4.0]
|
|
178
|
+
|
|
179
|
+
Memory intelligence + deeper local observability — closing the biggest gaps vs
|
|
180
|
+
mem0 / Letta / Zep / Langfuse, while staying single-file and server-free.
|
|
181
|
+
|
|
182
|
+
### Added
|
|
183
|
+
- **Memory lifecycle**: memories track `hit_count` / `last_used` and a
|
|
184
|
+
`valid_from` / `valid_to` / `active` window. Retrieval records hits and skips
|
|
185
|
+
inactive memories. Soft-forget via `engram forget --soft` and bulk
|
|
186
|
+
`engram prune --older-than DAYS --unused`. Opt-in recency/usage ranking
|
|
187
|
+
(`config recency_weight`) blends a lifecycle signal into retrieval via
|
|
188
|
+
weighted RRF. *(Zep/Letta-inspired.)*
|
|
189
|
+
- **Conflict resolution (ADD/UPDATE/DELETE/NOOP)**: opt-in `memory_ops = "llm"`
|
|
190
|
+
reconciles each new fact against its most-related memories so contradictions
|
|
191
|
+
are updated/removed instead of piling up. New `reconcile.py`; cost traced;
|
|
192
|
+
degrades to a plain ADD on any failure. *(mem0's signature.)*
|
|
193
|
+
- **Graph-lite**: a `relations` table stores `(subject, predicate, object)`
|
|
194
|
+
triples per scope — relational memory without a graph DB. Opt-in LLM mining
|
|
195
|
+
(`graph_extract`) from chats; `engram graph [entity]` to query, `--add` to add
|
|
196
|
+
manually. *(mem0/Zep/cognee-style, single-SQLite.)*
|
|
197
|
+
- **Local trace tree**: traces gain `session_id` / `parent_id` / `kind`, so a
|
|
198
|
+
turn's chat + its extraction/reconcile/graph calls form a tree. `engram trace`
|
|
199
|
+
renders per-turn call trees with token/cost totals; the dashboard gains a
|
|
200
|
+
"Recent turns" section.
|
|
201
|
+
- **Prompt templates / fragments**: `engram prompt save/list/show/use/rm` with
|
|
202
|
+
`{var}` substitution; `engram chat --template NAME --var k=v`. *(simonw/llm-style.)*
|
|
203
|
+
|
|
204
|
+
## [0.3.0]
|
|
205
|
+
|
|
206
|
+
Streaming, smarter memory, and the MCP bridge.
|
|
207
|
+
|
|
208
|
+
### Added
|
|
209
|
+
- **Streaming chat**: replies now type out token-by-token. `Recall.stream(...)`
|
|
210
|
+
yields chunks via an `on_token` callback and still returns the full
|
|
211
|
+
`ChatOutcome` (text, tokens, cost, auto-memory, budget). CLI: streams by
|
|
212
|
+
default; toggle with `engram chat --no-stream` or `config set stream false`.
|
|
213
|
+
Every adapter supports it — native OpenAI / Anthropic / Gemini adapters stream
|
|
214
|
+
for real, others transparently fall back to a single chunk.
|
|
215
|
+
- **LLM-based memory extraction** (opt-in): set `extraction_mode = "llm"` to let
|
|
216
|
+
a model pull durable first-person facts from each message — higher recall than
|
|
217
|
+
the heuristic patterns. Configurable extraction model (`extraction_model`),
|
|
218
|
+
its cost is traced, and it falls back to the heuristic extractor on any error.
|
|
219
|
+
- **MCP server** (`engram mcp`): exposes your memory to any MCP-aware agent
|
|
220
|
+
(Claude Desktop, Claude Code, Cursor, …) as tools — `remember`,
|
|
221
|
+
`recall_search`, `list_memories`, `forget`, `usage_stats`. Same local SQLite
|
|
222
|
+
store, nothing leaves your machine. Install with `pip install 'engram-ai[mcp]'`.
|
|
223
|
+
- **Memory editing**: `engram edit <id> "new content" [--tags ...]` updates a
|
|
224
|
+
memory in place and re-embeds it. Library: `Recall.edit(...)`.
|
|
225
|
+
- **Similarity merge / dedupe**: `engram dedupe [--threshold 0.9] [--all]
|
|
226
|
+
[--dry-run]` clusters near-duplicate memories by cosine similarity, keeps the
|
|
227
|
+
earliest, and unions their tags. Optional on-add suppression via
|
|
228
|
+
`config set dedupe_similarity 0.95` (both need embeddings; exact dedupe still
|
|
229
|
+
works without them).
|
|
230
|
+
- **Hybrid retrieval**: memory search now fuses semantic (embeddings) with
|
|
231
|
+
BM25 keyword ranking (SQLite FTS5) via Reciprocal Rank Fusion — exact terms,
|
|
232
|
+
names, and IDs the embeddings blur now surface, while semantically-close
|
|
233
|
+
memories still rank. FTS5 stays in sync via triggers and falls back to LIKE
|
|
234
|
+
where unavailable. No new dependencies. *(mem0 / Zep do the same.)*
|
|
235
|
+
- **Budget hard-stop**: `config set budget_enforce true` makes recall *refuse*
|
|
236
|
+
a call once today's spend hits `daily_budget_usd` (raises `BudgetExceeded`),
|
|
237
|
+
instead of only warning. *(LiteLLM-style.)*
|
|
238
|
+
|
|
239
|
+
### Fixed
|
|
240
|
+
- Install hints (`engram-ai[dashboard]`, `engram-ai[mcp]`) and model output are
|
|
241
|
+
no longer mangled by Rich markup parsing.
|
|
242
|
+
|
|
243
|
+
### Packaging
|
|
244
|
+
- PyPI Trusted Publishing workflow (`.github/workflows/publish.yml`): push a
|
|
245
|
+
`vX.Y.Z` tag to publish. CI workflow runs lint + tests on 3.9 / 3.11 / 3.12.
|
|
246
|
+
|
|
247
|
+
## [0.2.0]
|
|
248
|
+
|
|
249
|
+
Major feature round.
|
|
250
|
+
|
|
251
|
+
### Added
|
|
252
|
+
- **Auto-memory**: after each chat, recall heuristically captures durable
|
|
253
|
+
first-person facts/preferences (English + Chinese), tagged as `auto`.
|
|
254
|
+
- **Memory scopes**: isolate memories per project/context
|
|
255
|
+
(`engram scope work`, `--scope`, `--all`). Active scope stored in config.
|
|
256
|
+
- **Config system** (`~/.engram/config.json`): default provider/model, daily
|
|
257
|
+
budget, auto-memory toggle, inject limit, active scope.
|
|
258
|
+
CLI: `engram config show|set|path`.
|
|
259
|
+
- **Daily budget + warnings**: set `daily_budget_usd`; chat and `stats` warn at
|
|
260
|
+
80% and 100% of the day's spend.
|
|
261
|
+
- **Guided setup**: `engram init` (pick defaults, detect keys) and
|
|
262
|
+
`engram doctor` (which providers are ready).
|
|
263
|
+
- **Export / import**: `engram export mem.json` / `engram import mem.json`
|
|
264
|
+
(JSON, dedupe-aware).
|
|
265
|
+
- **Deduplication**: identical memories in the same scope are skipped.
|
|
266
|
+
- **Flexible chat**: `engram chat "prompt"` uses configured defaults; the
|
|
267
|
+
three-arg form still works.
|
|
268
|
+
- **Dashboard upgrades**: auto-refresh, daily-budget bar, scope chips.
|
|
269
|
+
- Safe schema migrations for existing databases.
|
|
270
|
+
|
|
271
|
+
### Changed
|
|
272
|
+
- `Recall.chat()` now returns a richer `ChatOutcome` (cost, latency,
|
|
273
|
+
auto-remembered list, budget warning).
|
|
274
|
+
|
|
275
|
+
## [0.1.0]
|
|
276
|
+
|
|
277
|
+
First MVP.
|
|
278
|
+
|
|
279
|
+
### Added
|
|
280
|
+
- Local-first SQLite store (`~/.engram/recall.db`) for memories + call traces.
|
|
281
|
+
- Memory engine with semantic search (sentence-transformers) and automatic
|
|
282
|
+
keyword fallback when embeddings are not installed.
|
|
283
|
+
- **22 model providers** out of the box: OpenAI, Anthropic, Gemini, DeepSeek,
|
|
284
|
+
Qwen, Moonshot (Kimi), Zhipu (GLM), MiniMax, Baichuan, 01.AI (Yi), StepFun,
|
|
285
|
+
Mistral, xAI (Grok), Groq, Together, Fireworks, DeepInfra, Perplexity,
|
|
286
|
+
OpenRouter, Ollama, LM Studio, and any OpenAI-compatible endpoint.
|
|
287
|
+
- Per-provider API key env var resolution with `ENGRAM_API_KEY` fallback.
|
|
288
|
+
- Expanded pricing table covering the new providers.
|
|
289
|
+
- Automatic per-call tracing: tokens, estimated cost, latency.
|
|
290
|
+
- CLI: `add`, `search`, `list`, `forget`, `chat`, `stats`, `recent`, `models`,
|
|
291
|
+
`dashboard`, `version`.
|
|
292
|
+
- Minimal local web dashboard (FastAPI, single page, no build step).
|
|
293
|
+
- Library API via `from recall import Recall`.
|
memstash-0.15.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 zionLyl
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|