docir — design documents Graph

Documents / Decisions / adr-78090be868ec

Where a downloaded embedding model lives

Why the model is cached in the user-level ~/.docir/models, passed as fastembed's cache_dir argument rather than left to its temp-directory default.

adr-78090be868ecdecisionproposed#cli#retrieval
View as Markdown◉ View in graph

Decision

The embedding model is downloaded to ~/.docir/models, and docir passes that path to fastembed as cache_dir rather than letting fastembed choose. FASTEMBED_CACHE_PATH overrides it where somebody has set it.

Why not the temp directory

That is fastembed's default, and it is wrong in one way said twice: a downloaded model is durable state, and a temp directory is where the system puts state it may delete. The consequence is a 64 MB download re-paid on every sweep, arriving as a read that takes 16 seconds instead of two, with nothing saying why.

Where there is no temp directory at all — a read-only agent sandbox — the default raises before docir runs, and every read fails inside the library (The embedding model is downloaded into a directory the system may delete).

Why not the store

A project store is one per repository and a committed artifact. A model inside it would be downloaded once per repository, and would need a .gitignore entry to stay out of every teammate's working tree — a 64 MB binary one git add -A away from the history.

The model is identical for every store on the machine, so it belongs to the machine. ~/.docir is the only docir directory that is already per-machine rather than per-project, which is why it is not derived from Settings.home: the home a command resolves is usually the project one.

Why the argument and not the variable

Passing cache_dir is not a style preference. fastembed computes its default before it reads the override:

python
default_cache_dir = os.path.join(tempfile.gettempdir(), "fastembed_cache")
cache_path = Path(os.getenv("FASTEMBED_CACHE_PATH", default_cache_dir))

so in a sandbox gettempdir() raises and the variable is never consulted. Setting it does nothing there; the argument is the only thing that works. Measured, not read off the page.

Why the variable still wins where it is set

docir reads FASTEMBED_CACHE_PATH itself and passes what it finds. A CI image that pins it is naming a directory it also caches, and this repository's own workflow carries a comment about the run where the two sides named different directories and the model was re-downloaded every time while the step claimed otherwise. Overriding it would recreate that.

Cost

One re-download for every existing install, because the model moves. It is the last one the sweep can force.

Nothing about the vectors changes: model_id identifies the model, not its location, so no store re-embeds (Semantic embeddings on by default).

To amend: Re-verify: