Orchestrating CLI Coding Agents#
AG2 can drive external CLI coding agents — Claude Code, Codex, OpenCode, Gemini CLI, and others — as first-class agents, using the Agent Client Protocol (ACP).
AG2 plays the ACP Client role; each CLI agent runs as an ACP Agent subprocess. Everything the agent does — message output, thinking, tool calls, plans, and permission prompts — is externalized onto AG2's event stream, so you can observe, gate, and orchestrate it like any other AG2 agent.
The integration is a configuration class — a subclass of ACPConfig carrying the launch defaults for each adapter (ClaudeCodeConfig, CodexConfig, OpenCodeConfig) — and there are no changes to the Agent API.
Basic Usage#
A single ask()/run() maps to one ACP prompt turn: the CLI agent runs its own internal tool loop and AG2 streams every step as it happens.
Choosing an agent#
Each adapter is a preset with its own launch command and authentication:
OpenCode model selection
As with the Claude Code and Codex adapters, OpenCodeConfig's model field is response metadata only. OpenCode's acp subcommand takes no --model flag — select the model in OpenCode's own config (opencode.json: "model": "provider/model"). With nothing configured and no authenticated provider, OpenCode falls back to the first model of its built-in opencode provider (OpenCode Zen).
Observing the agent's work#
Subscribe to the run's stream to see thoughts, tool calls, and plans live:
| ACP update | AG2 event |
|---|---|
| agent message | ModelMessageChunk → final ModelResponse |
| thinking | ModelReasoning |
| tool call / result | BuiltinToolCallEvent / BuiltinToolResultEvent |
| plan | ACPPlan |
| mode change | ACPModeChange |
| available commands | ACPAvailableCommands |
Permissions (Human-in-the-Loop)#
When the agent asks to perform a sensitive action, it sends a permission request. permission_policy controls the response:
| Policy | Behavior |
|---|---|
"ask" (default) | Route to the agent's hitl_hook / context.input; the human decides |
"auto" | Approve automatically (headless orchestration) |
"deny" | Reject automatically |
Orchestrating multiple agents#
Because each CLI agent is an Agent, you can compose them — including as tools of one another via .as_tool():
Note
Exposing AG2 tools=[...] (including .as_tool() subagents) to the CLI agent requires the MCP tool bridge, landing in a follow-up. Today, CLI-backed agents use their own built-in tools; tools=[...] orchestration via ACP is on the roadmap.
Configuration reference#
ACPConfig (and its presets like ClaudeCodeConfig) accept:
| Field | Default | Purpose |
|---|---|---|
command | preset per agent | Executable + args launching the agent in ACP mode |
cwd | "." | Workspace root for the session |
env | None | Extra environment variables for the subprocess |
model | None | Agent model selection, when supported |
permission_policy | "ask" | ask / auto / deny |
fs_root | cwd | Root for mediated fs/* access (path-confined) |
allow_terminal | True | Advertise the ACP terminal capability |
additional_directories | [] | Extra workspace roots |
startup_timeout | 30.0 | Subprocess spawn + handshake timeout (s) |
turn_timeout | None | Per-prompt-turn timeout (s) |
cancel_timeout | 5.0 | Grace period (s) after a timed-out turn signals session/cancel before the subprocess is hard-stopped |
File and terminal operations the agent requests are mediated by AG2: file access is confined to fs_root, and the agent's commands run under AG2's control.
Lifecycle#
The ACP subprocess is created on the first turn and reused for the run. Call await config.aclose() to tear down any live subprocesses started from a config (a finalizer terminates them as a safety net if you don't).