Skip to content

feat: add FTS5 full-text search for memory retrieval - #2

Merged
codejunkie99 merged 1 commit into
codejunkie99:masterfrom
sergi-rz:feat/memory-search-fts5
Apr 16, 2026
Merged

codejunkie99 merged 1 commit into
codejunkie99:masterfrom
sergi-rz:feat/memory-search-fts5

Conversation

@sergi-rz

@sergi-rz sergi-rz commented Apr 16, 2026 •

Copy link
Copy Markdown

Problem

The memory system can surface the top-k entries by salience score (context_budget.py), but there's no way to search by topic or keyword. If an agent needs to recall what it learned about deploys, or a specific past failure, it has no retrieval path — it only sees whatever happens to score highest globally.

Solution

A lightweight memory_search.py that builds a SQLite FTS5 index over all .md and .jsonl files in .agent/memory/. It:

  • Auto-rebuilds when any source file is newer than the index
  • Falls back to grep if FTS5 isn't compiled into the Python installation
  • Indexes JSONL entries by extracting action, reflection, detail, and skill fields into searchable text
  • Returns ranked results with context snippets highlighting matches

Usage

python3 .agent/memory/memory_search.py "deploy failure"
python3 .agent/memory/memory_search.py --status
python3 .agent/memory/memory_search.py --rebuild

What's changed

  • New file: .agent/memory/memory_search.py — the search tool (~170 lines, zero dependencies beyond stdlib)
  • .gitignore — excludes .agent/memory/.index/ (derived, auto-rebuilt)
  • memory-manager/SKILL.md — documents the search command so the agent knows it exists

No existing code is modified. This is purely additive.

Context

I'm building Claudia OS, a personal AI assistant on top of Claude Code. I adopted your episodic memory architecture, dream cycle, and salience scoring (credited in my ATTRIBUTION.md). While adapting it, I needed keyword search over memory — the salience-only retrieval wasn't enough when the agent needed to recall something specific. This FTS5 approach solved it cleanly without adding infrastructure.

🤖 Generated with Claude Code

Currently the memory system can only surface top-k entries by salience
score, but cannot search by topic or keyword. This adds a lightweight
SQLite FTS5 search tool that indexes all .md and .jsonl files under
.agent/memory/ and returns ranked results with context snippets.

- memory_search.py: FTS5 index with auto-rebuild and grep fallback
- .gitignore: exclude derived .index/ directory
- memory-manager SKILL.md: document the search command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codejunkie99 codejunkie99 self-assigned this Apr 16, 2026
@codejunkie99 codejunkie99 added the enhancement New feature or request label Apr 16, 2026
@codejunkie99
codejunkie99 merged commit a012575 into codejunkie99:master Apr 16, 2026
codejunkie99 pushed a commit that referenced this pull request Apr 16, 2026
Written by Minimax-M2.7 in Claude Code Harness.

Integrates sergi-rz's FTS5 memory search (#2) behind a beta feature
flag. Default OFF; users opt in through the onboarding wizard or by
editing .agent/memory/.features.json directly. Addresses the three
codex review findings on that PR at the same time.

Beta feature framework
- onboard_features.py (new): read/write .agent/memory/.features.json
  with a simple {key: {enabled: bool, beta: bool}} schema.
- onboard.py: adds a final "Optional features" step to the wizard.
  Default answer is No — beta features stay off unless the user
  explicitly opts in. --yes (non-interactive) path writes the
  features file too, all off.
- memory_search.py gates search/rebuild behind feature_enabled().
  --status still works regardless so users can see the toggle.

Codex review fixes on PR #2
- [P1] needs_rebuild now compares the set of memory files currently
  on disk with the set already in the index; any previously-indexed
  file that no longer exists flags the index stale. Without this,
  deleted/renamed files kept appearing in results until some
  unrelated file bumped the index.
- [P2] search_grep now passes explicit .md/.jsonl target paths to
  grep instead of scanning the whole .agent/memory/ tree. Source
  files (archive.py, auto_dream.py, etc.) no longer pollute
  fallback search results.
- [P3] .gitignore now ignores .agent/memory/.index/ correctly.
  The previous rule was cancelled by the !.agent/memory/**
  negation placed below it; moved the .index/ exclusion AFTER
  the negation so the later rule wins. Verified with
  git status --ignored.
joyanes97 pushed a commit to joyanes97/agentic-stack that referenced this pull request Sep 27, 2026
feat: add FTS5 full-text search for memory retrieval
joyanes97 pushed a commit to joyanes97/agentic-stack that referenced this pull request Sep 27, 2026
…nkie99#2 review

Written by Minimax-M2.7 in Claude Code Harness.

Integrates sergi-rz's FTS5 memory search (codejunkie99#2) behind a beta feature
flag. Default OFF; users opt in through the onboarding wizard or by
editing .agent/memory/.features.json directly. Addresses the three
codex review findings on that PR at the same time.

Beta feature framework
- onboard_features.py (new): read/write .agent/memory/.features.json
  with a simple {key: {enabled: bool, beta: bool}} schema.
- onboard.py: adds a final "Optional features" step to the wizard.
  Default answer is No — beta features stay off unless the user
  explicitly opts in. --yes (non-interactive) path writes the
  features file too, all off.
- memory_search.py gates search/rebuild behind feature_enabled().
  --status still works regardless so users can see the toggle.

Codex review fixes on PR codejunkie99#2
- [P1] needs_rebuild now compares the set of memory files currently
  on disk with the set already in the index; any previously-indexed
  file that no longer exists flags the index stale. Without this,
  deleted/renamed files kept appearing in results until some
  unrelated file bumped the index.
- [P2] search_grep now passes explicit .md/.jsonl target paths to
  grep instead of scanning the whole .agent/memory/ tree. Source
  files (archive.py, auto_dream.py, etc.) no longer pollute
  fallback search results.
- [P3] .gitignore now ignores .agent/memory/.index/ correctly.
  The previous rule was cancelled by the !.agent/memory/**
  negation placed below it; moved the .index/ exclusion AFTER
  the negation so the later rule wins. Verified with
  git status --ignored.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants