Skip to content

fix(backend): wire THUNDERBOLT_INFERENCE_URL through the inference proxy - #1203

Open
njbrake wants to merge 2 commits into
thunderbird:mainfrom
njbrake:pr4-wire-inference-gateway
Open

fix(backend): wire THUNDERBOLT_INFERENCE_URL through the inference proxy#1203
njbrake wants to merge 2 commits into
thunderbird:mainfrom
njbrake:pr4-wire-inference-gateway

Conversation

@njbrake

@njbrake njbrake commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Note: this PR description was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's.

Makes THUNDERBOLT_INFERENCE_URL work. It is documented in docs/self-hosting/configuration.md as the way to point a self-hosted backend at an OpenAI-compatible gateway, but nothing read it: the variable was absent from settings.ts and from the inference client, so setting it had no effect.

Adds the setting, a thunderbolt-inference provider in the inference client, and routing in inference/routes.ts for model ids the built-in table does not cover.

Models are discovered from the endpoint's GET /models rather than listed by hand, so a gateway that gains a model needs no redeploy. Discovery is cached for five minutes and refreshed when the app fetches /config. If the endpoint is unreachable its models are omitted and the built-ins keep working, so a gateway outage cannot break boot.

THUNDERBOLT_INFERENCE_MODELS stays optional and now does two things when set: restricts which discovered models are exposed, and supplies display names.

Requests are proxied through the backend, so the gateway key stays server side and the gateway needs no CORS configuration. Capabilities are advertised conservatively because the endpoint cannot be introspected.

Verified against a live gateway: 16 discovered models, and server logs confirming provider="thunderbolt-inference" with a 200 on a real completion.

@njbrake
njbrake deployed to fork-preview-approval August 6, 2026 22:23 — with GitHub Actions Active
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Preview environment deployed 🚀

Service URL
Marketing / blog / docs https://thunderbolt-pr-1203.preview.thunderbolt.io
App https://app-pr-1203.preview.thunderbolt.io
API https://api-pr-1203.preview.thunderbolt.io
Keycloak https://auth-pr-1203.preview.thunderbolt.io
PowerSync https://powersync-pr-1203.preview.thunderbolt.io

Stack: preview-pr-1203 · Commit: 2903ff48671625e92aeb437687a6f09f8856b05c

Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — demo@thunderbolt.io / demo by default.

_Note: this PR description was drafted by Claude via back-and-forth with @njbrake. The reasoning and decisions are his; the prose is Claude's._

Makes `THUNDERBOLT_INFERENCE_URL` work. It is documented in `docs/self-hosting/configuration.md` as the way to point a self-hosted backend at an OpenAI-compatible gateway, but nothing read it: the variable was absent from `settings.ts` and from the inference client, so setting it had no effect.

Adds the setting, a `thunderbolt-inference` provider in the inference client, and routing in `inference/routes.ts` for model ids the built-in table does not cover.

Models are **discovered** from the endpoint's `GET /models` rather than listed by hand, so a gateway that gains a model needs no redeploy. Discovery is cached for five minutes and refreshed when the app fetches `/config`. If the endpoint is unreachable its models are omitted and the built-ins keep working, so a gateway outage cannot break boot.

`THUNDERBOLT_INFERENCE_MODELS` stays optional and now does two things when set: restricts which discovered models are exposed, and supplies display names.

Requests are proxied through the backend, so the gateway key stays server side and the gateway needs no CORS configuration. Capabilities are advertised conservatively because the endpoint cannot be introspected.

Verified against a live gateway: 16 discovered models, and server logs confirming `provider="thunderbolt-inference"` with a 200 on a real completion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@njbrake
njbrake force-pushed the pr4-wire-inference-gateway branch from 875e4d7 to 2903ff4 Compare August 13, 2026 15:57
@njbrake
njbrake deployed to fork-preview-approval August 13, 2026 15:58 — with GitHub Actions Active

@ital0 ital0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for restoring THUNDERBOLT_INFERENCE_URL. The backend discovery and proxy path make sense, but I do not think the PR works end to end yet.

The main issue is that discovered models are published through reconciled defaults. The current frontend drops unknown model IDs without bundled profiles, so these models never reach the database or picker. The fixed version also means later catalog changes are ignored, while an empty or failed discovery can leave the frontend and backend with different model lists.

I also found inconsistencies around keyless gateways, allowlist parsing, model ID collisions, discovery timeouts, concurrent cache refreshes, and the deployment plumbing for THUNDERBOLT_INFERENCE_MODELS.

Because these issues affect the self-hosting flow described by the PR, my review is request changes.

Comment thread backend/src/inference/gateway-models.ts
Comment thread backend/src/api/config.ts Outdated
Comment thread backend/src/api/config.ts Outdated
Comment thread backend/src/inference/client.ts Outdated
Comment thread backend/src/inference/gateway-models.ts
Comment thread backend/src/config/settings.ts
Comment thread backend/src/api/config.test.ts Outdated
Comment thread backend/src/inference/routes.ts Outdated
Comment thread backend/src/inference/gateway-models.test.ts Outdated
Comment thread backend/.env.example Outdated
Deliver gateway-discovered models via a separate non-version-gated /config
field (defaults.gatewayModels) reconciled directly with a synthesized profile
per row, so they actually reach the picker; add discovery timeout, in-flight
dedup, serve-stale-on-failure, allowlist fail-closed, built-in slug-collision
drop, keyless-gateway support, and thread THUNDERBOLT_INFERENCE_MODELS through
the k8s/Pulumi/workflow deploy paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@njbrake
njbrake deployed to fork-preview-approval August 24, 2026 20:36 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants