Skip to content

Multi-Provider Support

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.

PropertyValue
Provider IDclaude-code
CLI binaryclaude
Installnpm install -g @anthropic-ai/claude-code
Hook system--settings flag with JSON hooks config
Default modelsSonnet 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.

When you create an agent, you set the cli_name field to either claude-code or codex. Abbado uses this to:

  1. Select the adapter — different launch logic for each CLI
  2. Check availability — verify the CLI binary is installed
  3. Configure hooks — each provider has its own hook setup
  4. Set environment variables — Codex needs specific env vars for credentials

Before launching a run, Abbado checks that the CLI is installed:

which claude # for claude-code
which codex # for codex

If the CLI is not found, the run fails with an error message and install instructions.

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 identifier
  • worktrees — list of (repo_name, worktree_path) pairs
  • task — the prompt text
  • state_dir — directory for CLI session state
  • session_id — for resume (optional)
  • allowed_tools — comma-separated tool names
  • instructions — system prompt to append

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.

The available models per provider are configurable via Settings > Models in the UI, or the API:

GET /api/settings/models
PUT /api/settings/models

Default 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.

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.