v0.5.3
Correctness and performance pass over the search and ingestion paths. No
API breakage; no new dependencies.
Bug fixes
- Hybrid search now reports scores correctly. Results from the
hybrid (vector + FTS) path were silently flagged as FTS-only and
rendered asN/A (FTS Match). The LanceDB_relevance_scorecolumn
is now read separately from the pure-vector_distancecolumn. - Search filters survive the FTS fallback. Previously, when the
FTS index was missing and the query fell back to pure-vector search,
source_filterandmin_timepushdowns were silently dropped —
callers received unfiltered results. Filters are now re-applied via
a single helper on whichever op actually runs. - MCP tools no longer block the event loop.
search_documentsand
search_sql_logsoffloadSearchService.execute_queryvia
asyncio.to_thread, mirroring the FastAPI pattern. Concurrent MCP
requests over the streamable-HTTP transport are no longer serialized.
Performance
- Dedup hash scan projects one column.
get_existing_hashesnow
reads onlycontent_hashviatable.search().select([...]).to_arrow()
instead of materialising the full table (including 768-dim vectors).
On a 100k-row SQL index this drops per-ingest I/O from ~300 MB to
~2 MB. - Unchanged files skip chunking entirely. Ingestion short-circuits
the chunker when a document's file-level hash is already in the
store. Re-runningingestover an unchanged markdown tree no longer
re-parses it.
Internal
- DI factory extracted to
services/bootstrap.py. The API layer
(api/state.py) no longer imports fromcli.py, removing the
typer + Hugging Face env-var side effects from the API import graph.
cli._build_dependenciesremains as a thin wrapper that converts
schema-mismatch errors totyper.Exit.
Upgrade notes
- Storage-stack refresh:
lance==1.2.1(dead PyPI pin from 2020) removed;lancedb0.29.2 → 0.30.2;pyarrow19 → 24 (5 major versions, zero code change);polars1.38 → 1.40. - ML stack refresh:
mlx-embeddings0.0.5 → 0.1.0, which pulledtransformers4.x → 5.x. Validated with live model load and smoke-test search against the embeddinggemma-300m-bf16 model. - Bug B2 (hybrid-score display):
services/search.py:53,api/mcp_server.py:42,api/mcp_server.py:91— all three display sites were branching only ondistance, mislabeling every hybrid hit asN/A (FTS Match). Fixed with a 3-branch check (distance → score → N/A), new TDD red-then-green unit tests for both the CLI and MCP surfaces, and live e2e verification (Score: 0.0325on paraphrased semantic query, correctly retrieved semantically-close chunks). - Total test count: 193 → 195 (2 added for B2).
Full Changelog: v0.5.1...v0.5.3