Skip to content

feat(atlascloud): add Atlas Cloud OpenAI-compatible translation provider#68

Open
lucaszhu-hue wants to merge 3 commits into
wxyhgk:mainfrom
lucaszhu-hue:feat/atlascloud-translation-backend
Open

feat(atlascloud): add Atlas Cloud OpenAI-compatible translation provider#68
lucaszhu-hue wants to merge 3 commits into
wxyhgk:mainfrom
lucaszhu-hue:feat/atlascloud-translation-backend

Conversation

@lucaszhu-hue

@lucaszhu-hue lucaszhu-hue commented Jun 11, 2026

Copy link
Copy Markdown

Summary

Adds Atlas Cloud as an optional translation provider. Atlas Cloud exposes an OpenAI-compatible /v1/chat/completions endpoint, so it plugs into the existing pluggable provider system (shared/provider_registry.py + providers/<provider>/) with a minimal footprint, exactly as described in backend/scripts/services/translation/llm/README.md ("新增 provider 时,优先在 providers/<provider>/ 下新增实现 … 在 shared/provider_registry.py 注册 runtime").

Changes:

  • providers/atlascloud/ — Atlas defaults only (base_url=https://api.atlascloud.ai/v1, default model deepseek-ai/deepseek-v4-pro, ATLASCLOUD_API_KEY env / atlascloud.env file) plus a matching get_api_key. The OpenAI-compatible transport and translation handlers are reused from the DeepSeek provider rather than duplicated, so retry/streaming/DNS/diagnostics logic stays in one place.
  • shared/provider_registry.py — registers ATLASCLOUD_RUNTIME and makes resolve_active_provider_runtime() selectable via the RETAIN_TRANSLATION_PROVIDER env var. Default remains deepseek, so runtime behavior is unchanged unless a user explicitly opts in. Unknown values raise a clear error listing known providers.
  • README.md — adds an Atlas Cloud block at the very top (logo + intro + UTM link), an opt-in RETAIN_TRANSLATION_PROVIDER=atlascloud env snippet, and the full Atlas Cloud LLM model list (59 models, grouped by vendor) inside a collapsed <details>. The default translation experience is unchanged.
  • Docs: doc/core/api/local-dev.md gains a "翻译 provider" section (DeepSeek default + Atlas Cloud opt-in); services/translation/llm/README.md lists the new provider dir and the env switch; backend/scripts/.env/README.md documents the atlascloud.env credential file with a placeholder-only atlascloud.env.example.
  • Tests: devtools/tests/translation/test_atlascloud_provider_runtime.py locks in the default-stays-deepseek contract, the Atlas defaults, transport reuse, env selection (case-insensitive), and the unknown-provider error.

deepseek-ai/deepseek-v4-pro is a reasoning model, so the docs and the provider default note that callers should give it enough max_tokens (>= 512); otherwise the budget is spent on the reasoning trace and content comes back empty with finish_reason=length.

Why This PR

The translation layer is already provider-agnostic (base_url/model/api_key flow through from the frontend/Rust API, with DeepSeek as the default). This PR gives users a documented, one-env-var way to route translation through Atlas Cloud's unified OpenAI-compatible API — useful for accessing additional models or a different provider — without changing the default experience or touching the working DeepSeek path.

Validation

  • New + existing provider contract tests pass:
    pytest devtools/tests/translation/test_atlascloud_provider_runtime.py devtools/tests/translation/test_provider_runtime_contract.py → 8 passed.
  • Full translation suite shows no new failures introduced by this change: PR branch 48 failed, 452 passed vs upstream/main baseline 48 failed, 446 passed — the failing set is byte-for-byte identical (the pre-existing failures are environment-only, from absolute paths / missing fitz/typst binaries unrelated to the provider layer); the +6 passes are the new Atlas tests.
  • Real API call to the default model deepseek-ai/deepseek-v4-pro with max_tokens=512HTTP 200, finish_reason=stop, non-empty content (correct EN→ZH translation).
  • End-to-end smoke through the real pipeline transport with RETAIN_TRANSLATION_PROVIDER=atlascloud: provider_runtime resolves to atlascloud, get_api_key() reads ATLASCLOUD_API_KEY, and request_chat_content(...) against the live endpoint (deepseek-ai/deepseek-v4-pro) returned a correct EN→ZH translation.
  • No credentials are committed; atlascloud.env.example contains only a placeholder and real *.env files remain git-ignored.

🤝 Partnership & contact

This PR comes from the Atlas Cloud team. Beyond the integration above, we'd love to explore a closer collaboration with retain-pdf — for example co-marketing or a featured integration.

If that sounds interesting, reach out anytime:

And of course, happy to revise this PR to match your project's conventions — just leave a comment. 🙌

Atlas Cloud (https://www.atlascloud.ai) exposes an OpenAI-compatible
/v1/chat/completions endpoint, so it slots into the existing pluggable
translation provider system with minimal surface.

- Add providers/atlascloud with Atlas defaults (base_url, default model
  deepseek-ai/DeepSeek-V3-0324, ATLASCLOUD_API_KEY env / atlascloud.env file)
  and reuse the shared OpenAI-compatible transport/translation handlers from
  the DeepSeek provider instead of duplicating retry/streaming/diagnostics.
- Register ATLASCLOUD_RUNTIME and make resolve_active_provider_runtime()
  env-selectable via RETAIN_TRANSLATION_PROVIDER. Default stays "deepseek",
  so runtime behavior is unchanged unless explicitly opted in.
- Document the provider switch in doc/core/api/local-dev.md and the
  translation llm README; document the atlascloud.env credential file and
  add a placeholder-only atlascloud.env.example.
- Add provider runtime contract tests for the new provider.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wxyhgk

wxyhgk commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Thank you for submitting the PR. If a third-party API has been added, please complete the following:

  1. Handle the error codes of the third-party API on the backend, including common ones such as 429, 502, etc.
  2. If available, add APIs on the backend for checking balance and usage.
  3. Test the concurrency capacity of the third-party API, as well as the stability of that API.

lucaszhu-hue and others added 2 commits June 12, 2026 11:15
- Atlas provider default model -> deepseek-ai/deepseek-v4-pro (reasoning),
  with a max_tokens>=512 note in code and docs.
- README: add Atlas Cloud block (logo + copy + UTM link) at the top, an
  opt-in env snippet, and the full 59-model Atlas LLM list in a collapsed
  <details>. Default translation provider stays deepseek.
- doc/core/api/local-dev.md: default model + reasoning note updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lucaszhu-hue

Copy link
Copy Markdown
Author

Thanks for the review @wxyhgk! Addressed all three points:

  1. Backend error-code handling (429/502, etc.) — The Atlas Cloud provider reuses the existing OpenAI-compatible transport (request_chat_content), which already retries transient codes 408/429/500/502/503/504 with exponential backoff + jitter, honours Retry-After on 429 (with a 300s cumulative wait budget), and does not retry 4xx client errors (400/401/403/404/422) — raising them with a response-body excerpt. I made this explicit for Atlas and added small transport-only helpers is_rate_limited(exc) / describe_api_error(exc) (stable, credential-free failure reasons) in providers/atlascloud/client.py, plus unit tests covering the retryable vs non-retryable split and 429 detection.

  2. Balance / usage backend API — Atlas Cloud returns OpenAI-style usage (prompt_tokens/completion_tokens/total_tokens) on every completion, so I added extract_usage(response_json) and a fetch_usage(...) probe to read live consumption from the backend (verified live: {prompt_tokens: 9, completion_tokens: 27, total_tokens: 36}). Atlas Cloud has no OpenAI-style /v1/dashboard/billing/* balance route (those return 404) — remaining credit is shown in the web console; documented this in doc/core/api/local-dev.md.

  3. Concurrency capacity & stability — The transport already uses a per-worker connection pool, thread-local sessions, and DNS prewarm/caching. I ran a real concurrency test (deepseek-ai/deepseek-v4-pro, concurrency 8, 24 requests, max_tokens=512): 24/24 success, 0 failures, p50 ≈ 3.6s, p95 ≈ 5.4s, ~1.9 req/s. Results + tuning notes are documented under "并发与稳定性".

Architecture check (check_pipeline_architecture.py) passes and the provider unit tests are green (28 passed). The PR shows unstable only because the fork's workflow run is in action_required (awaiting maintainer approval to run) — happy to have CI re-run when convenient.

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