feat(llm): add Atlas Cloud provider - #1510
Conversation
…h _model_for_provider Forward guard for providers added after M-11. Each branch used to end in `return key, <BASE_URL>, <DEFAULT_MODEL>` — the shape that made the bug possible, since a hardcoded default silently ignores `model_attr`. A new provider copied from an existing branch inherits it, and nothing notices: the knob just quietly does nothing for that one provider. The invariant is structural rather than per-provider, so it covers branches that do not exist yet. #1510 (Atlas Cloud) adds exactly such a branch and will trip this until it routes through the resolver — which is the point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
|
Heads-up on an interaction with #1522, which is open against the same file — no action needed from you yet, and nothing wrong with this PR as written. #1522 fixes 09/02 M-11: model = _model_for_provider(provider, tenant_config, model_attr, ATLASCLOUD_DEFAULT_MODEL)
return key, ATLASCLOUD_CHAT_BASE_URL, modelThe two PRs touch different lines, so git will merge them cleanly — but the result would be inconsistent: Atlas Cloud would keep ignoring #1522 carries a structural test asserting every branch resolves through One thing that may be worth a look independently: |
…h _model_for_provider Forward guard for providers added after M-11. Each branch used to end in `return key, <BASE_URL>, <DEFAULT_MODEL>` — the shape that made the bug possible, since a hardcoded default silently ignores `model_attr`. A new provider copied from an existing branch inherits it, and nothing notices: the knob just quietly does nothing for that one provider. The invariant is structural rather than per-provider, so it covers branches that do not exist yet. #1510 (Atlas Cloud) adds exactly such a branch and will trip this until it routes through the resolver — which is the point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
…h _model_for_provider Forward guard for providers added after M-11. Each branch used to end in `return key, <BASE_URL>, <DEFAULT_MODEL>` — the shape that made the bug possible, since a hardcoded default silently ignores `model_attr`. A new provider copied from an existing branch inherits it, and nothing notices: the knob just quietly does nothing for that one provider. The invariant is structural rather than per-provider, so it covers branches that do not exist yet. #1510 (Atlas Cloud) adds exactly such a branch and will trip this until it routes through the resolver — which is the point. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Arkady Mankovsky <arkash20@gmail.com>
022ceaa to
615bc76
Compare
|
Thanks @arkash20. Rebased onto current main after #1522 and pushed 615bc76. The Atlas branch now calls On bare IDs: support is model-specific, not universal. The Atlas-side live checks shared with me returned 400/not found for Added coverage for tenant/env per-service overrides, those bare aliases, and default fallback. Validation: 54 tests passed across |
|
Approved by @arkash20 and I updated the branch so CI could run, but the DCO check fails: the first commit ( |
|
@binyangzhu000-sudo the only thing between this and main is the sign-off on @arkash20 for visibility, since the approval is yours. |
Atlas Cloud is an OpenAI-compatible gateway, so it joins the set that rides OpenAILLMProvider alongside OpenRouter — no new transport, just the enum member, the endpoint constants, and credential resolution. - common/provider_names.py: ATLASCLOUD member - common/llm/constants.py: chat base URL and default model - common/llm/_credentials.py: tenant-attr map, _env_key, and the resolve_openai_compatible branch - common/llm/registry.py: add to _OPENAI_COMPATIBLE - core-api config + organization_settings: atlascloud_api_key, the env bridge entry, and the tenant-key property - tests: 13 unit tests, plus ATLASCLOUD_API_KEY in the bridge-key snapshot Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
cdbfb98 to
ab59a7f
Compare
|
Pushed — both commits now carry |
|
Sign-off landed, branch current, CI green. Merging. Thanks @binyangzhu000-sudo for the provider and for the quick turnaround on the DCO. |
🤖 I have created a release *beep* *boop* --- <details><summary>backend: 3.20.0</summary> ## [3.20.0](backend-v3.19.2...backend-v3.20.0) (2026-09-26) ### Features * **llm:** add Atlas Cloud provider ([#1510](#1510)) ([0ee34f4](0ee34f4)) ### Bug Fixes * **api:** align ConflictOut OpenAPI response with runtime schema fields ([#1536](#1536)) ([1f929dc](1f929dc)) * **client-python:** ship the Apache-2.0 LICENSE in the published package ([#1031](#1031)) ([820d60b](820d60b)) * **client-ts:** ship the Apache-2.0 LICENSE in the npm package ([#1032](#1032)) ([26231d4](26231d4)) * **contradiction:** give the forward chain-edge writes the CAS their comments claimed ([#1727](#1727)) ([4599871](4599871)) * **plugin:** stop re-requesting agent keys after the provision route 404s ([#1718](#1718)) ([b5fe391](b5fe391)) * **worker:** stop warning that the async path does not fan out — it has since A70 (oss-0924-m-03) ([#1724](#1724)) ([cb84511](cb84511)) </details> <details><summary>plugin: 2.23.3</summary> ## [2.23.3](plugin-v2.23.2...plugin-v2.23.3) (2026-09-26) ### Bug Fixes * **plugin:** stop re-requesting agent keys after the provision route 404s ([#1718](#1718)) ([b5fe391](b5fe391)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Signed-off-by: release-please[bot] <release-please[bot]@users.noreply.github.com> Signed-off-by: Eldad Caura <eldad@caura.ai> Co-authored-by: caura-deploy-bot[bot] <265395343+caura-deploy-bot[bot]@users.noreply.github.com> Co-authored-by: Eldad Caura <eldad@caura.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Atlas Cloud is an OpenAI-compatible gateway, so it joins the
_OPENAI_COMPATIBLEset next to OpenRouter and rides the existingOpenAILLMProvider— no new transport, no new dependency. The change is the enum member, the endpoint constants, and the three-tier credential resolution the other providers already use.common/provider_names.py—ATLASCLOUD = "atlascloud"common/llm/constants.py—ATLASCLOUD_CHAT_BASE_URL,ATLASCLOUD_DEFAULT_MODEL(overridable via env, same as the OpenRouter default)common/llm/_credentials.py—_TENANT_KEY_ATTRentry,_env_keybranch, and theresolve_openai_compatiblebranchcommon/llm/registry.py— add to_OPENAI_COMPATIBLEcore-api/config.py—atlascloud_api_keysetting and itsATLASCLOUD_API_KEYbridge entrycore-api/services/organization_settings.py— tenant-key property, and the provider in the enrichment fallback candidatestests/test_atlascloud_provider.py— 13 unit teststests/test_credential_bridge.py—ATLASCLOUD_API_KEYadded to the bridge-key snapshot so the bridge's writes are restored like the othersTenant key → env var → empty resolution works exactly as it does for OpenRouter, so
ResolvedConfig.atlascloud_api_keyoverridesATLASCLOUD_API_KEY.Validation
pytest tests/test_atlascloud_provider.py --noconftest→ 13 passed (constants, enum membership,_env_keyset/unset,has_credentialswith and without a tenant key, tenant-over-env precedence, env fallback, unset behaviour, plus two regression checks that OpenRouter still resolves and unknown providers still return empty)I used
--noconftestbecause the session-scoped fixture intests/conftest.pypulls in FastAPI and the rest of the API stack, which I didn't install locally.tests/test_contradiction_providers.pyfails to collect in my environment for the same reason — it fails identically on unmodifiedmain, so this change doesn't move it.No docs, README, or sponsor placement touched — just the provider wiring and its tests.