Conversation
…rmers.js Model2Vec static embeddings are context-free; for CJK vaults their concept-level discrimination is near bag-of-words (measured: semantic top-6 all irrelevant for a real Chinese concept query, while lexical ranked the correct note first). This adds an async transformer runtime alongside the untouched sync Model2Vec path: - Format detection: a model dir with onnx/ + config.json loads through @huggingface/transformers (mean pooling, L2-normalize, dtype q8); anything else stays Model2Vec (fully backward compatible). - New AsyncEmbedder seam; Semantic supports both runtimes (batched per-note embedding on the build path, warmup pins dim at boot). - searchAsync dispatched for the search tool; lexical + Model2Vec stay synchronous; MaxSim rerank passes through without token vectors. - Zero-network guarantee preserved: allowRemoteModels=false, models are fetched out-of-band like `seekstone fetch-model`. Verified live against a 1,244-note Chinese vault (Xenova/bge-small-zh-v1.5): the same probe query now ranks the correct note shaqmughal#1 (0.613) and its summary page shaqmughal#2, top-6 all relevant; index build 1,916 chunks in 166s (cached afterwards), query ~140ms. Co-Authored-By: Claude Code <noreply@anthropic.com>
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Security | 2 high |
🟢 Metrics 66 complexity
Metric Results Complexity 66
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Model2Vec static embeddings are context-free: token ids are gathered from a fixed matrix and mean-pooled. For CJK vaults this degrades to near bag-of-words — Chinese semantics are highly compositional, and the 256-dim PCA static models cannot separate concepts.
Measured on a real 1,244-note Chinese personal vault (probe query
中间人撮合模式 触达差 信任差):lexical: correct note ranked Launch foundations: build/publish + structured logging (SHA-31, SHA-30, SHA-41) #1semantic/hybrid(M2V_multilingual_output, the model registered in feat(semantic): register multilingual embedding model (M2V_multilingual_output) #326): top-6 all irrelevant (diary notes, course notes, internship summaries); the correct note absent entirelyThe static multilingual model from #326 is fine as a lightweight default, but CJK users need a contextualized model — and the loader is hardwired to the Model2Vec format, so there is currently no way to use one.
What this PR does
Adds an async transformer runtime next to the untouched sync Model2Vec path:
looksLikeTransformerModel): a model dir containingonnx/+config.json(HuggingFace layout, e.g. a local clone ofXenova/bge-small-zh-v1.5) loads via@huggingface/transformers; anything else stays Model2Vec → fully backward compatible.AsyncEmbedderseam (semantic/transformer-embedder.ts): mirrors the syncEmbedderinterface withembed()/embedBatch()returning Promises. Mean pooling + L2 normalize,dtype: q8,allowRemoteModels = false— the zero-network guarantee and out-of-band fetch contract are preserved exactly.Semanticsupports both runtimes: batched per-note embedding on the build path (one ONNX session per note instead of per chunk); a warmup embed at load pinsdimbeforeSemanticStoreconstruction.searchAsyncdispatched for thesearchtool: lexical and Model2Vec paths stay synchronous and byte-identical; hybrid routing logic is unchanged (only the query embedding awaits); MaxSim rerank passes through for runtimes without token vectors (by design, documented).Live verification (same vault, after swap)
Same probe query,
Xenova/bge-small-zh-v1.5(22.9 MB quantized ONNX, CPU-only):semanticLaunch foundations: build/publish + structured logging (SHA-31, SHA-30, SHA-41) #1 = the correct note (0.613), Cross-platform watcher (chokidar) + CI matrix (SHA-35) #2 = its summary page (0.557), top-6 all topically relatedNotes for review
@huggingface/transformersis added as a regular dependency but loaded via dynamicimport()— Model2Vec-only installs never pay the ONNX Runtime load cost.embedQuery()(sync) now throws a descriptive error when the runtime is async; the dispatched path always usesembedQueryAsync.status: supersedednotes) — happy to discuss shape first.🤖 Generated with Claude Code