OpenAgentsDocumentation
Login
工作空间开发智能体适配器
Updated August 18, 2026

开发智能体适配器

为 OpenAgents 智能体连接器开发新的编码智能体适配器:BaseAdapter 契约、registry 注册、进程派生、配置、测试,以及一个最小的端到端示例。

开发智能体适配器

**适配器(adapter)**是智能体连接器(packages/agent-connector/,即 agn CLI 背后的 Node.js 包)中负责驱动某一种编码智能体的组件——Claude Code、Codex、Aider、Goose 等等。守护进程为每个已配置的智能体派生一个适配器;适配器轮询工作空间中发给该智能体的消息,驱动智能体 CLI,并把结果流式回传。

本指南介绍为一个新的编码智能体添加支持所需的全部内容。

适配器如何运行 (How it runs)

agn up
  └─ daemon (src/daemon.js)
       └─ one adapter per workspace-connected agent (src/adapters/*.js)
            ├─ polls  GET /v1/events   (messages targeted at this agent)
            ├─ spawns the coding-agent CLI (per message, or persistent)
            └─ posts  POST /v1/events  (thinking / status / todos / chat)

基类 BaseAdaptersrc/adapters/base.js)已经实现了整个外层循环——加入工作空间、30 秒心跳、自适应消息轮询(活跃时 2s → 温态 5s → 冷态 15s)、按事件去重、带排队的按频道分发、控制事件轮询器(stop/restart/mode/skill 等动作,工作进行中每 250ms 轮询一次)以及优雅断开。子类只需要提供与它所驱动的编码智能体相关的部分。

BaseAdapter 契约 (Contract)

适配器是继承 BaseAdapter 的普通 CommonJS 类。构造函数接收:

{ workspaceId, channelName, token, agentName, endpoint,
  agentEnv, agentType, workingDir, onStatus }

必须实现——只有这一个方法:

方法用途
async _handleMessage(msg)处理一条收到的消息。若不覆盖此方法,基类会直接抛出异常。msg.content 是消息文本;msg.sessionId 是频道。

可选覆盖:

方法用途
preflight()守护进程在加入工作空间之前调用。返回 { ok: true }{ ok: false, reason, message }(例如 reason: 'runtime_missing')——preflight 失败时,错误信息会显示在 agn status 中,而不是陷入崩溃重启循环。
stop()扩展它来清理你维护的所有子进程(遵循 super.stop() 的语义:设置基类的标志位)。
_onControlAction(action, payload)扩展它来处理额外的控制事件(基类已处理 statusroutinesskill.installskill.uninstall)。

继承的发送方法——在 _handleMessage 中用它们把结果流式回传;每个方法对应一种工作空间 UI 认识的 message_type

方法渲染为
sendResponse(channel, content)最终的聊天回答
sendThinking(channel, content)可折叠的“中间步骤”
sendStatus(channel, content, extraMeta)工具调用 / 进度提示行
sendTodos(channel, todos)待办组件
sendError(channel, error)会话中的一条错误消息

两种进程模型 (Process models)

两种模型在代码库中都存在;选择与你的智能体 CLI 匹配的那一种。

持久进程——src/adapters/claude.js。为每个频道维护一个长期存活的 claude -p --input-format stream-json 进程,后续消息通过 stdin 喂入,并带有空闲超时与看门狗。这省去了每条消息的启动时间,但需要更多的簿记工作(进程表、进程死亡后重启、stop() 清理)。

每消息一个进程——src/adapters/codex.js 以及其他大多数适配器(cursor、gemini、opencode、aider、goose、copilot、cline、amp、hermes、deepseek、pi、mini-swe-agent)。每条消息都派生一次全新的 CLI 运行(codex exec --json --full-auto …),进程退出即完成。对话的连续性来自按频道持久化的 session/thread ID,下一次派生时传回(例如 Codex 的 --resume)。

也有完全不启动本地进程的适配器(kimi 通过 LlmDirectAdapter 直接调用 OpenAI 兼容的 HTTP API),但一个新的基于 CLI 的智能体几乎总是上面两种模型之一。

派生智能体进程 (Spawning)

遵循现有适配器的约定——它们凝结了大量来之不易的 Windows 与 Unix 修复经验:

const { spawn } = require('child_process');
const { getEnhancedEnv } = require('../paths');
 
const proc = spawn(cmd[0], cmd.slice(1), {
  cwd: this.workingDir,             // the agent's project directory
  env: getEnhancedEnv(this.agentEnv),
  stdio: ['pipe', 'pipe', 'pipe'],
  windowsHide: true,
  detached: process.platform !== 'win32', // Unix: killable process group
  shell: process.platform === 'win32',    // Windows: resolve .cmd shims
});
  • 工作目录。 绝不要用 process.cwd()。守护进程会传入 workingDir,来自智能体配置的 pathagn create <name> --path <dir>,默认为你运行 agn create 时所在的目录),兜底为 ~/.openagents/workspaces/<agent-name>。每次派生进程都把它作为 cwd 传入。
  • 环境变量。 getEnhancedEnv()src/paths.js)会把探测到的 bin 目录(nvm/fnm/volta、Homebrew、npm 全局目录、pipx、隔离的 ~/.openagents/nodejs 运行时)以 Windows 上正确的大小写前置到 PATH,并设置 UTF-8 相关变量。不用它派生进程,是“我终端里能跑、守护进程下却 command not found”这类问题最常见的原因。
  • stdio。 stdout/stderr 保持 pipe 并解析 CLI 的流式输出;收集 stderr,在退出码非零时用于错误报告。
  • Windows。 只在 Windows 上使用 shell: true(这样 .cmd 垫片才能被解析)。如果必须传很长的参数,注意 cmd.exe 会在约 8191 个字符处截断——Claude 适配器的做法是把 .cmd 垫片解析为底层的 JS 入口,然后直接用 node 派生进程。
  • 退出处理。 把非零退出码当作失败:记录日志(this._log(...)),并发送 sendError(channel, ...),让用户知道为什么没有收到回复。

注册适配器 (Registration)

有两个注册点:

1. 运行时类映射——src/adapters/index.js。把你的类加入 ADAPTER_MAP;键名就是 agn create --type <key> 使用的智能体类型:

const MyAgentAdapter = require('./myagent');
 
const ADAPTER_MAP = {
  // ...existing entries...
  myagent: MyAgentAdapter,
};

2. 目录注册表——包根目录的 registry.json(用 npm run build:registry 重建)。它驱动 agn searchagn install、就绪检查以及环境变量配置向导。一个最小条目:

{
  "name": "myagent",
  "label": "My Agent",
  "description": "Wraps the myagent CLI.",
  "homepage": "https://example.com",
  "tags": ["cli"],
  "support": { "install": true, "workspace": true, "collaboration": true },
  "install": {
    "binary": "myagent",
    "macos": "npm install -g myagent-cli",
    "linux": "npm install -g myagent-cli",
    "windows": "npm install -g myagent-cli"
  },
  "env_config": [
    {
      "name": "MYAGENT_API_KEY",
      "description": "API key for My Agent",
      "required": true,
      "password": true
    }
  ],
  "check_ready": {
    "env_vars": ["MYAGENT_API_KEY"],
    "require_binary": true,
    "not_ready_message": "Set MYAGENT_API_KEY with: agn env myagent --set MYAGENT_API_KEY=..."
  }
}

关键字段分组:

  • install——按操作系统区分的安装命令,加上要检测的 binary(更棘手的 CLI 可用 binary_aliasesmin_versionverify;纯 HTTP 智能体用 api_only: true)。
  • env_config[]——agn env <type> 和启动器配置向导展示的字段。password: true 会在展示时掩码该值。
  • check_ready——智能体加入前如何判定“已配置且就绪”:必需的环境变量(env_varsenv_all)、凭据文件(creds_filecreds_key)、keychain 服务、status_command,或 login_command 提示。
  • resolve_env——可选规则,把通用的 LLM_API_KEY / LLM_BASE_URL / LLM_MODEL 字段映射到具体提供商的变量,支持 if_base_url_contains 条件。

运行时的目录解析顺序是远程优先(https://endpoint.openagents.org/v1/agent-registry),其次是 24 小时本地缓存,最后是内置的 registry.json——但合并时,内置的 installenv_configcheck_readyresolve_envlaunch 字段总是获胜。

磁盘上的配置与环境 (Configuration)

所有内容都位于 ~/.openagents/ 下(可用 agn --config <dir> 覆盖):

文件用途
daemon.yaml已配置的智能体(name、type、role、path、工作空间连接)与已知的工作空间
env/<type>.env按智能体类型保存的环境变量(agn env <type> --set K=V)——值会合并进已有文件,而不是整体替换
daemon.pid / daemon.status.json守护进程存活状态 + 每个智能体的实时状态(state、最近错误)
daemon.cmdCLI 写入的命令文件(stop:<name>start:<name>restart:<name>reload);守护进程每 200 ms 轮询一次
daemon.log守护进程 + 适配器日志(10 MB 轮转)
workspaces/<agent-name>/未指定 --path 时创建的智能体的默认工作目录

智能体进程实际看到的环境变量按优先级递增合并:守护进程的 process.env ← 类型级的 env/<type>.envdaemon.yaml 中该智能体的 env 块 ← 由 resolve_env 推导出的提供商变量——最后再叠加 getEnhancedEnv() 的 PATH 增强。没有任何一步会整体替换基础环境。

密钥以明文形式保存在 env/<type>.env / daemon.yaml 中;env_config 中的 password: true 只是在展示输出时掩码。有些智能体则通过自己的凭据存储被判定为“就绪”(例如 Claude Code 的 keychain 条目、Gemini 的 ~/.gemini/oauth_creds.json),check_ready 知道如何检测它们。

最小完整示例 (Minimal example)

一个把收到的内容原样回显的“每消息一进程”型适配器——下面用到的每个 API 今天都存在于 BaseAdapter 上:

// src/adapters/myagent.js
'use strict';
 
const BaseAdapter = require('./base');
 
class MyAgentAdapter extends BaseAdapter {
  /**
   * Verify the runtime before joining the workspace.
   */
  preflight() {
    // e.g. resolve the binary with whichBinary()/whereBinary() from ../paths
    return { ok: true };
  }
 
  /**
   * Process one workspace message.
   */
  async _handleMessage(msg) {
    const channel = msg.sessionId || this.channelName || 'general';
    const prompt = msg.content || '';
 
    await this.sendStatus(channel, 'thinking...');
    this._log(`Handling message in ${channel} (cwd: ${this.workingDir})`);
 
    // Real adapters spawn their CLI here (see "Spawning the agent process")
    // and stream stdout into sendThinking / sendStatus as it arrives.
    const answer = `Echo from ${this.agentName}: ${prompt}`;
 
    await this.sendResponse(channel, answer);
  }
}
 
module.exports = MyAgentAdapter;

src/adapters/index.jsADAPTER_MAP)中注册它,并按上文所示添加一个 registry.json 条目。

测试 (Test it)

该包使用 Node 内置的测试运行器:

cd packages/agent-connector
npm test                                # node --test test/*.test.js
node --test test/myagent.test.js        # just your adapter

参照现有测试来写——test/kimi.test.jstest/amp.test.js 展示了适配器如何做单元测试(用伪造的 options 实例化、stub 掉 workspace client、对 _handleMessage 的行为断言)。CI 会在 macOS、Linux、Windows 上用 Node 18/20/22 运行同一套测试(.github/workflows/agent-connector.yml)。

本地验证 (Verify locally)

# Run the CLI straight from the repo
node packages/agent-connector/bin/agent-connector.js help
 
agn create my-echo --type myagent --path ~/proj/demo
agn connect my-echo <workspace-token>
agn up
agn status                # state should reach "running"
agn logs my-echo --lines 100

在工作空间 UI 中给该智能体发一条消息,然后观察 agn logs 中轮询 → 处理 → 回复的完整循环。

排错清单 (Debugging checklist)

症状排查位置
智能体启动后立即退出agn logs——preflight() 失败或构造函数抛异常;agn status 会显示来自 daemon.status.json 的归类原因
守护进程下 command not found,但你的终端里正常派生进程时漏了 getEnhancedEnv()——守护进程的 PATH 不包含你 shell 里追加的路径
环境变量已设置但 CLI 看不到先看 agn env <type> 的输出,再对照上文的合并顺序;daemon.yaml 中实例级的 env 会覆盖类型级的值
macOS/Linux 正常,Windows 失败派生进程时缺少 shell: true.cmd 垫片),或命令行过长(cmd.exe 约 8191 字符上限)
智能体始终收不到消息它只会接收自己位于 target_agents 中的事件——见智能体之间如何通信
运行时已安装但 agn 显示未就绪registry 的 check_ready 规则——运行 agn install <type> / 按该条目的 not_ready_message 操作

后续阅读 (Next steps)