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
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,79 @@
<p align="center">
<a href="https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=emdash">
<img src="https://www.atlascloud.ai/logo.png" alt="Atlas Cloud" width="200">
</a>
</p>

> **[Atlas Cloud](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=emdash)** is a full-modal AI inference platform — 59 frontier models (DeepSeek-V4, Qwen3, Kimi K2, GPT-5, Gemini 2.5 Pro, Claude, Grok-4…) via a single OpenAI-compatible endpoint. Power your Emdash agents with Atlas Cloud. [View all models](https://www.atlascloud.ai/models) · [Coding Plan](https://www.atlascloud.ai/console/coding-plan)

<details>
<summary>📋 59 models available on Atlas Cloud</summary>

| Model | Type |
|-------|------|
| deepseek-ai/deepseek-v4-pro | LLM |
| deepseek-ai/deepseek-v4-0520 | LLM |
| deepseek-ai/deepseek-v4-flash | LLM |
| deepseek-ai/deepseek-r2 | LLM |
| deepseek-ai/deepseek-r2-0528 | LLM |
| deepseek-ai/deepseek-r1-0528 | LLM |
| deepseek-ai/deepseek-r1 | LLM |
| deepseek-ai/deepseek-prover-v2 | LLM |
| moonshot-ai/kimi-k2 | LLM |
| moonshot-ai/kimi-k2-0711 | LLM |
| moonshot-ai/kimi-k1.5-long | LLM |
| qwen/qwen3-235b-a22b | LLM |
| qwen/qwen3-30b-a3b | LLM |
| qwen/qwen3-32b | LLM |
| qwen/qwq-32b | LLM |
| openai/gpt-5 | LLM |
| openai/gpt-5-mini | LLM |
| openai/gpt-4.1 | LLM |
| openai/gpt-4o | LLM |
| openai/o3 | LLM |
| openai/o4-mini | LLM |
| openai/o3-mini | LLM |
| anthropic/claude-sonnet-4-5 | LLM |
| anthropic/claude-opus-4 | LLM |
| anthropic/claude-sonnet-4 | LLM |
| anthropic/claude-haiku-4-5 | LLM |
| google/gemini-2.5-pro | LLM |
| google/gemini-2.5-flash | LLM |
| google/gemini-2.5-flash-lite | LLM |
| google/gemini-2.0-flash | LLM |
| xai/grok-4 | LLM |
| xai/grok-3 | LLM |
| xai/grok-3-mini | LLM |
| meta-llama/llama-4-scout | LLM |
| meta-llama/llama-4-maverick | LLM |
| meta-llama/llama-3.3-70b | LLM |
| cohere/command-a | LLM |
| mistral/mistral-large | LLM |
| minimax/minimax-m1 | LLM |
| 01ai/yi-lightning | LLM |
| seedance/seedance-v1-pro | Video |
| seedance/seedance-v1-pro-fast | Video |
| seedance/seedance-v1-lite | Video |
| kling/kling-v2.1-pro | Video |
| kling/kling-v2.1-standard | Video |
| kling/kling-v1.6-pro | Video |
| kling/kling-v1.6-standard | Video |
| wan2/wan2.1-t2v-turbo | Video |
| wan2/wan2.1-i2v-turbo | Video |
| veo/veo3.1-fast | Video |
| veo/veo3-fast | Video |
| veo/veo3 | Video |
| runway/gen4-turbo | Video |
| stable-diffusion/sd3.5-large | Image |
| flux/flux1.1-pro-ultra | Image |
| flux/flux1.1-pro | Image |
| ideogram/ideogram-v3 | Image |
| recraft/recraft-v3 | Image |
| minimax/hailuo-i2v-01-live | Video |
</details>

---

<img alt="Emdash" src="https://github.com/user-attachments/assets/a2ecaf3c-9d84-40ca-9a8e-d4f612cc1c6f" />

<div align="center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,29 @@ describe('resolveProviderEnv', () => {
resolveProviderEnv(undefined, { providerId: 'claude', autoApprove: true })
).toBeUndefined();
});

it('points Atlas Cloud at the Atlas OpenAI-compatible endpoint', () => {
expect(resolveProviderEnv(undefined, { providerId: 'atlascloud' })).toEqual({
OPENAI_BASE_URL: 'https://api.atlascloud.ai/v1',
});
});

it('lets the user override the Atlas Cloud base URL', () => {
expect(
resolveProviderEnv(
{ env: { OPENAI_BASE_URL: 'https://proxy.example/v1', OPENAI_API_KEY: 'sk-test' } },
{ providerId: 'atlascloud' }
)
).toEqual({
OPENAI_BASE_URL: 'https://proxy.example/v1',
OPENAI_API_KEY: 'sk-test',
});
});

it('inherits opencode auto-approve permissions for Atlas Cloud (runs via opencode)', () => {
expect(resolveProviderEnv(undefined, { providerId: 'atlascloud', autoApprove: true })).toEqual({
OPENCODE_PERMISSION: '{"*":"allow"}',
OPENAI_BASE_URL: 'https://api.atlascloud.ai/v1',
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,30 @@ import type { ProviderCustomConfig } from '@shared/core/app-settings';
const ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
const OPENCODE_ALLOW_ALL_PERMISSIONS = JSON.stringify({ '*': 'allow' });
const GEMINI_TRUST_WORKSPACE = 'true';
const ATLASCLOUD_BASE_URL = 'https://api.atlascloud.ai/v1';

export function resolveProviderEnv(
providerConfig: ProviderCustomConfig | undefined,
options: { providerId?: AgentProviderId; autoApprove?: boolean } = {}
): Record<string, string> | undefined {
const env: Record<string, string> = {};

if (options.providerId === 'opencode' && options.autoApprove) {
// Atlas Cloud is the OpenCode CLI pointed at Atlas's OpenAI-compatible
// endpoint, so it inherits OpenCode's auto-approve permission env and gets
// the Atlas base URL injected. The API key is supplied by the user via this
// provider's `env` settings (ATLASCLOUD_API_KEY / OPENAI_API_KEY) and merged
// in below; OPENAI_BASE_URL is defaulted here unless the user overrode it.
const isOpencodeBackend =
options.providerId === 'opencode' || options.providerId === 'atlascloud';

if (isOpencodeBackend && options.autoApprove) {
env.OPENCODE_PERMISSION = OPENCODE_ALLOW_ALL_PERMISSIONS;
}

if (options.providerId === 'atlascloud' && !providerConfig?.env?.OPENAI_BASE_URL) {
env.OPENAI_BASE_URL = ATLASCLOUD_BASE_URL;
}

if (options.providerId === 'gemini' && options.autoApprove) {
env.GEMINI_CLI_TRUST_WORKSPACE = GEMINI_TRUST_WORKSPACE;
}
Expand Down
2 changes: 2 additions & 0 deletions apps/emdash-desktop/src/renderer/lib/providers/meta.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ampcodeIcon from '@/assets/images/ampcode.svg?raw';
import antigravityIcon from '@/assets/images/antigravity.svg?raw';
import atlascloudIcon from '@/assets/images/atlas.png';
import atlassianIcon from '@/assets/images/atlassian.png';
import augmentcodeIcon from '@/assets/images/Auggie.svg?raw';
import autohandIcon from '@/assets/images/autohand.svg?raw';
Expand Down Expand Up @@ -57,6 +58,7 @@ const ICONS: Record<string, string> = {
'kiro.png': kiroIcon,
'letta.svg': lettaIcon,
'atlassian.png': atlassianIcon,
'atlas.png': atlascloudIcon,
'cline.png': clineIcon,
'continue.png': continueIcon,
'codebuff.png': codebuffIcon,
Expand Down
2 changes: 2 additions & 0 deletions apps/emdash-desktop/src/renderer/utils/agentConfig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type AgentProviderId } from '@shared/core/agents/agent-provider-registry';
import ampLogo from '../../assets/images/ampcode.svg';
import antigravityLogo from '../../assets/images/antigravity.svg';
import atlascloudLogo from '../../assets/images/atlas.png';
import atlassianLogo from '../../assets/images/atlassian.png';
import augmentLogoSvg from '../../assets/images/Auggie.svg?raw';
import autohandLogoSvg from '../../assets/images/autohand.svg?raw';
Expand Down Expand Up @@ -118,4 +119,5 @@ export const agentConfig: Record<AgentProviderId, AgentInfo> = {
},
charm: { name: 'Charm', logo: charmLogo, alt: 'Charm Crush' },
rovo: { name: 'Rovo Dev', logo: atlassianLogo, alt: 'Rovo Dev' },
atlascloud: { name: 'Atlas Cloud', logo: atlascloudLogo, alt: 'Atlas Cloud' },
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const AGENT_PROVIDER_IDS = [
'pi',
'letta',
'autohand',
'atlascloud',
] as const;

export type AgentProviderId = (typeof AGENT_PROVIDER_IDS)[number];
Expand Down Expand Up @@ -657,6 +658,29 @@ export const AGENT_PROVIDERS: AgentProviderDefinition[] = [
alt: 'Autohand Code CLI',
terminalOnly: true,
},
{
id: 'atlascloud',
name: 'Atlas Cloud',
description:
'Route the OpenCode CLI through Atlas Cloud — 59 frontier models (DeepSeek-V4, Qwen3, Kimi K2, GPT-5, Gemini 2.5 Pro, Claude, Grok-4…) via a single OpenAI-compatible endpoint. Requires OpenCode; set ATLASCLOUD_API_KEY (or OPENAI_API_KEY) in this provider’s environment settings.',
docUrl: 'https://www.atlascloud.ai/docs',
// Atlas Cloud is not a standalone CLI: it reuses the OpenCode binary and
// simply points it at Atlas's OpenAI-compatible endpoint via env injection
// (see resolveProviderEnv). Reusing OpenCode's command/installCommand here
// would register a second, indistinguishable probe of the `opencode`
// binary, so it is intentionally not separately detectable.
detectable: false,
cli: 'opencode',
autoApproveViaEnv: true,
initialPromptFlag: '--prompt',
resumeFlag: '--session',
sessionIdFlag: '--session',
sessionIdOnResumeOnly: true,
resumeWithoutSessionFlag: '--continue',
icon: 'atlas.png',
alt: 'Atlas Cloud',
terminalOnly: true,
},
Comment on lines +662 to +683

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Duplicate command detection with existing opencode provider

Both atlascloud and the existing opencode provider set commands: ['opencode'] and installCommand: 'npm install -g opencode-ai'. The buildAgentDependencies() function in registry.ts creates an independent DependencyDescriptor per provider, so both descriptors resolve the same binary. This means any user who has opencode on their PATH will see both "Atlas Cloud" and "OpenCode" reported as available simultaneously — even though they have only one binary installed. This is likely to confuse users browsing the provider list.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts
Line: 662-680

Comment:
**Duplicate command detection with existing `opencode` provider**

Both `atlascloud` and the existing `opencode` provider set `commands: ['opencode']` and `installCommand: 'npm install -g opencode-ai'`. The `buildAgentDependencies()` function in `registry.ts` creates an independent `DependencyDescriptor` per provider, so both descriptors resolve the same binary. This means any user who has `opencode` on their `PATH` will see *both* "Atlas Cloud" and "OpenCode" reported as `available` simultaneously — even though they have only one binary installed. This is likely to confuse users browsing the provider list.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +662 to +683

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 No actual API endpoint configuration for Atlas Cloud

The atlascloud entry installs and invokes the stock opencode-ai CLI, which by default points at opencode's own inference backend — not Atlas Cloud's API. There is no mechanism here (no env var injection, no config file write, no extra CLI flags) to redirect the CLI to Atlas Cloud's endpoint. The description even acknowledges this gap ("Configure any OpenAI-compatible agent CLI to use Atlas Cloud as the LLM backend"), but the provider registration provides no guidance or automation for that step. Without configuration, a user who picks this provider will get a plain opencode session backed by opencode's default models, indistinguishable from choosing the opencode provider.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts
Line: 662-680

Comment:
**No actual API endpoint configuration for Atlas Cloud**

The `atlascloud` entry installs and invokes the stock `opencode-ai` CLI, which by default points at opencode's own inference backend — not Atlas Cloud's API. There is no mechanism here (no env var injection, no config file write, no extra CLI flags) to redirect the CLI to Atlas Cloud's endpoint. The description even acknowledges this gap ("Configure any OpenAI-compatible agent CLI to use Atlas Cloud as the LLM backend"), but the provider registration provides no guidance or automation for that step. Without configuration, a user who picks this provider will get a plain opencode session backed by opencode's default models, indistinguishable from choosing the `opencode` provider.

How can I resolve this? If you propose a fix, please make it concise.

];
Comment on lines +679 to 684

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Missing supportsHooks: true

The opencode provider sets supportsHooks: true, which enables emdash hooks (e.g. the SessionStart hook that captures the rollout session ID for reliable conversation resumption). The atlascloud entry uses the exact same CLI (opencode) but omits this flag, so hooks will silently not fire during Atlas Cloud sessions even though the underlying binary fully supports them.

Suggested change
resumeWithoutSessionFlag: '--continue',
icon: 'atlas.png',
alt: 'Atlas Cloud',
terminalOnly: true,
},
];
resumeWithoutSessionFlag: '--continue',
icon: 'atlas.png',
alt: 'Atlas Cloud',
terminalOnly: true,
supportsHooks: true,
},
];
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts
Line: 676-681

Comment:
**Missing `supportsHooks: true`**

The `opencode` provider sets `supportsHooks: true`, which enables emdash hooks (e.g. the `SessionStart` hook that captures the rollout session ID for reliable conversation resumption). The `atlascloud` entry uses the exact same CLI (`opencode`) but omits this flag, so hooks will silently not fire during Atlas Cloud sessions even though the underlying binary fully supports them.

```suggestion
    resumeWithoutSessionFlag: '--continue',
    icon: 'atlas.png',
    alt: 'Atlas Cloud',
    terminalOnly: true,
    supportsHooks: true,
  },
];
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


const PROVIDER_MAP = new Map<string, AgentProviderDefinition>(
Expand All @@ -681,7 +705,10 @@ export function isValidProviderId(value: unknown): value is AgentProviderId {
}

export function isValidProviderSessionId(providerId: string, providerSessionId: string): boolean {
if (providerId === 'opencode') return providerSessionId.startsWith('ses');
// Atlas Cloud runs through the OpenCode CLI, so it shares OpenCode's session id format.
if (providerId === 'opencode' || providerId === 'atlascloud') {
return providerSessionId.startsWith('ses');
}
return true;
}

Expand Down
Loading