Multi-Provider Support
Overview
Section titled “Overview”Abbado supports multiple AI CLI providers. Each agent is configured with a specific provider, and Abbado handles the differences in CLI flags, hook systems, and session management.
Supported Providers
Section titled “Supported Providers”| Property | Value |
|---|---|
| Provider ID | claude-code |
| CLI binary | claude |
| Install | npm install -g @anthropic-ai/claude-code |
| Hook system | --settings flag with JSON hooks config |
| Default models | Sonnet 4.6, Opus 4.6, Haiku 4.5 |
Claude Code is the primary provider. All hook events are fully supported: UserPromptSubmit, Stop, StopFailure, SessionEnd, PreToolUse, PostToolUse, PostToolUseFailure, Notification, PermissionRequest, SubagentStart, SubagentStop.
| Property | Value |
|---|---|
| Provider ID | codex |
| CLI binary | codex |
| Install | npm install -g @openai/codex |
| Hook system | Custom hook installation via state directory |
| Default models | o3, o4-mini, GPT-4.1 |
Codex uses a different hook system. Abbado installs hooks via abbado_adapters::codex::install_run_hooks and prepares credentials via prepare_state_dir. The hook response format includes a hookSpecificOutput wrapper.
Provider Detection
Section titled “Provider Detection”When you create an agent, you set the cli_name field to either claude-code or codex. Abbado uses this to:
- Select the adapter — different launch logic for each CLI
- Check availability — verify the CLI binary is installed
- Configure hooks — each provider has its own hook setup
- Set environment variables — Codex needs specific env vars for credentials
CLI Availability Check
Section titled “CLI Availability Check”Before launching a run, Abbado checks that the CLI is installed:
which claude # for claude-codewhich codex # for codexIf the CLI is not found, the run fails with an error message and install instructions.
Adapter Architecture
Section titled “Adapter Architecture”Each provider has an adapter that implements the same interface:
pub trait Adapter { fn is_cli_available(&self) -> bool; async fn launch(self, config: LaunchConfig, tx: Sender<RunEvent>) -> Result<()>;}The LaunchConfig includes:
run_id— unique run identifierworktrees— list of(repo_name, worktree_path)pairstask— the prompt textstate_dir— directory for CLI session statesession_id— for resume (optional)allowed_tools— comma-separated tool namesinstructions— system prompt to append
Hook Differences
Section titled “Hook Differences”Claude Code
Section titled “Claude Code”Hooks are configured via a JSON settings file passed with --settings:
{ "hooks": { "PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "/path/to/hook.sh" }] }] }}Agent instructions are passed via --append-system-prompt.
Hooks are installed into the Codex state directory. The hook responses need a specific format:
{ "hookSpecificOutput": { "hookEventName": "SessionStart", "additionalContext": "" }}Codex also requires credential preparation and specific environment variables for authentication.
Model Configuration
Section titled “Model Configuration”The available models per provider are configurable via Settings > Models in the UI, or the API:
GET /api/settings/modelsPUT /api/settings/modelsDefault configuration:
{ "providers": [ { "id": "claude-code", "name": "Claude", "models": [ { "id": "claude-sonnet-4-6", "name": "Sonnet 4.6", "description": "Fast, balanced" }, { "id": "claude-opus-4-6", "name": "Opus 4.6", "description": "Most capable" }, { "id": "claude-haiku-4-5", "name": "Haiku 4.5", "description": "Fastest, cheapest" } ] }, { "id": "codex", "name": "ChatGPT", "models": [ { "id": "o3", "name": "o3", "description": "Reasoning" }, { "id": "o4-mini", "name": "o4-mini", "description": "Fast reasoning" }, { "id": "gpt-4.1", "name": "GPT-4.1", "description": "Flagship" } ] } ]}You can add custom providers or modify the model list. The model list is stored in the settings table and survives server restarts.
Pipeline Mode
Section titled “Pipeline Mode”In pipeline mode (when a run has a parent_run_id), Abbado uses the stream-json adapter instead of the PTY terminal. This mode:
- Launches the CLI with
-p(prompt mode) for non-interactive execution - Parses the JSON output stream for events
- Automatically transitions through the builder/reviewer pipeline
Interactive mode (no parent run) always uses the PTY terminal with hooks.