feat: integrate Google semantic search and branded desktop launcher
Core CI / core (ubuntu-latest) (push) Failing after 3m27s
Core CI / core (macos-latest) (push) Canceled after 0s
Core CI / core (windows-latest) (push) Canceled after 0s
Core CI / desktop (ubuntu-latest) (push) Successful in 5m45s
Core CI / desktop (macos-latest) (push) Canceled after 0s
Core CI / desktop (windows-latest) (push) Canceled after 0s

This commit is contained in:
karl committed 2026-10-12 17:44:56 +02:00
1 parent a90df15503
commit caf6a2f82e
80 files changed
+14971 -837

No files matched your search

+58
View File
@@ -0,0 +1,58 @@
"""Build a pinned isolated native worker; development VM builds use --backend cpu."""
import argparse
import os
from pathlib import Path
import shutil
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[2]
TAG = "b11461"
COMMIT = "4d756bc72bf00a4aacf410ae15a2d315f3db400d"
def run(arguments, cwd=None):
subprocess.run([str(value) for value in arguments], cwd=cwd, check=True)
def main():
parser = argparse.ArgumentParser(description="Build Searchi's pinned Google embedding worker")
parser.add_argument("--backend", choices=["cpu", "auto", "metal", "vulkan", "cuda"], default="cpu")
parser.add_argument("--jobs", type=int, default=2)
args = parser.parse_args()
if not 1 <= args.jobs <= 16:
parser.error("jobs must be 1–16")
source = ROOT / ".searchi/references/llama.cpp"
build = ROOT / ".searchi/runtime" / args.backend
if not source.exists():
source.parent.mkdir(parents=True, exist_ok=True)
run(["git", "clone", "--depth", "1", "--branch", TAG,
"https://github.com/ggml-org/llama.cpp.git", source])
actual = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=source, text=True).strip()
if actual != COMMIT:
raise RuntimeError("Runtime reference checkout differs from pinned commit; refusing to reset it")
patch = Path(__file__).with_name("no-logits.patch")
check = subprocess.run(["git", "apply", "--check", str(patch)], cwd=source, capture_output=True)
if check.returncode == 0:
run(["git", "apply", patch], cwd=source)
else:
reverse = subprocess.run(["git", "apply", "--reverse", "--check", str(patch)], cwd=source, capture_output=True)
if reverse.returncode:
raise RuntimeError("Runtime memory patch cannot be applied or verified")
cmake_exe = shutil.which("cmake")
if not cmake_exe:
try:
import cmake
cmake_exe = str(Path(cmake.CMAKE_BIN_DIR) / ("cmake.exe" if os.name == "nt" else "cmake"))
except ImportError as error:
raise RuntimeError("Install CMake first (python -m pip install cmake)") from error
worker_source = ROOT / "crates/searchi-semantic/native"
run([cmake_exe, "-S", worker_source, "-B", build,
"-DCMAKE_BUILD_TYPE=Release", f"-DLLAMA_CPP_DIR={source}",
f"-DSEARCHI_ACCELERATION={args.backend}"])
run([cmake_exe, "--build", build, "--config", "Release", "--parallel", args.jobs])
print(f"Runtime build complete: {build}")
if __name__ == "__main__":
main()
+54
View File
@@ -0,0 +1,54 @@
"""Explicitly provision the pinned Google model; search never calls this script."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import urllib.request
def verified(path, spec):
if not path.is_file() or path.stat().st_size != spec["bytes"]:
return False
with path.open("rb") as source:
return hashlib.file_digest(source, "sha256").hexdigest() == spec["sha256"]
def main():
parser = argparse.ArgumentParser(description="Download the verified Google EmbeddingGemma 2 Q8 model (865 MB)")
parser.add_argument("--model-dir", type=Path, default=Path(".searchi/models/embeddinggemma2"))
parser.add_argument("--text-only", action="store_true", help="Download only the 310 MB text backbone")
args = parser.parse_args()
manifest = json.loads(Path(__file__).with_name("model-manifest.json").read_text())
for spec in manifest["files"][:1] if args.text_only else manifest["files"]:
destination = args.model_dir / spec["path"]
if verified(destination, spec):
print(f"Verified {spec['path']}", flush=True)
continue
destination.parent.mkdir(parents=True, exist_ok=True)
temporary = destination.with_suffix(".part")
url = f"https://huggingface.co/{manifest['export_repository']}/resolve/{manifest['revision']}/{spec['path']}"
try:
request = urllib.request.Request(url, headers={"User-Agent": "Searchi/0.1"})
print(f"Downloading {spec['path']} ({spec['bytes']} bytes)", flush=True)
with urllib.request.urlopen(request, timeout=60) as response, temporary.open("wb") as output:
total = 0
last_report = 0
while chunk := response.read(1024 * 1024):
total += len(chunk)
if total > spec["bytes"]:
raise ValueError("Model download exceeds pinned size")
output.write(chunk)
if total - last_report >= 50 * 1024 * 1024:
print(f"Downloaded {total}/{spec['bytes']} bytes", flush=True)
last_report = total
if not verified(temporary, spec):
raise ValueError("Model size or SHA256 mismatch")
os.replace(temporary, destination)
print(f"Verified SHA256: {spec['sha256']}", flush=True)
finally:
temporary.unlink(missing_ok=True)
if __name__ == "__main__":
main()
+15
View File
@@ -0,0 +1,15 @@
{
"model_id": "google/embeddinggemma-2",
"export_repository": "ggml-org/embeddinggemma-2-GGUF",
"revision": "bfcd298762cc34d0357ece5ebdd31791a3a374d8",
"dimensions": 768,
"quantization": "Q8_0",
"license": "Apache-2.0",
"runtime_tag": "b11461",
"query_prefix": "task: search result | query: ",
"document_template": "title: {title} | text: {text}",
"files": [
{"path":"embeddinggemma-2-Q8_0.gguf","bytes":309855456,"sha256":"2188ac1deca4b77dffefd603c2776a9d76d9d74ec01841392982ebb840b09135"},
{"path":"mmproj-embeddinggemma-2-Q8_0.gguf","bytes":554821024,"sha256":"c4a8a52691ecef40618438928bdf9e68379b854e24166f292592353db0aab64f"}
]
}
+12
View File
@@ -0,0 +1,12 @@
diff --git a/src/llama-context.cpp b/src/llama-context.cpp
--- a/src/llama-context.cpp
+++ b/src/llama-context.cpp
@@ -2133,7 +2133,7 @@ uint32_t llama_context::output_reserve(int32_t n_outputs) {
const auto n_embd = hparams.n_embd;
const auto n_embd_out = hparams.n_embd_out();
- bool has_logits = true;
+ bool has_logits = !(cparams.embeddings && !cparams.causal_attn);
bool has_embd = cparams.embeddings;
bool has_embd_nextn = cparams.embeddings_nextn;
+45
View File
@@ -0,0 +1,45 @@
"""Stage the native worker for installers; optional offline model bundle."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import shutil
ROOT = Path(__file__).resolve().parents[2]
def main():
parser = argparse.ArgumentParser(description="Stage Searchi runtime resources")
parser.add_argument("--backend", choices=["cpu", "auto", "metal", "vulkan", "cuda"], default="cpu")
parser.add_argument("--bundle-model", action="store_true")
args = parser.parse_args()
name = "searchi-gemma-worker.exe" if os.name == "nt" else "searchi-gemma-worker"
source = ROOT / ".searchi/runtime" / args.backend
if os.name == "nt":
source /= "Release"
source /= name
if not source.is_file():
raise RuntimeError("Build the pinned native worker before staging")
destination = ROOT / "apps/desktop/src-tauri/resources"
destination.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, destination / name)
# Include the upstream runtime license with the statically linked helper.
shutil.copy2(ROOT / ".searchi/references/llama.cpp/LICENSE", destination / "LLAMA-LICENSE.txt")
if args.bundle_model:
manifest = json.loads(Path(__file__).with_name("model-manifest.json").read_text())
model_destination = destination / "embeddinggemma2"
model_destination.mkdir(exist_ok=True)
for spec in manifest["files"]:
artifact = ROOT / ".searchi/models/embeddinggemma2" / spec["path"]
if artifact.stat().st_size != spec["bytes"]:
raise RuntimeError("Model size mismatch")
with artifact.open("rb") as stream:
if hashlib.file_digest(stream, "sha256").hexdigest() != spec["sha256"]:
raise RuntimeError("Model checksum mismatch")
shutil.copy2(artifact, model_destination / spec["path"])
print(f"Staged native worker: {destination / name}")
if __name__ == "__main__":
main()