memtrace embed
Inspect and switch the embedding provider — local ONNX presets or a BYO OpenAI-compatible remote endpoint — with a guarded reset flow when the vector dimension changes.
Usage#
memtrace embed {list|status|set|test|cache-status} [OPTIONS]memtrace embed manages Memtrace's persistent embedder configuration: which provider (local ONNX presets or an OpenAI-compatible remote endpoint), which model, and what vector dimensionality. Settings are written to a TOML config file — per-user or per-workspace — and resolved through a strict precedence chain: workspace file > home file > env vars > built-in default (local jina-code, 768d).
Because a MemDB HNSW index cannot mix vector dimensions, switching to a model with a different dim triggers a guarded reset-and-reindex flow rather than silently corrupting the index.
Running memtrace embed with no subcommand, or memtrace embed help, prints the embed help text and exits 0. A malformed subcommand or unknown flag prints an error to stderr and exits 2.
Local presets#
Four local presets are built in. embed set <preset> always sets provider=local and clears any remote provider config.
| Preset | Dimensions | Notes |
|---|---|---|
jina-code | 768d | Default. Code-tuned embeddings. |
bge-small | 384d | Smaller and faster. |
bge-base | 768d | — |
nomic | 768d | — |
list & status#
memtrace embed listPrints the four local presets with their dims and blurbs, followed by the active model/provider/dim and where the config came from (workspace file, home file, env, or built-in default).
memtrace embed statusShows the fully resolved picture:
- Provider, model, dim, and config location.
- The live MemDB dim with a
(match)or(MISMATCH)indicator. - The last health-check result read from
~/.memtrace/last_health.json. - Remote-provider details (url, request_timeout_ms, max_batch, api_key_env set/unset) when provider is
openai-compat. - A note when
MEMTRACE_EMBED_MODEL/MEMTRACE_VECTOR_DIMSenv overrides are active.
set#
memtrace embed set <preset> [--workspace] [--yes-reset|--no-reset]Switches the persistent embedder config to one of the local presets. On success it saves the config atomically — writes a .toml.tmp file in the same directory, then renames — to ~/.memtrace/config.toml, or, with --workspace, to <workspace>/.memtrace/embed.toml — creating parent directories as needed — and prints > Configured: <model> (<provider>, <dim>d). Wrote <path>..
--workspace requires a .memtrace-workspace marker file at or above the current directory (or the active workspace override) whose membership actually claims the search root; otherwise it errors and asks you to choose a workspace first or omit the flag. The marker itself is a small file, not a directory — the config still lives at <workspace>/.memtrace/embed.toml.
Remote (BYO) providers#
memtrace embed set --remote openai-compat --url <URL> --model <NAME> [--api-key-env <VAR>] [--timeout-ms N] [--max-batch N] [--dim N] [--workspace] [--yes-reset|--no-reset]--remote openai-compat is the only supported remote kind — any other value errors with "Supported: openai-compat". This is how you point Memtrace at a self-hosted or hosted OpenAI-compatible embeddings endpoint: Ollama, Infinity, TEI, vLLM, LM Studio, or a hosted provider like OpenAI or Voyage behind an API key.
Without --dim, set sends a one-shot probe request to <url>/embeddings — body {"input":["probe"],"model":"<name>"}, plus Bearer auth if --api-key-env resolves a non-empty value — and records the length of data[0].embedding as the config dim. A non-2xx status, non-JSON body, or missing embedding fails the command (exit 2) and nothing is written.
Remote embedding requests authenticate purely with the env var named by --api-key-env, read fresh from the environment at request time. The key itself is never stored in the config file, and Memtrace's own session/license credentials are never sent to a remote embedding endpoint — BYO-remote is entirely decoupled from your Memtrace account.
If --api-key-env's variable is unset or empty at set-time, a warning prints to stderr but the config is still written — requests simply go out unauthenticated, which suits local Infinity/LM Studio setups with no auth in front of them.
--dim N pins the dimensionality instead of probing, and is also forwarded to the provider as a Matryoshka truncation request: OpenAI-style endpoints get dimensions: N, Voyage-hosted endpoints (host contains voyageai.com) get output_dimension: N instead, since Voyage 400s on an unrecognized argument.
Dim-mismatch reset flow#
The new config's dim is compared against the live MemDB dim. If they differ, an interactive prompt offers [r] Reset + reindex now / [c] Cancel (config NOT written) — but only when both stdin and stdout are TTYs. In a non-TTY context (CI, pipelines) the command instead errors with "dim mismatch detected and stdin is not a TTY" and exits 2, telling you to re-run with --yes-reset or --no-reset. When no MemDB dim is known yet, no reset is needed and the config is written directly.
Accepting the reset — via r or --yes-reset — prints a loud red stderr banner naming the exact directory (! ABOUT TO WIPE MEMDB DATA DIR: <path>), then runs the shared reset routine against that same path: stops OS supervisors (launchd/systemd), kills the daemon PID (SIGTERM) and anything on the UI port, then wipes the local MemDB data dir. The reset targets the exact data dir that produced the measured MemDB dim, not a newly resolved path from env/workspace.
The reset wipes the MemDB data dir but does not automatically reindex. Re-indexing happens on the next memtrace start or memtrace index .. The reset also runs before the new config file is written, so a save failure right after a reset can leave you with a wiped MemDB and the old config still in place.
--no-reset cancels without writing anything: "Cancelled — config NOT written." and exit 1. --yes-reset and --no-reset are mutually exclusive — supplying both is an error.
test & cache-status#
memtrace embed testProbes the currently active provider and prints > OK provider=... dim=... latency=...ms. For provider=local it runs a real embedding through the in-process worker — this can take 60s+ on a cold start while the model loads. For openai-compat it POSTs a single-input probe to the configured endpoint and fails if the returned dim differs from the configured dim. The result is persisted to ~/.memtrace/last_health.json, which embed status reads back.
memtrace embed cache-statusReports the on-disk embedding cache at ~/.memtrace/embed-cache/: total size and entry count, the configured cap (MEMTRACE_EMBED_CACHE_CAP_MB, default 2048 MB, 0 = disabled), the session hit rate, and eviction counters. Hit/miss counters are process-local, so a fresh invocation shows "(no lookups this session)".
Flags#
| Flag | Description |
|---|---|
--remote <kind> | (set) Configure a remote provider instead of a local preset. Only openai-compat is accepted. Mutually exclusive with a positional preset name. |
--url <URL> | (set, remote) Base URL of the OpenAI-compatible API. Must start with http:// or https://. /embeddings is appended automatically unless the URL already ends with it. |
--model <NAME> | (set, remote) Remote model id sent in every request body (e.g. nomic-embed-text). Required with --remote; empty or missing errors. |
--api-key-env <VAR> | (set, remote) Name of the env var holding the API key — never the key itself. Resolved at request time into a Bearer Authorization header. |
--timeout-ms <N> | (set, remote) Per-request HTTP timeout in milliseconds. Default 30000. |
--max-batch <N> | (set, remote) Maximum inputs per HTTP call. Default 64 — the remote worker splits larger batches at the HTTP boundary. |
--dim <N> | (set, remote) Pin the vector dimensionality instead of probing; also requests Matryoshka truncation from the provider. |
--workspace | (set) Write the config to <workspace>/.memtrace/embed.toml instead of ~/.memtrace/config.toml. |
--yes-reset | (set) On dim mismatch, skip the interactive prompt and proceed with reset + reindex. Mutually exclusive with --no-reset. Required (or --no-reset) when stdin/stdout is not a TTY. |
--no-reset | (set) On dim mismatch, abort without writing the config and exit 1. Mutually exclusive with --yes-reset. |
Environment variables#
| Variable | Default | Description |
|---|---|---|
MEMTRACE_EMBED_MODEL | (unset) | Transient escape-hatch override for the embed model. Sits below workspace and home config files in the precedence chain, above the built-in default. Aliases are canonicalized (e.g. jinaai/jina-embeddings-v2-base-code → jina-code). embed status prints a note when it's set. |
MEMTRACE_VECTOR_DIMS | (unset; effective default 768) | Transient override for the vector dimensionality, paired with MEMTRACE_EMBED_MODEL. Also feeds the "live MemDB dim" that set/status compare against. |
<value of --api-key-env> | (unset) | User-named var (e.g. OPENAI_API_KEY) whose value becomes the Bearer Authorization header for remote embedding requests and probes. Missing/empty means requests go out with no Authorization header. |
MEMTRACE_EMBED_CACHE_CAP_MB | 2048 | Cap in MB for the on-disk embedding cache reported by embed cache-status. 0 disables the cap. |
Gotchas#
MEMTRACE_EMBED_MODEL / MEMTRACE_VECTOR_DIMS sit below workspace/home config files in precedence — once either config file exists, these env vars no longer affect resolution. embed status's note that they "override the config file" describes the runtime worker's env contract, not this module's file-first load order.
--timeout-ms, --max-batch, and --dim silently drop unparseable values rather than erroring — a typo'd --dim abc behaves as if --dim were omitted (the remote path then probes instead of pinning).
embed test with the local provider spins up the real embedding worker — the first run can take 60+ seconds while the model cold-starts.
Exit codes: 0 on success (including help/list/status/cache-status); 1 when you cancel a dim-mismatch reset or embed test fails; 2 for argv parse errors and all other set failures (unknown preset/remote kind, invalid URL, missing model, no workspace marker, non-interactive dim mismatch, probe/save failures, conflicting reset flags).
Examples#
$ memtrace embed list # See the four local presets and which config is currently active. $ memtrace embed status # Full resolved view: provider, model, dim, config location, # live MemDB dim match/mismatch, last health-check result. $ memtrace embed set bge-small # Switch to the smaller/faster 384d local preset. # Prompts [r]eset/[c]ancel if your MemDB was built at a different dim. $ memtrace embed set bge-small --yes-reset # Same switch for scripts/CI: skips the prompt, wipes the MemDB data dir # (loud stderr warning shows the exact path), and writes the config. $ memtrace embed set --remote openai-compat --url http://localhost:11434/v1 --model nomic-embed-text # Point at a self-hosted OpenAI-compatible endpoint (Ollama, Infinity, TEI, vLLM, LM Studio). # The dim is auto-discovered with a one-shot probe. $ memtrace embed set --remote openai-compat --url https://api.openai.com/v1 \ --model text-embedding-3-small --api-key-env OPENAI_API_KEY --dim 768 # Hosted provider with auth from an env var; --dim 768 pins the config dim # and requests Matryoshka truncation from the provider. $ memtrace embed set jina-code --workspace # Write the config to <workspace>/.memtrace/embed.toml # (requires a .memtrace-workspace marker) so only this workspace uses it. $ memtrace embed test # Probe the active provider end-to-end; prints dim + latency # and records the result in ~/.memtrace/last_health.json. $ memtrace embed cache-status # Inspect the on-disk embedding cache size, cap, hit rate, and evictions.
See also Embedding providers for local vs remote choice, provider tables, cost/privacy, and Matryoshka dims, memtrace warmup to pre-pay the model-download and session-init cost before switching, memtrace start, memtrace index, memtrace reset.