Studio: always pre-fetch RAG + min-score threshold + retrieval logging

- chat-adapter pre-fetches retrieval on every turn when RAG is on,
  regardless of provider. Users no longer have to phrase queries as
  'the document I attached' for retrieval to fire. Local tool models
  still get search_knowledge_base registered as a refinement path.
- New per-thread ragMinScore slider (Min relevance, 0..1) gates
  retrieved hits by dense cosine similarity. Hits below the floor
  (and BM25-only hits with no dense signal) are dropped server-side
  so unrelated docs don't get injected when the user's query is
  off-topic from what's indexed.
- Backend logs at search start (scope, top_k, min_score, query
  preview), after retrieval (retrieved vs met_threshold counts),
  and on return (final hit count) for both /api/rag/search and the
  search_knowledge_base tool path.
- System-prompt nudge prepended when pre-fetch returns hits so the
  model knows to cite [1], [2] rather than paraphrase silently.
This commit is contained in:
Roland Tannous 2026-05-24 18:15:02 +04:00
commit ccebbed190
9 changed files with 148 additions and 15 deletions

View file

@ -138,13 +138,15 @@ def test_execute_tool_dispatches_to_search_knowledge_base():
called = {}
def _stub(*, query, top_k = None, scope_kb_id = None, scope_thread_id = None,
enable_rerank = False, reranker_model = None, default_top_k = 5):
enable_rerank = False, reranker_model = None, default_top_k = 5,
min_score = 0.0):
called["query"] = query
called["top_k"] = top_k
called["scope_kb_id"] = scope_kb_id
called["scope_thread_id"] = scope_thread_id
called["enable_rerank"] = enable_rerank
called["default_top_k"] = default_top_k
called["min_score"] = min_score
return "stub-result"
with patch("core.rag.tool.search_knowledge_base", _stub):
@ -156,6 +158,7 @@ def test_execute_tool_dispatches_to_search_knowledge_base():
"kb_id": "kb-1",
"enable_rerank": True,
"default_top_k": 3,
"min_score": 0.35,
}
},
)
@ -166,6 +169,7 @@ def test_execute_tool_dispatches_to_search_knowledge_base():
assert called["scope_thread_id"] is None
assert called["enable_rerank"] is True
assert called["default_top_k"] == 3
assert called["min_score"] == 0.35
def test_execute_tool_handles_missing_tool_context():