Skip to content

Add Atlas Cloud provider - #194

Open
binyangzhu000-sudo wants to merge 6 commits into
lemony-ai:mainfrom
binyangzhu000-sudo:codex/add-atlascloud-provider
Open

binyangzhu000-sudo wants to merge 6 commits into
lemony-ai:mainfrom
binyangzhu000-sudo:codex/add-atlascloud-provider

Conversation

@binyangzhu000-sudo

Copy link
Copy Markdown

Summary

  • add an Atlas Cloud provider that reuses the existing OpenAI-compatible provider path
  • register atlascloud in the provider registry and LiteLLM prefix mapping
  • document the provider dependency row and add focused provider tests

Validation

  • python3 -m pytest -o addopts='' tests/test_atlascloud.py tests/test_agent_module_callable.py -q
  • python3 -m compileall cascadeflow/providers/atlascloud.py cascadeflow/providers/__init__.py cascadeflow/providers/base.py tests/test_atlascloud.py
  • git diff --check
  • Atlas live catalog returned qwen/qwen3.5-flash and deepseek-ai/deepseek-v4-pro

Notes: local environment does not have ruff or black installed, so those checks could not be run here.

README: no README changes; docs update only, no sponsor/logo/credits/partner promotion.

@saschabuehrle saschabuehrle left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the compact OpenAI-compatible provider implementation. The endpoint matches Atlas Cloud’s current official docs and the isolated tests, Ruff, and Black pass, but two runtime integration blockers remain.

Required before merge:

  1. Register atlascloud in ModelConfig.validate_provider and PROVIDER_CAPABILITIES. Today ModelConfig(name="x", provider="atlascloud", cost=0) raises a validation error, so a CascadeAgent cannot configure it.
  2. Fix provider attribution inherited from OpenAIProvider. A mocked successful request correctly calls https://api.atlascloud.ai/v1/chat/completions but returns ModelResponse.provider == "openai"; inherited errors also identify OpenAI. This breaks provider telemetry and routing traces.
  3. Fix or explicitly define cost behavior. Current _get_litellm_prefix() produces openai/qwen/qwen3.5-flash, which LiteLLM rejects before falling back to inherited OpenAI estimates. Add Atlas-aware estimation/capability semantics and tests.
  4. Add an end-to-end provider test covering ModelConfig/registry resolution plus response attribution, not only constructor registration.

Please update against current main and re-request review.

@binyangzhu000-sudo

Copy link
Copy Markdown
Author

Updated against current main (d4cf48b, no conflicts) and re-requesting review.

Worth flagging first: all four required items were addressed in 3e9a555, which landed after the commit your review pointed at (6f3afbd6), so they may not have been visible when you looked. Here is where each one lives now:

  1. ModelConfig.validate_provider + PROVIDER_CAPABILITIESatlascloud is in the allowed list in cascadeflow/schema/config.py, and PROVIDER_CAPABILITIES["atlascloud"] is defined in cascadeflow/providers/base.py (supports_logprobs: False, supports_streaming: True, supports_tools: True, max_top_logprobs: 0, has_cost_tracking: False). ModelConfig(name="qwen/qwen3.5-flash", provider="atlascloud", cost=0) now validates.
  2. Provider attributionAtlasCloudProvider sets response.provider = self.name on both success paths and error.provider = self.name on the error path, so ModelResponse.provider and ProviderError.provider both report atlascloud instead of the inherited openai.
  3. Cost behaviour_get_litellm_prefix() returns None so Atlas model IDs are never rewritten as openai/qwen/..., _litellm_cost_provider / _litellm_provider_prefix are cleared, and _use_litellm_pricing is False. Cost is explicitly untracked rather than silently falling back to OpenAI estimates: calculate_accurate_cost(...) returns 0.0.
  4. End-to-end testtest_registry_provider_response_attribution goes through ModelConfigPROVIDER_REGISTRY[config.provider] → a mocked complete(), and asserts the request hits https://api.atlascloud.ai/v1/chat/completions, that result.provider == "atlascloud", and that result.cost == 0.0. test_error_attribution_uses_atlascloud covers the error path, and test_cost_is_explicitly_untracked pins the cost semantics.

Validation

  • pytest tests/test_atlascloud.py — 9 passed.
  • ruff check on the touched files — clean.
  • Full pytest tests/ (excluding test_google_adk_integration.py and test_production_readiness.py, which cannot be collected here without google / numpy) — 999 passed, 13 failed, 29 errors. A clean origin/main worktree with the same interpreter gives 13 failed / 29 errors as well, with 990 passed — identical failure counts, and my branch has exactly 9 more passing tests (the Atlas suite). None of the failures involve atlascloud; they are pre-existing and come from optional extras missing in my environment.

One note on Black, stated plainly rather than silently changed: black --check (26.5.1) wants to reformat tests/test_atlascloud.py. I did not apply it, because the same run flags 11 files across the repo, and tests/test_atlascloud.py at 6f3afbd6 — the commit where you confirmed Black passed — is flagged too. So this is a Black version difference (pyproject.toml pins only black>=23.0.0), not a regression from this branch. Reformatting only my file would put it out of step with the other ten. Happy to run Black across the branch's files if you tell me which version CI uses.

@binyangzhu000-sudo

Copy link
Copy Markdown
Author

@saschabuehrle Updated against current main and re-requesting review.

I should be straightforward about the state of your four blockers: they were addressed in 3e9a555 ("fix: complete Atlas Cloud runtime integration"), pushed on 2026-08-17, which is after your 2026-08-06 review. So this has been sitting in CHANGES_REQUESTED on a branch that already changed. Sorry for not pinging you at the time. Verifying each against the current head rather than asserting it:

  1. Registry/config registration. ModelConfig(name="x", provider="atlascloud", cost=0) now constructs — I ran it, it returns provider == "atlascloud". PROVIDER_CAPABILITIES["atlascloud"] and PROVIDER_REGISTRY["atlascloud"] are both populated, and your own tests/test_model_config_provider_validation.py, which iterates PROVIDER_CAPABILITIES and validates each entry, passes.

  2. Provider attribution. _complete_impl and complete_with_tools set response.provider = self.name, and _attribute_error rewrites error.provider plus the "OpenAI" substring in inherited ProviderError / ModelError messages. Covered by test_registry_provider_response_attribution (asserts result.provider == "atlascloud" through a registry-resolved provider) and test_error_attribution_uses_atlascloud.

  3. Cost behaviour. _get_litellm_prefix() returns None, so no openai/qwen/... id is ever synthesised, and _use_litellm_pricing / _litellm_cost_provider are cleared. estimate_cost() returns an explicit 0.0 — cost is declared untracked rather than silently inheriting OpenAI estimates. Pinned by test_cost_is_explicitly_untracked.

  4. End-to-end test. test_registry_provider_response_attribution goes through ModelConfigPROVIDER_REGISTRY → mocked request → response attribution, not just constructor registration.

New in this update:

  • Merged current main (the n8n CascadeFlow Agent changes); no conflicts.
  • black wanted one reformat in tests/test_atlascloud.py; applied it, so black --check is now clean on both changed files. ruff check was already clean.

Verification on the merged branch:

  • pytest tests/test_atlascloud.py tests/test_model_config_provider_validation.py15 passed
  • full pytest tests/ --ignore=tests/test_google_adk_integration.py1160 passed, 8 failed

The 8 failures are all test_unified_embedding.py::TestEmbeddingCache. I ran that file in a clean upstream/main worktree and got the same 8 failures, so they are pre-existing and not from this branch. (test_google_adk_integration.py is ignored only because google isn't installed here.)

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