Skip to content

Commit 46e84aa

Browse files
Merge pull request #92 from DMontgomery40/feat/native-cloud-embeddings-20260905
Route cloud embeddings through native LiteLLM accounting
2 parents 0945a5a + 4b756e0 commit 46e84aa

53 files changed

Lines changed: 2022 additions & 340 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
# Copy this file to .env and fill in the values
33

44
# ===== API Keys =====
5-
OPENAI_API_KEY=sk-your-openai-key
65
VOYAGE_API_KEY=your-voyage-key
76
COHERE_API_KEY=your-cohere-key
87
JINA_API_KEY=your-jina-key
98
LANGTRACE_API_KEY=your-langtrace-key # Optional (UI checks presence only)
109

11-
# Ragweld generation calls only the local LiteLLM gateway. Upstream provider
12-
# secrets belong in infra/litellm.env and are never loaded into the API.
10+
# Generation and OpenAI embeddings call the local LiteLLM gateway. Their upstream
11+
# provider secrets, including OPENAI_API_KEY, belong only in infra/litellm.env.
1312
LITELLM_BASE_URL=http://127.0.0.1:54000/v1
1413
LITELLM_API_KEY=sk-ragweld-local
1514

README.md

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -229,29 +229,30 @@ Each search method compensates for the others' weaknesses. The result: **dramati
229229

230230
## Performance
231231

232-
ragweld measures real pipeline latency and throughput via **Prometheus + Grafana** (see dashboards `tribrid-overview` and `tribrid-rag-metrics`). For reproducible local benchmarking (index + search), use the built-in benchmark runner.
232+
ragweld measures pipeline latency and throughput via **Prometheus + Grafana** (see dashboards `tribrid-overview` and `tribrid-rag-metrics`). The benchmark runner measures complete HTTP search requests against a running Ragweld API, including application processing and network time. Warmup requests are excluded from measured latency and throughput.
233233

234234
### Reproducible benchmark (index + search)
235235

236236
Prereqs:
237237

238238
```bash
239-
docker compose up -d postgres neo4j
240-
# If using the docker-compose defaults:
241-
export NEO4J_PASSWORD=password
239+
# Run on LXC100 against the already running API and a registered corpus.
240+
uv run python -m scripts.benchmark_perf \
241+
--api-base-url http://127.0.0.1:58012 \
242+
--corpus-id ragweld --skip-index --iterations 5 --warmup 1 \
243+
--query 'How does the indexing run fence prevent concurrent replacement?' \
244+
--out-json /var/tmp/ragweld-benchmark.json
242245
```
243246

244-
Run:
247+
To include indexing, omit `--skip-index`. The server uses the registered corpus path unless `--corpus-path` supplies another path on that server. Indexing uses the normal run fence, validation and promotion lifecycle. `--force-reindex` permits changed embedding settings; semantic graph indexing also requires `--approved-graph-schema-hash` with the exact reviewed schema hash.
245248

246-
```bash
247-
uv run scripts/benchmark_perf.py --corpus-id ragweld --corpus-path . --force-reindex --iterations 5 --warmup 1
248-
```
249+
The runner prints Markdown and writes JSON when `--out-json` is supplied. `--request-timeout` bounds each HTTP request (default 60 seconds); `--index-timeout` bounds waiting for the accepted run (default 3,600 seconds). A failed, cancelled or unfinished index produces no success report. A wait timeout leaves the server-owned job running, so inspect that corpus's run before starting another benchmark.
249250

250-
This prints **Markdown + JSON** summary you can paste into docs/PRs.
251+
`--out-json` replaces the selected report: after input validation, the runner removes the previous report before making API requests and publishes a complete JSON file only on success. A failed rerun therefore leaves no stale metrics at that path. Concurrent invocations using the same output path are rejected without changing the active writer's report.
251252

252253
### Latest benchmark (local dev run)
253254

254-
Generated on `2026-02-01` with the command above (vector+sparse+graph enabled, `final_k=10`).
255+
Historical internal-pipeline measurement from `2026-02-01` (vector+sparse+graph enabled, `final_k=10`); these values are not directly comparable to the current HTTP benchmark.
255256

256257
| Operation | Performance | Notes |
257258
|---|---:|---|
@@ -281,7 +282,7 @@ Treat the mainline status section above as the architecture truth for modernizat
281282
- Docker & Docker Compose
282283
- Python 3.11+ with [uv](https://github.com/astral-sh/uv)
283284
- Node.js 18+
284-
- API keys for your preferred embedding provider (OpenAI, Voyage, etc.)
285+
- Provider credentials for the configured cloud workflows; OpenAI embedding credentials belong to LiteLLM
285286

286287
### 1. Clone and Configure
287288

@@ -291,17 +292,37 @@ cd ragweld
291292
cp .env.example .env
292293
```
293294

294-
Edit `.env` with your API keys:
295+
The app's `.env` configures its gateway connection with `LITELLM_BASE_URL` and
296+
`LITELLM_API_KEY`. OpenAI embeddings and generation call LiteLLM; their upstream
297+
provider credentials belong in the gateway's private `infra/litellm.env`.
298+
299+
For a new install without an existing gateway environment file:
300+
295301
```bash
296-
OPENAI_API_KEY=sk-...
297-
# or
298-
VOYAGE_API_KEY=pa-...
302+
cp infra/litellm.env.example infra/litellm.env
303+
chmod 600 infra/litellm.env
299304
```
300305

306+
Edit that private file to replace `OPENAI_API_KEY=disabled` when enabling OpenAI
307+
embeddings. Preserve existing gateway settings and Langfuse credentials when
308+
updating an installation. Do not put `OPENAI_API_KEY` in the app's `.env` or
309+
export it into the app process. Compose passes the app's `LITELLM_API_KEY` to
310+
the gateway as `LITELLM_MASTER_KEY`; this gateway client credential is separate
311+
from the upstream OpenAI key.
312+
313+
On the Proxmox deployment, `.env` points to `/etc/ragweld/runtime.env` and
314+
`infra/litellm.env` points to `/etc/ragweld/litellm.env`. Update the existing
315+
owner-only files on LXC100 instead of replacing those symlinks. After changing
316+
the gateway environment, reconcile/recreate the `litellm` service through the
317+
deployment's Compose configuration during an idle interval. Restarting only the
318+
API does not reload the gateway environment. See
319+
[gateway credentials](docs/references/generation-gateway-catalog.md#gateway-credentials)
320+
and [Proxmox activation](docs/references/native-run-accounting.md#proxmox-activation).
321+
301322
### 2. Start Infrastructure
302323

303324
```bash
304-
docker compose up -d postgres neo4j
325+
docker compose --project-name ragweld up -d postgres neo4j qdrant litellm
305326
```
306327

307328
By default, Docker volumes are stored alongside the repo. To store DB data **outside** the repo (recommended for real corpora),
@@ -317,6 +338,7 @@ This starts:
317338
- **PostgreSQL** for corpus control/state rows and caches (port 5432)
318339
- **Qdrant** vector store for dense + sparse chunk vectors (port 56333)
319340
- **Neo4j** graph database (ports 7474, 7687)
341+
- **LiteLLM** gateway for generation and OpenAI embeddings (loopback port 54000)
320342

321343
### 2a. Start The Observability Overlay For This Branch
322344

@@ -350,6 +372,9 @@ uv run uvicorn server.main:app --reload --port 58012
350372
Notes:
351373
- The backend will **auto-load** repo-root `.env` on startup (dev convenience).
352374
- If you change `.env` while the backend is running, you must **restart** the backend for changes to take effect.
375+
- `GET /api/secrets/check?keys=LITELLM_API_KEY` checks only whether the app's
376+
gateway credential is present. It does not validate the key or inspect
377+
`OPENAI_API_KEY` in LiteLLM; upstream provider keys are outside this endpoint.
353378

354379
API available at http://localhost:58012
355380
OpenAPI docs at http://localhost:58012/docs

data/models.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5952,6 +5952,8 @@
59525952
"provider": "openai",
59535953
"family": "text-embedding-3-large",
59545954
"model": "text-embedding-3-large",
5955+
"gateway_alias": "openai.text-embedding-3-large",
5956+
"gateway_upstream": "openai/text-embedding-3-large",
59555957
"components": [
59565958
"EMB"
59575959
],
@@ -5969,6 +5971,8 @@
59695971
"provider": "openai",
59705972
"family": "text-embedding-3-small",
59715973
"model": "text-embedding-3-small",
5974+
"gateway_alias": "openai.text-embedding-3-small",
5975+
"gateway_upstream": "openai/text-embedding-3-small",
59725976
"components": [
59735977
"EMB"
59745978
],

docker-compose.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ services:
258258
- LITELLM_BASE_URL=http://litellm:4000/v1
259259
- LITELLM_API_KEY=${LITELLM_API_KEY:-sk-ragweld-local}
260260
- VLLM_BASE_URL=http://host.docker.internal:58080/v1
261+
- OPENAI_API_KEY=
261262
- OPENROUTER_API_KEY=
263+
- ANTHROPIC_API_KEY=
264+
- GOOGLE_API_KEY=
262265
env_file:
263266
- .env
264267
extra_hosts:

docs/references/config-control-plane.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,21 @@ OSS-composition branch.
7272
- `GET /api/secrets/check` now uses the registry-backed secret list rather than
7373
a hardcoded allowlist.
7474
- The workbench dependency panel is the operator-facing place to confirm whether
75-
required credentials are present.
75+
required app credentials are present.
76+
77+
OpenAI embeddings and generation authenticate to LiteLLM using the app's
78+
`LITELLM_API_KEY`; Compose supplies that credential to the gateway as
79+
`LITELLM_MASTER_KEY`. Upstream keys such as `OPENAI_API_KEY` belong only in the
80+
gateway's private `infra/litellm.env`, outside the app registry and browser secret
81+
controls. See [gateway credentials](generation-gateway-catalog.md#gateway-credentials)
82+
for the Proxmox file mapping and required gateway recreation after an env change.
83+
84+
For an app-side presence check on LXC100:
85+
86+
```bash
87+
curl -sS "http://127.0.0.1:58012/api/secrets/check?keys=LITELLM_API_KEY" | jq .
88+
```
89+
90+
This returns presence only, never a credential value or proof that the gateway
91+
accepts the key. Requesting `OPENAI_API_KEY` here returns an unsupported-secret
92+
error; it cannot check the gateway's upstream key or establish provider readiness.

0 commit comments

Comments
 (0)