From 2f07f8eabd1334fb054ae6701ab3ee9f335431a7 Mon Sep 17 00:00:00 2001 From: Robert Sigmundsson Date: Fri, 10 Jul 2026 09:23:05 +0200 Subject: [PATCH] =?UTF-8?q?feat(reranker):=20HttpReranker=20Bearer=20auth?= =?UTF-8?q?=20+=20accept=20'score'=20field=20(F5=20=E2=80=94=20wire=20reca?= =?UTF-8?q?ll=20to=20BGE-M3=20/rerank)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The self-hosted BGE-M3 /rerank service requires Bearer auth and returns a 'score' field; the OpenAI-compatible HttpReranker sent no auth and read 'relevance_score'. Add optional Bearer (SURREAL_MEMORY_RERANKER_API_KEY / BGE_M3_API_KEY) and accept both score fields, so recall can rerank over the BGE-M3 service (llamastash still works). (cherry picked from commit d17a310cdced8a7f1c992580a457c7f38bd4088d) (cherry picked from commit 1d29f67f555e6f79193afb317c7756235d94ebf7) (cherry picked from commit a9b40beb53f44867d48f52ab2ef325788d1c72bf) --- src/surreal_memory/engine/reranker.py | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/surreal_memory/engine/reranker.py b/src/surreal_memory/engine/reranker.py index 287d076e..f0799daa 100755 --- a/src/surreal_memory/engine/reranker.py +++ b/src/surreal_memory/engine/reranker.py @@ -180,26 +180,42 @@ def __init__( blend_weight: float = 0.7, max_candidates: int = 30, timeout: float = 15.0, + api_key: str = "", ) -> None: self._endpoint = endpoint.rstrip("/") self._model = model_name self._blend_weight = min(max(blend_weight, 0.0), 1.0) self._max_candidates = min(max_candidates, 100) self._timeout = timeout + # Bearer auth for endpoints that require it (e.g. the self-hosted BGE-M3 + # /rerank service). llamastash/llama.cpp need none — an empty key sends no header. + self._api_key = ( + api_key + or os.environ.get("SURREAL_MEMORY_RERANKER_API_KEY", "") + or os.environ.get("BGE_M3_API_KEY", "") + ).strip() def _raw_scores(self, query: str, documents: list[str]) -> list[float]: payload = json.dumps({"model": self._model, "query": query, "documents": documents}).encode( "utf-8" ) - req = urllib.request.Request( # noqa: S310 - fixed local llamastash endpoint + headers = {"Content-Type": "application/json"} + if self._api_key: + headers["Authorization"] = f"Bearer {self._api_key}" + req = urllib.request.Request( # noqa: S310 - fixed local rerank endpoint f"{self._endpoint}/rerank", data=payload, - headers={"Content-Type": "application/json"}, + headers=headers, method="POST", ) with urllib.request.urlopen(req, timeout=self._timeout) as resp: # noqa: S310 data = json.loads(resp.read().decode("utf-8")) - by_index = {int(r["index"]): float(r["relevance_score"]) for r in data.get("results", [])} + # Accept both the OpenAI-compatible field (`relevance_score`, llamastash) and + # the BGE-M3 service field (`score`). + by_index = { + int(r["index"]): float(r.get("relevance_score", r.get("score", 0.0))) + for r in data.get("results", []) + } return [by_index.get(i, float("-inf")) for i in range(len(documents))] def rerank(