50/50 RevShare Integration: Mercury & AIML API - #117
Open
hugoaimlapi wants to merge 5 commits into
Open
Conversation
One key reaches 350+ chat models from OpenAI, Anthropic, Google, DeepSeek, Alibaba and others through a single OpenAI-compatible surface, which fits the existing `OpenAICompatProvider` without a new client. - `aimlapi` joins `ProviderName`, the config block and the registry, routed through Chat Completions — the catalogue is mostly third-party models reached that way. - Configured by `AIMLAPI_API_KEY` / `AIMLAPI_BASE_URL` / `AIMLAPI_MODEL` like every other provider here. The default model is `anthropic/claude-sonnet-4.6`; the preferred list was checked against the live catalogue rather than copied from another provider's shape, since ids there are namespaced by lab. - Listed first in `PROVIDER_OPTIONS`, the picker a user reads. Two placement decisions worth stating rather than leaving to review: - In `ProviderRegistry.create` the entry sits AFTER `mercuryCloud`. That array is the fallback order, and moving a first-party hosted provider off the front of it changes behaviour for existing installs, which is a different thing from where a name appears in a list. - The picker position is the opposite call and is deliberate; revert that one line if the ordering there is meant to stay fixed. The gateway attributes traffic by header. `aimlapi-attribution.ts` supplies them, and returns `undefined` for every other host, so nothing else routed through `OpenAICompatProvider` sends anything extra. The host check parses the URL and compares `hostname` instead of matching a prefix. That is the whole point of the module: a request carrying the wrong partner id is served normally and attributed to nobody, so a leak to `api.aimlapi.com.example.test` would never surface at runtime — and users can point a base URL anywhere. Tests cover the lookalikes, not just the hit. Verified: `tsc --noEmit` clean; 55 test files, 325 passing. Replacing the URL parse with a substring check, tests kept, fails the lookalike case.
…eb UI Four defects, all found by opening the Providers page rather than by reading the diff. The first made the integration unusable from the UI. **Model discovery returned nothing.** With no branch of its own, `aimlapi` fell through to the default filter, which keeps ids starting with `gpt-` or `o<digit>`. Ids here are namespaced by lab — `anthropic/claude-sonnet-4.6`, `alibaba/qwen3.8-max` — so all 353 chat models were dropped and the page said "Mercury could not find any supported chat models for this provider" against a listing that had them. The listing carries `type` naming the surface each row belongs to, so the chat set is the rows on the OpenAI-compatible one; ids repeat across surfaces and `uniq` already collapses them. **Saving from the UI was rejected.** `POST /api/providers/:name` validates against a hardcoded `validNames` that nobody updated, so the Save button returned an error for a provider the rest of the app already knew. **The provider was fourth in the UI.** That list is built from `Object.entries(config.providers)`, so its order is the key order of the defaults object, not the picker array in `index.ts`. Moved to the front. **No badge.** `GET /api/providers` now returns `recommended`, and the card renders it next to Active/Disabled. One constant names the provider rather than a list, so the claim stays reviewable and reverting it is one line. Verified end to end against production, not just in tests: Test Connection returns `success: true` with a populated model list and `anthropic/claude-sonnet-4.6` as recommended; the API lists `aimlapi` first with `recommended: true`; a message sent through the web channel reaches `api.aimlapi.com` with all four attribution headers and answers 200. 57 test files, 329 passing. Removing the discovery branch with the tests kept fails both new tests with the exact message the UI showed.
feat(providers): add AI/ML API as an OpenAI-compatible provider
`mercury setup` / `mercury doctor` list AI/ML API as option 1, but the per-provider loop had no `aimlapi` branch, so picking it prompted for nothing and setup ended with "No LLM provider configured yet". Added the branch, same shape as Atlas Cloud: ask for the key, validate it by fetching the model list, let the user pick a model.
Adds AIMLAPI_API_KEY / AIMLAPI_BASE_URL / AIMLAPI_MODEL to `.env.example` and `aimlapi` to the DEFAULT_PROVIDER comment, as for Atlas Cloud.
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.
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 Mercury — so we went ahead and did all the technical work on our side.
To build our partnership, we offer a 50/50 revenue share on all traffic from this integration. (P.S.: tracking starts as soon as this release goes live, so no earnings will be lost during setup)
My contacts: hugo@aimlapi.com (email / Slack), Telegram: @hug0the
Why
Mercury has no AI/ML API preset. It can be reached through "OpenAI Compilations" (
openaiCompat) with a hand-typed base URL, but model discovery there keeps every id in the listing — image, video and speech models included — and requests carry no attribution.Summary
config.ts:aimlapiadded toProviderNameand the default config —AIMLAPI_API_KEY/AIMLAPI_BASE_URL(defaulthttps://api.aimlapi.com/v1) /AIMLAPI_MODEL(defaultanthropic/claude-sonnet-4.6) /AIMLAPI_ENABLED. Without a key it is not configured and not registered.DEFAULT_PROVIDERstaysdeepseek.registry.ts: served byOpenAICompatProviderover Chat Completions, registered right aftermercuryCloud.aimlapi-attribution.ts+openai-compat.ts:X-AIMLAPI-Partner-ID,X-AIMLAPI-Source,HTTP-Referer,X-Titlepassed asheaderstocreateOpenAI. Only when the parsed base URL hostname is exactlyapi.aimlapi.com; every other host gets no extra headers. The check is on the host, so it also applies ifopenaiCompatpoints atapi.aimlapi.com.provider-models.ts: discovery keeps the rows withtype: "openai/chat-completions"(353 chat models today) and collapses repeated ids; 4 preferred ids checked against the live catalogue.index.ts: CLI setup (mercury setup/mercury doctor) lists AI/ML API first; picking it asks for the key, validates it by fetching models and offers a model pick — same flow as Atlas Cloud.aimlapiadded tovalidNamesinPOST /api/providers/:name;GET /api/providersreturnsrecommended(true only foraimlapi), shown as a "Recommended" badge on the Providers page; provider color in Usage..env.example:AIMLAPI_*vars.aimlapi-attribution.test.ts,openai-compat.aimlapi.test.ts,provider-models.aimlapi.test.ts.Before / After
anthropic/claude-sonnet-4.6recommended; requests toapi.aimlapi.comcarry the attribution headers. Other providers: no extra headers, default provider unchanged.How to Test
Web UI: Providers → AI/ML API → paste key → Save → Test Connection returns the chat model list with
anthropic/claude-sonnet-4.6as recommended.Type
Notes
validNames,.env.example. No new dependencies, no breaking changes; previously saved configs load unchanged —aimlapicomes from the defaults and stays unconfigured until a key is set.mercuryCloud. The badge is one constant (RECOMMENDED_PROVIDER) and the picker entry is one line, if you'd rather keep the ordering neutral.