Skip to content

RFC: ACP Tool-First MVP via invoke_acp_agent #1302

@hetaoBackend

Description

@hetaoBackend

Summary

This RFC proposes a Tool-first ACP integration for DeerFlow:

  • DeerFlow adds a single built-in tool: invoke_acp_agent
  • The MVP does not add ACP subagent support
  • The MVP does not add one-tool-per-agent dynamic named tools

This RFC is the narrowed follow-up to the discussion in #1296. Its purpose is to make the MVP scope explicit and implementation-oriented.


Motivation

DeerFlow currently cannot invoke external ACP-compatible agents such as:

  • Claude Code
  • Codex CLI
  • Gemini CLI
  • OpenCode

ACP support would let DeerFlow delegate specialized coding or repository tasks to these agents without building provider-specific adapters.

The main product need for the MVP is simple:

Let the lead agent call an external ACP agent for one-shot work.

That does not require introducing a new subagent executor yet.


Decision

This RFC makes the following MVP decisions:

  1. Implement Option B only: a built-in invoke_acp_agent tool
  2. Do not implement ACP subagent mode in the MVP
  3. Do not implement dynamic named tools in the MVP

Rationale:

  • ACP agents are interface-homogeneous: prompt -> response
  • DeerFlow already has a natural tool assembly path
  • A single tool is the smallest useful surface area
  • Most expected initial use cases are one-shot coding tasks, not background multi-agent orchestration
  • Streaming progress, cancellation, and concurrency are useful, but they are not required for the first ACP milestone

Proposed MVP

Built-in Tool

DeerFlow exposes one built-in tool:

@tool
async def invoke_acp_agent(
    agent: str,
    prompt: str,
    cwd: str | None = None,
) -> str:
    """Invoke an external ACP-compatible agent and return its final response."""
    ...

Runtime Configuration

ACP agents are configured at runtime.

Example shape:

acp_agents:
  claude_code:
    command: claude-code-acp
    args: []
    description: Claude Code for implementation, refactoring, and debugging
    model: null

  codex:
    command: codex-acp
    args: []
    description: Codex CLI for repository tasks and code generation
    model: null

Tool Description

The tool description should be generated dynamically from configured ACP agents.

Example:

Invoke an external ACP-compatible agent.

Available agents:
- claude_code: Claude Code for implementation, refactoring, and debugging
- codex: Codex CLI for repository tasks and code generation

Important:

  • The available agent list must come from config at runtime
  • Do not hardcode a static Python Literal[...] for agent names

Execution Model

What the MVP Does

  • Launch an ACP-compatible agent via stdio subprocess
  • Pass the DeerFlow thread workspace as default cwd
  • Translate DeerFlow virtual paths to physical sandbox paths before session launch
  • Optionally inject MCP configuration into the ACP session
  • Return the ACP agent's final text result to DeerFlow

What the MVP Does Not Do

  • No ACP task / subagent integration
  • No task_running SSE progress streaming
  • No background lifecycle management for ACP tasks
  • No cancellation API
  • No per-agent named tools such as claude_code(...) or codex(...)

Why Not ACP Subagent First

ACP subagent mode is valuable, but it solves a different class of problems:

  • long-running background execution
  • streaming progress events
  • cancellation and lifecycle control
  • parallel orchestration under DeerFlow's task model

Those are not necessary to validate ACP integration itself.

Starting with a tool gives DeerFlow:

  • smaller implementation scope
  • lower architectural risk
  • faster validation of real user demand

If later product requirements show that streaming/background execution is essential, DeerFlow can add ACP subagent support in a separate RFC.


Why Not Dynamic Named Tools First

Generating one tool per ACP agent is possible, but not the right MVP tradeoff.

Example of the rejected approach:

  • claude_code(...)
  • codex(...)
  • gemini(...)

Reasons to defer:

  • ACP agents share one invocation schema
  • one generic tool is easier to maintain as config changes
  • named tools mainly help UI/tool-picker presentation, not backend capability

This can be revisited later if the product needs separate agent-specific tool exposure.


Implementation Plan

Phase 1 — Core ACP Tool MVP

  • Add ACP dependency as an optional extra
  • Add ACP agent config schema and loader
  • Implement ACP client wrapper
  • Implement built-in invoke_acp_agent
  • Dynamically generate tool description from configured ACP agents
  • Register the tool in DeerFlow tool assembly when ACP agents are configured
  • Pass thread workspace as default cwd
  • Translate DeerFlow sandbox virtual paths to physical paths

Phase 2 — MCP Forwarding

  • Forward DeerFlow MCP server config into ACP session config
  • Map DeerFlow MCP config into ACP mcpServers format

Phase 3 — Config API / UI

  • API support for managing ACP agent configuration
  • UI support for managing ACP agent configuration

Future RFC — ACP Subagent Mode

  • type: acp subagent config
  • ACPSubagentExecutor
  • SSE progress forwarding
  • lifecycle / timeout / cancellation support

Open Questions

  1. Should ACP be an optional dependency or a default dependency?
  2. What permission model should DeerFlow apply for ACP terminal/file operations?
  3. Should MCP forwarding be automatic by default?
  4. What concrete product requirement should trigger a follow-up ACP subagent RFC?

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRequest for comments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions