# Provider Reference Agents Orchestrator supports 4 agent providers. Each provider has its own sidecar runner, message adapter, and capability set. Providers are selected per-project in `groups.json` or via the Settings tab. ## Provider summary | Provider | ID | Default Model | Sidecar Runner | API | |----------|----|---------------|----------------|-----| | Claude Code | `claude` | claude-opus-4-6 | `claude-runner.mjs` | Claude Agent SDK | | Codex CLI | `codex` | gpt-5.4 | `codex-runner.mjs` | @openai/codex-sdk | | Ollama | `ollama` | qwen3:8b | `ollama-runner.mjs` | REST (localhost:11434) | | Aider | `aider` | openrouter/anthropic/claude-sonnet-4 | `aider-runner.mjs` | OpenRouter / direct | ## Capabilities Each provider declares capabilities that gate UI features: | Capability | Claude | Codex | Ollama | Aider | |------------|--------|-------|--------|-------| | `hasProfiles` | Yes | No | No | No | | `hasSkills` | Yes | No | No | No | | `hasModelSelection` | Yes | Yes | Yes | Yes | | `hasSandbox` | No | Yes | No | No | | `supportsSubagents` | Yes | No | No | No | | `supportsCost` | Yes | No | No | No | | `supportsResume` | Yes | Yes | No | No | When a capability is `false`, the corresponding UI element is hidden. For example, profile selectors and skill autocomplete only appear for Claude. ## Provider type ```typescript type ProviderId = 'claude' | 'codex' | 'ollama' | 'aider'; ``` Defined in `src/lib/providers/types.ts`. ## Provider selection Set `provider` on a `ProjectConfig` in `groups.json`: ```json { "id": "my-project", "name": "My Project", "cwd": "/home/user/code/project", "provider": "codex", "model": "o3" } ``` If omitted, defaults to `claude`. ## Claude Code - **Source:** `src/lib/providers/claude.ts` - **Runner:** `sidecar/claude-runner.ts` (compiled to `sidecar/dist/claude-runner.mjs`) - **SDK:** `@anthropic-ai/claude-agent-sdk` `query()` function - **CLI detection:** Auto-detects Claude CLI at startup. Checks paths in order: `~/.local/bin/claude`, `~/.claude/local/claude`, `/usr/local/bin/claude`, `/usr/bin/claude`, then `which claude`. Agent errors immediately if not found. - **Config dir:** Override with `CLAUDE_CONFIG_DIR` for multi-account setups. Mapped to `claude_config_dir` in `AgentQueryOptions`. Available models: | Model ID | Label | |----------|-------| | `claude-opus-4-6` | Opus 4.6 | | `claude-sonnet-4-6` | Sonnet 4.6 | | `claude-haiku-4-5-20251001` | Haiku 4.5 | ## Codex CLI - **Source:** `src/lib/providers/codex.ts` - **Runner:** `sidecar/codex-runner.ts` (compiled to `sidecar/dist/codex-runner.mjs`) - **SDK:** `@openai/codex-sdk` (dynamic import; graceful failure if not installed) - **Sandbox:** Maps agor sandbox settings to Codex approval modes. - **Env:** Requires `OPENAI_API_KEY`. Available models: | Model ID | Label | |----------|-------| | `gpt-5.4` | GPT-5.4 | | `o3` | o3 | | `o4-mini` | o4-mini | ## Ollama - **Source:** `src/lib/providers/ollama.ts` - **Runner:** `sidecar/ollama-runner.ts` (compiled to `sidecar/dist/ollama-runner.mjs`) - **API:** Direct HTTP to `localhost:11434` (native fetch, zero external deps) - **Prereq:** Ollama must be running locally before starting an agent session. Available models: | Model ID | Label | |----------|-------| | `qwen3:8b` | Qwen3 8B | | `qwen3:32b` | Qwen3 32B | | `llama3.3:70b` | Llama 3.3 70B | | `deepseek-r1:14b` | DeepSeek R1 14B | | `codellama:13b` | Code Llama 13B | ## Aider - **Source:** `src/lib/providers/aider.ts` - **Runner:** `sidecar/aider-runner.ts` (compiled to `sidecar/dist/aider-runner.mjs`) - **Routing:** Supports OpenRouter, OpenAI direct, Anthropic direct, and Ollama local models via model ID prefixes. - **Env:** Requires `OPENROUTER_API_KEY` for OpenRouter models, `OPENAI_API_KEY` for OpenAI direct, `ANTHROPIC_API_KEY` for Anthropic direct. - **Autonomous mode:** Supports `restricted` (surfaces commands for approval) and `autonomous` (auto-executes with audit logging) via `autonomousMode` project config. Available models: | Model ID | Label | |----------|-------| | `openrouter/anthropic/claude-sonnet-4` | Claude Sonnet 4 (OpenRouter) | | `openrouter/anthropic/claude-haiku-4` | Claude Haiku 4 (OpenRouter) | | `openrouter/openai/gpt-4.1` | GPT-4.1 (OpenRouter) | | `openrouter/openai/o3` | o3 (OpenRouter) | | `openrouter/google/gemini-2.5-pro` | Gemini 2.5 Pro (OpenRouter) | | `openrouter/deepseek/deepseek-r1` | DeepSeek R1 (OpenRouter) | | `openrouter/meta-llama/llama-4-maverick` | Llama 4 Maverick (OpenRouter) | | `anthropic/claude-sonnet-4-5-20250514` | Claude Sonnet 4.5 (direct) | | `o3` | o3 (OpenAI direct) | | `ollama/qwen3:8b` | Qwen3 8B (Ollama) | ## Sidecar architecture Each provider has a runner script compiled to a standalone ESM bundle in `sidecar/dist/`. The sidecar communicates with the Rust backend via stdio NDJSON. Build all runners: ```bash npm run build:sidecar ``` ### Provider routing `SidecarManager.resolve_sidecar_for_provider(provider)` selects the runner file based on `ProviderId`. The sidecar process runs under Deno (preferred, faster startup) with Node.js as fallback. ### Environment stripping The sidecar strips provider-specific environment variables to prevent cross-contamination. The function `strip_provider_env_var()` in `agor-core/src/sidecar.rs` filters the process environment: - **Stripped:** `CLAUDE_*`, `CODEX_*`, `OLLAMA_*` (and similar provider vars) - **Preserved:** `CLAUDE_CODE_EXPERIMENTAL_*` (whitelist for experimental flags) - **Preserved:** Standard vars (`HOME`, `PATH`, `USER`, `SHELL`, `TERM`, `XDG_*`, `RUST_LOG`, etc.) This is applied in two layers: 1. **Rust:** `env_clear()` + filtered `clean_env` on the spawned process 2. **JavaScript:** Runner SDK `env` option for provider-specific overrides ## Message adapters Each provider has a message adapter that parses provider-specific output into a common `AgentMessage` format: | Provider | Adapter | Tests | |----------|---------|-------| | Claude | `src/lib/adapters/claude-messages.ts` | 25 tests | | Codex | `src/lib/adapters/codex-messages.ts` | 19 tests | | Ollama | `src/lib/adapters/ollama-messages.ts` | 11 tests | | Aider | `sidecar/aider-parser.ts` | 72 tests | Adapters are registered in `src/lib/adapters/message-adapters.ts` and routed by `ProviderId`. The dispatcher (`src/lib/agent-dispatcher.ts`) delegates to the correct adapter based on the session's provider.