fix(context_enhancer): refactor embed_query_sparse to use stdin (#4)

fix(context_enhancer): refactor embed_query_sparse to use stdin instead of f-string interpolation

- Eliminates shlex.quote() crash with apostrophes (SyntaxError in subprocess)
- Eliminates user text interpolation into Python code string
- Hardcodes BM25 model name (was already hardcoded module-level)
- Corrects FastEmbed API usage: model.embed([query]) instead of model.embed(string)
This commit is contained in:
David Soff 2026-06-02 18:28:32 +02:00 committed by GitHub
parent 02018160d2
commit 0d6fc33c00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 8 additions and 9 deletions

View File

@ -167,22 +167,21 @@ def embed_query(text: str) -> Optional[List[float]]:
def embed_query_sparse(text: str) -> Optional[Tuple[List[int], List[float]]]:
"""
Generate sparse BM25 embedding via FastEmbed (subprocess in ai-lab venv).
Query text passes via stdin never embedded in a -c code string.
Fail-open: if it fails, return None. Caller falls back to dense-only.
"""
try:
# Shell-quote the text to prevent injection in Python -c
import shlex
safe_text = shlex.quote(text)
result = subprocess.run(
[_FASTEMBED_PYTHON, "-c", f"""\
import os, sys
[_FASTEMBED_PYTHON, "-c", """\
import os, sys, json
sys.path.insert(0, os.environ["FASTEMBED_SITEPKGS"])
from fastembed.sparse import SparseTextEmbedding
import json
model = SparseTextEmbedding(model_name=\\"{BM25_MODEL}\\")
sparse = list(model.embed({safe_text}))[0]
print(json.dumps({{\\"indices\\": sparse.indices.tolist(), \\"values\\": sparse.values.tolist()}}))
query = sys.stdin.read()
model = SparseTextEmbedding(model_name="Qdrant/bm25")
sparse = list(model.embed([query]))[0]
print(json.dumps({"indices": sparse.indices.tolist(), "values": sparse.values.tolist()}))
"""],
input=text,
capture_output=True, text=True, timeout=15
)
data = json.loads(result.stdout.strip())