Skip to content

AI Providers

Doable supports 60+ AI providers via two paths: bring your own key (BYOK) or use platform-managed credentials via the Provider Bridge. Pick at least one path; the chat agent is dormant without a configured provider.

The full provider catalog is defined in packages/shared/src/ai/provider-catalog.ts.


Bring your own key

With BYOK, you supply API keys directly, either as server environment variables (global default) or per-workspace in the UI.

Per-workspace overrides are configured from Workspace Settings โ†’ AI โ†’ Providers. The environment variables below are the global defaults the API falls back to.

Anthropic (Claude)

Recommended for highest-quality code generation and longest context windows.

ANTHROPIC_API_KEY=sk-ant-...

Models: Claude Opus 4, Claude Sonnet 4, Claude Haiku 4.5
Capabilities: Streaming, tool calling, vision, extended thinking

OpenAI

OPENAI_API_KEY=sk-...

Models: GPT-4.1, GPT-4o, o3, o4-mini
Capabilities: Streaming, tool calling, vision

Google AI Studio (Gemini)

GOOGLE_AI_API_KEY=...

Models: Gemini 2.5 Pro, Gemini 2.5 Flash
Capabilities: Streaming, tool calling, vision

Azure OpenAI

AZURE_OPENAI_API_KEY=...
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com
AZURE_OPENAI_DEPLOYMENT=your-deployment-name

Models: Your deployed models (GPT-4.1, GPT-4o, etc.)
Capabilities: Streaming, tool calling, vision

AWS Bedrock

AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1

Models: Claude, Llama, custom models via Bedrock
Capabilities: Streaming, tool calling, vision

Google Vertex AI

GOOGLE_VERTEX_PROJECT=your-project
GOOGLE_VERTEX_LOCATION=us-central1

Models: Gemini, Claude, custom models
Capabilities: Streaming, tool calling, vision

GitHub Copilot SDK

The most powerful option (the same agent that powers GitHub Copilot Chat), but requires a separately installed CLI.

Option A: local CLI

  1. Install the CLI: see the Copilot SDK README.
  2. Authenticate it once: copilot auth login.
  3. Set the path:
COPILOT_CLI_PATH=/usr/local/bin/copilot

Doable spawns a subprocess per session.

Option B: remote CLI server

If you want one shared Copilot CLI server (useful for scaling), run copilot --server somewhere and point Doable at it:

COPILOT_CLI_URL=http://copilot.internal:7878

Pick a default model

COPILOT_DEFAULT_MODEL=claude-sonnet-4

Available models depend on the user's Copilot subscription. Doable surfaces the full list per session.

"Bring your own GitHub Copilot" flow

If a workspace member has a personal Copilot subscription, they can connect it from Settings โ†’ AI โ†’ GitHub Copilot. Doable runs the OAuth flow at GITHUB_COPILOT_REDIRECT_URI and stores an encrypted token. The agent then uses their Copilot quota, not yours. Implementation lives in services/api/src/routes/auth/ and services/api/src/ai/providers/copilot-manager.ts.

Personal vs workspace scope

Doable distinguishes workspace-scoped AI accounts (shared across every member) from personal-scoped accounts (visible only to the user who connected them). The split was introduced in migration 072_ai_personal_scope.sql and applies to both github_copilot_accounts and ai_providers.

What changed in migration 072

  • Both tables gained a scope ai_account_scope column ('workspace' | 'user') and an owner_user_id uuid column. A CHECK constraint enforces that personal rows have owner_user_id set and workspace rows have it NULL.
  • The old workspace-wide UNIQUE on (workspace_id, github_login) was replaced by two partial uniques: gca_workspace_login_unique (scope = workspace) and gca_user_login_unique (scope = user, scoped to the owning user). Two different users can each connect the same GitHub login as a personal Copilot account in the same workspace; a single user cannot connect the same login twice.
  • The enforce_workspace_default_scope() trigger blocks workspace_ai_settings from pointing at a personal row for any of default, suggestion, or enforced (account or provider). If you try to set a personal row as the workspace default, the INSERT or UPDATE raises an exception.
  • The enforce_uap_account_ownership() trigger blocks a user from referencing another user's personal account or provider via user_ai_preferences. Workspace-scoped rows remain referenceable by anyone in the workspace.
  • RLS policies (gca_scope_visibility and ai_providers_scope_visibility) provide defense in depth: workspace rows are visible to workspace members and mutable by admins; personal rows are visible and mutable only by their owning user.

What this means in the UI

  • The /ai-settings page splits its lists into a Personal section (the current user's scope='user' rows) and a Workspace section (scope='workspace' rows). Personal rows are not shown to anyone else, including workspace admins.
  • The setup wizard's Copilot tile passes scope=workspace when an admin connects an account during first-time setup (see apps/web/src/app/setup/steps/Step2AIProvider.tsx); the resulting account is shared, not personal.
  • Workspace defaults, suggestion defaults, and enforced choices can only point at workspace-scoped rows. If an admin wants to enforce a model for the whole workspace, that model's account or provider must live at workspace scope.

Admin invariant

An admin or owner cannot see other users' personal rows, full stop. The gca_scope_visibility policy makes the visibility check scope = 'user' AND owner_user_id = doable_current_user_id() for personal rows; an admin running the same query observes only their own personal rows plus the workspace pool. This is intentional: the migration's header note is explicit that "non-admins couldn't add their own [accounts] before; they could only pick from the admin-curated pool", and the fix should not flip the inverse asymmetry into existence.

If you need to recover access to a personal row that an ex-user left behind, the only legitimate path is a direct SQL operation by a platform admin against the database, with audit logging; the API does not expose a "view all personal rows" endpoint.


Platform-managed (Provider Bridge)

With the Provider Bridge, a platform admin loads API keys once for the whole organisation. Users pick a model from the provider picker without ever entering a key themselves.

See Provider Bridge for the full setup guide, security model, and user experience details.


Supported providers

Specialized cloud providers

High-performance inference or specialized models:

Provider Env Variable Notable Models
Groq GROQ_API_KEY Llama 3, Mixtral (ultra-fast inference)
Mistral AI MISTRAL_API_KEY Mistral Large, Codestral
Cohere COHERE_API_KEY Command R+
xAI (Grok) XAI_API_KEY Grok-2
DeepSeek DEEPSEEK_API_KEY DeepSeek V3, DeepSeek Coder
Perplexity PERPLEXITY_API_KEY Sonar Pro (web-grounded)
SambaNova SAMBANOVA_API_KEY Fast Llama inference
Novita AI NOVITA_API_KEY Various open models
PPIO PPIO_API_KEY GPU cloud inference

All specialized providers support streaming and tool calling.

Aggregators (multi-model routers)

Access hundreds of models through a single API key:

Provider Env Variable Description
OpenRouter OPENROUTER_API_KEY 200+ models from all providers
Together AI TOGETHER_API_KEY Open-source model hosting
Fireworks AI FIREWORKS_API_KEY Fast open-model inference
Unify AI UNIFY_API_KEY Intelligent model routing
DeepInfra DEEPINFRA_API_KEY Serverless GPU inference

Tip

OpenRouter is a great choice if you want access to models from every provider without managing multiple API keys. Set OPENROUTER_API_KEY and your users can pick from Claude, GPT-4, Gemini, Llama, and more, all from one account.

Regional & emerging providers

Provider Region Env Variable
Moonshot (Kimi) China MOONSHOT_API_KEY
DashScope (Qwen) China DASHSCOPE_API_KEY
Zhipu (GLM) China ZHIPU_API_KEY
Baidu Qianfan China QIANFAN_API_KEY
Volcengine (Doubao) China VOLCENGINE_API_KEY
MiniMax China MINIMAX_API_KEY
StepFun China STEPFUN_API_KEY
01.AI (Yi) China YI_API_KEY
Tencent Hunyuan China HUNYUAN_API_KEY
Cerebras US CEREBRAS_API_KEY
AI21 Labs US AI21_API_KEY
Hyperbolic US HYPERBOLIC_API_KEY

Infrastructure providers

Cloud GPU and inference platforms:

Provider Env Variable
NVIDIA NIM NVIDIA_API_KEY
Cloudflare Workers AI CLOUDFLARE_API_KEY
Nebius NEBIUS_API_KEY
Scaleway SCALEWAY_API_KEY
Infermatic INFERMATIC_API_KEY
Lepton AI LEPTON_API_KEY
OVHcloud OVH_API_KEY

Local & self-hosted models

Run models on your own hardware with zero API costs. All local providers use the OpenAI-compatible endpoint format:

# Point Doable at your local model server
OPENAI_BASE_URL=http://localhost:11434/v1
OPENAI_API_KEY=not-needed

Primary local engines

Engine Default Port Setup
Ollama 11434 ollama serve then ollama pull llama3
LM Studio 1234 Download app, load model, start server
vLLM 8000 vllm serve model-name
llama.cpp 8080 ./llama-server -m model.gguf
Jan 1337 Download app, start local API
LocalAI 8080 Docker container with model gallery
GPT4All 4891 Desktop app with local server mode

Additional self-hosted options

Engine Notes
text-generation-webui Popular Gradio UI with API mode
KoboldCpp GGUF models with OpenAI-compatible API
TGI (Text Generation Inference) Hugging Face's production serving
TabbyML Code completion focused
llamafile Single-file executable models
Cortex Local AI platform
LMDeploy High-throughput serving
SGLang Fast structured generation
TabbyAPI ExLlamaV2 backend
MLC LLM Universal deployment
Aphrodite vLLM fork with extras

Local model frontends

  • Msty: Desktop app for managing local models
  • Open WebUI: Web interface (Docker-based)
  • LibreChat: Self-hosted ChatGPT-like interface

Model discovery

Doable auto-discovers available models by querying GET /v1/models on the configured endpoint. If that fails, it falls back to a chat completions ping to verify connectivity.

OpenAI-compatible endpoints

Any server that implements the OpenAI chat completions API (POST /v1/chat/completions) works with Doable:

OPENAI_BASE_URL=http://your-server:port/v1
OPENAI_API_KEY=your-key-or-dummy

This covers vLLM, llama.cpp, TGI, LM Studio, Ollama, and dozens of other servers.


Per-workspace overrides

Stored in workspaces.ai_settings (JSONB). Edit from Workspace Settings โ†’ AI. The relevant tables:

  • ai_providers: provider configs with encrypted API keys at workspace scope.
  • ai_provider_models: cached model list per provider.
  • user_ai_preferences: personal model preferences.
  • mode_tool_config: which tools each mode can use.

The encryption key for stored credentials is ENCRYPTION_KEY from your env.

Routing & fallback

If multiple providers are configured, the engine resolver (services/api/src/ai/engine-resolver.ts) picks based on:

  1. Explicit per-message override (the user picked a model in the UI).
  2. Workspace default model.
  3. Global default (env var).
  4. First-available healthy provider.

If a provider call fails (rate limit, 5xx), the resolver retries the next provider in the chain.

Cost control

  • Credit limits per user / per session, configured in Workspace Settings โ†’ AI โ†’ Limits.
  • Model allow-list to restrict expensive models to admins.
  • Token budgets: automatic context compaction kicks in well before the model's hard limit (session.compaction_start / session.compaction_complete events).

Verifying it works

Sign in, create a project, and send the message "What's 2+2?". You should see streaming text within a second or two. If you see "No AI provider configured":

  1. Confirm the env var is set in the API environment (not just the shell).
  2. Check the API logs: docker compose logs api or journalctl -u doable -e.
  3. Verify the workspace's AI settings haven't disabled all providers.

Next: Provider Bridge ยท How docore works.