mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-13 02:41:50 +08:00
feat(codex-lens): add unified reranker architecture and file watcher
Unified Reranker Architecture: - Add BaseReranker ABC with factory pattern - Implement 4 backends: ONNX (default), API, LiteLLM, Legacy - Add .env configuration parsing for API credentials - Migrate from sentence-transformers to optimum+onnxruntime File Watcher Module: - Add real-time file system monitoring with watchdog - Implement IncrementalIndexer for single-file updates - Add WatcherManager with signal handling and graceful shutdown - Add 'codexlens watch' CLI command - Event filtering, debouncing, and deduplication - Thread-safe design with proper resource cleanup Tests: 16 watcher tests + 5 reranker test files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
139
codex-lens/tests/test_hybrid_search_reranker_backend.py
Normal file
139
codex-lens/tests/test_hybrid_search_reranker_backend.py
Normal file
@@ -0,0 +1,139 @@
|
||||
"""Tests for HybridSearchEngine reranker backend selection."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from codexlens.config import Config
|
||||
from codexlens.search.hybrid_search import HybridSearchEngine
|
||||
|
||||
|
||||
def test_get_cross_encoder_reranker_uses_factory_backend_legacy(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path,
|
||||
) -> None:
|
||||
calls: dict[str, object] = {}
|
||||
|
||||
def fake_check_reranker_available(backend: str):
|
||||
calls["check_backend"] = backend
|
||||
return True, None
|
||||
|
||||
sentinel = object()
|
||||
|
||||
def fake_get_reranker(*, backend: str, model_name=None, device=None, **kwargs):
|
||||
calls["get_args"] = {
|
||||
"backend": backend,
|
||||
"model_name": model_name,
|
||||
"device": device,
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
return sentinel
|
||||
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.check_reranker_available",
|
||||
fake_check_reranker_available,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.get_reranker",
|
||||
fake_get_reranker,
|
||||
)
|
||||
|
||||
config = Config(
|
||||
data_dir=tmp_path / "legacy",
|
||||
enable_reranking=True,
|
||||
enable_cross_encoder_rerank=True,
|
||||
reranker_backend="legacy",
|
||||
reranker_model="dummy-model",
|
||||
)
|
||||
engine = HybridSearchEngine(config=config)
|
||||
|
||||
reranker = engine._get_cross_encoder_reranker()
|
||||
assert reranker is sentinel
|
||||
assert calls["check_backend"] == "legacy"
|
||||
|
||||
get_args = calls["get_args"]
|
||||
assert isinstance(get_args, dict)
|
||||
assert get_args["backend"] == "legacy"
|
||||
assert get_args["model_name"] == "dummy-model"
|
||||
assert get_args["device"] is None
|
||||
|
||||
|
||||
def test_get_cross_encoder_reranker_uses_factory_backend_onnx_gpu_flag(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path,
|
||||
) -> None:
|
||||
calls: dict[str, object] = {}
|
||||
|
||||
def fake_check_reranker_available(backend: str):
|
||||
calls["check_backend"] = backend
|
||||
return True, None
|
||||
|
||||
sentinel = object()
|
||||
|
||||
def fake_get_reranker(*, backend: str, model_name=None, device=None, **kwargs):
|
||||
calls["get_args"] = {
|
||||
"backend": backend,
|
||||
"model_name": model_name,
|
||||
"device": device,
|
||||
"kwargs": kwargs,
|
||||
}
|
||||
return sentinel
|
||||
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.check_reranker_available",
|
||||
fake_check_reranker_available,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.get_reranker",
|
||||
fake_get_reranker,
|
||||
)
|
||||
|
||||
config = Config(
|
||||
data_dir=tmp_path / "onnx",
|
||||
enable_reranking=True,
|
||||
enable_cross_encoder_rerank=True,
|
||||
reranker_backend="onnx",
|
||||
embedding_use_gpu=False,
|
||||
)
|
||||
engine = HybridSearchEngine(config=config)
|
||||
|
||||
reranker = engine._get_cross_encoder_reranker()
|
||||
assert reranker is sentinel
|
||||
assert calls["check_backend"] == "onnx"
|
||||
|
||||
get_args = calls["get_args"]
|
||||
assert isinstance(get_args, dict)
|
||||
assert get_args["backend"] == "onnx"
|
||||
assert get_args["model_name"] is None
|
||||
assert get_args["device"] is None
|
||||
assert get_args["kwargs"]["use_gpu"] is False
|
||||
|
||||
|
||||
def test_get_cross_encoder_reranker_returns_none_when_backend_unavailable(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
tmp_path,
|
||||
) -> None:
|
||||
def fake_check_reranker_available(backend: str):
|
||||
return False, "missing deps"
|
||||
|
||||
def fake_get_reranker(*args, **kwargs):
|
||||
raise AssertionError("get_reranker should not be called when backend is unavailable")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.check_reranker_available",
|
||||
fake_check_reranker_available,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"codexlens.semantic.reranker.get_reranker",
|
||||
fake_get_reranker,
|
||||
)
|
||||
|
||||
config = Config(
|
||||
data_dir=tmp_path / "unavailable",
|
||||
enable_reranking=True,
|
||||
enable_cross_encoder_rerank=True,
|
||||
reranker_backend="onnx",
|
||||
)
|
||||
engine = HybridSearchEngine(config=config)
|
||||
|
||||
assert engine._get_cross_encoder_reranker() is None
|
||||
Reference in New Issue
Block a user