feat(aionrs): attribute AI/ML API traffic on the wire - #1
Merged
Conversation
FORK-ONLY. Drops the moment `extra_headers` lands upstream and aionrs cuts a tag — at which point this goes back to `tag = "v0.2.11+"` and nothing else in the tree changes. The attribution commit that follows needs `TransportCompat::extra_headers`, which v0.2.11 does not have, so without this the next commit does not build. Kept separate and first so every commit in this branch compiles on its own and the feature commit stays reviewable as the change it actually is. Upstream PR: aimlapi/aionrs-aimlapi#1
Conversations never carried attribution. The desktop client sets `HTTP-Referer`
and `X-Title` in `ClientFactory.ts`, but the only thing routed through that
code is the built-in image-generation MCP server — chat and model listing go
through this crate and out via aionrs, which until now wrote authorization and
content type and nothing else. So the headers existed and reached almost no
traffic.
`resolve_aionrs_url_and_compat_with_mode` now resolves the four attribution
headers when the configured base URL is AI/ML API's, and both places that
apply compat overrides (`manager::aionrs::agent` and `services::provider_health`)
carry them into the aionrs config. They extend rather than assign, so a preset
that already carries headers keeps them.
The host match is exact, mirroring `is_openai_host` beside it. That matters
more than it looks: AI/ML API serves a request with a wrong or missing partner
id normally and simply attributes it to nobody, so every failure mode here is
silent. A substring match would hand our partner id to whoever registers
`api.aimlapi.com.example.test`, and nothing at runtime would say so. Hence
tests for the near-misses rather than only for the hit, and a test asserting
the id still matches the gateway's `^part_[A-Za-z0-9]{1,64}$`.
The `is_full_url` early return is covered too — a user who pasted a complete
endpoint is still talking to the same host, and that path exits before the
rest of the compat work.
Verified: 1005 tests in `aionui-ai-agent` pass. Removing the one line that
sets the headers, with the tests kept, fails exactly the two that assert they
are sent and leaves the three that assert they are NOT sent elsewhere passing
— which is what those should do.
Generated by the dependency repoint two commits back, and drops with it.
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.
Conversations never carried attribution.
The desktop client sets
HTTP-Referer/X-TitleinClientFactory.ts, but the only caller routed through that code is the built-in image-generation MCP server. Chat and model listing go through this crate and out via aionrs, which wrote authorization and content type and nothing else — so the headers existed and reached almost no traffic.What changed
build(fork-only)aion-*deps at the aionrs branch carryingextra_headersfeat(aionrs)build(fork-only)Commits 1 and 3 are fork-only and drop the moment
extra_headerslands upstream and aionrs cuts a tag — at which point the dependency goes back to a tag and commit 2 stands alone as the upstreamable change. They are separate and first so every commit here compiles on its own.Upstream half: aimlapi/aionrs-aimlapi#1 — a generic
extra_headersmap onTransportCompat, no provider named anywhere in it.Why the host match is exact
is_aimlapi_hostmirrorsis_openai_hostbeside it rather than doing acontains. That matters more than it looks: AI/ML API serves a request with a wrong or missing partner id normally and simply attributes it to nobody, so every failure mode here is silent. A substring match would hand our partner id to whoever registersapi.aimlapi.com.example.test, and nothing at runtime would report it.So the tests cover the near-misses, not just the hit:
not-api.prefix, and the host appearing in a query string — all must get no headersis_full_urlearly return, which exits before the rest of the compat work: a user who pasted a complete endpoint is still talking to the same host, and must still be attributed^part_[A-Za-z0-9]{1,64}$, since a malformed one fails silently and nothing else would catch itBoth places that apply compat overrides —
manager::aionrs::agentandservices::provider_health— carry the map through, extending rather than assigning so a preset that already has headers keeps them.Verification
1005 tests in
aionui-ai-agentpass;cargo checkclean;cargo fmtclean.Removing the single line that sets the headers, with the tests kept, fails exactly the two that assert they are sent — and leaves the three that assert they are not sent elsewhere passing, which is what those should do.