feat: ANTHROPIC_BASE_URL override + opt-in headroom proxy overlay #39

Open
lz wants to merge 9 commits from feat/api-proxy into main
Owner

Summary

Adds support for routing worker claude traffic through a transparent proxy (e.g. headroom, a context-compression layer), via a new instance-wide ANTHROPIC_BASE_URL override, plus an opt-in bundled headroom compose overlay.

Two layers, decoupled:

  • Tool-agnostic knob — a new anthropic_base_url instance setting (registry-driven, env > db > default, validated http(s):// or empty). When non-empty it's injected into each worker's plain Env array at spawn (a base URL is not a secret, so deliberately not the tmpfs secret block). Works with any transparent proxy. Surfaces automatically in the instance settings UI with a label + help text.
  • Bundled headroomdocker-compose.headroom.yml, an opt-in overlay running a headroom code image (AST-aware code compression) with HEADROOM_CODE_AWARE_ENABLED=1 and HEADROOM_TELEMETRY=off, joined to the nexus-workers bridge. It sets ANTHROPIC_BASE_URL on the nexus service, which env-locks the setting so workers route through headroom automatically when the overlay is up.

Auth model is transparent OAuth passthrough: Nexus only sets the base URL; no API-key handling, subscription billing preserved. This relies on the proxy forwarding claude's OAuth Authorization header untouched (Remote Control requires OAuth, not an API key — see AGENTS.md facts #2/#3).

Changes

  • nexus/src/lib/server/settings/registry.tsanthropic_base_url setting (+ tests)
  • nexus/src/lib/server/workers/anthropic-env.ts — pure anthropicBaseUrlEnv helper (+ tests)
  • nexus/src/lib/server/workers/service.ts — inject into worker Env at spawn
  • nexus/src/lib/server/settings/service.test.ts — default + env-lock precedence tests
  • nexus/src/lib/components/settings/InstancePanel.svelte — UI label + help text
  • docker-compose.headroom.yml — opt-in overlay (gateway-pinned nexus-workers net)
  • AGENTS.md — env-var table row + verified-fact #19
  • docs/superpowers/specs|plans/ — design spec + implementation plan

Test Plan

Automated (green on this branch):

  • pnpm test — 542/542 pass
  • pnpm exec tsc --noEmit clean
  • pnpm typecheck (svelte-check) — 0 errors / 0 warnings
  • docker-compose.headroom.yml parses; nexus-workers net has subnet + pinned gateway

Runtime verification (operator-side, pending — blocking gate for the overlay only):

  • OAuth passthrough (BLOCKING): point a worker at headroom, run a real claude turn — confirm it succeeds on the shared OAuth login and billing stays on the subscription (headroom forwards the Bearer header, doesn't inject its own ANTHROPIC_API_KEY). If this fails, withdraw the overlay; the knob still ships.
  • Streaming/SSE intact — long streamed turn completes without buffering/truncation
  • Image env probe — confirm HEADROOM_CODE_AWARE_ENABLED truthy form and no blocking model fetch on cold start
  • docker compose -f docker-compose.yml -f docker-compose.headroom.yml config merges cleanly on a real Docker host

https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn

## Summary Adds support for routing worker `claude` traffic through a transparent proxy (e.g. [headroom](https://github.com/chopratejas/headroom), a context-compression layer), via a new instance-wide `ANTHROPIC_BASE_URL` override, plus an **opt-in** bundled headroom compose overlay. Two layers, decoupled: - **Tool-agnostic knob** — a new `anthropic_base_url` instance setting (registry-driven, `env > db > default`, validated http(s):// or empty). When non-empty it's injected into each worker's **plain `Env` array** at spawn (a base URL is not a secret, so deliberately *not* the tmpfs secret block). Works with any transparent proxy. Surfaces automatically in the instance settings UI with a label + help text. - **Bundled headroom** — `docker-compose.headroom.yml`, an opt-in overlay running a headroom `code` image (AST-aware code compression) with `HEADROOM_CODE_AWARE_ENABLED=1` and `HEADROOM_TELEMETRY=off`, joined to the `nexus-workers` bridge. It sets `ANTHROPIC_BASE_URL` on the nexus service, which env-locks the setting so workers route through headroom automatically when the overlay is up. Auth model is **transparent OAuth passthrough**: Nexus only sets the base URL; no API-key handling, subscription billing preserved. This relies on the proxy forwarding claude's OAuth `Authorization` header untouched (Remote Control requires OAuth, not an API key — see AGENTS.md facts #2/#3). ### Changes - `nexus/src/lib/server/settings/registry.ts` — `anthropic_base_url` setting (+ tests) - `nexus/src/lib/server/workers/anthropic-env.ts` — pure `anthropicBaseUrlEnv` helper (+ tests) - `nexus/src/lib/server/workers/service.ts` — inject into worker `Env` at spawn - `nexus/src/lib/server/settings/service.test.ts` — default + env-lock precedence tests - `nexus/src/lib/components/settings/InstancePanel.svelte` — UI label + help text - `docker-compose.headroom.yml` — opt-in overlay (gateway-pinned `nexus-workers` net) - `AGENTS.md` — env-var table row + verified-fact #19 - `docs/superpowers/specs|plans/` — design spec + implementation plan ## Test Plan Automated (green on this branch): - [x] `pnpm test` — 542/542 pass - [x] `pnpm exec tsc --noEmit` clean - [x] `pnpm typecheck` (svelte-check) — 0 errors / 0 warnings - [x] `docker-compose.headroom.yml` parses; `nexus-workers` net has subnet + pinned gateway Runtime verification (**operator-side, pending — blocking gate for the overlay only**): - [ ] **OAuth passthrough (BLOCKING):** point a worker at headroom, run a real `claude` turn — confirm it succeeds on the shared OAuth login and billing stays on the subscription (headroom forwards the Bearer header, doesn't inject its own `ANTHROPIC_API_KEY`). If this fails, withdraw the overlay; the knob still ships. - [ ] **Streaming/SSE intact** — long streamed turn completes without buffering/truncation - [ ] **Image env probe** — confirm `HEADROOM_CODE_AWARE_ENABLED` truthy form and no blocking model fetch on cold start - [ ] `docker compose -f docker-compose.yml -f docker-compose.headroom.yml config` merges cleanly on a real Docker host https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
lz added 9 commits 2026-06-21 13:45:54 +02:00
Design for routing worker claude traffic through a transparent proxy via
an instance-wide ANTHROPIC_BASE_URL setting, plus an opt-in headroom
compose overlay (code-aware image + telemetry off). OAuth passthrough is
the blocking verification gate.

Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
fix(compose): pin nexus-workers gateway; add settings UI label/help
Some checks failed
ci / nexus (pull_request) Failing after 2m4s
ci / images (./nexus, agent-nexus) (pull_request) Has been skipped
ci / images (./worker, agent-nexus-worker, base) (pull_request) Has been skipped
ci / images (PLAYWRIGHT_CLI_VERSION=0.1.13, ./worker, agent-nexus-worker, -playwright0.1.13, playwright) (pull_request) Has been skipped
7484014e1c
Addresses final review: ensureWorkersBridge requires a populated IPAM gateway,
so pin 172.30.0.1 explicitly in the headroom overlay. Add a friendly label and
help text for anthropic_base_url in the instance settings panel, matching
sibling settings. Tighten the overlay restart-to-apply comment.

Claude-Session: https://claude.ai/code/session_01HdTWo7DzxEhk63aKPo4Xpn
Some checks failed
ci / nexus (pull_request) Failing after 2m4s
ci / images (./nexus, agent-nexus) (pull_request) Has been skipped
ci / images (./worker, agent-nexus-worker, base) (pull_request) Has been skipped
ci / images (PLAYWRIGHT_CLI_VERSION=0.1.13, ./worker, agent-nexus-worker, -playwright0.1.13, playwright) (pull_request) Has been skipped
This pull request has changes conflicting with the target branch.
  • AGENTS.md
  • nexus/src/lib/server/workers/service.ts
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/api-proxy:feat/api-proxy
git switch feat/api-proxy

Merge

Merge the changes and update on Forgejo.
git switch main
git merge --no-ff feat/api-proxy
git switch feat/api-proxy
git rebase main
git switch main
git merge --ff-only feat/api-proxy
git switch feat/api-proxy
git rebase main
git switch main
git merge --no-ff feat/api-proxy
git switch main
git merge --squash feat/api-proxy
git switch main
git merge --ff-only feat/api-proxy
git switch main
git merge feat/api-proxy
git push origin main
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lz/agent-nexus!39
No description provided.