Skip to content

feat(providers): let a provider send configured extra headers - #1

Merged
Lookoff-AIMLAPI merged 1 commit into
mainfrom
feat/provider-extra-headers
Sep 11, 2026
Merged

feat(providers): let a provider send configured extra headers#1
Lookoff-AIMLAPI merged 1 commit into
mainfrom
feat/provider-extra-headers

Conversation

@Lookoff-AIMLAPI

Copy link
Copy Markdown
Member

Adds a generic extra_headers map to TransportCompat, applied by the OpenAI and Anthropic transports.

Why

OpenAiTransport::build_projected_request writes exactly two headers — authorization and content type — and there is no way to add a third. Several gateways ask callers to identify themselves on the wire (an app name, a referer, a partner id) and cannot attribute traffic without it, so anything routed through this crate arrives anonymous no matter what the caller configured further up.

Nothing in this change names a provider. Which headers to send is a per-deployment question, so it belongs in configuration rather than in a match arm on a host name — there are no host-specific branches in this crate today and this does not add the first one.

Three deliberate details

Reserved headers win the map is written first and the protocol headers after, so a config typo cannot unauthenticate a request, change the wire format, or downgrade anthropic-version. No blocklist to keep in sync — the ordering is the rule, pinned by tests for both transports
Merging is per key TransportCompat::merge extends rather than replaces, so setting one header in user config does not drop the preset's others the way .or() semantics would
Bedrock and Vertex excluded Bedrock signs its headers with SigV4; a header added outside the signing step invalidates the signature instead of being attributed. Better to leave those transports alone than ship something that fails confusingly

Backward compatibility

#[serde(default)] with skip_serializing_if, so an empty map never appears in a rendered config and existing files parse unchanged. There is a test for that specifically, since it is the part a release would break quietly.

Verification

aion-config and aion-providers suites pass (240 in the providers lib alone), cargo check --workspace clean, cargo fmt clean.

Reverting the two insert_extra_headers calls while keeping the tests fails exactly the three that assert the new behaviour — and leaves the reserved-headers-win test passing, which is correct, since that one holds either way.

`OpenAiTransport::build_projected_request` writes exactly two headers —
authorization and content type — and there is no way to add a third. Several
gateways ask callers to identify themselves on the wire (an app name, a
referer, a partner id) and cannot attribute traffic without it, so anything
routed through this crate arrives anonymous no matter what the caller
configured further up.

Adds `extra_headers` to `TransportCompat`, applied by the OpenAI and Anthropic
transports. Nothing here names a provider: which headers to send is a
per-deployment question, so it belongs in configuration rather than in a match
arm on a host name.

Three details that are deliberate:

- **Reserved headers win.** The map is written first and the protocol headers
  after it, so a config typo cannot unauthenticate a request, change the wire
  format, or downgrade `anthropic-version`. No blocklist to keep in sync — the
  ordering is the rule, and tests pin it for both transports.
- **Merging is per key.** `TransportCompat::merge` extends rather than
  replaces, so setting one header in user config does not drop the preset's
  others the way `.or()` semantics would.
- **Bedrock and Vertex are not covered.** Bedrock signs its headers with
  SigV4; a header added outside the signing step invalidates the signature
  instead of being attributed. Better to leave those transports alone than to
  ship something that fails confusingly.

Backward compatible on disk: the field is `#[serde(default)]` with
`skip_serializing_if`, so an empty map never appears in a rendered config and
existing files parse unchanged. A test pins that too, since it is the part a
release would break quietly.

Verified: aion-config and aion-providers suites pass (240 in the providers lib
alone). Reverting the two `insert_extra_headers` calls while keeping the tests
fails exactly the three that assert the new behaviour, and leaves the
reserved-headers-win test passing — which is what it should do, since that one
holds either way.
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