From 062ba9ddfc375d540c799505df79cf5739e8060b Mon Sep 17 00:00:00 2001 From: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com> Date: Mon, 17 Aug 2026 08:16:14 +0800 Subject: [PATCH] feat: integrate MiniMax Code as a native ACP agent (#4846) * feat: integrate MiniMax Code as an ACP agent * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Willem Jiang Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- README.md | 17 +++++++++++++++ README_zh.md | 17 +++++++++++++++ backend/docs/CONFIGURATION.md | 12 ++++++++++- .../packages/harness/deerflow/tools/AGENTS.md | 2 ++ .../tools/builtins/invoke_acp_agent_tool.py | 7 ++++++- backend/tests/test_invoke_acp_agent_tool.py | 21 ++++++++++++++++++- config.example.yaml | 9 ++++++++ 7 files changed, 82 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6a4543e24..b19aaa34b 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,23 @@ That prompt is intended for coding agents. It tells the agent to clone the repo - Codex CLI reads `~/.codex/auth.json` - Claude Code accepts `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_CREDENTIALS_PATH`, or `~/.claude/.credentials.json` - ACP agent entries are separate from model providers — if you configure `acp_agents.codex`, point it at a Codex ACP adapter such as `npx -y @zed-industries/codex-acp` + - MiniMax Code speaks ACP directly. Install and authenticate it, then add it as an ACP agent: + + ```bash + npm install --global @minimax-ai/code + mcode login + ``` + + ```yaml + acp_agents: + mcode: + command: mcode + args: ["acp"] + description: MiniMax Code for implementation, refactoring, debugging, and repository tasks + auto_approve_permissions: false + ``` + + `mcode` must be on the Gateway process's `PATH`; installing it only on the Docker host does not make it available inside the Gateway container. DeerFlow invokes it through `invoke_acp_agent` in a per-thread ACP workspace and forwards enabled MCP servers. Keep `auto_approve_permissions: false` for untrusted tasks; enable it only when MCode must edit files or run commands and you trust the task. - On macOS, export Claude Code auth explicitly if needed: ```bash diff --git a/README_zh.md b/README_zh.md index 5f253b057..566c56ccd 100644 --- a/README_zh.md +++ b/README_zh.md @@ -196,6 +196,23 @@ DeerFlow 新近集成了 BytePlus 自研的智能搜索与抓取工具集——[ - Codex CLI 会读取 `~/.codex/auth.json` - Claude Code 支持 `CLAUDE_CODE_OAUTH_TOKEN`、`ANTHROPIC_AUTH_TOKEN`、`CLAUDE_CODE_CREDENTIALS_PATH`,或 `~/.claude/.credentials.json` - ACP agent 条目与 model provider 是分开配置的——如果你配置了 `acp_agents.codex`,请把它指向一个 Codex ACP 适配器,例如 `npx -y @zed-industries/codex-acp` + - MiniMax Code 原生支持 ACP,不需要额外适配器。先安装并登录,再把它配置成 ACP agent: + + ```bash + npm install --global @minimax-ai/code + mcode login + ``` + + ```yaml + acp_agents: + mcode: + command: mcode + args: ["acp"] + description: MiniMax Code for implementation, refactoring, debugging, and repository tasks + auto_approve_permissions: false + ``` + + `mcode` 必须位于 Gateway 进程的 `PATH` 中;只安装在 Docker host 上并不会让 Gateway 容器内可用。DeerFlow 会通过 `invoke_acp_agent` 在每个 thread 独立的 ACP workspace 中调用 MCode,并转发已启用的 MCP server。处理不可信任务时请保持 `auto_approve_permissions: false`;只有在任务可信且确实需要 MCode 修改文件或执行命令时才启用它。 - 在 macOS 上,如有需要可显式导出 Claude Code 的认证信息: ```bash diff --git a/backend/docs/CONFIGURATION.md b/backend/docs/CONFIGURATION.md index 4ad0f0268..761145e85 100644 --- a/backend/docs/CONFIGURATION.md +++ b/backend/docs/CONFIGURATION.md @@ -742,7 +742,7 @@ To keep this off the default attack surface: > for CLI auto-auth in **all** modes. These hold long-lived CLI credentials; > scope or omit them when the gateway runs untrusted workloads. -### CLI Credential Mounts (Claude Code / Codex) +### CLI Credential Mounts (Claude Code / Codex / MiniMax Code) DeerFlow can reuse your Claude Code / Codex CLI subscription login as a model provider (`ClaudeChatModel`, the Codex provider) or for ACP agents that run the @@ -771,6 +771,16 @@ adapter's documented env auth, and reach for the `docker-compose.cli-auth.yaml` overlay only as a fallback for an adapter that genuinely reads the full CLI config directory. +MiniMax Code is a native ACP agent, so it does not need an adapter. For local +Gateway runs, install it with `npm install --global @minimax-ai/code`, run +`mcode login`, and configure `acp_agents.mcode` with `command: mcode` and +`args: ["acp"]`. The executable and its authenticated runtime must be available +inside the Gateway environment; a host-only installation is not visible to a +Docker container. DeerFlow forwards enabled MCP servers to the MCode session. +Leave `auto_approve_permissions` disabled for untrusted tasks, and enable it +only when the agent is expected to edit files or run commands for a trusted +task. + ## Best Practices diff --git a/backend/packages/harness/deerflow/tools/AGENTS.md b/backend/packages/harness/deerflow/tools/AGENTS.md index 6c0df03dc..ad77e87b6 100644 --- a/backend/packages/harness/deerflow/tools/AGENTS.md +++ b/backend/packages/harness/deerflow/tools/AGENTS.md @@ -31,5 +31,7 @@ E2B output sync records remote file versions and actual host file metadata in a **ACP agent tools**: - `invoke_acp_agent` - Invokes external ACP-compatible agents from `config.yaml` - ACP launchers must be real ACP adapters. The standard `codex` CLI is not ACP-compatible by itself; configure a wrapper such as `npx -y @zed-industries/codex-acp` or an installed `codex-acp` binary +- MiniMax Code speaks ACP directly: configure `command: mcode` with `args: ["acp"]`. It receives DeerFlow's enabled MCP servers and uses the per-thread ACP workspace; the Gateway process must have an authenticated `mcode` executable on `PATH` +- ACP results collect only `agent_message_chunk` text. Thought chunks remain internal and must not be concatenated into the tool result - Missing ACP executables now return an actionable error message instead of a raw `[Errno 2]` - Each ACP agent uses a per-thread workspace at `{base_dir}/users/{user_id}/threads/{thread_id}/acp-workspace/`. The workspace is accessible to the lead agent via the virtual path `/mnt/acp-workspace/` (read-only). In docker sandbox mode, the directory is volume-mounted into the container at `/mnt/acp-workspace` (read-only); in local sandbox mode, path translation is handled by `tools.py` diff --git a/backend/packages/harness/deerflow/tools/builtins/invoke_acp_agent_tool.py b/backend/packages/harness/deerflow/tools/builtins/invoke_acp_agent_tool.py index 82f5fbe9e..4d464cece 100644 --- a/backend/packages/harness/deerflow/tools/builtins/invoke_acp_agent_tool.py +++ b/backend/packages/harness/deerflow/tools/builtins/invoke_acp_agent_tool.py @@ -134,6 +134,11 @@ def _format_invocation_error(agent: str, cmd: str, exc: Exception) -> str: if cmd == "codex-acp" and shutil.which("codex"): return f"{message} The installed `codex` CLI does not speak ACP directly. Install a Codex ACP adapter (for example `npx @zed-industries/codex-acp`) or update `acp_agents.codex.command` and `args` in config.yaml." + if agent == "mcode": + return ( + f"{message} Install it with `npm install --global @minimax-ai/code`, run `mcode login`, and restart DeerFlow so it inherits the updated PATH. " + "If the Gateway runs in Docker, ensure `mcode` is installed and authenticated inside the Gateway container/image." + ) return f"{message} Install the agent binary or update `acp_agents.{agent}.command` in config.yaml." @@ -193,7 +198,7 @@ def build_invoke_acp_agent_tool(agents: dict) -> BaseTool: try: from acp.schema import TextContentBlock - if hasattr(update, "content") and isinstance(update.content, TextContentBlock): + if getattr(update, "session_update", None) == "agent_message_chunk" and isinstance(update.content, TextContentBlock): self._chunks.append(update.content.text) except Exception: pass diff --git a/backend/tests/test_invoke_acp_agent_tool.py b/backend/tests/test_invoke_acp_agent_tool.py index 3efbd79ac..186e7b339 100644 --- a/backend/tests/test_invoke_acp_agent_tool.py +++ b/backend/tests/test_invoke_acp_agent_tool.py @@ -14,6 +14,7 @@ from deerflow.tools.builtins.invoke_acp_agent_tool import ( _build_acp_mcp_servers, _build_mcp_servers, _build_permission_response, + _format_invocation_error, _get_work_dir, build_invoke_acp_agent_tool, ) @@ -122,6 +123,14 @@ def test_build_permission_response_denies_when_auto_approve_false(): assert response.outcome.outcome == "cancelled" +def test_missing_mcode_command_returns_install_and_login_guidance(): + result = _format_invocation_error("mcode", "mcode", FileNotFoundError()) + + assert "npm install --global @minimax-ai/code" in result + assert "mcode login" in result + assert "restart DeerFlow" in result + + @pytest.mark.anyio async def test_build_invoke_tool_description_and_unknown_agent_error(): tool = build_invoke_acp_agent_tool( @@ -223,7 +232,17 @@ async def test_invoke_acp_agent_uses_fixed_acp_workspace(monkeypatch, tmp_path): client = captured["client"] await client.session_update( "session-1", - SimpleNamespace(content=text_content_block("ACP result")), + SimpleNamespace( + session_update="agent_thought_chunk", + content=text_content_block("internal reasoning"), + ), + ) + await client.session_update( + "session-1", + SimpleNamespace( + session_update="agent_message_chunk", + content=text_content_block("ACP result"), + ), ) class DummyProcessContext: diff --git a/config.example.yaml b/config.example.yaml index 92802160d..7533fda37 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -1494,6 +1494,15 @@ sandbox: # Configure external ACP-compatible agents for the built-in `invoke_acp_agent` tool. # acp_agents: +# mcode: +# # MiniMax Code speaks ACP directly; no adapter package is required. +# # Install with `npm install --global @minimax-ai/code`, then run `mcode login`. +# command: mcode +# args: ["acp"] +# description: MiniMax Code for implementation, refactoring, debugging, and repository tasks +# # auto_approve_permissions: false # Enable only for trusted tasks that need MCode to edit files or run commands +# # timeout_seconds: 1800 # Abort + kill the subprocess if it doesn't respond in time (default: 1800 = 30 min) +# # claude_code: # # DeerFlow expects an ACP adapter here. The standard `claude` CLI does not # # speak ACP directly. Install `claude-agent-acp` separately or use: