Impact: Medium (memory)
`server/main.py:46` constructs `BM25SparseProvider()` and stores it in `server/state.py` (used by the search tools via `get_sparse_provider()`), while `IndexPipeline.init` (`server/indexer/pipeline.py:149`) calls `get_sparse_embedding_provider()` — a different singleton defined in `server/embeddings/bm25.py:39-43`.
So indexing and querying each load their own `Bm25` model (double memory), and `close_sparse_embedding_provider()` (`bm25.py:46-48`) only clears the module singleton, never the one held in state.
Recommended change
Share a single BM25 instance between the pipeline and the search tools.
Impact: Medium (memory)
`server/main.py:46` constructs `BM25SparseProvider()` and stores it in `server/state.py` (used by the search tools via `get_sparse_provider()`), while `IndexPipeline.init` (`server/indexer/pipeline.py:149`) calls `get_sparse_embedding_provider()` — a different singleton defined in `server/embeddings/bm25.py:39-43`.
So indexing and querying each load their own `Bm25` model (double memory), and `close_sparse_embedding_provider()` (`bm25.py:46-48`) only clears the module singleton, never the one held in state.
Recommended change
Share a single BM25 instance between the pipeline and the search tools.