feat: implement EMBEDDING_DIM=0 auto-infer and add dim mismatch detection#53
Open
allengaoo wants to merge 4 commits intomatrixorigin:mainfrom
Open
feat: implement EMBEDDING_DIM=0 auto-infer and add dim mismatch detection#53allengaoo wants to merge 4 commits intomatrixorigin:mainfrom
allengaoo wants to merge 4 commits intomatrixorigin:mainfrom
Conversation
…tion
The documentation has long promised that EMBEDDING_DIM=0 would
auto-infer the embedding dimension from the configured service, but
this was never actually implemented — the default silently fell back
to 1024, and EMBEDDING_DIM=0 would have caused a vecf32(0) SQL error.
This commit delivers the promised behaviour:
**Auto-infer (EMBEDDING_DIM=0, new default)**
- `probe_embedding_dim()` builds a temporary HttpEmbedder, calls
`embed("dimension probe")`, and returns `vec.len()` as the actual
dimension before any database schema is created or validated.
- Both `cmd_serve` and `cmd_mcp` (embedded mode) call the probe when
`cfg.embedding_dim == 0 && cfg.has_embedding()`.
- `cfg.embedding_dim` is updated in-place so `build_embedder()` and
subsequent code all see the correct value.
- Clear error message when the probe fails, with explicit guidance to
set EMBEDDING_DIM if the embedding service is unavailable at boot.
**Dimension mismatch detection**
- `SqlMemoryStore::check_embedding_dim_compat()` queries
`information_schema.columns` for the actual `vecf32(N)` type of the
`embedding` column and compares it against `self.embedding_dim`.
- Called after `migrate()` in both `cmd_serve` and `cmd_mcp`.
- Returns a descriptive error (rather than silently failing on the
first INSERT) when the schema dimension differs from the config.
**Config default change**
- `Config::from_env()` now defaults `embedding_dim` to `0` instead of
`1024`, making auto-infer the out-of-the-box experience.
**Docs**
- README and skills/deployment/SKILL.md updated to reflect that
EMBEDDING_DIM=0 now actually auto-infers the dimension.
Fixes: EMBEDDING_DIM=0 documented but not implemented.
Closes: silent dimension-mismatch failures when switching embedding models.
aptend
approved these changes
Mar 19, 2026
Contributor
Hi Teacher Gao @allengaoo , run |
Clippy lint `match_result_ok` requires replacing: if let Some(x) = expr.parse().ok() with the idiomatic: if let Ok(x) = expr.parse() This removes the intermediate Option conversion and makes the intent clearer.
Runs cargo check + clippy on every push to feat/**, fix/**, chore/** so issues are caught before opening a PR to upstream.
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
The documentation has long promised that
EMBEDDING_DIM=0auto-infers the embedding dimension from the configured service — but this was never implemented. The actual behavior was:Config::from_env()defaulted to1024, silently ignoring the documented0 = autosemanticsEMBEDDING_DIM=0explicitly would have produced avecf32(0)SQL error on first startupBAAI/bge-m3@ 1024d tonomic-embed-text@ 768d), Memoria would start without error but silently fail on everyINSERTbecause the existing schema dimension didn't matchChanges
memoria-service/src/config.rsembedding_dimchanged from1024→0(auto-infer, as documented)memoria-cli/src/main.rsprobe_embedding_dim()async helper: builds a temporaryHttpEmbedder, callsembed("dimension probe"), and returnsvec.len()as the actual dimensioncmd_serveandcmd_mcp(embedded mode) call the probe whencfg.embedding_dim == 0 && cfg.has_embedding()cfg.embedding_dimis updated beforeSqlMemoryStore::connect()so the schema is created with the correct dimensionmemoria-storage/src/store.rscheck_embedding_dim_compat()method: queriesinformation_schema.columnsfor the actualvecf32(N)type of theembeddingcolumn and compares it againstself.embedding_dimMemoriaError::Internalwhen a mismatch is detected — fast-fails at startup instead of silently producing wrong results on every writemigrate()in bothcmd_serveandcmd_mcpREADME.md+skills/deployment/SKILL.mdEMBEDDING_DIMdescription to reflect that0now actually performs the probeUser impact
Before this PR, Ollama users (e.g.
nomic-embed-text, 768d) had to:EMBEDDING_DIM=768manuallyAfter this PR:
EMBEDDING_DIMunset (or=0) → Memoria probes on startup, schema is created correctlyTesting
Verified manually against a local MatrixOne instance with:
nomic-embed-textvia Ollama (http://localhost:11434/v1, 768d auto-inferred)CI build will verify compilation across the full workspace.