Skip to content

Commit 534f622

Browse files
author
Flamehaven CI
committed
style: black format 4 files — CI black --check fix
1 parent dea1d6a commit 534f622

4 files changed

Lines changed: 44 additions & 31 deletions

File tree

flamehaven_filesearch/_search_local.py

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

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

1519
logger = logging.getLogger(__name__)
1620

@@ -100,18 +104,13 @@ def _resolve_fused_docs(
100104
def _run_hybrid_rerank(
101105
self, store_name: str, query: str, semantic_results: List
102106
) -> Tuple[List[Dict[str, Any]], float]:
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-
"""
107+
"""BM25 + ChronosGrid semantic -> RRF -> resolved docs + confidence score."""
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_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))
113+
bm25_top_k = int(self.config.max_sources * 2 * max(0.5, 1.5 - alpha))
115114

116115
bm25_ranked = self._collect_bm25_ranked(store_name, query, bm25_top_k)
117116
sem_ranked = self._collect_sem_ranked(store_name, semantic_results)
@@ -120,11 +119,10 @@ def _run_hybrid_rerank(
120119
[sem_ranked, bm25_ranked], k=60, top_k=self.config.max_sources
121120
)
122121

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

130128
# ------------------------------------------------------------------
@@ -186,22 +184,28 @@ def _local_search(
186184
}
187185

188186
if not docs:
189-
result = {
187+
res = {
190188
"status": "success",
191189
"answer": "No documents indexed yet.",
192190
"sources": [],
193191
**base,
194192
}
195193
if search_mode in ["semantic", "hybrid", "multimodal"]:
196-
result["semantic_results"] = semantic_results or []
197-
return result
194+
res["semantic_results"] = semantic_results or []
195+
return res
198196

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

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

207211
if fused_docs:
@@ -270,7 +274,9 @@ def _local_search(
270274
result["semantic_results"] = semantic_results or []
271275
return result
272276

273-
def _run_meta_adapt(self, store_name: str, meta_learner: "SearchMetaLearner") -> None:
277+
def _run_meta_adapt(
278+
self, store_name: str, meta_learner: "SearchMetaLearner"
279+
) -> None:
274280
"""Apply MetaLearner alpha recommendation when adaptation cycle triggers."""
275281
if not meta_learner.should_adapt():
276282
return
@@ -282,7 +288,10 @@ def _run_meta_adapt(self, store_name: str, meta_learner: "SearchMetaLearner") ->
282288
self._meta_alpha[store_name] = new_alpha
283289
logger.info(
284290
"[QualityGate] store=%s alpha %.3f -> %.3f trend=%s",
285-
store_name, current, new_alpha, meta_learner.store_trend(store_name),
291+
store_name,
292+
current,
293+
new_alpha,
294+
meta_learner.store_trend(store_name),
286295
)
287296

288297
# ------------------------------------------------------------------
@@ -313,7 +322,8 @@ def _resolve_semantic_sources(
313322
if not resolved:
314323
return None
315324
snippets = [
316-
self._build_snippet(d.get("content", ""), query) or d.get("content", "")[:200]
325+
self._build_snippet(d.get("content", ""), query)
326+
or d.get("content", "")[:200]
317327
for d in resolved[:5]
318328
]
319329
answer = " ".join(s for s in snippets if s) or (

flamehaven_filesearch/engine/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
from .parse_cache import get as parse_cache_get
1313
from .parse_cache import put as parse_cache_put
1414
from .parse_cache import stats as parse_cache_stats
15-
from .quality_gate import SearchQualityGate, SearchMetaLearner, compute_search_confidence
15+
from .quality_gate import (
16+
SearchQualityGate,
17+
SearchMetaLearner,
18+
compute_search_confidence,
19+
)
1620

1721
__all__ = [
1822
"BM25",

flamehaven_filesearch/engine/quality_gate.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@
77
LEDA 4.0.1 forge_loop.py -> FORGE retry concept in SearchQualityGate
88
LEDA 4.0.1 meta_learning.py -> SearchMetaLearner
99
10-
Zero new dependencies: only Python stdlib (math, statistics).
10+
Zero new dependencies: only Python stdlib (statistics).
1111
"""
12+
1213
from __future__ import annotations
1314

1415
import statistics
1516
from typing import Dict, List, Set, Tuple
1617

1718
# -- Tuning constants (analogous to LOGOS jsd_gate=0.06, LEDA theta_low/high) --
18-
_DIV_GATE: float = 0.50 # Jaccard divergence at which confidence halves
19+
_DIV_GATE: float = 0.50 # Jaccard divergence at which confidence halves
1920
_THETA_PASS: float = 0.75 # confidence above this -> PASS
20-
_THETA_FORGE: float = 0.45 # confidence above this (but <= PASS) -> FORGE
21-
_ADAPT_EVERY: int = 100 # queries between MetaLearner adaptation cycles
22-
_MOMENTUM: float = 0.70 # EMA weight on current alpha (LEDA ema_alpha=0.30 complement)
21+
_THETA_FORGE: float = 0.45 # confidence above this (but <= PASS) -> FORGE
22+
_ADAPT_EVERY: int = 100 # queries between MetaLearner adaptation cycles
23+
_MOMENTUM: float = 0.70 # EMA weight on current alpha (LEDA ema_alpha=0.30 complement)
2324

2425

2526
def compute_search_confidence(
@@ -157,9 +158,7 @@ def recommend_alpha(self, store_name: str, current_alpha: float = 0.5) -> float:
157158
for mode, conf in entries:
158159
by_mode.setdefault(mode, []).append(conf)
159160

160-
avg: Dict[str, float] = {
161-
m: statistics.mean(v) for m, v in by_mode.items() if v
162-
}
161+
avg: Dict[str, float] = {m: statistics.mean(v) for m, v in by_mode.items() if v}
163162

164163
sem_avg = avg.get("semantic", avg.get("hybrid", current_alpha))
165164
kw_avg = avg.get("keyword", current_alpha)

tests/test_quality_gate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
Tests for engine/quality_gate.py
33
Covers: compute_search_confidence, SearchQualityGate, SearchMetaLearner.
44
"""
5+
56
import pytest
67
from flamehaven_filesearch.engine.quality_gate import (
78
SearchMetaLearner,
89
SearchQualityGate,
910
compute_search_confidence,
1011
)
1112

12-
1313
# ---------------------------------------------------------------------------
1414
# compute_search_confidence
1515
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)