Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/configuration/models/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ models:
first_available: [list] # Optional: candidate model refs, tried in order by available credentials.
# Mutually exclusive with other model settings.
provider: string # Required unless using first_available. One of: openai, anthropic, google, amazon-bedrock,
# dmr, mistral, xai, nebius, nvidia, minimax, baseten, ovhcloud, groq, fireworks, deepseek, cerebras, together, huggingface, moonshot, vercel, cloudflare-workers-ai, cloudflare-ai-gateway, requesty, openrouter,
# dmr, mistral, xai, nebius, nvidia, minimax, baseten, ovhcloud, groq, fireworks, deepseek, cerebras, together, huggingface, moonshot, vercel, cloudflare-workers-ai, cloudflare-ai-gateway, requesty, openrouter, atlascloud,
# azure, ollama, github-copilot, or a named provider defined
# under the top-level `providers:` section.
model: string # Required: model identifier
Expand Down Expand Up @@ -56,7 +56,7 @@ models:
| Property | Type | Required | Description |
| --------------------- | ---------- | -------- | ------------------------------------------------------------------------------------- |
| `first_available` | array | ✗ | Candidate model references tried in order; selects the first whose credentials are configured. Mutually exclusive with other model settings. |
| `provider` | string | ✓/✗ | Required for regular model definitions; omitted for `first_available` selectors. Provider: `openai`, `anthropic`, `google`, `amazon-bedrock`, `dmr`, `mistral`, `xai`, `nebius`, `nvidia`, `minimax`, `baseten`, `ovhcloud`, `groq`, `fireworks`, `deepseek`, `cerebras`, `together`, `huggingface`, `moonshot`, `vercel`, `cloudflare-workers-ai`, `cloudflare-ai-gateway`, `requesty`, `openrouter`, `azure`, `ollama`, `github-copilot`, `chatgpt`, or any [named provider](../../providers/custom/index.md). |
| `provider` | string | ✓/✗ | Required for regular model definitions; omitted for `first_available` selectors. Provider: `openai`, `anthropic`, `google`, `amazon-bedrock`, `dmr`, `mistral`, `xai`, `nebius`, `nvidia`, `minimax`, `baseten`, `ovhcloud`, `groq`, `fireworks`, `deepseek`, `cerebras`, `together`, `huggingface`, `moonshot`, `vercel`, `cloudflare-workers-ai`, `cloudflare-ai-gateway`, `requesty`, `openrouter`, `atlascloud`, `azure`, `ollama`, `github-copilot`, `chatgpt`, or any [named provider](../../providers/custom/index.md). |
| `model` | string | ✓/✗ | Required for regular model definitions; omitted for `first_available` selectors. Model name (e.g., `gpt-4o`, `claude-sonnet-4-5`, `gemini-3.5-flash`) |
| `description` | string | ✗ | Informational, human-readable summary of the model's purpose or strengths (e.g., "fast and cheap, good for summaries"). Not sent to the model. Can be combined with `first_available` (a selector's description is kept when it resolves). |
| `temperature` | float | ✗ | Sampling randomness. Range is provider-dependent — typically `0.0–2.0` (Anthropic caps at `1.0`). `0.0` is deterministic. |
Expand Down
65 changes: 65 additions & 0 deletions docs/providers/atlascloud/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: "Atlas Cloud"
description: "Use Atlas Cloud models with Docker Agent."
keywords: docker agent, ai agents, model providers, llm, atlas cloud
weight: 235

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Provider pages use alphabetical-by-title weights in increments of 10 (Anthropic 20, AWS Bedrock 30, Baseten 40, ...). "Atlas Cloud" sorts between Anthropic and AWS Bedrock, so 235 places the page between OpenRouter and OVHcloud in weight-ordered listings.

Suggested change
weight: 235
weight: 25

canonical: https://docs.docker.com/ai/docker-agent/providers/atlascloud/
---

_Use Atlas Cloud models with Docker Agent._

## Overview

Atlas Cloud provides access to multiple model families through an OpenAI-compatible API. Docker Agent includes built-in support for Atlas Cloud as an alias provider.

## Setup

1. [Create an Atlas Cloud API key](https://www.atlascloud.ai/docs/api-keys)
2. Set the environment variable:

```bash
export ATLASCLOUD_API_KEY=your-api-key
```

## Usage

### Inline Syntax

Use an Atlas Cloud model by prefixing its model ID with `atlascloud/`:

```yaml
agents:
root:
model: atlascloud/qwen/qwen3.8-max
description: Assistant using Atlas Cloud
instruction: You are a helpful assistant.
```

Docker Agent splits only the first slash, so model IDs that include a model family prefix are preserved.

### Named Model

For more control over parameters:

```yaml
models:
atlas_qwen:
provider: atlascloud
model: qwen/qwen3.8-max
temperature: 0.7
max_tokens: 8192

agents:
root:
model: atlas_qwen
description: Assistant using Atlas Cloud
instruction: You are a helpful assistant.
```

## How It Works

Atlas Cloud is implemented as a built-in alias in Docker Agent:

- **API Type:** OpenAI-compatible (`openai`)
- **Base URL:** `https://api.atlascloud.ai/v1`
- **Token Variable:** `ATLASCLOUD_API_KEY`
1 change: 1 addition & 0 deletions docs/providers/overview/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Docker Agent also includes built-in aliases for these providers:
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_GATEWAY_ID` |
| Requesty | `requesty` | `REQUESTY_API_KEY` |
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
| Atlas Cloud | [`atlascloud`](../atlascloud/index.md) | `ATLASCLOUD_API_KEY` |
| Azure OpenAI | `azure` | `AZURE_API_KEY` + `base_url` |
| [Ollama](../local/index.md) | `ollama` | None (local; optional `base_url`) |
| GitHub Copilot | `github-copilot` | `GITHUB_TOKEN` (PAT with `copilot` scope) |
Expand Down
2 changes: 2 additions & 0 deletions pkg/config/auto.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ var cloudProviders = []providerConfig{
}, "GOOGLE_API_KEY (or GEMINI_API_KEY, GOOGLE_GENAI_USE_VERTEXAI)", "GOOGLE_API_KEY"},
{"mistral", []string{"MISTRAL_API_KEY"}, "MISTRAL_API_KEY", "MISTRAL_API_KEY"},
{"openrouter", []string{"OPENROUTER_API_KEY"}, "OPENROUTER_API_KEY", "OPENROUTER_API_KEY"},
{"atlascloud", []string{"ATLASCLOUD_API_KEY"}, "ATLASCLOUD_API_KEY", "ATLASCLOUD_API_KEY"},
{"baseten", []string{"BASETEN_API_KEY"}, "BASETEN_API_KEY", "BASETEN_API_KEY"},
{"ovhcloud", []string{"OVH_AI_ENDPOINTS_ACCESS_TOKEN"}, "OVH_AI_ENDPOINTS_ACCESS_TOKEN", "OVH_AI_ENDPOINTS_ACCESS_TOKEN"},
{"groq", []string{"GROQ_API_KEY"}, "GROQ_API_KEY", "GROQ_API_KEY"},
Expand Down Expand Up @@ -157,6 +158,7 @@ var DefaultModels = map[string]string{
"dmr": "ai/qwen3:latest",
"mistral": "mistral-small-latest",
"openrouter": "meta-llama/llama-3.3-70b-instruct",
"atlascloud": "qwen/qwen3.8-max",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can the existence of qwen/qwen3.8-max in the Atlas Cloud catalog be confirmed (catalog link or output of the live smoke test mentioned in the PR description)? Two concerns:

  • This ID is the auto-selection default: if it is wrong, every user with only ATLASCLOUD_API_KEY set gets a broken first run.
  • Neither an atlascloud provider nor any qwen3.8-max entry exists in pkg/modelsdev/snapshot.json, so capability lookup falls back to text-only with a warning. A "-max" model is also unusual for an open-model host (the -max line is API-only, not open weights), which is worth double-checking against the openModelHostProviders classification.

If the ID changes, the two examples in docs/providers/atlascloud/index.md (atlascloud/qwen/qwen3.8-max and model: qwen/qwen3.8-max) and the assertions in pkg/config/auto_test.go and pkg/model/provider/openai_alias_providers_test.go must be updated in sync.

"baseten": "deepseek-ai/DeepSeek-V3.1",
"ovhcloud": "Qwen3.5-397B-A17B",
"groq": "llama-3.3-70b-versatile",
Expand Down
15 changes: 13 additions & 2 deletions pkg/config/auto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ func TestAvailableProviders_NoGateway(t *testing.T) {
},
expectedProvider: "openrouter",
},
{
name: "atlascloud api key present",
envVars: map[string]string{
"ATLASCLOUD_API_KEY": "test-key",
},
expectedProvider: "atlascloud",
},
{
name: "baseten api key present",
envVars: map[string]string{
Expand Down Expand Up @@ -476,7 +483,7 @@ func TestDefaultModels(t *testing.T) {
t.Parallel()

// Test that DefaultModels map has all expected providers
expectedProviders := []string{"openai", "anthropic", "google", "dmr", "mistral", "openrouter", "baseten", "ovhcloud", "groq", "fireworks", "deepseek", "cerebras", "together", "huggingface", "moonshot", "vercel", "amazon-bedrock", "opencode-zen", "opencode-go", "github-copilot"}
expectedProviders := []string{"openai", "anthropic", "google", "dmr", "mistral", "openrouter", "atlascloud", "baseten", "ovhcloud", "groq", "fireworks", "deepseek", "cerebras", "together", "huggingface", "moonshot", "vercel", "amazon-bedrock", "opencode-zen", "opencode-go", "github-copilot"}

for _, provider := range expectedProviders {
t.Run(provider, func(t *testing.T) {
Expand All @@ -494,6 +501,7 @@ func TestDefaultModels(t *testing.T) {
assert.Equal(t, "ai/qwen3:latest", DefaultModels["dmr"])
assert.Equal(t, "mistral-small-latest", DefaultModels["mistral"])
assert.Equal(t, "meta-llama/llama-3.3-70b-instruct", DefaultModels["openrouter"])
assert.Equal(t, "qwen/qwen3.8-max", DefaultModels["atlascloud"])
assert.Equal(t, "deepseek-ai/DeepSeek-V3.1", DefaultModels["baseten"])
assert.Equal(t, "Qwen3.5-397B-A17B", DefaultModels["ovhcloud"])
assert.Equal(t, "llama-3.3-70b-versatile", DefaultModels["groq"])
Expand All @@ -513,7 +521,7 @@ func TestAutoModelConfig_IntegrationWithDefaultModels(t *testing.T) {
t.Parallel()

// Verify that AutoModelConfig always returns a model from DefaultModels
providers := []string{"openai", "anthropic", "google", "mistral", "openrouter", "baseten", "ovhcloud", "groq", "fireworks", "deepseek", "cerebras", "together", "huggingface", "moonshot", "vercel", "opencode-zen", "github-copilot"}
providers := []string{"openai", "anthropic", "google", "mistral", "openrouter", "atlascloud", "baseten", "ovhcloud", "groq", "fireworks", "deepseek", "cerebras", "together", "huggingface", "moonshot", "vercel", "opencode-zen", "github-copilot"}

for _, provider := range providers {
t.Run(provider, func(t *testing.T) {
Expand All @@ -535,6 +543,8 @@ func TestAutoModelConfig_IntegrationWithDefaultModels(t *testing.T) {
envVars["MISTRAL_API_KEY"] = "test-key"
case "openrouter":
envVars["OPENROUTER_API_KEY"] = "test-key"
case "atlascloud":
envVars["ATLASCLOUD_API_KEY"] = "test-key"
case "baseten":
envVars["BASETEN_API_KEY"] = "test-key"
case "ovhcloud":
Expand Down Expand Up @@ -1129,6 +1139,7 @@ func TestProviderAPIKeyEnvVars(t *testing.T) {
"GOOGLE_API_KEY",
"MISTRAL_API_KEY",
"OPENROUTER_API_KEY",
"ATLASCLOUD_API_KEY",
"XAI_API_KEY",
"NEBIUS_API_KEY",
} {
Expand Down
5 changes: 5 additions & 0 deletions pkg/model/provider/aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ var Aliases = map[string]Alias{
BaseURL: "https://openrouter.ai/api/v1",
TokenEnvVar: "OPENROUTER_API_KEY",
},
"atlascloud": {
APIType: "openai",
BaseURL: "https://api.atlascloud.ai/v1",
TokenEnvVar: "ATLASCLOUD_API_KEY",
},
"mistral": {
APIType: "openai",
BaseURL: "https://api.mistral.ai/v1",
Expand Down
1 change: 1 addition & 0 deletions pkg/model/provider/aliases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestCatalogAliases(t *testing.T) {

expected := map[string]Alias{
"openrouter": {APIType: "openai", BaseURL: "https://openrouter.ai/api/v1", TokenEnvVar: "OPENROUTER_API_KEY"},
"atlascloud": {APIType: "openai", BaseURL: "https://api.atlascloud.ai/v1", TokenEnvVar: "ATLASCLOUD_API_KEY"},
"baseten": {APIType: "openai", BaseURL: "https://inference.baseten.co/v1", TokenEnvVar: "BASETEN_API_KEY"},
"ovhcloud": {APIType: "openai", BaseURL: "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1", TokenEnvVar: "OVH_AI_ENDPOINTS_ACCESS_TOKEN"},
"groq": {APIType: "openai", BaseURL: "https://api.groq.com/openai/v1", TokenEnvVar: "GROQ_API_KEY"},
Expand Down
1 change: 1 addition & 0 deletions pkg/model/provider/openai/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ func (c *Client) convertMessages(ctx context.Context, messages []chat.Message) [
// (openai, mistral, xai, minimax, github-copilot, opencode) tolerate multiple
// system messages and are deliberately absent so their behavior is unchanged.
var openModelHostProviders = map[string]bool{
"atlascloud": true,
"baseten": true,
"ovhcloud": true,
"openrouter": true,
Expand Down
8 changes: 8 additions & 0 deletions pkg/model/provider/openai_alias_providers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ type openAIAliasProvider struct {
}

var openAIAliasProviders = []openAIAliasProvider{
{
provider: "atlascloud",
envVar: "ATLASCLOUD_API_KEY",
testKey: "test-atlascloud-key",
model: "qwen/qwen3.8-max",
greeting: "Hello from Atlas Cloud",
mergesSystemMessages: true,
},
{
provider: "deepseek",
envVar: "DEEPSEEK_API_KEY",
Expand Down
Loading