|
1 | 1 | # Changelog |
2 | 2 |
|
| 3 | +## 2.3.0 (2026-03-26) |
| 4 | + |
| 5 | +### Multi-Path Retrieval with RRF Fusion |
| 6 | + |
| 7 | +Search now runs three retrieval paths in parallel and merges results using Reciprocal Rank Fusion — dramatically improving recall for exact names, technical terms, and entity-connected memories. |
| 8 | + |
| 9 | +#### New Retrieval Paths |
| 10 | +- **BM25 keyword search** — Full-text search via Postgres tsvector/GIN index or SQLite FTS5 fallback. Catches exact term matches that embedding similarity misses (client names, technical terms, error codes). |
| 11 | +- **Entity graph BFS retrieval** — Breadth-first spreading activation through the entity relationship graph. Starts from entities mentioned in the query, traverses co-occurrence and typed relationships (uses, works_on, contact_of) with configurable activation decay. Surfaces memories connected by entity relationships, not just text similarity. |
| 12 | +- **Reciprocal Rank Fusion (RRF)** — Merges ranked lists from all three paths using `score(d) = sum(1/(k+rank))`. Items found by multiple paths get boosted. Pure JS, zero dependencies. |
| 13 | + |
| 14 | +#### New Files |
| 15 | +- `api/src/services/rrf.js` — RRF fusion algorithm with 13 unit tests |
| 16 | +- `api/src/services/keyword-search.js` — BM25/FTS keyword search service |
| 17 | +- `api/src/services/graph-search.js` — BFS spreading activation graph retrieval |
| 18 | +- `api/scripts/backfill-keyword-index.js` — One-time migration for existing memories |
| 19 | +- `api/tests/rrf.test.js` — Comprehensive test suite (edge cases, score verification, 3-path scenarios) |
| 20 | + |
| 21 | +#### API Changes |
| 22 | +- `GET /memory/search` runs all 3 paths via `Promise.all()`, fuses with RRF |
| 23 | +- `format=full` results include `retrieval_sources` array showing which paths contributed (e.g. `["vector", "keyword", "graph"]`) |
| 24 | +- `format=full` response includes `retrieval` metadata with per-path hit counts |
| 25 | +- `POST /memory` indexes content for keyword search on write (fire-and-forget) |
| 26 | +- `DELETE /memory/:id` and supersede logic deactivate keyword index entries |
| 27 | +- `GET /stats` includes `retrieval` section with keyword index count and path availability |
| 28 | + |
| 29 | +#### MCP Tool Updates |
| 30 | +- `brain_search` description updated to reflect multi-path retrieval |
| 31 | + |
| 32 | +#### Schema Changes |
| 33 | +- **Postgres**: `memory_search` table with tsvector column, GIN index, auto-compute trigger. Partial indexes on `entity_relationships` for co-occurrence lookups. |
| 34 | +- **SQLite**: FTS5 virtual table `memory_search_fts` for keyword search fallback. |
| 35 | +- **Qdrant**: `getPoints()` batch retrieval endpoint for RRF payload hydration. |
| 36 | + |
| 37 | +#### Configuration |
| 38 | +- `MULTI_PATH_SEARCH=true|false` — Feature flag (default: true) |
| 39 | +- `RRF_K=60` — RRF smoothing constant (range 50-100) |
| 40 | +- `GRAPH_SEARCH_MAX_DEPTH=2` — Max BFS hops through entity graph |
| 41 | +- `GRAPH_SEARCH_DECAY=0.8` — Activation decay per hop |
| 42 | +- `GRAPH_SEARCH_CAUSAL_BOOST=2.0` — Boost for typed relationships vs co_occurrence |
| 43 | + |
| 44 | +#### Testing |
| 45 | +- 13 new RRF unit tests, 114 total tests passing |
| 46 | + |
| 47 | +Inspired by [vectorize-io/hindsight](https://github.com/vectorize-io/hindsight)'s 4-way parallel search architecture. |
| 48 | + |
3 | 49 | ## 2.0.0 (2026-03-20) |
4 | 50 |
|
5 | 51 | ### Features |
|
0 commit comments