diff --git a/.docker/gbrain/entrypoint.sh b/.docker/gbrain/entrypoint.sh index e7276212b..f0a1f796c 100644 --- a/.docker/gbrain/entrypoint.sh +++ b/.docker/gbrain/entrypoint.sh @@ -280,35 +280,14 @@ gbrain config set dream.synthesize.link_manifest true >/dev/null gbrain config set agent.use_gateway_loop true >/dev/null echo "[gbrain-entrypoint] corpus checkout: $BRAIN_DIR (filesystem + Postgres index)" -# Route gbrain's OpenRouter reranker through the same Roomote credential -# gateway as embeddings and chat. Do this after initialization so exposing an -# OpenRouter-compatible endpoint does not change which provider gbrain chooses -# when it creates the Brain. An empty forwarded setting restores the default, -# including after a deployment previously selected another reranker. -GBRAIN_RERANKER_MODEL="${GBRAIN_RERANKER_MODEL:-openrouter:voyageai/rerank-2.5-lite}" -case "$GBRAIN_RERANKER_MODEL" in - openrouter:*) - if [ -z "${OPENROUTER_BASE_URL:-}" ] && [ -n "${OPENAI_BASE_URL:-}" ]; then - OPENROUTER_BASE_URL="${OPENAI_BASE_URL%/}" - case "$OPENROUTER_BASE_URL" in - */v1) ;; - *) OPENROUTER_BASE_URL="$OPENROUTER_BASE_URL/v1" ;; - esac - export OPENROUTER_BASE_URL - fi - if [ -z "${OPENROUTER_API_KEY:-}" ] && [ -n "${OPENAI_API_KEY:-}" ]; then - OPENROUTER_API_KEY="$OPENAI_API_KEY" - export OPENROUTER_API_KEY - fi - if [ -z "${OPENROUTER_BASE_URL:-}" ] || [ -z "${OPENROUTER_API_KEY:-}" ]; then - echo "[gbrain-entrypoint] WARNING: $GBRAIN_RERANKER_MODEL needs OPENROUTER_BASE_URL and OPENROUTER_API_KEY." - echo "[gbrain-entrypoint] WARNING: reranking will remain fail-open until the gateway is configured." - fi - ;; -esac - -gbrain config set search.reranker.model "$GBRAIN_RERANKER_MODEL" >/dev/null -echo "[gbrain-entrypoint] reranker: $GBRAIN_RERANKER_MODEL" +# The Brain does not use a reranker. gbrain's own init already writes +# `search.reranker.enabled false` for installs keyed the way ours are, but +# make the choice explicit so every brain — including ones created before +# this line and ones hit by upstream mode-bundle default flips — converges +# on the same shipped behavior. Retrieval is hybrid RRF; autocut no-ops +# without rerank scores by design. +gbrain config set search.reranker.enabled false >/dev/null +echo "[gbrain-entrypoint] reranker: disabled" # Adding a key to a brain created without one is a first-class flow rather # than an edge case: on hosts whose compose parser ignores `profiles` the diff --git a/.env.production.example b/.env.production.example index eb8f77702..20791d1f1 100644 --- a/.env.production.example +++ b/.env.production.example @@ -142,21 +142,19 @@ DEFAULT_COMPUTE_PROVIDER=docker # R_GITHUB_APP_SLUG= # Optional comma-separated GitHub App slugs that are also trusted as Roomote-managed. # R_GITHUB_ADDITIONAL_APP_SLUGS= -# Self-run Brain inference (embeddings/rerank stay on your hardware; chat +# Self-run Brain embeddings (embeddings stay on your hardware; chat # synthesis keeps using the configured provider). With the bundled service, # set COMPOSE_PROFILES=brain,local-inference and ALL of the settings below — -# the model names and dimensions must match what the inference server +# the model name and dimensions must match what the inference server # serves, and the embedding pair is create-time: set everything BEFORE the # Brain's first boot. gbrain's defaults (text-embedding-3-small, 1536) name -# models the bundled server does not serve, so the URLs alone are not a +# models the bundled server does not serve, so the URL alone is not a # working configuration. Self-run model names pass through unchanged and # must exactly match the ids served by the upstream. # R_BRAIN_EMBEDDINGS_UPSTREAM_URL=http://infinity:7997 -# R_BRAIN_RERANK_UPSTREAM_URL=http://infinity:7997 # R_BRAIN_INFERENCE_UPSTREAM_API_KEY= # R_BRAIN_EMBEDDING_MODEL=BAAI/bge-m3 # R_BRAIN_EMBEDDING_DIMENSIONS=1024 -# R_BRAIN_RERANKER_MODEL=BAAI/bge-reranker-v2-m3 # R_GITHUB_APP_ID= # Raw GitHub App private-key PEM with newlines escaped as \n; do not base64 it. # R_GITHUB_APP_PRIVATE_KEY= diff --git a/apps/api/src/handlers/brain-inference/__tests__/brain-inference.test.ts b/apps/api/src/handlers/brain-inference/__tests__/brain-inference.test.ts index 13d2d27c0..b24f66d26 100644 --- a/apps/api/src/handlers/brain-inference/__tests__/brain-inference.test.ts +++ b/apps/api/src/handlers/brain-inference/__tests__/brain-inference.test.ts @@ -146,57 +146,6 @@ describe('brain inference gateway', () => { }); }); - it('routes reranking through OpenRouter without exposing its key to gbrain', async () => { - const fetchMock = vi.fn( - async (_url: string, _init: RequestInit) => - new Response(JSON.stringify({ results: [] }), { status: 200 }), - ); - vi.stubGlobal('fetch', fetchMock); - - const body = { - model: 'cohere/rerank-v3.5', - query: 'Which result is relevant?', - documents: ['relevant', 'unrelated'], - top_n: 2, - }; - const response = await post('/v1/rerank', { - token: GATEWAY_TOKEN, - body, - }); - - expect(response.status).toBe(200); - const [url, init] = fetchMock.mock.calls[0]!; - expect(url).toBe('https://openrouter.ai/api/v1/rerank'); - expect((init.headers as Headers).get('authorization')).toBe( - `Bearer ${OPENROUTER.apiKey}`, - ); - expect(JSON.parse(init.body as string)).toEqual(body); - }); - - it('reports reranking as unavailable when only OpenAI is configured', async () => { - mockResolveBrainInferenceProvider.mockResolvedValue({ - providerId: 'openai', - apiKey: 'sk-openai-provider-key', - }); - const fetchMock = vi.fn(); - vi.stubGlobal('fetch', fetchMock); - - const response = await post('/v1/rerank', { - token: GATEWAY_TOKEN, - body: { - model: 'cohere/rerank-v3.5', - query: 'query', - documents: ['document'], - }, - }); - - expect(response.status).toBe(503); - await expect(response.json()).resolves.toMatchObject({ - error: expect.stringContaining('OpenRouter'), - }); - expect(fetchMock).not.toHaveBeenCalled(); - }); - it('surfaces an unreachable provider as 502 rather than a crash', async () => { vi.stubGlobal( 'fetch', @@ -265,27 +214,35 @@ describe('local inference upstreams', () => { expect(mockResolveBrainInferenceProvider).not.toHaveBeenCalled(); }); - it('allows rerank without OpenRouter when a rerank upstream is set', async () => { - mockEnv.R_BRAIN_RERANK_UPSTREAM_URL = 'http://infinity:7997/'; - mockResolveBrainInferenceProvider.mockResolvedValue({ - providerId: 'openai' as const, - apiKey: 'sk-openai', + it('rejects the removed rerank path like any other unlisted path', async () => { + const fetchMock = vi.fn(); + vi.stubGlobal('fetch', fetchMock); + + const response = await post('/v1/rerank', { + token: GATEWAY_TOKEN, + body: { model: 'bge-reranker-base', query: 'q', documents: ['a'] }, }); + + expect(response.status).toBe(403); + expect(fetchMock).not.toHaveBeenCalled(); + }); + + it('keeps the trailing slash on a configured upstream from doubling up', async () => { + mockEnv.R_BRAIN_EMBEDDINGS_UPSTREAM_URL = 'http://infinity:7997/'; const fetchMock = vi .fn() - .mockResolvedValue( - new Response(JSON.stringify({ results: [] }), { status: 200 }), - ); + .mockResolvedValue(new Response('{}', { status: 200 })); vi.stubGlobal('fetch', fetchMock); - const response = await post('/v1/rerank', { + const response = await post('/v1/embeddings', { token: GATEWAY_TOKEN, - body: { model: 'bge-reranker-base', query: 'q', documents: ['a'] }, + body: { model: 'bge-small-en-v1.5', input: ['a'] }, }); expect(response.status).toBe(200); - // Trailing slash on the configured URL must not double up. - expect(fetchMock.mock.calls[0]![0]).toBe('http://infinity:7997/v1/rerank'); + expect(fetchMock.mock.calls[0]![0]).toBe( + 'http://infinity:7997/v1/embeddings', + ); }); it('sends no authorization header when the upstream has no key', async () => { @@ -306,7 +263,6 @@ describe('local inference upstreams', () => { it('keeps chat on the provider even when upstreams are configured', async () => { mockEnv.R_BRAIN_EMBEDDINGS_UPSTREAM_URL = 'http://infinity:7997'; - mockEnv.R_BRAIN_RERANK_UPSTREAM_URL = 'http://infinity:7997'; const fetchMock = vi .fn() .mockResolvedValue(new Response('{}', { status: 200 })); diff --git a/apps/api/src/handlers/brain-inference/index.ts b/apps/api/src/handlers/brain-inference/index.ts index 398a507aa..f97043588 100644 --- a/apps/api/src/handlers/brain-inference/index.ts +++ b/apps/api/src/handlers/brain-inference/index.ts @@ -20,14 +20,15 @@ import type { Variables } from '../../types'; const LOG_PREFIX = '[Brain Inference]'; /** - * The Brain's whole inference surface: embeddings for recall, reranking for - * precision, and chat for sourced synthesis and query expansion. Deliberately - * narrower than the task-sandbox gateway's allowlist, because this credential - * is a static deployment secret rather than a short-lived run token. + * The Brain's whole inference surface: embeddings for recall and chat for + * sourced synthesis and query expansion. Deliberately narrower than the + * task-sandbox gateway's allowlist, because this credential is a static + * deployment secret rather than a short-lived run token. Reranking is not + * part of the Brain: retrieval is hybrid RRF, and the reranker is disabled + * per-brain by the gbrain entrypoint. */ const BRAIN_ALLOWED_PATHS = new Set([ '/v1/embeddings', - '/v1/rerank', '/v1/chat/completions', '/v1/responses', ]); @@ -119,13 +120,13 @@ async function rewriteBody( } /** - * A self-run inference upstream for one gateway path. Embeddings and rerank - * are the Brain's bulk data paths (memory text in, vectors/scores out), so - * they are the ones a deployment may want on its own hardware; chat synthesis - * stays with the configured model provider. Model names pass through - * unrewritten — the upstream owns its own model registry, and every Brain is - * locked to its embedding model at creation, so the name must mean exactly - * one thing forever. + * A self-run inference upstream for one gateway path. Embeddings are the + * Brain's bulk data path (memory text in, vectors out), so they are the one + * a deployment may want on its own hardware; chat synthesis stays with the + * configured model provider. Model names pass through unrewritten — the + * upstream owns its own model registry, and every Brain is locked to its + * embedding model at creation, so the name must mean exactly one thing + * forever. */ function resolveLocalUpstream( upstreamPath: string, @@ -133,9 +134,7 @@ function resolveLocalUpstream( const baseUrl = upstreamPath === '/v1/embeddings' ? Env.R_BRAIN_EMBEDDINGS_UPSTREAM_URL - : upstreamPath === '/v1/rerank' - ? Env.R_BRAIN_RERANK_UPSTREAM_URL - : undefined; + : undefined; if (!baseUrl?.trim()) { return null; @@ -266,20 +265,6 @@ brainInference.post('/*', async (c) => { ); } - // gbrain's OpenRouter reranker speaks the same authenticated gateway - // contract as embeddings and chat, but OpenAI itself has no compatible - // rerank endpoint. Fail explicitly instead of forwarding a doomed request - // to api.openai.com and obscuring the missing capability as a 404. - if (upstreamPath === '/v1/rerank' && resolved.providerId !== 'openrouter') { - return c.json( - { - error: - 'Brain reranking requires an OpenRouter provider configured in Settings, or a local rerank upstream (R_BRAIN_RERANK_UPSTREAM_URL).', - }, - 503, - ); - } - const provider = getInferenceGatewayProvider(resolved.providerId); if (!provider?.authHeader) { diff --git a/apps/docs/environment-variables.mdx b/apps/docs/environment-variables.mdx index efb846f87..d5542818a 100644 --- a/apps/docs/environment-variables.mdx +++ b/apps/docs/environment-variables.mdx @@ -220,15 +220,13 @@ as per-task auth tokens or workspace paths. | `OPENAI_COMPATIBLE__LABEL` | Optional | Display label stored with a named OpenAI-compatible connection. | | `VLLM_BASE_URL` | vLLM | vLLM OpenAI-compatible endpoint URL, usually including its `/v1` path. | | `VLLM_API_KEY` | Optional | Bearer API key for a vLLM endpoint that requires authentication. | -| `R_BRAIN_OPENROUTER_API_KEY` | Memory provider | OpenRouter key that enables Memory embeddings, reranking, and synthesis. | +| `R_BRAIN_OPENROUTER_API_KEY` | Memory provider | OpenRouter key that enables Memory embeddings and synthesis. | | `R_BRAIN_OPENAI_API_KEY` | Memory provider | OpenAI key that enables Memory embeddings and synthesis. | | `R_BRAIN_MODEL` | Optional | Memory synthesis model in the configured provider's naming. Changes apply immediately. | | `R_BRAIN_EMBEDDING_MODEL` | Before first Memory boot | Embedding model id that sizes Memory's vector storage. Changing it later requires re-embedding. | | `R_BRAIN_EMBEDDING_DIMENSIONS` | Before first Memory boot | Output width for `R_BRAIN_EMBEDDING_MODEL`; it must match the served model. | -| `R_BRAIN_RERANKER_MODEL` | Optional | Memory reranker model. Use OpenRouter's model id for OpenRouter, or the exact bare model id served by a self-run rerank upstream. | | `R_BRAIN_EMBEDDINGS_UPSTREAM_URL` | Optional | OpenAI-compatible embeddings endpoint used instead of the Memory provider. | -| `R_BRAIN_RERANK_UPSTREAM_URL` | Optional | OpenAI-compatible rerank endpoint used instead of OpenRouter. | -| `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` | Optional | Bearer key shared by the self-run embeddings and rerank upstreams; omit it for a trusted private-network service. | +| `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` | Optional | Bearer key for the self-run embeddings upstream; omit it for a trusted private-network service. | ### Sandbox providers diff --git a/apps/docs/memory.mdx b/apps/docs/memory.mdx index ed715ae7b..e99416b21 100644 --- a/apps/docs/memory.mdx +++ b/apps/docs/memory.mdx @@ -101,22 +101,18 @@ Changing that key later takes effect on Memory's next request, with no redeploy. OpenRouter and OpenAI both support Memory's embedding and synthesis calls. -Search reranking requires OpenRouter unless a self-run rerank upstream is -configured. -### Run embeddings and reranking locally +### Run embeddings locally -Self-hosted Compose deployments can keep embeddings and reranking on their own -hardware while continuing to send chat synthesis to the configured Memory -provider. Enable both services and point Memory at the bundled inference server: +Self-hosted Compose deployments can keep embeddings on their own hardware +while continuing to send chat synthesis to the configured Memory provider. +Enable both services and point Memory at the bundled inference server: ```sh COMPOSE_PROFILES=brain,local-inference R_BRAIN_EMBEDDINGS_UPSTREAM_URL=http://infinity:7997 -R_BRAIN_RERANK_UPSTREAM_URL=http://infinity:7997 R_BRAIN_EMBEDDING_MODEL=BAAI/bge-m3 R_BRAIN_EMBEDDING_DIMENSIONS=1024 -R_BRAIN_RERANKER_MODEL=BAAI/bge-reranker-v2-m3 ``` The bundled CPU service uses multilingual models so recall can cross languages. @@ -125,11 +121,11 @@ dimensions is a lighter embedding alternative. Choose the embedding model and dimensions before Memory's first boot; changing that pair later requires re-embedding the corpus. -The two upstream URLs can instead target any OpenAI-compatible embedding and -rerank server. Set `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` when that server requires -a bearer key. Roomote forwards model names unchanged to self-run upstreams, so -`R_BRAIN_EMBEDDING_MODEL` and `R_BRAIN_RERANKER_MODEL` must exactly match the -models that server exposes, without a provider prefix. +The upstream URL can instead target any OpenAI-compatible embedding server. +Set `R_BRAIN_INFERENCE_UPSTREAM_API_KEY` when that server requires a bearer +key. Roomote forwards model names unchanged to self-run upstreams, so +`R_BRAIN_EMBEDDING_MODEL` must exactly match a model that server exposes, +without a provider prefix. Without a Memory key, Memory stays inert. Agents are not told it exists, and nothing is ingested. @@ -229,23 +225,19 @@ in staging is distinguishable from one written against production. ## Choosing models -Three settings pick Memory's models: +Two settings pick Memory's models: | Variable | What it does | Written as | Changeable | | ----------------------------- | ----------------- | --------------------------------- | --------------------- | | `R_BRAIN_MODEL` | Sourced synthesis | your provider's naming | any time | | `R_BRAIN_EMBEDDING_MODEL` | Semantic recall | a plain model id | before the first boot | -| `R_BRAIN_RERANKER_MODEL` | Search precision | provider or upstream naming | after a restart | -Leave the first two unset and Memory uses OpenAI's `gpt-5.6-luna` and +Leave them unset and Memory uses OpenAI's `gpt-5.6-luna` and `text-embedding-3-small` through whichever provider you configured. -The reranker defaults to OpenRouter's `voyageai/rerank-2.5-lite`. Set -`R_BRAIN_RERANKER_MODEL` to choose another model from -OpenRouter's reranker catalog. Reranking requires an OpenRouter key; with only -OpenAI configured, gbrain keeps the unreranked results instead of failing the -search. When `R_BRAIN_RERANK_UPSTREAM_URL` is set, use the exact bare model id -served by that upstream instead. +Memory search does not use a cross-encoder reranker: retrieval is hybrid +(vector + keyword fusion), which keeps search latency flat and provider +requirements minimal. The synthesis model is applied by Roomote when it forwards the call and passed to the provider as written, so use that provider's naming diff --git a/deploy/compose/docker-compose.prod.yml b/deploy/compose/docker-compose.prod.yml index 50af5f5db..4c55624ab 100644 --- a/deploy/compose/docker-compose.prod.yml +++ b/deploy/compose/docker-compose.prod.yml @@ -24,12 +24,10 @@ x-roomote-base-env: &roomote-base-env R_BRAIN_MODEL: ${R_BRAIN_MODEL:-} R_BRAIN_EMBEDDING_MODEL: ${R_BRAIN_EMBEDDING_MODEL:-} R_BRAIN_EMBEDDING_DIMENSIONS: ${R_BRAIN_EMBEDDING_DIMENSIONS:-} - R_BRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} - # Optional self-run inference: point embeddings/rerank at the bundled + # Optional self-run inference: point embeddings at the bundled # `infinity` service (profile local-inference) or any OpenAI-compatible # server. Chat synthesis keeps flowing to the configured model provider. R_BRAIN_EMBEDDINGS_UPSTREAM_URL: ${R_BRAIN_EMBEDDINGS_UPSTREAM_URL:-} - R_BRAIN_RERANK_UPSTREAM_URL: ${R_BRAIN_RERANK_UPSTREAM_URL:-} R_BRAIN_INFERENCE_UPSTREAM_API_KEY: ${R_BRAIN_INFERENCE_UPSTREAM_API_KEY:-} R_GBRAIN_URL: ${R_GBRAIN_URL:-http://gbrain:8931} R_GBRAIN_ADMIN_TOKEN_FILE: /gbrain-data/admin-bootstrap-token @@ -542,7 +540,6 @@ services: # provider key below instead makes the Brain call the provider directly. OPENAI_BASE_URL: ${GBRAIN_OPENAI_BASE_URL:-http://api:3001/api/brain/inference} OPENAI_API_KEY: ${R_BRAIN_GATEWAY_TOKEN:-} - GBRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. @@ -555,7 +552,7 @@ services: security_opt: - no-new-privileges:true - # Self-run embedding/reranking models for the Brain (opt-in, CPU). + # Self-run embedding model for the Brain (opt-in, CPU). # Enable with the `local-inference` compose profile. The upstream URLs are # NOT sufficient on their own: R_BRAIN_EMBEDDING_MODEL and # R_BRAIN_EMBEDDING_DIMENSIONS must name what this server serves (gbrain's @@ -590,8 +587,6 @@ services: # Brain's first boot; the embedding choice is create-time. - --model-id - ${INFINITY_EMBEDDING_MODEL:-BAAI/bge-m3} - - --model-id - - ${INFINITY_RERANKER_MODEL:-BAAI/bge-reranker-v2-m3} volumes: - infinity_cache:/app/.cache security_opt: diff --git a/deploy/coolify/README.md b/deploy/coolify/README.md index 96753f8cd..fc037a040 100644 --- a/deploy/coolify/README.md +++ b/deploy/coolify/README.md @@ -278,10 +278,9 @@ Two operational notes: database in Postgres holds its searchable index, extracted facts, and durable jobs, so keep it in the normal `pg_data` backup too. - **Model choice is a variable, not a rebuild.** `R_BRAIN_MODEL` selects the - synthesis model, `R_BRAIN_EMBEDDING_MODEL` the embedding model, and - `R_BRAIN_RERANKER_MODEL` the reranker. Set them on the app services. Leave - them empty for the defaults. The synthesis model can change at any time; - the reranker changes after a gbrain restart; the embedding model + synthesis model and `R_BRAIN_EMBEDDING_MODEL` the embedding model. Set them + on the app services. Leave them empty for the defaults. The synthesis model + can change at any time; the embedding model sizes Memory's vector storage when it is first created, so set it (with `R_BRAIN_EMBEDDING_DIMENSIONS`) before first boot or not at all. A later change is ignored and reported in Memory's logs rather than silently diff --git a/deploy/coolify/docker-compose.yaml b/deploy/coolify/docker-compose.yaml index 81fada84a..34b0d80a0 100644 --- a/deploy/coolify/docker-compose.yaml +++ b/deploy/coolify/docker-compose.yaml @@ -82,7 +82,6 @@ x-roomote-shared-env: &roomote-shared-env R_BRAIN_MODEL: ${R_BRAIN_MODEL:-} R_BRAIN_EMBEDDING_MODEL: ${R_BRAIN_EMBEDDING_MODEL:-} R_BRAIN_EMBEDDING_DIMENSIONS: ${R_BRAIN_EMBEDDING_DIMENSIONS:-} - R_BRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} R_GBRAIN_URL: http://gbrain:8931 # Roomote uses this only to register its own scoped clients against the # Brain. Coolify's SERVICE_PASSWORD_64_* generates an @@ -166,7 +165,6 @@ services: # provider key below instead makes the Brain call the provider directly. OPENAI_BASE_URL: ${GBRAIN_OPENAI_BASE_URL:-http://api:3001/api/brain/inference} OPENAI_API_KEY: ${SERVICE_PASSWORD_64_BRAINGATEWAY} - GBRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. diff --git a/deploy/railway/README.md b/deploy/railway/README.md index c5be4eebb..39fc8e8b5 100644 --- a/deploy/railway/README.md +++ b/deploy/railway/README.md @@ -432,10 +432,9 @@ Two operational notes: no longer recognizes them — but the deployment starts cold until that finishes. - **Model choice is a variable, not a rebuild.** `R_BRAIN_MODEL` selects the - synthesis model, `R_BRAIN_EMBEDDING_MODEL` the embedding model, and - `R_BRAIN_RERANKER_MODEL` the reranker, all set on **api**. Leave them empty - for the defaults. The synthesis model can change at any time; the reranker - changes after a gbrain restart; the embedding model + synthesis model and `R_BRAIN_EMBEDDING_MODEL` the embedding model, both set + on **api**. Leave them empty for the defaults. The synthesis model can + change at any time; the embedding model sizes Memory's vector storage when it is first created, so set it (with `R_BRAIN_EMBEDDING_DIMENSIONS`) before first boot or not at all. A later change is ignored and reported in Memory's logs rather than silently diff --git a/deploy/railway/template.yaml b/deploy/railway/template.yaml index 7bad5d363..5dd041913 100644 --- a/deploy/railway/template.yaml +++ b/deploy/railway/template.yaml @@ -144,7 +144,6 @@ services: # goes over the public origin, exactly as TRPC_URL already does. OPENAI_BASE_URL: https://${{api.RAILWAY_PUBLIC_DOMAIN}}/api/brain/inference OPENAI_API_KEY: ${{api.R_BRAIN_GATEWAY_TOKEN}} - GBRAIN_RERANKER_MODEL: ${{api.R_BRAIN_RERANKER_MODEL}} # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. @@ -214,7 +213,6 @@ services: R_BRAIN_MODEL: '' R_BRAIN_EMBEDDING_MODEL: '' R_BRAIN_EMBEDDING_DIMENSIONS: '' - R_BRAIN_RERANKER_MODEL: '' # Railway's private network is IPv6-only and never leaves the project, # so the Brain is unreachable from the internet by construction. R_GBRAIN_URL: http://${{gbrain.RAILWAY_PRIVATE_DOMAIN}}:8931 @@ -262,7 +260,6 @@ services: R_BRAIN_GATEWAY_TOKEN: ${{api.R_BRAIN_GATEWAY_TOKEN}} R_BRAIN_MODEL: ${{api.R_BRAIN_MODEL}} R_BRAIN_EMBEDDING_MODEL: ${{api.R_BRAIN_EMBEDDING_MODEL}} - R_BRAIN_RERANKER_MODEL: ${{api.R_BRAIN_RERANKER_MODEL}} R_GBRAIN_URL: ${{api.R_GBRAIN_URL}} R_GBRAIN_ADMIN_TOKEN: ${{api.R_GBRAIN_ADMIN_TOKEN}} R_APP_ENV: ${{api.R_APP_ENV}} diff --git a/deploy/render/README.md b/deploy/render/README.md index 38c16ea34..2148240c2 100644 --- a/deploy/render/README.md +++ b/deploy/render/README.md @@ -397,10 +397,9 @@ Two operational notes: longer recognizes them — but the deployment starts cold until that finishes. - **Model choice is a variable, not a rebuild.** `R_BRAIN_MODEL` selects the - synthesis model, `R_BRAIN_EMBEDDING_MODEL` the embedding model, and - `R_BRAIN_RERANKER_MODEL` the reranker. Set them on the api service. Leave - them empty for the defaults. The synthesis model can change at any time; - the reranker changes after a gbrain restart; the embedding model + synthesis model and `R_BRAIN_EMBEDDING_MODEL` the embedding model. Set them + on the api service. Leave them empty for the defaults. The synthesis model + can change at any time; the embedding model sizes Memory's vector storage when it is first created, so set it (with `R_BRAIN_EMBEDDING_DIMENSIONS`) before first boot or not at all. A later change is ignored and reported in Memory's logs rather than silently diff --git a/docker-compose.self-host.yml b/docker-compose.self-host.yml index e89888772..9c5c9dd93 100644 --- a/docker-compose.self-host.yml +++ b/docker-compose.self-host.yml @@ -36,7 +36,6 @@ x-roomote-env: &roomote-env R_BRAIN_MODEL: ${R_BRAIN_MODEL:-} R_BRAIN_EMBEDDING_MODEL: ${R_BRAIN_EMBEDDING_MODEL:-} R_BRAIN_EMBEDDING_DIMENSIONS: ${R_BRAIN_EMBEDDING_DIMENSIONS:-} - R_BRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} R_GBRAIN_URL: ${R_GBRAIN_URL:-http://gbrain:8931} # Roomote reads the brain's bootstrap token once to register its own # scoped clients; api and bullmq mount the brain volume read-only. @@ -299,7 +298,6 @@ services: # provider key below instead makes the Brain call the provider directly. OPENAI_BASE_URL: ${GBRAIN_OPENAI_BASE_URL:-http://api:3001/api/brain/inference} OPENAI_API_KEY: ${R_BRAIN_GATEWAY_TOKEN:-} - GBRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. diff --git a/docker-compose.yml b/docker-compose.yml index 0c090ffb9..7423912fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,6 @@ services: # provider key below instead makes the Brain call the provider directly. OPENAI_BASE_URL: ${GBRAIN_OPENAI_BASE_URL:-http://host.docker.internal:3001/api/brain/inference} OPENAI_API_KEY: ${R_BRAIN_GATEWAY_TOKEN:-} - GBRAIN_RERANKER_MODEL: ${R_BRAIN_RERANKER_MODEL:-} # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. diff --git a/packages/env/src/index.ts b/packages/env/src/index.ts index 476fc42be..62793cbc8 100644 --- a/packages/env/src/index.ts +++ b/packages/env/src/index.ts @@ -378,11 +378,10 @@ const serverSchema = { R_TRIAL_OPENROUTER_API_KEY: z.string().min(1).optional(), // Optional self-run inference upstreams for the Brain gateway. When set, // the gateway routes that path's requests there instead of the configured - // model provider — embeddings and rerank can move to a local or fleet + // model provider — embeddings can move to a local or fleet // inference service while chat synthesis keeps flowing to the provider. // Model names pass through unrewritten: the upstream owns its own names. R_BRAIN_EMBEDDINGS_UPSTREAM_URL: z.string().url().optional(), - R_BRAIN_RERANK_UPSTREAM_URL: z.string().url().optional(), // One key for both paths: they are the same service in every planned // deployment shape. Optional because a compose-network upstream may have // no auth at all. @@ -540,7 +539,6 @@ const OPTIONAL_NON_EMPTY_KEYS = new Set([ 'R_BRAIN_OPENAI_API_KEY', 'R_TRIAL_OPENROUTER_API_KEY', 'R_BRAIN_EMBEDDINGS_UPSTREAM_URL', - 'R_BRAIN_RERANK_UPSTREAM_URL', 'R_BRAIN_INFERENCE_UPSTREAM_API_KEY', 'R_BRAIN_GATEWAY_TOKEN', 'R_BRAIN_GATEWAY_TOKEN_FILE', @@ -738,7 +736,6 @@ export function isBrainConfigured(env: { R_BRAIN_OPENROUTER_API_KEY?: string; R_BRAIN_OPENAI_API_KEY?: string; R_BRAIN_EMBEDDINGS_UPSTREAM_URL?: string; - R_BRAIN_RERANK_UPSTREAM_URL?: string; R_BRAIN_INFERENCE_UPSTREAM_API_KEY?: string; }): boolean { return Boolean( diff --git a/render.yaml b/render.yaml index 677f1188a..f33ff57ff 100644 --- a/render.yaml +++ b/render.yaml @@ -164,11 +164,6 @@ services: type: web name: roomote-api envVarKey: R_BRAIN_GATEWAY_TOKEN - - key: GBRAIN_RERANKER_MODEL - fromService: - type: web - name: roomote-api - envVarKey: R_BRAIN_RERANKER_MODEL # Create-time, and it has to be the container that receives these: the # embedding model and its width are decided when the Brain is created, # and the gateway must never substitute a different one afterwards. @@ -267,8 +262,6 @@ services: sync: false - key: R_BRAIN_EMBEDDING_MODEL sync: false - - key: R_BRAIN_RERANKER_MODEL - value: '' - key: ROOMOTE_GBRAIN_HOSTPORT fromService: type: pserv