Skip to content

feat: local embedding backend via Candle (#18) - #57

Merged
savioruz merged 1 commit into
mainfrom
feat/local-embedding
Aug 16, 2026
Merged

savioruz merged 1 commit into
mainfrom
feat/local-embedding

Conversation

@savioruz

@savioruz savioruz commented Aug 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds a local embedder backend via Candle (issue #18): run text embedding on-device with a quantized GGUF model (e.g. all-MiniLM-L6-v2) so Memayu works fully offline for the embedding leg — no external embedder API needed.

⚠️ Note: This PR's content is a subset of PR #58, which additionally adds the interactive CLI setup wizard (#54) and the headless-serve fallback (#45) on the same base commit. If you intend to merge #58, this PR can be closed as a duplicate. Review below assumes standalone.

Changes

New local embedder (crates/memayu-llm-client/src/local_embedder.rs)

  • LocalEmbedder loads a quantized gguf via candle-*, exposes embed(query) -> Vec<f32> (dim matches config dimension) and supports(model) -> bool for availability probing without loading.
  • Registered when MEMAYU_EMBEDDER_PROVIDER=local; base_url is unused in this mode.

Core plumbing

  • crates/memayu-llm-client/src/lib.rs: branch on EmbedderKind::Local; register LocalEmbedder as the provider; fall back to the remote embedder otherwise.
  • crates/memayu-llm-client/Cargo.toml: candle-* deps are optional/feature-gated so non-local builds don't pay compile cost.
  • crates/memayu-config/src/lib.rs: parse + validate local embedder provider (model = gguf path); check() validates the model file exists.
  • crates/memayu-api/src/modules/providers/service.rs + crates/memayu-web/src/pages/providers.rs: surface "local model" in the providers admin API + web page.

Docs

  • README documents MEMAYU_EMBEDDER_PROVIDER=local and MEMAYU_EMBEDDER_MODEL=<gguf path>.

Migration / behavior

  • No DB schema change. Opt-in via config/env; existing remote-embedder users are unaffected.

Tests

  • crates/memayu-llm-client/tests/local_embedding.rs (171 lines): loads a small model, asserts embed output dimension and supports() == true.
  • Existing cli.rs/doctor.rs roundtrips run raw-mode with a fixed-vector embedder mock via env overrides (local path not exercised there, but the remote fallback branch is).

Checklist

  • candle deps feature-gated (not compiled for non-local builds).
  • no schema change; dimension probe still works via the existing embedder.
  • README + config docs updated.
  • issue Local embedding backend via Candle #18 referenced.

Fixes #18

Add an in-process, zero-API-key embedding backend powered by Candle so
memayu can run fully on-device with no external runtime dependencies.

- LocalEmbedder (Candle BERT) with lazy one-time model download from HF,
  cached under the data dir (models--<owner>--<name>/snapshots/<rev>)
- Default multilingual model paraphrase-multilingual-MiniLM-L12-v2 (384-d,
  covers Bahasa Indonesia + English); override via embedder.model / MEMAYU_MODEL_DIR
- Direct ureq download that follows HF's relative redirects (hf-hub 0.3
  mishandles them), with concurrency-safe temp files
- build_embedder + is_local_backend wiring; config EmbedderBackend::Local
- doctor reports on-device backend and skips HTTP probes; setup wizard offers
  local as default backend
- web dashboard /providers gains a backend selector; probe uses build_embedder
  so local backends are honest and config stays authoritative
- mixed EN/ID retrieval gate test (recall@3 5/5) plus dimension + normalization tests
- README documents the local embedding backend
@savioruz savioruz added this to the v0.1.0-rc2 milestone Aug 16, 2026
@savioruz savioruz mentioned this pull request Aug 16, 2026
4 tasks done
@savioruz savioruz added storage libsql storage provider infra CI/release/distribution priority-medium Medium priority — important but not blocking labels Aug 16, 2026
@savioruz
savioruz marked this pull request as ready for review August 16, 2026 02:23
@savioruz savioruz modified the milestones: v0.1.0-rc2, v0.1.0 Aug 16, 2026
@savioruz
savioruz merged commit 82045c8 into main Aug 16, 2026
5 checks passed
@savioruz
savioruz deleted the feat/local-embedding branch August 25, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infra CI/release/distribution priority-medium Medium priority — important but not blocking storage libsql storage provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Local embedding backend via Candle

1 participant