Skip to content

Keep Claude custom request headers scoped to launch - #687

Open
andy-xu-db wants to merge 30 commits into
mainfrom
andy/custom-request-headers-claude
Open

andy-xu-db wants to merge 30 commits into
mainfrom
andy/custom-request-headers-claude

Conversation

@andy-xu-db

@andy-xu-db andy-xu-db commented Sep 16, 2026 •

Copy link
Copy Markdown
Collaborator

🥞 Stacked PR

Use this link to review incremental changes.


ug claude --header "Name: value" adds repeatable headers through a launch-only Claude settings override, preserving required headers without writing custom values into shared settings. The global ug --header ... claude form uses the same implementation. Direct, smart-routing, and relayed launches compose this override with existing launch settings.

Claude launches reject --header when OS-managed settings define env.ANTHROPIC_CUSTOM_HEADERS, including an empty value. That policy takes precedence over launch settings, so silently accepting the flag would not deliver the requested header. Existing private/admin header-name collisions are also rejected.

Headers reach model discovery before Claude starts. Scoped model lists and defaults stay in the launch context. The obsolete global-header journal, cleanup, and recovery tests are removed; focused launch/policy/discovery tests cover the replacement behavior. Shared invocation handling, cache isolation, usage, and routing propagation come from #610.

Merged the updated #610, including main at 7deeaf7a.

Validation (2026-10-07):

  • 3,486 passed, 6 skipped: uv run --frozen pytest -q --ignore=tests/test_e2e.py --ignore=tests/test_e2e_user_agent.py.
  • 656 focused HTTP/cache, Claude launch, and routing tests passed after the final cache-test strengthening and redundant-edit cleanup.
  • Ruff lint/format, Ty, and git diff --check passed.

Native-agent capture validation remains unverified: four Claude/Codex capture checks failed because no request reached the local capture server. Live LiteSwap validation was not completed. Component tests verify request construction and launch configuration; they do not establish a live agent or gateway pass.

@andy-xu-db
andy-xu-db changed the base branch from andy/custom-request-headers to main September 16, 2026 20:14
@andy-xu-db
andy-xu-db force-pushed the andy/custom-request-headers-claude branch from c85880d to c65f808 Compare September 16, 2026 20:42
@andy-xu-db andy-xu-db changed the title Support temporary custom request headers for Claude Code Support temporary global custom request headers for Claude Code Sep 16, 2026
@andy-xu-db
andy-xu-db force-pushed the andy/custom-request-headers-claude branch 2 times, most recently from b2ce76d to cc94c21 Compare September 21, 2026 20:24
@andy-xu-db
andy-xu-db force-pushed the andy/custom-request-headers-claude branch from cc94c21 to 635dad9 Compare September 21, 2026 21:28
@andy-xu-db

Copy link
Copy Markdown
Collaborator Author

Live LiteSwap + Actual TUI Validation (2026-09-21)

Validated the combined #610/#687 stack at 635dad951b3050351913a00dcdcac23ebc669741 using real Claude Code 2.1.278 and Codex 0.154.0 TUIs, driven through a PTY with the repository's terminal helpers. No mocked clients or responses, headless substitutes, sandbox overrides, or manually seeded onboarding state.

Deployed a harmless AI Gateway marker change to staging-aws-us-east-1-0 and used eng-ml-inference-staging. Both launches passed repeated --header options for x-databricks-traffic-id: testenv://liteswap/andy-ug-headers-0921 and a client-specific probe.

Actual TUI run Assistant answer Result
ug claude --header ... --header ... 1739 + 2846 = 4585 Swap logged /ai-gateway/anthropic/v1/messages?beta=true with both exact headers and Claude User-Agent
ug codex --header ... --header ... 1927 + 3648 = 5575 Swap logged /ai-gateway/codex/v1/responses with both exact headers and Codex User-Agent
Header-free ug claude 1839 + 2846 = 4685 No new swap markers; both temporary headers and their state entry removed
Header-free ug codex 2027 + 3648 = 5675 No new swap markers; headers never persisted in user/managed config

All four TUIs exited normally with code 0. Server marker evidence was collected at 22:18:49 UTC (Claude, request 73c97621-fea1-4a8a-8b25-04b9a208dd5c) and 22:19:12 UTC (Codex, request f093e6ee-61fe-41d9-b0f5-0f30f0c477b6). Marker logs before and after header-free controls were byte-identical.

Scope limitation: staging smart-router selection returned HTTP 400 both with and without custom headers. The TUIs fell back successfully to their current models. This verifies actual inference header propagation through that fallback path, not a successful live smart-router model switch. MCP tool execution was not exercised.

No additional header-code fix was needed. The temporary container/token were removed and LiteSwap teardown succeeded. The marker change was not added to these PRs.

…261006

# Conflicts:
#	src/ucode/databricks.py
@andy-xu-db andy-xu-db changed the title Support temporary global custom request headers for Claude Code Keep Claude custom request headers scoped to launch Oct 7, 2026
andy-xu-db and others added 3 commits October 8, 2026 16:36
Reject a global `--header` on non-launch subcommands such as `configure`,
which skipped per-agent validation and persisted header-scoped discovery.
Propagate the header scope into skill and catalog worker threads, which
otherwise sent their requests without it, and reject non-ASCII values
before they fail during the request.

Co-authored-by: Isaac <no-reply@databricks.com>
…eaders-claude

Co-authored-by: Isaac <no-reply@databricks.com>
`ug configure` mirrors ug's headers into Claude Code's OS-managed
settings, which take precedence over launch settings, so `--header` was
rejected with a misleading "contact your administrator" message. Name
ug as the source in that case, check managed-settings.d drop-ins, and
report unreadable managed files instead of raising a traceback.

Co-authored-by: Isaac <no-reply@databricks.com>
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.

1 participant