Skip to content

50/50 RevShare Integration: DeepCode & AIML API - #211

Open
hugoaimlapi wants to merge 3 commits into
HKUDS:mainfrom
aimlapi:feat/aimlapi-provider-upstream
Open

50/50 RevShare Integration: DeepCode & AIML API#211
hugoaimlapi wants to merge 3 commits into
HKUDS:mainfrom
aimlapi:feat/aimlapi-provider-upstream

Conversation

@hugoaimlapi

@hugoaimlapi hugoaimlapi commented Sep 8, 2026

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 DeepCode—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.

Description

Why

AI/ML API is an OpenAI-compatible router over ~350 chat models, but DeepCode has no template for it, so today it can only be wired as a custom connection — with no attribution on requests (unlike OpenRouter and Requesty), an unfiltered model directory (936 rows across image, video, speech and embedding endpoint families, of which only 353 are chat models a chat request accepts), and invented context windows: the gateway nests its numbers under info rather than publishing OpenRouter's flat keys, so every model falls through to the built-in 128k/8k fallback.

This PR adds aimlapi.com as a first-class gateway template on the same generic openai_compat path as OpenRouter and Requesty — no new backend.

Related Issues

None — new provider integration; no existing issue tracks it.

Changes Made

  • core/providers/registry.py + core/config.py: the aimlapi ProviderSpec (env key AIMLAPI_API_KEY, default base https://api.aimlapi.com/v1, openai_compat backend, gateway with OpenRouter-style vendor/model ids, supports_prompt_caching=True) and the matching ProvidersConfig.aimlapi field. Both halves are required — the config is read via getattr(providers, spec.name), so a spec without a field is silently skipped. Same wiring as Requesty and Forge in feat(providers): add Requesty, MiniMax and Forge #159.
  • core/providers/openai_compat.py: _DEFAULT_AIMLAPI_HEADERS (HTTP-Referer, X-Title, X-AIMLAPI-Source, X-AIMLAPI-Partner-ID) merged into the client's default headers by _uses_aimlapi_attribution() — the same mechanism as the OpenRouter and Requesty headers, with one deliberate difference: those helpers substring-match the base URL, which would also fire for a third-party proxy that merely fronts the gateway. Here the resolved base URL's host must be aimlapi.com / *.aimlapi.com, so DeepCode's partner identity never travels to someone else's endpoint. User-supplied extra_headers still win on a clash; no env vars are touched.
  • core/providers/catalog_service.py: model discovery for this provider asks for the chat surface only (/models?type=openai%2Fchat-completions), and _parse_model reads the gateway's nested info.contextLength / info.outputMax / info.name after the flat OpenRouter keys — a provider that publishes both keeps winning at the top level.
  • tests/test_aimlapi_provider.py: 19 tests — registry wiring pinned against OpenRouter/Requesty, header shape and origin scoping (the partner id fails silently when malformed: the gateway answers 200 and records the traffic as untagged, so its shape is asserted here rather than left to be noticed in production), catalog request and parsing, and env hygiene.

How to Test

pytest tests/test_aimlapi_provider.py -q   # 19 passed
python -c "
from core.providers.openai_compat import OpenAICompatProvider
from core.providers.registry import find_by_name
for name in ('aimlapi', 'openai'):
    p = OpenAICompatProvider(api_key='x', spec=find_by_name(name))
    h = p._client.default_headers
    print(name, '->', {k: v for k, v in h.items() if k.startswith('X-AIMLAPI')})
"
# aimlapi -> {'X-AIMLAPI-Source': 'agent/deepcode', 'X-AIMLAPI-Partner-ID': 'part_CxcOejScJ3hI0O2cExWchiBy'}
# openai -> {}
python -c "
from core.config import DeepCodeConfig, ProviderConfig, ProvidersConfig
from core.providers.catalog_service import _catalog_request
from core.providers.profiles import ConnectionResolver
cfg = DeepCodeConfig(providers=ProvidersConfig(aimlapi=ProviderConfig(api_key='x')))
print(_catalog_request(ConnectionResolver(cfg).resolve_connection('aimlapi'))[0])
"
# https://api.aimlapi.com/v1/models?type=openai%2Fchat-completions

Live run:

deepcode provider set my-aimlapi --template aimlapi --label "aimlapi.com" --api-key
deepcode provider models my-aimlapi --refresh   # 353 chat models with real context windows
deepcode provider test my-aimlapi --model <model-id>

Checklist

  • Changes tested locally
  • Code reviewed
  • Documentation updated (if necessary)
  • Unit tests added (if applicable)

Additional Notes

Follows the existing OpenRouter/Requesty attribution pattern. Nothing in the agent loop or routing changes; previously saved connections load unchanged (the new ProvidersConfig field has a default). Verified against the live gateway: chat, tool calling and streaming return through core.config.make_llm_provider, and cache_control markers come back with cached_tokens in usage, which is why supports_prompt_caching is set. No user-facing doc enumerates provider templates individually, so no documentation change is needed.

hugoaimlapi and others added 3 commits September 8, 2026 20:36
AI/ML API is an OpenAI-compatible router over ~350 chat models, wired on the generic openai_compat path like Requesty and Forge (HKUDS#159). Attribution headers follow the OpenRouter/Requesty pattern but are keyed on the resolved base URL's host. Model discovery asks the directory for the chat surface only and reads the gateway's nested info metadata after the flat OpenRouter keys.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZwkQDQ6xQfwH8kikYJPNU
The registry spec is read via getattr(providers, spec.name), so a spec without the matching ProvidersConfig field is silently skipped everywhere — both halves are required. The new field has a default, so previously saved configs load unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZwkQDQ6xQfwH8kikYJPNU
…sing

19 tests: registry wiring pinned against OpenRouter/Requesty, header shape (the partner id fails silently when malformed, so its shape is asserted here), origin-scoped attribution, catalog request and nested-metadata parsing, and env hygiene.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZwkQDQ6xQfwH8kikYJPNU
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.

1 participant