Documentation

Embeddings

How prom.codes embeds your code, why one model is pinned per workspace, and how to keep embeddings inside the EU.

prom.codes uses a single, code-tuned embedding model per workspace, selected for retrieval quality on real code. The model is fixed for the life of a workspace so that every vector lives in the same space.

The managed embedding proxy

Embeddings run through api.prom.codes, authenticated with the PROMETHEUS_API_KEY you mint in the dashboard (/app/api-keys). That one key unlocks managed code embeddings — your raw code never leaves your machine, only the embedding text transits to the proxy, which routes it to the upstream model on your behalf. The upstream provider and model are abstracted: you talk to the proxy, not to any one vendor.

What a re-embed costs

One embed call per symbol, billed to your quota. Indexing is not free: every symbol that gets a vector is one metered call against the plan attached to your PROMETHEUS_API_KEY. A steady-state session embeds a handful of changed symbols and costs almost nothing — but a few situations re-embed a whole repository at once, and some of them arrive without anyone asking:

  • A fresh index. First run in a repo, or an index you deleted.
  • A moved or renamed checkout. The local index file is keyed by the absolute workspace path, so a moved folder is a new, empty index.
  • A newly supported language. Files the previous version skipped carry no stored hash, so an upgrade that adds a language embeds all of them.
  • A forced re-embedreindex with force: true, or dashboard --reindex-all --force.
  • An upstream model or input-format change, which invalidates every stored vector.

Because auto-update is on by default, two of those can happen while you are doing something else. So the server tells you before it spends anything:

  • On stderr, before the first call — the count, the cause, and that it is billed. A whole-repo pass is marked !! COST NOTICE; a routine incremental pass is a one-line note (threshold: PROMETHEUS_EMBED_WARN_AT, default 500).
  • In index_statusembeddings.pendingEmbed carries symbols, estimatedEmbedCalls and willBill, so an agent can quote the price before it calls reindex.
  • In the reindex resultcost.meteredEmbedCalls is what that run actually billed.
  • In the local dashboard — each workspace row shows the pending count next to its Reindex button.

How the default is chosen

The default is whichever model gives the best retrieval quality per unit cost on our internal code benchmark. We measure whether the right code chunk lands inside the top candidates an agent ever sees — that is the number that drives answer quality downstream.

Specific model identifiers are deliberately not published: they shift as providers ship new versions and we re-run the benchmark. What is visible per workspace is the pinned embedding profile (an opaque fingerprint and dimension), so you can tell when a re-index against a new profile is due — without the vendor or model name ever being part of the contract.

One model per workspace

Every workspace is pinned to one model. The indexer verifies that the configured model matches the workspace before it writes, so a misconfiguration cannot silently corrupt the index with vectors from the wrong model. Changing the model later is a managed re-embed, not an in-place edit.

Provider flexibility

The embedding layer is provider-agnostic. Behind the proxy, prom.codes can route to a managed provider or to an EU-hosted endpoint we operate ourselves, selected per workspace via Region mode. This stays an implementation detail — your config never changes, and your key keeps working when we swap models.

Region implications

In the default profile the embedding call is the single non-EU hop in an otherwise EU-resident pipeline. The Region mode doc covers how to keep that hop inside the EU.