These are deployment-level, not per-tenant: a brain’s configuration is a property of the
API that serves it, and
GET /v1/brain/status is the read that tells you which state you
are in. It is the one brain route that is not plan-metered.How each leg resolves
Each leg walks its own ladder and stops at the first rung that answers. An explicitBRAIN_*_BASE always wins over the hosted default, so pointing a leg at your own endpoint
does not require un-setting the hosted key.
The rung that answered is reported per service as
source:
Explicit overrides:
BRAIN_EMBED_KEY / BRAIN_EMBED_AUTH_HEADER (authorization,
api-key, or x-api-key — for Azure-style endpoints), BRAIN_ANSWER_KEY, and
BRAIN_RERANK_KEY apply to the explicit rung. The auth-header knob is ignored on the
hosted embedder rung: api.openai.com accepts nothing but a bearer token. Embedding width
is BRAIN_EMBED_DIM (default 1536), it is the fixed width of the stored vector column,
and it is enforced — a vector of the wrong length is rejected loudly rather than truncated
or padded. On the hosted rung a text-embedding-3-* model is asked for that width
explicitly, so a non-default BRAIN_EMBED_DIM still produces correctly-sized vectors — but
only up to the model’s native width (1536 for text-embedding-3-small, 3072 for
-large). Above it, or on a BRAIN_EMBED_MODEL that takes no dimensions field and whose
native width is not BRAIN_EMBED_DIM, the hosted rung declines rather than resolving:
source is null and configured: false even with OPENAI_API_KEY set, ready is
false, and ingest 501s. The rung refuses up front instead of accepting documents that
would fail the dim check minutes later. The explicit rung is exempt — an operator who sets
BRAIN_EMBED_BASE sets BRAIN_EMBED_DIM to match it.GET /v1/brain/status
Model configuration, per-service health, and knowledge-base / document / projection counts.
Present at both prefixes (/v1/brain/status and /v1/users/{user_id}/brain/status), and
nested as runtime inside GET /v1/brain/ops-status.
Every service line that resolved to an HTTP endpoint is probed live on this call —
GET <base>/models for the embedder and for an explicit answerer base, GET https://openrouter.ai/api/v1/key on the hosted answerer rung (it 401s on a revoked key,
where /models answers 200 with no key at all), GET <base>/health for the reranker,
each authenticated with that leg’s key and bounded by a 2.5 s timeout — so ok reflects
the endpoint now, not at boot. latency_ms is that probe. Mock and unresolved legs issue
no request and carry no latency_ms.
Fields
The three inference services share one shape:
ready
ready is true when the embedding service is up, the projection queue has no failures,
and — only if a semantic engine is configured — that engine is healthy.
The answerer and the reranker are excluded on purpose: both are optional, and a query
still answers without them. A brain can be ready: true while services.reranker reports
configured: false.
Degraded, but still serving
Most of these are normal operating states, not incidents.Synthesized answers are bounded by
BRAIN_ANSWER_MAX_TOKENS. Unset, it resolves per
rung: 512 output tokens on the hosted OpenRouter rung, 128 on an explicit
BRAIN_ANSWER_BASE. If the model stops because it hit the cap, the response falls back
to answer_mode: "grounded" rather than returning a truncated paraphrase — so answer
is always complete, in one form or the other. /status does not report this value.When nothing is configured
With no embedder on any rung, the two document paths refuse with501 feature_not_configured and a hint naming every way to satisfy it. Ingest refuses at the
door, before the document is accepted or any credit is charged:
501
POST /v1/brain/query fails the same way when it tries to embed the question. The
credit check runs before retrieval and the deduction after it, so a query that fails this
way is not charged.
GET /v1/brain/status on such a deployment reports the following — abridged to the fields
that differ from the example above; the rest of the object is unchanged and no probe is
issued:
200
As the hint says, semantic memory does not need the embedder.
POST /remember,
/recall, /graph and /timeline keep answering; recall and think simply return no
document cards, and POST /think is still charged its 0.08 credits because the recall and
synthesis legs still run.Local development
BRAIN_MOCK=true (or BLOCKBRAIN_MOCK=true) swaps the whole brain provider for a
deterministic in-memory mock — not just the three legs. No Postgres spine, no network, no
keys. It is a development and test mode, not a degraded production one: query is answered
out of the mock store, and its response carries no answer_mode field at all.
/status under mock reports source: "mock" on all three legs, with ok: true for
embedding and reranker and configured: false for answerer — the mock rung resolves
to no answerer, which is why it is the one leg whose mock arm is not “configured”. Every
models.* entry is null except embedding_dim, and ready is true.