Skip to content

Commit 5a1299f

Browse files
author
Flamehaven CI
committed
docs: strengthen README badges + refine _search_local.py
- README: 4 badges -> 8 (CI, PyPI version, downloads, GitHub stars, MIT, Python, black, Docker) - _search_local.py: max(1,...) guard on bm25_top_k, named uri sets, res->result rename, log args inline
1 parent 30a452c commit 5a1299f

2 files changed

Lines changed: 26 additions & 32 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66

77
### Self-hosted RAG search engine. Production-ready in 3 minutes.
88

9+
[![CI](https://github.com/flamehaven01/Flamehaven-Filesearch/actions/workflows/ci.yml/badge.svg)](https://github.com/flamehaven01/Flamehaven-Filesearch/actions/workflows/ci.yml)
10+
[![PyPI version](https://img.shields.io/pypi/v/flamehaven-filesearch.svg)](https://pypi.org/project/flamehaven-filesearch/)
11+
[![PyPI downloads](https://img.shields.io/pypi/dm/flamehaven-filesearch.svg?label=PyPI%20downloads)](https://pypi.org/project/flamehaven-filesearch/)
12+
[![GitHub stars](https://img.shields.io/github/stars/flamehaven01/Flamehaven-Filesearch?style=flat&label=stars)](https://github.com/flamehaven01/Flamehaven-Filesearch/stargazers)
913
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10-
[![Version](https://img.shields.io/badge/version-1.6.2-blue.svg)](CHANGELOG.md)
1114
[![Python](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/)
15+
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
1216
[![Docker](https://img.shields.io/badge/docker-ready-brightgreen.svg)](https://hub.docker.com/r/flamehaven/filesearch)
1317

1418
[Quick Start](#-quick-start)[Features](#-features)[Documentation](#-documentation)[API Reference](http://localhost:8000/docs)[Contributing](#-contributing)

flamehaven_filesearch/_search_local.py

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@
1010
from urllib.parse import quote
1111

1212
from .engine.hybrid_search import BM25, reciprocal_rank_fusion
13-
from .engine.quality_gate import (
14-
SearchQualityGate,
15-
SearchMetaLearner,
16-
compute_search_confidence,
17-
)
13+
from .engine.quality_gate import SearchQualityGate, SearchMetaLearner, compute_search_confidence
1814

1915
logger = logging.getLogger(__name__)
2016

@@ -104,13 +100,18 @@ def _resolve_fused_docs(
104100
def _run_hybrid_rerank(
105101
self, store_name: str, query: str, semantic_results: List
106102
) -> Tuple[List[Dict[str, Any]], float]:
107-
"""BM25 + ChronosGrid semantic -> RRF -> resolved docs + confidence score."""
103+
"""BM25 + ChronosGrid semantic -> RRF -> resolved docs + confidence score.
104+
105+
Returns:
106+
(resolved_docs, confidence) where confidence is rank-divergence-gated [0, 1].
107+
"""
108108
if store_name not in self._bm25_indices or store_name in self._bm25_dirty:
109109
self._rebuild_bm25(store_name)
110110

111111
# alpha->0 (keyword-dominant): expand BM25 pool; alpha->1: contract it.
112112
alpha = (getattr(self, "_meta_alpha", {})).get(store_name, 0.5)
113-
bm25_top_k = int(self.config.max_sources * 2 * max(0.5, 1.5 - alpha))
113+
bm25_multiplier = max(0.5, 1.5 - alpha) # alpha=0.2->1.3x, 0.5->1.0x, 0.8->0.7x
114+
bm25_top_k = max(1, int(self.config.max_sources * 2 * bm25_multiplier))
114115

115116
bm25_ranked = self._collect_bm25_ranked(store_name, query, bm25_top_k)
116117
sem_ranked = self._collect_sem_ranked(store_name, semantic_results)
@@ -119,10 +120,11 @@ def _run_hybrid_rerank(
119120
[sem_ranked, bm25_ranked], k=60, top_k=self.config.max_sources
120121
)
121122

123+
bm25_uri_set = {r["id"] for r in bm25_ranked}
124+
sem_uri_set = {r["id"] for r in sem_ranked}
122125
raw_score = fused[0]["score"] if fused else 0.0
123-
confidence = compute_search_confidence(
124-
raw_score, {r["id"] for r in bm25_ranked}, {r["id"] for r in sem_ranked}
125-
)
126+
confidence = compute_search_confidence(raw_score, bm25_uri_set, sem_uri_set)
127+
126128
return self._resolve_fused_docs(store_name, fused), confidence
127129

128130
# ------------------------------------------------------------------
@@ -184,28 +186,22 @@ def _local_search(
184186
}
185187

186188
if not docs:
187-
res = {
189+
result = {
188190
"status": "success",
189191
"answer": "No documents indexed yet.",
190192
"sources": [],
191193
**base,
192194
}
193195
if search_mode in ["semantic", "hybrid", "multimodal"]:
194-
res["semantic_results"] = semantic_results or []
195-
return res
196+
result["semantic_results"] = semantic_results or []
197+
return result
196198

197-
quality_gate: SearchQualityGate = getattr(
198-
self, "_quality_gate", SearchQualityGate()
199-
)
200-
meta_learner: SearchMetaLearner = getattr(
201-
self, "_meta_learner", SearchMetaLearner()
202-
)
199+
quality_gate: SearchQualityGate = getattr(self, "_quality_gate", SearchQualityGate())
200+
meta_learner: SearchMetaLearner = getattr(self, "_meta_learner", SearchMetaLearner())
203201

204202
# Hybrid: BM25 + semantic RRF with quality gate
205203
if search_mode == "hybrid" and semantic_results:
206-
fused_docs, confidence = self._run_hybrid_rerank(
207-
store_name, query, semantic_results
208-
)
204+
fused_docs, confidence = self._run_hybrid_rerank(store_name, query, semantic_results)
209205
verdict = quality_gate.evaluate(confidence)
210206

211207
if fused_docs:
@@ -274,9 +270,7 @@ def _local_search(
274270
result["semantic_results"] = semantic_results or []
275271
return result
276272

277-
def _run_meta_adapt(
278-
self, store_name: str, meta_learner: "SearchMetaLearner"
279-
) -> None:
273+
def _run_meta_adapt(self, store_name: str, meta_learner: "SearchMetaLearner") -> None:
280274
"""Apply MetaLearner alpha recommendation when adaptation cycle triggers."""
281275
if not meta_learner.should_adapt():
282276
return
@@ -288,10 +282,7 @@ def _run_meta_adapt(
288282
self._meta_alpha[store_name] = new_alpha
289283
logger.info(
290284
"[QualityGate] store=%s alpha %.3f -> %.3f trend=%s",
291-
store_name,
292-
current,
293-
new_alpha,
294-
meta_learner.store_trend(store_name),
285+
store_name, current, new_alpha, meta_learner.store_trend(store_name),
295286
)
296287

297288
# ------------------------------------------------------------------
@@ -322,8 +313,7 @@ def _resolve_semantic_sources(
322313
if not resolved:
323314
return None
324315
snippets = [
325-
self._build_snippet(d.get("content", ""), query)
326-
or d.get("content", "")[:200]
316+
self._build_snippet(d.get("content", ""), query) or d.get("content", "")[:200]
327317
for d in resolved[:5]
328318
]
329319
answer = " ".join(s for s in snippets if s) or (

0 commit comments

Comments
 (0)