From 317e440b22634a225c0760271e60b892156c22b4 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Mon, 11 May 2026 11:40:50 -0400 Subject: [PATCH] docs: document ACP workflow backend --- docs/public/agents/outputs.mdx | 2 +- docs/public/agents/subagents.mdx | 2 +- docs/public/agents/tools.mdx | 2 +- docs/public/changelog/2026-02-27.mdx | 6 ++-- docs/public/core-concepts/agents.mdx | 50 +++++++++++++++++++++----- docs/public/reference/dot-language.mdx | 3 +- docs/public/tutorials/multi-model.mdx | 2 +- docs/public/workflows/stylesheets.mdx | 2 +- 8 files changed, 51 insertions(+), 18 deletions(-) diff --git a/docs/public/agents/outputs.mdx b/docs/public/agents/outputs.mdx index 2fda1a5a8..1407f4db6 100644 --- a/docs/public/agents/outputs.mdx +++ b/docs/public/agents/outputs.mdx @@ -127,7 +127,7 @@ The tracked paths are stored as `files_touched` on the stage outcome: For the **API backend**, Fabro subscribes to agent session events. When a `ToolCallStarted` event fires for `write_file` or `edit_file`, Fabro records the `file_path` argument as pending. When the corresponding `ToolCallCompleted` arrives without an error, the path is confirmed as touched. Failed tool calls are discarded. -For the **CLI backend**, Fabro takes a different approach: it runs `git diff --name-only` and `git ls-files --others --exclude-standard` before and after the agent session, then computes the difference. Any files that appear in the "after" snapshot but not "before" are recorded as touched. +For the **CLI** and **ACP** backends, Fabro takes a different approach: it runs `git diff --name-only` and `git ls-files --others --exclude-standard` before and after the external agent session, then computes the difference. Any files that appear in the "after" snapshot but not "before" are recorded as touched. ## Artifact offloading diff --git a/docs/public/agents/subagents.mdx b/docs/public/agents/subagents.mdx index cc3741ed1..0427b9fa8 100644 --- a/docs/public/agents/subagents.mdx +++ b/docs/public/agents/subagents.mdx @@ -6,7 +6,7 @@ description: "Delegate subtasks to child agent sessions" An agent can spawn **sub-agents** to delegate work to independent child sessions. Each sub-agent gets its own LLM session and tool access, runs concurrently with the parent, and returns its result when finished. -Sub-agents are only available with the [API backend](/core-concepts/agents#api-backend-default) (the default). Agents using the [CLI backend](/core-concepts/agents#cli-backend) cannot spawn sub-agents. +Sub-agents are only available with the [API backend](/core-concepts/agents#api-backend-default) (the default). Agents using the [CLI backend](/core-concepts/agents#cli-backend) or [ACP backend](/core-concepts/agents#acp-backend) cannot spawn Fabro sub-agents. ## Tools diff --git a/docs/public/agents/tools.mdx b/docs/public/agents/tools.mdx index 1c9b6a7c9..5185cfc18 100644 --- a/docs/public/agents/tools.mdx +++ b/docs/public/agents/tools.mdx @@ -6,7 +6,7 @@ description: "Built-in tools for file I/O, shell commands, search, and web acces Every agent in Fabro has access to a set of built-in tools for interacting with the codebase and environment. Tools execute inside the agent's [sandbox](/execution/environments) — whether that's the local machine, a Docker container, or a Daytona VM — so the same tool calls work identically regardless of provider. -The tools described on this page apply to the **API backend** (the default). When using the [CLI backend](/core-concepts/agents#cli-backend), the external CLI tool (`claude`, `codex`, or `gemini`) provides its own tools — Fabro's built-in tools are not used. +The tools described on this page apply to the **API backend** (the default). When using the [CLI backend](/core-concepts/agents#cli-backend) or [ACP backend](/core-concepts/agents#acp-backend), the external agent process provides its own tools — Fabro's built-in tools are not used. ## Core tools diff --git a/docs/public/changelog/2026-02-27.mdx b/docs/public/changelog/2026-02-27.mdx index 67ee8ef40..acc252a59 100644 --- a/docs/public/changelog/2026-02-27.mdx +++ b/docs/public/changelog/2026-02-27.mdx @@ -13,11 +13,11 @@ Two new built-in tools bring real-time information into workflow decisions. `web ## CLI backends -Individual workflow nodes can now delegate work to external AI coding assistants. Set the backend to `claude-code`, `codex`, or `gemini-cli` and the node will use that CLI tool instead of the built-in agent loop. +Individual workflow nodes can delegate work to external AI coding assistants. Set `backend="cli"` and choose a provider; Fabro selects `claude`, `codex`, or `gemini` for the node instead of the built-in API agent loop. Current backend values are `api`, `cli`, and `acp`. ```dot -implement [handler=codergen, cli_backend=codex] -review [handler=codergen, cli_backend=claude-code] +implement [type="agent", backend="cli", provider="openai"] +review [type="agent", backend="cli", provider="anthropic"] ``` This means each stage in a workflow can use a different AI tool — use Codex for implementation and Claude Code for review, for example. diff --git a/docs/public/core-concepts/agents.mdx b/docs/public/core-concepts/agents.mdx index e3d4abf7e..2bede229a 100644 --- a/docs/public/core-concepts/agents.mdx +++ b/docs/public/core-concepts/agents.mdx @@ -18,7 +18,7 @@ This loop continues until the model stops calling tools, indicating it considers ## Backends -Every agent node uses a **backend** that determines how Fabro interacts with the LLM. There are two options: +Every agent and prompt node uses a **backend** that determines how Fabro interacts with the LLM. There are three options: ### API backend (default) @@ -31,7 +31,7 @@ Fabro manages the agent loop directly — it calls the LLM provider's API, execu ### CLI backend -Fabro delegates execution to an external coding assistant CLI. The CLI tool manages its own tool loop internally — Fabro sends the prompt, waits for the CLI to finish, and tracks file changes via `git diff` before and after execution. +Fabro delegates execution to a legacy external coding assistant CLI. The CLI tool manages its own tool loop internally — Fabro sends the prompt, waits for the CLI to finish, and tracks file changes via `git diff` before and after execution. The CLI is selected automatically based on the node's provider: @@ -52,15 +52,41 @@ implement [label="Implement", backend="cli"] * { backend: cli; } ``` +### ACP backend + +Fabro can also run Agent Client Protocol (ACP) stdio agents with `backend="acp"`. ACP agents run inside the active Fabro sandbox, so local and Docker runs keep the same workspace isolation, secret forwarding, cancellation, and file-change tracking behavior as other agent stages. + +Set ACP on a node with `backend="acp"`: + +```dot +implement [label="Implement", backend="acp", provider="openai"] +``` + +Fabro chooses a default ACP command from the provider: + +| Provider | Default ACP command | +|---|---| +| Anthropic | `npx -y @zed-industries/claude-code-acp@latest` | +| OpenAI and OpenAI-compatible providers | `npx -y @zed-industries/codex-acp@latest` | +| Gemini | `npx -y -- @google/gemini-cli@latest --experimental-acp` | + +Use `acp_command="..."` to point a node at a specific ACP stdio command: + +```dot +implement [label="Implement", backend="acp", acp_command="python3 tools/fake_acp_agent.py"] +``` + +ACP v1 does not have a portable model-selection request. Fabro records the selected provider and model in events and run projections, but model-specific ACP behavior must be encoded in the chosen command for now. ACP is supported with local and Docker sandboxes; Daytona does not expose bidirectional stdio yet, so ACP nodes fail there with an explicit unsupported-provider error. + ### Comparison -| Capability | API backend | CLI backend | -|---|---|---| -| Tools | Fabro built-in tools + MCP | CLI's own tool set | -| Session caching | Supported (`fidelity` + `thread_id`) | Not supported | -| Sub-agents | Supported | Not supported | -| Provider failover | Supported | Not supported | -| File tracking | Tool call events | `git diff` before/after | +| Capability | API backend | CLI backend | ACP backend | +|---|---|---|---| +| Tools | Fabro built-in tools + MCP | CLI's own tool set | ACP agent's own tool set | +| Session caching | Supported (`fidelity` + `thread_id`) | Not supported | Agent-dependent | +| Sub-agents | Supported | Not supported | Not supported through Fabro tools | +| Provider failover | Supported | Not supported | Not supported | +| File tracking | Tool call events | `git diff` before/after | `git diff` before/after | ### When to use the CLI backend @@ -68,6 +94,12 @@ implement [label="Implement", backend="cli"] - **CLI-only models** — use models that are only available through a CLI tool, not via API - **Existing workflows** — integrate a CLI tool you already depend on without rewriting its configuration +### When to use the ACP backend + +- **Protocol adapters** — run ACP-compatible coding agents through a stable stdio protocol +- **Sandbox parity** — keep agent process execution inside Fabro's local or Docker sandbox +- **Custom agents** — use `acp_command` for a checked-in or preinstalled ACP adapter + ## Tools Agents have access to a set of built-in tools for interacting with the codebase and environment: diff --git a/docs/public/reference/dot-language.mdx b/docs/public/reference/dot-language.mdx index 12436ec70..290acc74c 100644 --- a/docs/public/reference/dot-language.mdx +++ b/docs/public/reference/dot-language.mdx @@ -206,7 +206,8 @@ Start nodes can also be identified by ID (`start` or `Start`). Exit nodes can be | `model` | String | Explicit model ID (overrides stylesheet) | | `provider` | String | Explicit provider name (overrides stylesheet). Auto-inferred from the model catalog when omitted. | | `project_memory` | Boolean | When `true` (default), prompt nodes discover and include project docs (`AGENTS.md`, `CLAUDE.md`, etc.) as a system prompt. Set to `false` to disable. | -| `backend` | String | Agent execution backend. `api` (default): Fabro calls the LLM API directly and runs its own tool loop. `cli`: Fabro delegates to an external CLI tool (`claude`, `codex`, or `gemini` based on provider). See [Agents — Backends](/core-concepts/agents#backends). | +| `backend` | String | Agent execution backend: `api` (default), `cli`, or `acp`. `api` runs Fabro's tool loop through provider APIs; `cli` delegates to the legacy provider CLI; `acp` runs an Agent Client Protocol stdio agent inside the active sandbox. See [Agents — Backends](/core-concepts/agents#backends). | +| `acp_command` | String | Optional ACP stdio command override for nodes with `backend="acp"`. Defaults are selected from `provider`; model selection is recorded in Fabro but not sent through stable ACP v1. | ### Command nodes diff --git a/docs/public/tutorials/multi-model.mdx b/docs/public/tutorials/multi-model.mdx index 9f444ddcb..16567d597 100644 --- a/docs/public/tutorials/multi-model.mdx +++ b/docs/public/tutorials/multi-model.mdx @@ -88,7 +88,7 @@ Stylesheets support four properties: | `model` | Model ID or alias (e.g. `claude-sonnet-4-5`, `opus`, `gemini-pro`) | | `provider` | Provider name (optional — auto-inferred from the model catalog when omitted) | | `reasoning_effort` | `low`, `medium`, or `high` | -| `backend` | `api` (default) or `cli` | +| `backend` | `api` (default), `cli`, or `acp` | ## Why route models? diff --git a/docs/public/workflows/stylesheets.mdx b/docs/public/workflows/stylesheets.mdx index 6f171f92e..c1035b430 100644 --- a/docs/public/workflows/stylesheets.mdx +++ b/docs/public/workflows/stylesheets.mdx @@ -68,7 +68,7 @@ Stylesheets support four properties: | `provider` | Provider name (optional — auto-inferred from the model catalog when omitted) | `anthropic`, `openai`, `gemini` | | `reasoning_effort` | Reasoning effort level | `low`, `medium`, `high` | | `speed` | Output speed mode. `fast` enables Anthropic's fast mode for up to 2.5x faster output at higher cost. | `fast` | -| `backend` | Agent execution backend — `api` (default) runs Fabro's own tool loop, `cli` delegates to an external CLI tool. See [Backends](/core-concepts/agents#backends). | `cli`, `api` | +| `backend` | Agent execution backend — `api` (default) runs Fabro's own tool loop, `cli` delegates to a legacy external CLI tool, and `acp` runs an Agent Client Protocol stdio agent in the active sandbox. See [Backends](/core-concepts/agents#backends). | `api`, `cli`, `acp` | See [Models](/core-concepts/models) for the full list of model IDs and aliases.