Skip to content

Commit ae27ad2

Browse files
Add Atlas Cloud BYOK provider preset (#5406)
* Add Atlas Cloud BYOK provider preset * Add UTM to Atlas Cloud provider link --------- Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com>
1 parent 6426847 commit ae27ad2

7 files changed

Lines changed: 95 additions & 4 deletions

File tree

QUICKSTART.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ location /api/ {
274274
| Mode | Picker value | How a request flows |
275275
|---|---|---|
276276
| **Local CLI** (default when daemon detects an agent) | "Local CLI" | Frontend → daemon `/api/chat``spawn(<agent>, ...)` → stdout → SSE → artifact parser → preview |
277-
| **API mode** (fallback / no CLI) | "Anthropic API" / "OpenAI API" / "Azure OpenAI" / "Google Gemini" | Frontend → daemon `/api/proxy/{provider}/stream` → provider SSE normalized to `delta/end/error` → artifact parser → preview |
277+
| **API mode** (fallback / no CLI) | "Anthropic API" / "OpenAI API" / "Atlas Cloud" / "Azure OpenAI" / "Google Gemini" | Frontend → daemon `/api/proxy/{provider}/stream` → provider SSE normalized to `delta/end/error` → artifact parser → preview |
278278

279279
Both modes feed the **same** `<artifact>` parser and the **same** sandboxed iframe. The only thing that differs is the transport and the system-prompt delivery (local CLIs have no separate system channel, so the composed prompt is folded into the user message).
280280

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Inside a project's Studio, the same design system streams out multiple artifact
137137
<img src="https://repo-assets.open-design.ai/resources/images/coding-agents.png" alt="The 21 coding-agent CLIs Open Design supports — Claude Code · Codex · OpenCode · Hermes · Antigravity · Gemini · Grok Build · Kimi · Cursor Agent · Qwen · Qoder · GitHub Copilot · Pi · Kiro · Kilo · Mistral Vibe · DeepSeek · Reasonix · Aider · Devin · Trae" width="100%" />
138138
</p>
139139

140-
**No CLI installed?** The BYOK proxy at `POST /api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream` gives you the same loop (no process spawn) — paste `baseUrl` + `apiKey` + `model`, with support for OpenAI, Anthropic, Azure OpenAI, Google Gemini, Ollama, LM Studio, vLLM, or any OpenAI-compatible endpoint. Per-target SSRF protection blocks internal IPs / link-local / CGNAT at the daemon edge.
140+
**No CLI installed?** The BYOK proxy at `POST /api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream` gives you the same loop (no process spawn) — paste `baseUrl` + `apiKey` + `model`, with presets for OpenAI, Atlas Cloud, Anthropic, Azure OpenAI, Google Gemini, Ollama, LM Studio, vLLM, or any OpenAI-compatible endpoint. Atlas Cloud uses `https://api.atlascloud.ai/v1` with your own key and OpenAI-compatible model ids such as `qwen/qwen3.5-flash`. Per-target SSRF protection blocks internal IPs / link-local / CGNAT at the daemon edge.
141141

142142
The adapter contract and stream parsers live in [`apps/daemon/src/agents.ts`](apps/daemon/src/agents.ts). Adding a new CLI is one entry — see [`docs/agent-adapters.md`](docs/agent-adapters.md).
143143

@@ -589,7 +589,7 @@ Full architecture → [`docs/architecture.md`](docs/architecture.md). Skill prot
589589
- [x] Web app + chat + question form + 5-direction picker + todo progress + sandboxed preview
590590
- [x] 100+ skills · 150 design systems · 5 visual directions · 5 device frames
591591
- [x] SQLite-backed projects · conversations · messages · tabs · templates
592-
- [x] Multi-provider BYOK proxy (`/api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream`) + SSRF guard
592+
- [x] Multi-provider BYOK proxy (`/api/proxy/{anthropic,openai,azure,google,ollama,senseaudio}/stream`) with OpenAI-compatible presets including Atlas Cloud + SSRF guard
593593
- [x] Claude Design ZIP import (`/api/import/claude-design`)
594594
- [x] Sidecar protocol + Electron desktop + IPC automation
595595
- [x] Artifact lint API + 5-dim self-critique pre-emit gate

apps/web/src/components/SettingsDialog.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2709,7 +2709,7 @@ export function SettingsDialog({
27092709
};
27102710

27112711
const apiProtocol = cfg.apiProtocol ?? 'anthropic';
2712-
const apiKeyConsoleLink = API_KEY_CONSOLE_LINKS[apiProtocol];
2712+
const defaultApiKeyConsoleLink = API_KEY_CONSOLE_LINKS[apiProtocol];
27132713
const byokProviderPresets: ReadonlyArray<ByokProviderPreset> = [
27142714
{
27152715
id: 'anthropic',
@@ -2725,6 +2725,13 @@ export function SettingsDialog({
27252725
baseUrl: 'https://api.openai.com/v1',
27262726
model: 'gpt-4o',
27272727
},
2728+
{
2729+
id: 'atlascloud',
2730+
title: 'Atlas Cloud',
2731+
protocol: 'openai',
2732+
baseUrl: 'https://api.atlascloud.ai/v1',
2733+
model: 'qwen/qwen3.5-flash',
2734+
},
27282735
{
27292736
id: 'google-ai-studio',
27302737
title: 'Google Gemini',
@@ -3194,6 +3201,8 @@ export function SettingsDialog({
31943201
(p) => p.baseUrl === cfg.apiProviderBaseUrl && p.baseUrl === cfg.baseUrl,
31953202
);
31963203
const selectedProvider = selectedProviderIndex >= 0 ? protocolProviders[selectedProviderIndex] : undefined;
3204+
const apiKeyConsoleLink =
3205+
selectedProvider?.apiKeyConsoleLink ?? defaultApiKeyConsoleLink;
31973206
const showProviderPreset =
31983207
protocolProviders.length > 0 && !isFixedOriginGateway(apiProtocol);
31993208
// Fixed-origin gateways resolve their Base URL automatically; nothing for the

apps/web/src/state/config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export interface KnownProvider {
108108
model: string;
109109
/** Optional provider-specific model choices shown in Settings. */
110110
models?: string[];
111+
/** Optional provider-specific key console link shown in Settings. */
112+
apiKeyConsoleLink?: { host: string; url: string };
111113
/** Some local/self-hosted endpoints do not require bearer credentials. */
112114
requiresApiKey?: boolean;
113115
}
@@ -164,6 +166,24 @@ export const KNOWN_PROVIDERS: KnownProvider[] = [
164166
model: 'gpt-4o',
165167
models: ['gpt-4o', 'gpt-4o-mini', 'o3', 'o4-mini'],
166168
},
169+
{
170+
label: 'Atlas Cloud',
171+
protocol: 'openai',
172+
baseUrl: 'https://api.atlascloud.ai/v1',
173+
model: 'qwen/qwen3.5-flash',
174+
models: [
175+
'qwen/qwen3.5-flash',
176+
'qwen/qwen3.5-plus',
177+
'qwen/qwen3.7-plus',
178+
'deepseek-ai/deepseek-v4-flash',
179+
'deepseek-ai/deepseek-v4-pro',
180+
'google/gemini-3.5-flash',
181+
],
182+
apiKeyConsoleLink: {
183+
host: 'atlascloud.ai',
184+
url: 'https://atlascloud.ai/?utm_source=open_design&utm_medium=provider_preset&utm_campaign=atlascloud_byok',
185+
},
186+
},
167187
{
168188
label: 'OpenRouter',
169189
protocol: 'openai',

apps/web/tests/components/SettingsDialog.execution.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,28 @@ describe('SettingsDialog execution settings BYOK interactions', () => {
793793
expect((screen.getByLabelText('Base URL') as HTMLInputElement).value).toBe('https://api.deepseek.com');
794794
});
795795

796+
it('offers Atlas Cloud as an OpenAI-compatible gateway preset', () => {
797+
renderSettingsDialog({
798+
apiProtocol: 'openai',
799+
baseUrl: 'https://api.openai.com/v1',
800+
model: 'gpt-4o',
801+
apiProviderBaseUrl: 'https://api.openai.com/v1',
802+
});
803+
804+
fireEvent.click(screen.getByRole('tab', { name: 'OpenAI' }));
805+
selectGatewayPreset('Atlas Cloud');
806+
807+
expect(screen.getByRole('combobox', { name: 'Model' }).textContent).toContain(
808+
'qwen/qwen3.5-flash',
809+
);
810+
expect((screen.getByLabelText('Base URL') as HTMLInputElement).value).toBe(
811+
'https://api.atlascloud.ai/v1',
812+
);
813+
expect(screen.getByRole('link', { name: 'Get key ↗' }).getAttribute('href')).toBe(
814+
'https://atlascloud.ai/?utm_source=open_design&utm_medium=provider_preset&utm_campaign=atlascloud_byok',
815+
);
816+
});
817+
796818
it('keeps Anthropic-compatible gateway presets selectable', () => {
797819
renderSettingsDialog();
798820

apps/web/tests/components/SettingsDialog.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,27 @@ describe('SettingsDialog API protocol switching', () => {
378378
});
379379
});
380380

381+
it('keeps Atlas Cloud as an OpenAI-compatible known provider without changing the OpenAI default', () => {
382+
const openai = switchApiProtocolConfig(baseConfig, 'openai');
383+
const atlas = updateCurrentApiProtocolConfig(openai, {
384+
baseUrl: 'https://api.atlascloud.ai/v1',
385+
model: 'qwen/qwen3.5-flash',
386+
apiProviderBaseUrl: 'https://api.atlascloud.ai/v1',
387+
});
388+
389+
expect(openai).toMatchObject({
390+
baseUrl: 'https://api.openai.com/v1',
391+
model: 'gpt-4o',
392+
apiProviderBaseUrl: 'https://api.openai.com/v1',
393+
});
394+
expect(atlas).toMatchObject({
395+
apiProtocol: 'openai',
396+
baseUrl: 'https://api.atlascloud.ai/v1',
397+
model: 'qwen/qwen3.5-flash',
398+
apiProviderBaseUrl: 'https://api.atlascloud.ai/v1',
399+
});
400+
});
401+
381402
it('auto-fills Google defaults when switching from a selected known provider', () => {
382403
expect(switchApiProtocolConfig(baseConfig, 'google')).toMatchObject({
383404
mode: 'api',

apps/web/tests/state/api-protocols.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,23 @@ describe('apiProtocols table consistency', () => {
2525
expect(ollamaCloudProvider?.models).toContain(model);
2626
}
2727
});
28+
29+
it('keeps the Atlas Cloud preset wired to OpenAI-compatible chat models', () => {
30+
const atlasCloudProvider = KNOWN_PROVIDERS.find(
31+
(provider) =>
32+
provider.protocol === 'openai' &&
33+
provider.baseUrl === 'https://api.atlascloud.ai/v1',
34+
);
35+
36+
expect(atlasCloudProvider).toMatchObject({
37+
label: 'Atlas Cloud',
38+
model: 'qwen/qwen3.5-flash',
39+
apiKeyConsoleLink: {
40+
host: 'atlascloud.ai',
41+
url: 'https://atlascloud.ai/?utm_source=open_design&utm_medium=provider_preset&utm_campaign=atlascloud_byok',
42+
},
43+
});
44+
expect(atlasCloudProvider?.models).toContain('qwen/qwen3.5-flash');
45+
expect(atlasCloudProvider?.models).toContain('deepseek-ai/deepseek-v4-flash');
46+
});
2847
});

0 commit comments

Comments
 (0)