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 <willem.jiang@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
DanielWalnut 2026-08-17 08:16:14 +08:00 committed by GitHub
parent a181c3398b
commit 062ba9ddfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 82 additions and 3 deletions

View File

@ -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` - Codex CLI reads `~/.codex/auth.json`
- Claude Code accepts `CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_CREDENTIALS_PATH`, or `~/.claude/.credentials.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` - 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: - On macOS, export Claude Code auth explicitly if needed:
```bash ```bash

View File

@ -196,6 +196,23 @@ DeerFlow 新近集成了 BytePlus 自研的智能搜索与抓取工具集——[
- Codex CLI 会读取 `~/.codex/auth.json` - Codex CLI 会读取 `~/.codex/auth.json`
- Claude Code 支持 `CLAUDE_CODE_OAUTH_TOKEN``ANTHROPIC_AUTH_TOKEN``CLAUDE_CODE_CREDENTIALS_PATH`,或 `~/.claude/.credentials.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` - 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 的认证信息: - 在 macOS 上,如有需要可显式导出 Claude Code 的认证信息:
```bash ```bash

View File

@ -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; > for CLI auto-auth in **all** modes. These hold long-lived CLI credentials;
> scope or omit them when the gateway runs untrusted workloads. > 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 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 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 `docker-compose.cli-auth.yaml` overlay only as a fallback for an adapter that
genuinely reads the full CLI config directory. 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 ## Best Practices

View File

@ -31,5 +31,7 @@ E2B output sync records remote file versions and actual host file metadata in a
**ACP agent tools**: **ACP agent tools**:
- `invoke_acp_agent` - Invokes external ACP-compatible agents from `config.yaml` - `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 - 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]` - 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` - 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`

View File

@ -134,6 +134,11 @@ def _format_invocation_error(agent: str, cmd: str, exc: Exception) -> str:
if cmd == "codex-acp" and shutil.which("codex"): 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." 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." 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: try:
from acp.schema import TextContentBlock 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) self._chunks.append(update.content.text)
except Exception: except Exception:
pass pass

View File

@ -14,6 +14,7 @@ from deerflow.tools.builtins.invoke_acp_agent_tool import (
_build_acp_mcp_servers, _build_acp_mcp_servers,
_build_mcp_servers, _build_mcp_servers,
_build_permission_response, _build_permission_response,
_format_invocation_error,
_get_work_dir, _get_work_dir,
build_invoke_acp_agent_tool, build_invoke_acp_agent_tool,
) )
@ -122,6 +123,14 @@ def test_build_permission_response_denies_when_auto_approve_false():
assert response.outcome.outcome == "cancelled" 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 @pytest.mark.anyio
async def test_build_invoke_tool_description_and_unknown_agent_error(): async def test_build_invoke_tool_description_and_unknown_agent_error():
tool = build_invoke_acp_agent_tool( 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"] client = captured["client"]
await client.session_update( await client.session_update(
"session-1", "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: class DummyProcessContext:

View File

@ -1494,6 +1494,15 @@ sandbox:
# Configure external ACP-compatible agents for the built-in `invoke_acp_agent` tool. # Configure external ACP-compatible agents for the built-in `invoke_acp_agent` tool.
# acp_agents: # 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: # claude_code:
# # DeerFlow expects an ACP adapter here. The standard `claude` CLI does not # # DeerFlow expects an ACP adapter here. The standard `claude` CLI does not
# # speak ACP directly. Install `claude-agent-acp` separately or use: # # speak ACP directly. Install `claude-agent-acp` separately or use: