From f4aea78b55021e8692387a8e47077ff4cbb56333 Mon Sep 17 00:00:00 2001 From: jon Date: Thu, 23 Jul 2026 13:58:05 -0500 Subject: [PATCH] feat(rag): overlapping chunker, retrieval knobs, sqlite-vec index - Chunker: char overlap across boundaries + hard-split of oversized paragraphs. - Retrieval knobs: rag_top_k / rag_min_score in settings + Settings UI. - Vector index: sqlite-vec ANN over document embeddings, dual-written and backfilled, with brute-force cosine as the guaranteed fallback. Co-Authored-By: Claude Opus 4.8 --- interface/web/src/Settings.jsx | 32 ++++++++ requirements-base.txt | 3 + requirements-windows.txt | 3 + synapse/main.py | 6 +- synapse/memory/store.py | 143 ++++++++++++++++++++++++++++++--- tests/test_documents.py | 40 +++++++++ 6 files changed, 216 insertions(+), 11 deletions(-) diff --git a/interface/web/src/Settings.jsx b/interface/web/src/Settings.jsx index 94bc4c9..03c21c7 100644 --- a/interface/web/src/Settings.jsx +++ b/interface/web/src/Settings.jsx @@ -6,6 +6,8 @@ const DEFAULTS = { think: false, // Qwen3-style reasoning; off = much faster chat/memory temperature: 0.7, num_ctx: 0, // context window in tokens; 0 = model default + rag_top_k: 3, // document chunks injected into chat + rag_min_score: 0.6, // min cosine similarity for a chunk to count system_prompt: "", timeout: 120, gpu_offload: -1, // -1 = Auto; 0–100 = percent of layers forced onto the GPU @@ -209,6 +211,36 @@ export function Settings() { +
+
+ + update("rag_top_k", Math.max(0, parseInt(e.target.value) || 0))} + style={{ width: "100%", padding: "0.6rem", background: "#222", color: "#eee", border: "1px solid #333", borderRadius: "8px", boxSizing: "border-box" }} + /> +
+
+ + update("rag_min_score", parseFloat(e.target.value))} + style={{ width: "100%", accentColor: "#007acc" }} + /> +
+
+
+ How many uploaded-document chunks to pull into chat, and the minimum cosine + similarity each must clear. Higher relevance = fewer, tighter matches. +
+