Skip to content

50/50 RevShare Integration: OpenFang & AIML API - #1292

Open
hugoaimlapi wants to merge 2 commits into
RightNow-AI:mainfrom
aimlapi:feat/aimlapi-provider-upstream
Open

hugoaimlapi wants to merge 2 commits into
RightNow-AI:mainfrom
aimlapi:feat/aimlapi-provider-upstream

Conversation

@hugoaimlapi

Copy link
Copy Markdown

Hi! I'm Hugo from aimlapi.com — an AI aggregator that gives access to 1000+ models in one API, trusted by 400k+ users.

We'd love to be available as a verified provider option inside OpenFang — so we went ahead and did all the technical work on our side, in our fork: https://github.com/aimlapi/openfang-aimlapi

To build our partnership, we offer a 50/50 revenue share on all traffic from this integration.

My contacts: hugo@aimlapi.com (email / Slack), Telegram: @hug0the


Summary

Adds aimlapi.com as a built-in OpenAI-compatible provider (provider = "aimlapi", key in AIMLAPI_API_KEY, base URL https://api.aimlapi.com/v1). It follows the Requesty pattern: a base-URL constant, a provider_defaults arm, a ProviderInfo row and catalog rows. No new driver.

Requests to api.aimlapi.com carry four attribution headers. They identify traffic from OpenFang to aimlapi.com; the partner ID is what the revenue share is counted on.

Changes

  • openfang-types: AIMLAPI_BASE_URL = "https://api.aimlapi.com/v1".
  • drivers/mod.rs:
    • provider_defaults("aimlapi"): AIMLAPI_API_KEY, key required. Uses OpenAIDriver; base_url in config still overrides the default.
    • aimlapi_attribution_headers(base_url): headers only when the parsed URL host is api.aimlapi.com (case-insensitive), otherwise nothing. Headers: HTTP-Referer: https://github.com/RightNow-AI/openfang, X-Title: OpenFang, X-AIMLAPI-Source: agent/openfang, X-AIMLAPI-Partner-ID: part_Z6HbToJ3l2ht1dFSzHC98vk6.
    • Both OpenAI-compatible paths in create_driver (known provider, and custom provider with base_url) pass these headers to the driver. The check is on the resolved URL, not the provider name: a custom provider pointed at api.aimlapi.com gets them; other hosts, look-alike hosts and proxies never do. There's no setting to turn them off. No key, prompt or user data in them.
  • drivers/openai.rs: with_extra_headers appends instead of replacing, so a second call can't drop headers set earlier. The only other caller (copilot.rs) calls it once on a new driver, so its behaviour is unchanged.
  • model_catalog.rs: aimlapi provider row and 5 models at the gateway's prices: aimlapi/anthropic/claude-sonnet-4.6, aimlapi/openai/gpt-5-5, aimlapi/google/gemini-2.5-flash, aimlapi/alibaba/qwen-max, aimlapi/meta-llama/Llama-3.3-70B-Instruct-Turbo. strip_provider_prefix sends <vendor>/<model> on the wire.
  • metering.rs: estimate_cost rates for those 5 ids, matched only under the aimlapi/ prefix. Without them aimlapi/anthropic/claude-sonnet-4.6 would be priced at Anthropic's direct rate through contains("sonnet").
  • openfang init: aimlapi.com entry after OpenRouter, default model aimlapi/google/gemini-2.5-flash.
  • Settings page: aimlapi grouped under "Aggregators & Gateways".
  • .env.example: # AIMLAPI_API_KEY=....

Testing

  • cargo clippy --workspace --all-targets -- -D warnings passes
  • cargo test --workspace passes
  • Live integration tested (if applicable)

New tests:

  • drivers/mod.rs: provider defaults, partner id format (^part_[A-Za-z0-9]{1,64}$), headers for api.aimlapi.com, none for OpenRouter/OpenAI/proxy/look-alike/invalid URLs, headers for a custom provider on api.aimlapi.com, missing-key error.
  • drivers/openai.rs: with_extra_headers merges; unset optional request fields are omitted, not sent as null.
  • model_catalog.rs: provider row and models present, every aimlapi id is aimlapi/-prefixed. Provider count 42 → 43.
  • metering.rs: fallback rates equal catalog rates and don't apply to bare <vendor>/<model> ids.

rustfmt --check on the touched .rs files: no diff. All 5 model ids are in the live catalog.

Security

  • No new unsafe code
  • No secrets or API keys in diff (the partner ID is a public attribution id, not a credential; tests use dummy keys)
  • User input validated at boundaries (no new input surface; base_url is parsed with reqwest::Url::parse before the host check, an unparsable URL gets no headers)

Lookoff-AIMLAPI and others added 2 commits September 3, 2026 12:52
OpenFang already routes every OpenAI-compatible vendor through the shared
driver tables, so a gateway needs a base-URL constant, a provider-defaults
arm, a ProviderInfo row and a handful of catalog rows rather than a new
driver file. This follows the Requesty (issue RightNow-AI#995) and Novita wiring
exactly so there is one shape to maintain, not two.

The five catalog rows are gateway-priced rather than upstream-priced: the
same model costs a different amount through a router than direct, and
letting `aimlapi/anthropic/claude-sonnet-4.6` fall through to the generic
`contains("sonnet")` arm would silently bill it at Anthropic's own rate.
The metering fallback carries matching arms scoped to the `aimlapi/`
prefix, with a test that fails if those rates ever drift from the catalog.

Attribution headers are keyed on the request *origin*, not on the
configured provider name. A user can point any provider at any base_url,
and partner headers must never ride a request to a different vendor or to
a third-party proxy that merely fronts the same API. `with_extra_headers`
now appends instead of assigning, so attribution cannot silently discard
headers an earlier caller configured (Copilot's IDE auth is the existing
caller).

The partner id shape is asserted in a unit test because a malformed id is
accepted by the gateway and then ignored — it fails silently, earning
nothing, with no runtime error to notice.
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