Commit Graph

195 Commits

Author SHA1 Message Date
Paul Hernandez df7452e3ba fix(core): make note_types search filter case-insensitive (#912)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 22:44:04 -05:00
Paul Hernandez 4fe6fe09c8 feat(core): add observation category filter to search (#908)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 19:57:19 -05:00
Paul Hernandez 8acdb49a41 fix(core): reuse a single embedding provider per process (#903)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 19:14:07 -05:00
Paul Hernandez 5b034f081d fix(core): self-heal corrupt FastEmbed model cache (#900)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:37:30 -05:00
Paul Hernandez 271c883ea8 fix(core): load sqlite-vec for embedding-status query (#901)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:37:27 -05:00
Sourish Chakraborty f916662ff3 fix(core): allow cross-project context traversal 2026-06-06 21:43:21 -05:00
tk f6565b9d23 fix(core): L2-normalize FastEmbed vectors (#843)
L2-normalizes FastEmbed output vectors at the provider boundary so SQLite vector scoring keeps its unit-vector contract for custom FastEmbed models such as multilingual MiniLM variants.

Zero vectors are preserved as-is to avoid division errors, and the provider tests cover both non-unit vectors and zero-vector behavior.

Verification:
- uv run pytest tests/repository/test_fastembed_provider.py -q
- uv run ruff check src/basic_memory/repository/fastembed_provider.py tests/repository/test_fastembed_provider.py
- uv run ruff format --check src/basic_memory/repository/fastembed_provider.py tests/repository/test_fastembed_provider.py

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: tk-pkm111 <133480534+tk-pkm111@users.noreply.github.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-06-06 17:15:19 -05:00
Aarish Alam b6e8c636ce feat(core): add LiteLLM embedding provider (#809)
Adds LiteLLM as a semantic embedding provider, including provider configuration, vector normalization, live-provider evaluation tooling, and documentation for OpenAI, Cohere, Azure Foundry, Azure OpenAI, and NVIDIA NIM-style cases.

Maintainer follow-up on this PR added provider hardening, asymmetric document/query embedding support, dimension-forwarding controls, SQLite/Postgres vector invalidation coverage, and the repeatable live LiteLLM harness.

Verification:
- Full base-repo Tests workflow passed for 3d4e092ceb: https://github.com/basicmachines-co/basic-memory/actions/runs/27072071785
- Live LiteLLM harness passed locally for OpenAI, Cohere, and Azure Foundry.

Co-authored-by: Aarish Alam <arishalam121@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: RheagalFire <arishalam121@gmail.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-06-06 17:13:09 -05:00
phernandez 5365f971ef chore(integrations): consolidate agent packages
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-30 14:16:04 -05:00
Drew Cain 9af320187c fix(core): load sqlite-vec before vector table cleanup (#852)
Signed-off-by: Drew Cain <groksrc@gmail.com>
2026-05-26 00:27:47 -05:00
Paul Hernandez 9e3fe26a83 fix(core): purge SQLite search_index on project delete (#832)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-16 16:47:24 -05:00
Paul Hernandez 3bed6d8890 chore(deps): update deps and harden security (#825)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-15 10:45:14 -05:00
Paul Hernandez 415c2b3d6e feat(cli): add orphan entity command (#816)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-11 12:13:14 -05:00
Drew Cain 9862ef5411 fix(core): use updated_at for recent_activity filter and ordering (#812)
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Signed-off-by: Drew Cain <groksrc@gmail.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: phernandez <paul@basicmachines.co>
2026-05-11 09:14:06 -05:00
Paul Hernandez 26381aeed1 fix(mcp): use lightweight graph hydration lookup (#806)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-08 10:07:29 -05:00
Paul Hernandez 09a4b09436 feat(api): include search result totals (#791)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-05-04 14:57:04 -05:00
Paul Hernandez 0b335476d6 fix(mcp): resolve projects by external_id, remove workspace from MCP tools (#777)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-01 05:15:44 -05:00
Paul Hernandez 2bfb9c76df fix(core): degrade gracefully when sqlite-vec cannot load on init (#774)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-29 08:57:31 -05:00
Paul Hernandez 1b39062ecd refactor(core): rip telemetry wrappers, use logfire directly (#754)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:58:19 -05:00
Paul Hernandez c4cf0aff1e perf(sync): speed up single markdown file indexing (#751)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-17 07:08:21 -05:00
Drew Cain bf9a6b4a75 fix(core): resolve FastEmbed cache under data dir instead of /tmp (#743)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:55:00 -05:00
phernandez 8f2b25f0e0 test(core): stabilize postgres fixtures
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-13 14:25:26 -05:00
Paul Hernandez 052545b661 chore(core): make ty the default typechecker (#736)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-13 10:34:01 -05:00
Paul Hernandez 093c94fea5 fix(core): clean up delete vectors and cloud sync (#733)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-09 21:23:45 -05:00
Paul Hernandez 7945c1e2f7 perf(core): speed up vector sync and tune fastembed defaults (#731)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-09 00:20:12 -05:00
Paul Hernandez 540da418b3 perf(sync): batch file indexing in core (#726)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-08 01:21:49 -05:00
Paul Hernandez 3e40cb9657 fix(core): remove runtime ALTER TABLE from vector init (#728)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-08 00:39:37 -05:00
Paul Hernandez 8c81d3ce17 perf(core): reduce postgres vector sync work (#723)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-07 19:00:19 -05:00
Drew Cain b35d594ef0 fix(core): preserve external_id during entity upsert on re-index (#724)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 10:26:10 -05:00
Paul Hernandez 88c8f18200 feat(core): add note_content tenant schema primitive (#719)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-04-04 22:06:37 -05:00
Drew Cain 367fcaac50 perf: eliminate redundant DB queries in upsert_entity_from_markdown (#714)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: phernandez <paul@basicmachines.co>
2026-04-04 12:40:27 -05:00
Paul Hernandez 30a89357cb fix(core): handle SQLite and Windows semantic regressions (#655)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-03-09 22:18:17 -05:00
phernandez d15f6a8427 Add batched vector sync orchestration across repositories 2026-03-03 16:36:06 -06:00
phernandez b8a3a14ad2 Add semantic query timing and FastEmbed parallel guardrails
Signed-off-by: phernandez <paul@basicmachines.co>
2026-03-03 14:04:03 -06:00
phernandez 9b199c6dcb fix: add FastEmbed runtime tuning knobs and provider caching
Add configurable cache_dir, threads, and parallel settings for FastEmbed
to support cloud deployments where defaults fail. Cache embedding providers
at the process level to avoid re-creating heavy ONNX model instances.

- Add semantic_embedding_cache_dir, semantic_embedding_threads, and
  semantic_embedding_parallel config fields
- Thread-safe provider cache with double-checked locking in factory
- Forward runtime knobs through to TextEmbedding and embed() calls
- Fix if/elif chain in factory for correct error handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-03-03 10:26:47 -06:00
Paul Hernandez e97eafa55a fix: build_context related_results schema validation failure (#631)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 12:30:44 -06:00
phernandez 54b968b93c fix: reduce excessive log volume by demoting per-request noise to DEBUG (#613)
Demote high-frequency per-request/per-item logs from INFO to DEBUG:
- 🔇 Client routing decisions (async_client.py) — logged every MCP tool call
- 🔇 DB migration checks (db.py) — logged every ASGI client creation
- 🔇 Vector table ensure/ready (sqlite + postgres search repos) — logged every search
- 🔇 Per-entity search index start/complete (search_service.py) — logged every file sync
- 🔇 Incremental scan details + per-file permalink updates (sync_service.py)
- 🔇 MCP search tool params and no-results (search.py)
- 📉 Log retention: "10 days" → 5 files (~50MB cap)

API v2 request/response logs remain at INFO for observability.

Closes #613

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-26 19:48:24 -06:00
phernandez 9331126ba1 feat: improve content hit rate in search results (#609)
Three changes to surface more answer text in search results:

- Populate matched_chunk_text for FTS-only hybrid results from content_snippet,
  preventing fallback to truncated content when vector search has no match
- Increase TOP_CHUNKS_PER_RESULT from 3 to 5, catching answers in deeper chunks
  for large notes (~2700 → ~4500 chars of matched context)
- Increase CONTENT_DISPLAY_LIMIT from 2000 to 4000, doubling the safety-net
  content truncation for results without matched_chunk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-26 11:55:38 -06:00
phernandez f9b2a075a9 feat: return richer content context in search results (#609)
Two strategies to improve content hit rate when the right document is found:

1. Small notes (<=2000 chars): return full content_snippet as matched_chunk
   so the answer is always present for correctly-retrieved small notes
2. Large notes: return top-3 chunks by similarity joined with \n---\n
   instead of just the single best chunk (~2700 chars vs ~900 chars)

Also raises CONTENT_DISPLAY_LIMIT from 250 to 2000 for richer FTS results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-26 08:36:54 -06:00
phernandez f5a0e942b0 fix: replace RRF with score-based fusion in hybrid search (#577)
RRF compressed all fused scores to ~0.016, destroying ranking differentiation.
The new formula `max(vec, fts) + FUSION_BONUS * min(vec, fts)` preserves
dominant signals and rewards dual-source agreement.

Changes:
- Remove RRF_K constant; add FUSION_BONUS (0.3) and FTS_GATE_THRESHOLD (0.0)
- Use raw vector similarity scores instead of re-normalizing by vec_max
- Zero-score results now produce zero fused score (no 0.1 weight floor)
- Rename test_hybrid_rrf.py → test_hybrid_fusion.py with updated assertions
- Update docs and docstrings to reflect score-based fusion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-25 22:53:00 -06:00
phernandez b6369d3d14 fix: cap sqlite-vec knn k parameter at 4096 limit
sqlite-vec enforces k <= 4096 for nearest-neighbor queries. Projects with
>4096 vector chunks would crash all vector/hybrid search because
candidate_limit = max(100, (limit + offset) * 10) exceeded this hard limit.

Clamp the knn k in _run_vector_query while keeping the outer SQL LIMIT
unclamped. Only affects SQLite — pgvector has no such constraint.

Fixes #604

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-24 23:23:15 -06:00
phernandez 054178d155 fix: parameterize SQL queries in search repository type filters
Replace f-string interpolation with parameterized queries for note_types,
search_item_types, and metadata filter paths to prevent SQL injection.

Fixes #591

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-23 22:16:46 -06:00
Paul Hernandez 0f3889fdd0 fix: Return matched chunk text in search results (#601)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:01:20 -06:00
Paul Hernandez c44291830c chore: rename entity_type to note_type (#600)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 20:28:57 -06:00
Paul Hernandez b86dd6fb53 feat: Fix bm CLI runtime defects and audit regressions (#596)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-20 22:59:29 -06:00
Drew Cain 9c9ff2931d fix: backend-specific distance-to-similarity conversion (#593)
Signed-off-by: Drew Cain <groksrc@gmail.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
Co-authored-by: phernandez <paul@basicmachines.co>
2026-02-20 20:15:46 -06:00
Paul Hernandez edb7991ccf fix: strip NUL bytes from content before PostgreSQL search indexing (#592)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:11:04 -06:00
jope-bm deef89a724 feat: Add display_name and is_private to ProjectItem (#574)
Signed-off-by: Joe P <joe@basicmemory.com>
Signed-off-by: phernandez <paul@basicmachines.co>
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Paul Hernandez <60959+phernandez@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Paul Hernandez <phernandez@users.noreply.github.com>
Co-authored-by: phernandez <paul@basicmachines.co>
Co-authored-by: jope-bm <jope-bm@users.noreply.github.com>
2026-02-20 01:44:07 -06:00
Paul Hernandez 306e562281 chore: Make semantic deps default, auto-backfill embeddings, and default search to semantic (#586)
Signed-off-by: phernandez <paul@basicmachines.co>
2026-02-19 18:31:15 -06:00
Paul Hernandez 55d675e278 feat: min_similarity override, cloud promo improvements (#570)
Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:44:02 -06:00