Apply managed http_headers to Codex's provider block - #773
Merged
Merged
Conversation
Wire the managed coding-agent config's `http_headers` into Codex, independent of
the Claude change: `managed_state_overrides` emits `{tool}_http_headers`, and
`_provider_block` merges them into the Databricks provider's `[http_headers]`
table (current and legacy layouts).
Admin headers win on a case-insensitive name collision, replacing ucode's own
header (including routing headers) rather than emitting two spellings of one HTTP
header. ug is the sole author of that table, so it is pruned wholesale before
each merge and rewritten from render_overlay — dropping routing headers that no
longer apply and any admin header removed from managed config, with no ug state.
Adds a wire-level check to tests/test_e2e_user_agent.py that launches the real
Codex binary and asserts an admin header arrives on the inference request.
Note: shares the small managed_resolve plumbing and the `_header` test helper
with the Claude PR (#772); whichever merges second
resolves a trivial overlap.
Co-authored-by: Isaac <no-reply@databricks.com>
tt-le
force-pushed
the
tien/codex-managed-http-headers
branch
from
September 21, 2026 16:25
f96fa67 to
ab2be5f
Compare
tt-le
changed the base branch from
tien/claude-managed-http-headers
to
main
September 21, 2026 16:25
Removes the duplicate `if tool in ("claude", "codex")` in managed_state_overrides
by grouping the http_headers override with static_models. No behavior change; the
override is still emitted only for the agents whose writers consume it.
Co-authored-by: Isaac <no-reply@databricks.com>
Emit `{tool}_http_headers` for any tool rather than only claude/codex. Only those
writers consume it today, so the override is inert for other agents, and dropping
the gate keeps the resolver simple.
Co-authored-by: Isaac <no-reply@databricks.com>
david-siqi-liu
approved these changes
Sep 21, 2026
The smart-routing launch path rebuilds the provider overlay and passes it to the Codex app-server as `-c model_providers.Databricks=...` overrides, which replace the whole provider block (including its http_headers table). That overlay omitted the admin headers, so they were written to config.toml but stripped from the launched inference calls whenever smart routing was active. Thread `codex_http_headers` into the launch overlay in launch_codex, and add a regression test asserting the admin header appears in the app-server config args. Co-authored-by: Isaac <no-reply@databricks.com>
tt-le
added this pull request to stack #776
September 21, 2026 19:08
tt-le
added a commit
that referenced
this pull request
Sep 21, 2026
#775) ## What **Stacked on #773.** Adds an integration test proving the managed `http_headers` feature reaches Codex's OS-managed config end to end through the real `ug` CLI. - `test_managed_fixture_codex_http_headers_in_managed_file` (in `test_ug_configure_managed_mcp.py`): injects an admin `http_headers` map via the `managed_fixture` stub, runs the **interactive** `ug configure codex` (`ConfigureTerminal`), and asserts `/etc/codex/managed_config.toml` contains `[model_providers.Databricks.http_headers]` with `x-databricks-workspace = "eng-ml-inference"`. - Extends `build_codex_agent_config` with an optional `http_headers` arg. - Updates the coverage matrices in `tests/README.md` and `tests/integration/README.md`. ## Why interactive The OS-managed file `/etc/codex/managed_config.toml` is only written when `managed_writes_allowed()` (i.e. `sys.stdin.isatty()`) — so this uses the PTY `ConfigureTerminal` flow, mirroring the existing `test_managed_fixture_codex_mcp_written_to_managed_file`. (The per-profile `~/.codex/ucode.config.toml` is written non-interactively, but the OS-managed file is the high-precedence one worth asserting.) ## Verification Structural checks pass locally (`ruff check`/`format`, `test_integration_contract.py` 5 passed, `run_integration.py --help`). The live run needs `UCODE_TEST_WORKSPACE` + `DATABRICKS_BEARER` + an interactive PTY + Codex ≥ 0.145.0, so it runs in the integration CI job, not locally. This pull request and its description were written by Isaac. Co-authored-by: Isaac <no-reply@databricks.com>
tt-le
added a commit
that referenced
this pull request
Sep 22, 2026
## What Admin-supplied `http_headers` in the managed coding-agent config were parsed and publishable but never reached any agent. Wire them into **Claude Code**. Independent of the Codex PR (#773) — both target `main`. - `managed_resolve.managed_state_overrides` emits `{tool}_http_headers`. - `claude.render_overlay` merges the admin headers into `ANTHROPIC_CUSTOM_HEADERS`. ## Behavior - **Admin wins on a case-insensitive name collision** — replaces ucode's own line in place, appends new ones. - **Clean removal, no ug state** — the ucode-owned set of header names is derived from the files themselves: ucode owns `ucode-settings.json` wholesale (every header there is ucode's, so a dropped managed header can't linger), and for the OS-managed file only the names ucode last wrote (`last_applied_by_ug`) are treated as ucode's, leaving IT-authored headers untouched. (An earlier revision tracked names in ug state; that isn't preserved across runs, so a removed header lingered — fixed here.) ## Tests - `render_overlay` / `_merge_anthropic_custom_headers`: add, in-place override, removal, IT-header preservation. - `write_tool_config`: admin header written; dropped after removal on the ucode file; IT header preserved on the managed file via `last_applied_by_ug`. - `managed_resolve`: `http_headers` → `{tool}_http_headers` override. - Wire-level (`tests/test_e2e_user_agent.py`): the capture-server harness launches the real Claude binary and asserts an admin header arrives on the inference request. ## Note on overlap with #773 Shares the small `managed_resolve` plumbing and the `_header` test helper with #773; identical in both, trivial overlap on whichever merges second. Neither depends on the other. This pull request and its description were written by Isaac. --------- Co-authored-by: Isaac <no-reply@databricks.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Wire the managed coding-agent config's
http_headersinto Codex. Independent of the Claude PR (#772) — both targetmain.managed_resolve.managed_state_overridesemits{tool}_http_headers.codex.write_tool_configreadscodex_http_headers;_provider_blockmerges the admin headers into the Databricks provider's[http_headers]table (current per-profile layout and legacy< 0.134.0layout).Behavior
http_headerstable, so it's pruned wholesale before each merge and rewritten fromrender_overlay. This drops routing headers that no longer apply and any admin header removed from managed config;deep_mergealone cannot delete keys.Tests
render_overlay: admin header added; admin overrides ucode's routing header case-insensitively with no duplicate spelling.write_tool_configend-to-end: admin header written toconfig.toml; dropped after removal whileUser-Agentis kept.tests/test_e2e_user_agent.py): the capture-server harness launches the real Codex binary and asserts an admin header arrives on the inference request.Note on overlap with #772
This PR shares the small
managed_resolveplumbing (the{tool}_http_headersemit) and the_headertest helper with #772. They're identical in both; whichever merges second resolves a trivial overlap. Neither depends on the other.This pull request and its description were written by Isaac.