
如何把任意 stdio ACP 服务器以 Custom 预设接入 OpenHands Agent Canvas【免费下载链接】OpenHands OpenHands: AI-Driven Development项目地址: https://gitcode.com/GitHub_Trending/ope/OpenHands如果你的 ACPAgent Client Protocol服务器不是 OpenHands 内置的三个预设Claude Code、Codex、Gemini CLI而是自己维护或第三方发布的 stdio ACP 服务器仍然可以让 Agent Canvas 驱动它在Settings → Agent中选择Custom预设填入启动命令通过 Secrets 面板提供凭据保存后新对话就会改用你的服务器。整个过程不需要改 Canvas 代码也不涉及新增 provider 注册——内置 provider 列表由上游 SDK 维护Custom 预设就是为「预设之外的一切」留的口子见 docs/ACP_AGENTS.md。Custom 预设的工作方式Agent Canvas 不直接调用 LLM。选择 ACP 后Agent Server 会在它运行的机器上把你填的命令作为子进程启动通过 stdio 上的 JSON-RPC 逐回合中转对话docs/ACP_AGENTS.mdAgent CanvasUI → Agent Server保存 agent_kind / acp_* 设置 → 你的 ACP 服务器子进程stdio JSON-RPC → 服务器自己的 LLM / 工具 / 执行外部服务器自管自己的 LLM、工具和执行Canvas 只负责发消息、渲染返回。与内置预设相比Custom 预设有两个直接后果docs/ACP_AGENTS.md没有整理好的模型列表——需要在 Model 字段手动填服务器期望的 model ID如果它需要没有 onboarding 凭据表单——设置页面只对内置 provider 显示凭据区块Custom 的凭据一律走Settings → Secrets的全局 secret。前提条件一套可用的 Agent Canvas 且能连通一个运行中的 Agent Server。agent 选择的存储是per backend的切换 backend 可能换 agent所以确认你配置的是目标 backend。你的 ACP 服务器命令必须能在 Agent Server 运行的机器上执行——因为子进程由 Agent Server 拉起而不是由浏览器拉起。本地或 self-hosted backend 就是你自己这台机器容器化 backend 则是容器内见文末边界说明。命令指向的是一个真实的 ACP 协议 stdio 服务器这一点在排查章节里有具体的失败现象。第一步进入 Settings → Agent切到 ACP 并选 Custom打开Settings → Agent。在Agent下拉中从 OpenHands 切到ACP。若命令框为空界面会预填第一个内置 provider 的默认命令这只是占位下一步会被清空。在Preset下拉中选择Custom。选择 Custom 时界面会清空 Command 和 Model 两个字段src/routes/agent-settings.tsx 中 preset 切换逻辑——目的是防止上一个 provider 的默认命令或模型例如claude-opus-4-7被误存到无关的 wrapper 上。一个容易忽略的行为预设是按命令文本自动检测的。如果你把命令逐字改成某个内置 provider 的默认命令例如npx -y agentclientprotocol/claude-agent-acp下拉框会自动跳回对应 provider 而不是停在 Custom。反过来只要命令与三个内置默认命令不完全相等检测结果就是 Custom无需手动干预。第二步填写启动命令与模型Command输入用于拉起 ACP 子进程的完整命令行。输入框的占位符格式为npx -y package-name把package-name替换为你服务器的实际包名或换成任意可执行入口如python -m my_acp_server。这个命令是 Agent Server 侧执行的API key 不写在这里——页面提示原文是 “API keys go through the Secrets panel”src/routes/agent-settings.tsx。命令为空时 Save 按钮保持禁用。ModelCustom 预设没有建议模型下拉界面直接显示一个可选的模型输入框。文档原文是 “enter the model ID the server expects (if any) as a custom model”docs/ACP_AGENTS.md——如果你的服务器接受 model 覆盖就填它期望的 ID否则留空即可让服务器自选。第三步通过 Secrets 面板提供凭据Custom 服务器需要鉴权时把它读取的环境变量逐条添加为全局 secret位置是Settings → Secretsdocs/ACP_AGENTS.mdsecret 名必须与 Agent Server 导出给子进程的环境变量名完全一致例如ANTHROPIC_API_KEY。正是「secret 名 环境变量名」这一点让保存的密钥真正到达 ACP 子进程。变量名需符合 secret 命名规则^[a-zA-Z][a-zA-Z0-9_]{0,63}$src/constants/acp-providers.ts。保存后随时可在 Secrets 面板编辑或删除。注意方向Canvas 只负责保存和引用 secretAgent Server 在 spawn 子进程时把值导出为环境变量如果你的服务器支持某种已登录凭据的复用那也是服务器 CLI 自己的行为Canvas 不参与。保存时会写入什么点击Save changes后Canvas 向PATCH /api/settings提交agent_settings_diffCustom 场景下的字段为docs/ACP_AGENTS.md、src/constants/acp-providers.ts字段值agent_kindacpacp_servercustom预设哨兵键acp_command你填写的命令按 token 拆分后的数组acp_args[]显式重置避免旧参数在 spawn 时与命令拼接acp_model你填写的模型 ID留空时为null验证与已知失败现象保存成功会弹出 “Saved” 提示。真正生效的验证方式是新开一个对话文档明确说明正在进行的对话保留它启动时的 agent新选择只作用于之后开始的对话docs/ACP_AGENTS.md。在侧边栏为 Custom 对话显示的标识是通用 ACP 图标加你填的模型 ID——Custom 没有品牌名可显示src/constants/acp-providers.ts。如果对话挂起、没有任何回合响应优先检查命令本身。文档给出了一个具体反例src/constants/acp-providers.ts 中的注释npx -y openai/codex acp看起来很合理但它不是ACP 服务器——codex CLI 没有acp子命令在没有 TTY 的 spawn 环境下会以Error: stdin is not a terminal退出静默地卡死 agent-server 的 ACP 握手正确做法是使用对应的 ACP wrapper如agentclientprotocol/codex-acp同理你的自定义服务器也必须真正实现 ACP stdio 协议。边界说明容器化 backend以上路径针对 Agent Server 直接跑在宿主机/VM 上的场景self-hosting 方式见 docs/SELF_HOSTING.md。如果 Agent Server 跑在容器里有两点不同docs/ACP_AGENTS.md、examples/acp-docker/README.md容器内没有宿主机的登录态和依赖凭据必须通过 UI 提供仓库提供的现成镜像ghcr.io/openhands/agent-server:1.28.0-python起该版本是文档标注的当前 Canvas 兼容的最低镜像只预装了三个内置 ACP wrapperSDK 会把npx -y pkg改写为容器内对应的预装二进制。你的自定义包不在预装之列需要自行保证它在容器内可用——文档没有给出为自定义包装容器的现成步骤这一点属于当前示例的覆盖边界。容器场景的版本钉选建议沿用 examples/acp-docker/README.md 中的npm run example:acp-docker:env从config/defaults.json生成.env避免手工.env把镜像版本钉在compatibility.minimumAgentServer之下。完成保存并在新对话中确认你的 ACP 服务器接管回合后这条 Custom 配置就固定在该 backend 上了之后想换回内置预设或改命令回到Settings → Agent重走一遍即可。【免费下载链接】OpenHands OpenHands: AI-Driven Development项目地址: https://gitcode.com/GitHub_Trending/ope/OpenHands创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考