Repository navigation
feat(providers): add AI Stupid Level as an OpenAI-compatible gateway - #276
Open
StudioPlatforms wants to merge 1 commit into
Open
StudioPlatforms wants to merge 1 commit into
StudioPlatforms wants to merge 1 commit into
Conversation
AI Stupid Level's Smart Router is an OpenAI-compatible endpoint at https://aistupidlevel.info/v1. Its routing modes (auto-coding, auto-tooling, ...) send each request to a model chosen from ASL's benchmark results, and the router calls that model with the provider keys the user saved on their own ASL account. Mirrors the Opper provider added in HKUDS#242: a ProviderSpec on the generic openai_compat gateway path, the matching ProviderConfig block, the endpoint-class row in tests/test_provider_egress.py, and tests pinning the wiring. Two provider specific decisions, both covered by tests that build a request through OpenAICompatProvider._build_kwargs. strip_model_prefix is on, as for Forge: the router serves bare ids only and answers aistupidlevel/auto-coding with model_not_found. Prompt caching stays off: the router already asks Claude to cache every conversation that continues, so DeepCode's cache-control markers are not needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Disclosure: this PR comes from the AI Stupid Level team, so we are the vendor of the service it adds. It was prepared with Claude Code (Claude Opus 5.5) for the AI Stupid Level team. Happy to adjust anything to match project conventions, or to close it if a named provider is not wanted.
Description
Adds AI Stupid Level's Smart Router as a provider template:
deepcode provider set my-asl --template aistupidlevel --api-key. The router is an OpenAI-compatible endpoint athttps://aistupidlevel.info/v1(API docs). It mirrors the Opper template from #242: aProviderSpecon the genericopenai_compatgateway path, the matchingProviderConfigblock, and tests pinning the wiring. This time the("aistupidlevel", "gateway")row intests/test_provider_egress.pyis in the PR itself; for Opper it was added at merge.The router forwards each request with the user's own provider key (OpenAI, Anthropic, Google, DeepSeek, Kimi or GLM, saved on their AI Stupid Level account), so the provider bills the user directly. The terms say: "The provider bills you directly for that usage, under your agreement with it. We do not resell model access and do not mark up provider prices."
A request names one of two kinds of model id:
auto-codingfor coding,auto-toolingfor tool use.claude-opus-4-7pins that model.Each routed response carries two headers:
X-AISM-Model(the model that answered) andX-AISM-Reasoning(why it was chosen).The trust boundary is the same as for any gateway. The router terminates TLS and reads prompts and tool results, and the user's provider keys are stored on their AI Stupid Level account.
endpoint_class="gateway"says so, andproviders.egresscan blockaistupidlevel.info. ASL's terms say: "You give us permission to process it only to provide the service to you. We do not use your requests to train models or to build our benchmarks."Related Issues
None.
Changes Made
core/providers/registry.py: anaistupidlevelProviderSpecafteropper, with these values:AISTUPIDLEVEL_API_KEY, default basehttps://aistupidlevel.info/v1,endpoint_class="gateway", base keywordaistupidlevel.info, and key prefixaism_(router keys start with it).core/config.py: the matchingProviderConfigblock.tests/test_provider_egress.py: the("aistupidlevel", "gateway")endpoint-class row.tests/test_aistupidlevel_provider.py(new): pins the wiring and the two decisions below. Both decision tests build a real request throughOpenAICompatProvider._build_kwargs.Two provider-specific decisions:
strip_model_prefixis on, as for Forge. The router serves bare ids only. In a sandbox request to the live endpoint (see below),aistupidlevel/auto-codingandanthropic/claude-opus-4-7both get400 model_not_found, whileauto-codingandclaude-opus-4-7route.Checklist
Additional Notes
Code reviewed is unticked because no one outside the AI Stupid Level team has reviewed the change. Documentation is unticked because no docs change is needed:
docs/guide/models.mduses OpenRouter as its example and gives a section only to Bedrock, whose setup differs. Requesty, Opper and Forge are not listed there either.Commands run (Python 3.12.15, deps from
scripts/ci/requirements.lock, Linux):pytest tests/test_aistupidlevel_provider.py tests/test_provider_egress.py tests/test_opper_provider.py tests/test_forge_provider.py: 62 passed.tests/*provider*,test_catalog,test_config_*,test_model_compat,test_model_catalog_service,test_llm_runtime_connections,test_reasoning_*,test_init_config): 264 passed. Cleanmaingives 257; the difference is the 6 new tests plus the new egress row.strip_model_prefixandsupports_prompt_cachingin the spec, and the two decision tests failed. With the values restored, they pass.pytest tests --ignore=tests/e2e): 2750 passed, 37 skipped, 11 failed.main(49805ef):test_ci_scope×4,test_verification,test_unified_impl_workflow,test_p4_code_workbench×2 andtest_shell_search_tools. They depend on this machine: there is nopythonexecutable on PATH, and the systempython3has an older pytest than the lock.test_service_tuidropped connection,test_mcp_runtime_lazytimeout) pass when re-run alone, on bothmainand this branch.pre-commit run --files <the 4 files>: all hooks passed. Actionlint was skipped because no workflow changed.Live check without spending anything: ASL has a sandbox mode. A request with
X-ASL-Sandbox: truegoes through real authentication and routing but gets a mock answer. No provider is called and nothing is billed. I used a temporary router key and a local proxy that adds the header:deepcode provider set asl-sandbox --template aistupidlevel --api-base http://127.0.0.1:<port>/v1 --api-key-env AISTUPIDLEVEL_API_KEY --model auto-codingdeepcode provider models asl-sandbox --refresh: 39 models (15 routing modes and 24 pinnable models).deepcode provider test asl-sandbox --model auto-coding: the credential, catalog and model stages passed.deepcode provider test ... --agent: the tool stage passed. The continuation stage failed, as expected: the sandbox's mock answer cannot reproduce the nonce. I did not run Agent verification against a real model.OpenAICompatProviderwith the registry spec, run both through the proxy and against the default base URL withextra_headers={"X-ASL-Sandbox": "true"}. Each request returned 200 withX-AISM-Modelset:auto-codingwas routed togpt-5.6-luna.aistupidlevel/auto-codingwas sent asauto-coding.claude-opus-4-7withreasoning_effort="high"was accepted.auto-toolingwith one tool returned a parsedread_filetool call.auto-codinggave 3 deltas, thenstop.The catalog lists the routing modes with DeepCode's defaults for unknown models (128,000 context, 8,192 output), which is conservative. For any routed model the limits are 262,144 context and 64,000 output. Users can declare those with
--model-declarationsif they want. The router is text only, so image, audio and file parts get400 unsupported_content.🤖 Generated with Claude Code