nexus-agentd 0.1.1 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +376 -185
  3. package/dist/a2a/runtime.d.ts +32 -0
  4. package/dist/a2a/runtime.js +382 -0
  5. package/dist/acp/runtime.d.ts +14 -3
  6. package/dist/acp/runtime.js +256 -17
  7. package/dist/agent-instructions.d.ts +11 -0
  8. package/dist/agent-instructions.js +44 -0
  9. package/dist/artifact-store.d.ts +41 -0
  10. package/dist/artifact-store.js +340 -0
  11. package/dist/auth.d.ts +13 -0
  12. package/dist/auth.js +77 -0
  13. package/dist/cli.js +58 -1
  14. package/dist/config.d.ts +10 -0
  15. package/dist/config.js +284 -53
  16. package/dist/control-plane.d.ts +92 -0
  17. package/dist/control-plane.js +646 -0
  18. package/dist/drivers/hermes.d.ts +2 -0
  19. package/dist/drivers/hermes.js +10 -0
  20. package/dist/drivers/index.js +6 -0
  21. package/dist/events.js +13 -2
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +15 -3
  24. package/dist/run-store.d.ts +49 -0
  25. package/dist/run-store.js +291 -0
  26. package/dist/server.d.ts +3 -2
  27. package/dist/server.js +913 -41
  28. package/dist/session-contract.d.ts +16 -4
  29. package/dist/session.d.ts +74 -8
  30. package/dist/session.js +433 -38
  31. package/dist/types.d.ts +204 -6
  32. package/dist/types.js +2 -1
  33. package/dist/webui/app.d.ts +1 -0
  34. package/dist/webui/app.js +1074 -0
  35. package/dist/webui/icons.d.ts +9 -0
  36. package/dist/webui/icons.js +10 -0
  37. package/dist/webui/index.d.ts +3 -0
  38. package/dist/webui/index.js +32 -0
  39. package/dist/webui/markup.d.ts +1 -0
  40. package/dist/webui/markup.js +68 -0
  41. package/dist/webui/styles.d.ts +1 -0
  42. package/dist/webui/styles.js +269 -0
  43. package/dist/workspace-files.d.ts +48 -0
  44. package/dist/workspace-files.js +269 -0
  45. package/nexus-agentd.example.json +31 -27
  46. package/package.json +6 -6
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lumia1998
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md CHANGED
@@ -1,39 +1,202 @@
1
- # nexus-agentd
1
+ # Agent Nexus Gateway
2
2
 
3
- `nexus-agentd` 运行在 Coding Agent 所在机器,通过 Bearer Token 保护的 HTTP/SSE Gateway
4
- 向 AgentNexus 暴露本机白名单 Agent。当前支持 OpenCode、Claude Code、Codex、Pi 和
5
- OpenClaw ACP Driver;Hermes 使用其原生 A2A Server,不经过 agentd。
3
+ [![CI](https://github.com/lumia1998/nexus-gateway/actions/workflows/ci.yml/badge.svg)](https://github.com/lumia1998/nexus-gateway/actions/workflows/ci.yml)
6
4
 
7
- 当前部署目标是 Linux/Unix Agent 主机。
5
+ `nexus-agentd` Agent Nexus 的本地 Gateway。它在一台机器上统一管理 ACP 进程和远程 A2A
6
+ Agent,并向 Koishi AgentNexus 或其他客户端提供 HTTP/SSE API。管理控制台使用 **Agent Nexus**
7
+ 品牌,不依赖 CDN、前端框架或父仓库。
8
8
 
9
- ```text
10
- AgentNexus
11
- │ HTTP/SSE
12
-
13
- nexus-agentd
14
- │ ACP stdio
15
-
16
- OpenCode / Claude Code / Codex / Pi / OpenClaw
17
- ```
9
+ 如果你从 Koishi 使用 Gateway,请先阅读配套插件的
10
+ [安装与配置说明](https://github.com/lumia1998/koishi-plugin-agent-nexus#readme)。
18
11
 
19
- ## 安装与启动
12
+ ## 快速开始
20
13
 
21
- 推荐直接在 AgentNexus **Computer** 页点击 **部署 ACP 网关**。AgentNexus 会通过 SSH
22
- install-only 安装本包和缺失 Adapter,生成 Token/配置/systemd,并自动注册 Gateway 与逻辑
23
- Agent,不需要手动导出环境变量。
24
-
25
- 以下命令用于独立部署、故障恢复或高级配置:
14
+ 当前稳定版本已发布到 npm,推荐按下面的 npm 流程启动;如果要运行 GitHub 上尚未发布的分支代码,
15
+ 再使用下方的源码部署方式。首次初始化、systemd Agent 准备的完整说明见下文。
26
16
 
27
17
  ```bash
28
- npm install -g nexus-agentd
29
- curl -fsSL \
30
- https://raw.githubusercontent.com/lumia1998/koishi-plugin-agent-nexus/main/packages/nexus-agentd/nexus-agentd.example.json \
31
- -o nexus-agentd.json
32
- export NEXUS_AGENTD_TOKEN='TOKEN'
33
- nexus-agentd --config nexus-agentd.json
18
+ NPM_CONFIG_PREFIX="$HOME/.local"
19
+ npm install --global --prefix "$NPM_CONFIG_PREFIX" nexus-agentd@latest
20
+ export PATH="$NPM_CONFIG_PREFIX/bin:$PATH"
21
+ mkdir -p "$HOME/.config/agent-nexus" "$HOME/projects"
22
+ nexus-agentd \
23
+ --config "$HOME/.config/agent-nexus/nexus-agentd.json" \
24
+ --host 0.0.0.0 \
25
+ --port 8787 \
26
+ --workspace "$HOME/projects"
34
27
  ```
35
28
 
36
- OpenCode OpenClaw 自带 ACP 入口。Claude Code、Codex、Pi 需要先安装对应 adapter:
29
+ 当前仓库版本 `0.1.6` 已发布到 npm;可用 `npm view nexus-agentd version` 检查 registry 的 latest,
30
+ 也可以将安装命令固定为 `nexus-agentd@0.1.6`。
31
+
32
+ ## 安装与部署
33
+
34
+ ### 运行要求
35
+
36
+ - Node.js 20 或更高版本。
37
+ - 一个明确的工作区目录。Gateway 只允许 Agent 访问 workspaceRoots 及其子目录。
38
+ - 计划使用的 ACP CLI/Adapter 已安装,并且对运行 Gateway 的同一个操作系统用户可用。
39
+ - LAN 部署需要在主机防火墙中限制 8787 端口来源;公网部署应放在 HTTPS/mTLS 反向代理或可信隧道后。
40
+
41
+ Gateway 不会替你安装 Agent,也不会替你执行 OpenCode、Claude Code 或 Hermes 的登录命令;这些属于宿主机运维步骤。
42
+
43
+ ### npm 包安装(已发布版本)
44
+
45
+ `0.1.6` 已发布到 npm。目标版本尚未发布时,请使用下面的源码部署,或将本仓库打包后的 tarball 安装到目标机器。
46
+
47
+ 发布状态可用 `npm view nexus-agentd version` 检查;生产环境需要可复现部署时,建议固定为 `nexus-agentd@0.1.6`。
48
+
49
+ 生产环境建议使用专用的低权限系统用户,并把 npm 全局包安装到用户目录:
50
+
51
+ ~~~bash
52
+ NPM_CONFIG_PREFIX="$HOME/.local"
53
+ npm install --global --prefix "$NPM_CONFIG_PREFIX" nexus-agentd@0.1.6
54
+ export PATH="$NPM_CONFIG_PREFIX/bin:$PATH"
55
+ ~~~
56
+
57
+ 启动命令是 nexus-agentd,npm 包的 CLI 入口是 dist/cli.js。
58
+
59
+ ### 首次初始化
60
+
61
+ 首次启动时指定配置文件、监听地址和工作区:
62
+
63
+ ~~~bash
64
+ mkdir -p "$HOME/.config/agent-nexus" "$HOME/projects"
65
+ nexus-agentd \
66
+ --config "$HOME/.config/agent-nexus/nexus-agentd.json" \
67
+ --host 0.0.0.0 \
68
+ --port 8787 \
69
+ --workspace "$HOME/projects"
70
+ ~~~
71
+
72
+ 首次启动后:
73
+
74
+ 1. 打开终端打印的 http://<gateway-host>:8787/ui/。
75
+ 2. 设置至少 12 位的 Console Password。
76
+ 3. 在 API Keys 页面创建给 Koishi 或其他客户端使用的数据面 API Key。
77
+ 4. 在 Workspaces 页面确认工作区 allowlist,在 Agents 页面检查 ACP/A2A Agent。
78
+
79
+ Console Password 和 API Key 是两套凭证:前者只用于管理页面登录,后者只用于数据面 API。不要把 Console Password 填到 Koishi 插件的 gatewayKey。
80
+
81
+ 配置已经存在时,--host、--port 和 --workspace 不会重新覆盖已有配置;后续启动只需要指定同一个 --config。
82
+ 也可以通过 NEXUS_AGENTD_CONFIG 环境变量提供配置路径。
83
+
84
+ ### systemd user service(可选)
85
+
86
+ 仓库不内置 systemd unit。使用 npm 包时,可以创建 ~/.config/systemd/user/nexus-agentd.service:
87
+
88
+ ~~~ini
89
+ [Unit]
90
+ Description=Nexus Agent Gateway
91
+ After=network-online.target
92
+ Wants=network-online.target
93
+
94
+ [Service]
95
+ Type=simple
96
+ WorkingDirectory=%h/projects
97
+ Environment=NODE_ENV=production
98
+ Environment="PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin"
99
+ ExecStart=%h/.local/bin/nexus-agentd --config %h/.config/agent-nexus/nexus-agentd.json
100
+ Restart=on-failure
101
+ RestartSec=3
102
+ TimeoutStopSec=20
103
+ KillMode=mixed
104
+ UMask=0077
105
+
106
+ [Install]
107
+ WantedBy=default.target
108
+ ~~~
109
+
110
+ 加载、启用和检查:
111
+
112
+ ~~~bash
113
+ systemctl --user daemon-reload
114
+ systemctl --user enable --now nexus-agentd.service
115
+ systemctl --user status nexus-agentd.service
116
+ ~~~
117
+
118
+ 常用运维命令:
119
+
120
+ ~~~bash
121
+ systemctl --user restart nexus-agentd.service
122
+ journalctl --user -u nexus-agentd.service -n 100 --no-pager
123
+ curl http://127.0.0.1:8787/health
124
+ ~~~
125
+
126
+ 如果使用 nvm、mise 或其他用户级 Node 安装方式,请把 unit 中的 PATH 改成实际值,否则 Gateway 可能能启动,但找不到 Agent CLI。
127
+ 需要用户未登录时也自动启动时,可按发行版策略执行 loginctl enable-linger "$USER"。
128
+
129
+ 如果按源码部署,把 unit 中的 `WorkingDirectory` 改成 Gateway 工作树,并将 `ExecStart` 改为实际 Node
130
+ 绝对路径加上 `dist/cli.js`,例如:`/usr/bin/node %h/nexus-gateway/dist/cli.js --config
131
+ %h/.config/agent-nexus/nexus-agentd.json`。不要在 systemd 中依赖交互式 Shell 的 nvm 初始化。
132
+
133
+ ### 源码部署(开发分支或未发布版本)
134
+
135
+ 源码部署适合当前仓库和尚未发布到 npm 的版本;生产环境请使用外部进程管理器负责守护,
136
+ 不要把运行数据、Artifact 仓库或密钥放进 Git 工作树:
137
+
138
+ ~~~bash
139
+ git clone https://github.com/lumia1998/nexus-gateway.git
140
+ cd nexus-gateway
141
+ mkdir -p "$HOME/.config/agent-nexus" "$HOME/projects"
142
+ npm ci
143
+ npm run build
144
+ node dist/cli.js \
145
+ --config "$HOME/.config/agent-nexus/nexus-agentd.json" \
146
+ --host 0.0.0.0 \
147
+ --port 8787 \
148
+ --workspace "$HOME/projects"
149
+ ~~~
150
+
151
+ 源码仓库没有 Docker、PM2 或 systemd 配置,需要由宿主机的进程管理器负责守护和重启。
152
+
153
+ ## 认证边界
154
+
155
+ 控制面和数据面使用不同凭证:
156
+
157
+ - Console Password 只用于管理员登录。服务端以 scrypt 哈希保存,登录后只下发
158
+ `HttpOnly; SameSite=Strict` Cookie,浏览器不保存密码。
159
+ - API Key 只用于 `/v1/agents` 和 `/v1/sessions/*`。Key 可以命名、限制为全部或指定 Agent、
160
+ 停用、删除、重生成和按需 reveal。
161
+ - Key 自动生成为 `nx_sk_...`;也可设置至少 16 位的自定义值。
162
+ - 为支持管理员按需 reveal,API Key 可恢复地保存在权限为 `0600` 的配置文件中,不会出现在
163
+ 普通配置响应或日志里。
164
+
165
+ 旧配置中的 `authToken` 会继续作为名为 `Legacy Access Key` 的全 Agent 数据面 Key 工作。它不会
166
+ 被当成 Console Password。升级后第一次打开 WebUI 会要求单独设置管理员密码,原有 Agent 和
167
+ Workspace 配置保持不变。
168
+
169
+ ## WebUI
170
+
171
+ 固定侧栏有总览、运行记录、智能体、工作区、文件、API 密钥和运行设置七个主页面。管理员菜单位于侧栏底部,
172
+ 提供 Light / Dark / System 主题、修改密码和退出登录。
173
+
174
+ - Overview 只显示真实 Agent、Ready 和当前内存 Session 数量。
175
+ - 运行记录把当前任务和历史任务分开显示,记录用户原始任务、真实运行阶段、状态、结果摘要、
176
+ 耗时和产物;每 5 秒自动刷新,也可查看完整详情。
177
+ - Agents 支持本地 ACP 与远程 A2A;readiness 每 20 秒自动刷新,也可手动刷新。
178
+ - Workspaces 管理 ACP 的 realpath allowlist;A2A 不使用本地 Workspace。
179
+ - 文件页面在 allowlist 内浏览、上传、下载、新建目录、重命名和删除文件,并可生成临时公开链接。
180
+ 发布操作只复制选定文件,不会把工作区映射成公开静态目录。
181
+ - API Keys 显示真实状态和最后使用时间,并提供独立的显式 reveal 操作。
182
+ - 运行设置可以直接修改 Session 空闲有效期、ACP 单次任务超时和清理任务周期,保存后立即热生效。
183
+ 默认值分别是 24 小时、30 分钟和 60 秒;A2A 请求超时在每个 Agent 的编辑页单独设置,默认 60 秒、
184
+ 最大 30 分钟。
185
+
186
+ ## Agent 协议
187
+
188
+ ### ACP
189
+
190
+ | Driver | 默认入口 |
191
+ |---|---|
192
+ | `opencode` | `opencode acp` |
193
+ | `claude` | `claude-agent-acp` |
194
+ | `codex` | `codex-acp` |
195
+ | `pi` | `pi-acp` |
196
+ | `openclaw` | `openclaw acp` |
197
+ | `hermes` | `hermes acp` |
198
+
199
+ Claude Code、Codex、Pi 通常需要对应 Adapter:
37
200
 
38
201
  ```bash
39
202
  npm install -g \
@@ -42,216 +205,240 @@ npm install -g \
42
205
  pi-acp
43
206
  ```
44
207
 
45
- 还需要分别完成各 Agent 自身的登录或 API Key 配置。`claude-agent-acp` 当前要求 Node.js 22
46
- 或更高版本;其他 adapter 的版本要求以各自发布包为准。
208
+ `command`、`args`、`inheritEnv` `env` 是仅可在本机配置文件修改的高级字段,WebUI 不接受这些
209
+ 字段。Workspace 在启动进程前经过 `realpath` 边界校验。
47
210
 
48
- 也可以设置配置路径:
211
+ ### OpenCode、Claude Code 和 Hermes 的宿主机准备
49
212
 
50
- ```bash
51
- export NEXUS_AGENTD_CONFIG=/etc/agent-nexus/nexus-agentd.json
52
- nexus-agentd
53
- ```
213
+ 这三个 Agent 不需要修改 Gateway 源码,差异只在宿主机的可执行文件、ACP 入口和登录环境:
54
214
 
55
- 从仓库开发:
215
+ | Agent | Gateway 默认启动命令 | readiness 检查 | 宿主机要求 |
216
+ | --- | --- | --- | --- |
217
+ | OpenCode | opencode acp | opencode --version | 安装 OpenCode CLI;使用原生 ACP。 |
218
+ | Claude Code(CC) | claude-agent-acp | claude-agent-acp --version | 安装 @agentclientprotocol/claude-agent-acp,并准备 Claude Code 登录环境。 |
219
+ | Hermes | hermes acp | hermes acp --check | 安装 Hermes CLI;使用原生 ACP。 |
56
220
 
57
- ```bash
58
- npm install
59
- npm run build
60
- node dist/cli.js --config nexus-agentd.json
61
- ```
221
+ Claude Code、Codex 和 Pi 的常用 Adapter 可以一起安装:
62
222
 
63
- ## 配置
223
+ ~~~bash
224
+ npm install --global --prefix "$HOME/.local" \
225
+ @agentclientprotocol/claude-agent-acp \
226
+ @agentclientprotocol/codex-acp \
227
+ pi-acp
228
+ ~~~
64
229
 
65
- ```json
230
+ OpenCode 和 Hermes 请按各自项目的官方方式安装。Gateway 不执行 OpenCode、Claude Code 或 Hermes 的登录命令;登录必须在运行 nexus-agentd 的同一个操作系统用户环境中完成。
231
+
232
+ 可在同一用户的交互式 Shell 中检查:
233
+
234
+ ~~~bash
235
+ command -v opencode && opencode --version
236
+ command -v claude-agent-acp && claude-agent-acp --version
237
+ command -v hermes && hermes acp --check
238
+ ~~~
239
+
240
+ 如果命令在交互式 Shell 中可用、在 systemd 中不可用,检查 unit 的 PATH、HOME、XDG_CONFIG_HOME 和登录凭据。某个 Agent 未安装或检查失败不会影响其他 Agent。
241
+
242
+ 一个最小的 ACP 配置示例(可在 WebUI 的 Agents 页面创建,也可写入本机配置文件):
243
+
244
+ ~~~json
66
245
  {
67
- "listen": {
68
- "host": "127.0.0.1",
69
- "port": 8787
70
- },
71
- "authToken": "env:NEXUS_AGENTD_TOKEN",
72
- "workspaceRoots": [
73
- "/data/repos"
74
- ],
246
+ "workspaceRoots": ["/home/lumia/projects"],
75
247
  "agents": {
76
248
  "opencode": {
249
+ "protocol": "acp",
77
250
  "driver": "opencode",
78
- "command": "opencode",
79
- "args": ["acp"],
80
- "permissionPolicy": "ask",
81
- "inheritEnv": [
82
- "OPENAI_API_KEY",
83
- "ANTHROPIC_API_KEY"
84
- ]
251
+ "name": "OpenCode",
252
+ "workspace": "/home/lumia/projects"
85
253
  },
86
254
  "claude": {
255
+ "protocol": "acp",
87
256
  "driver": "claude",
88
- "command": "claude-agent-acp",
89
- "permissionPolicy": "ask"
90
- },
91
- "codex": {
92
- "driver": "codex",
93
- "command": "codex-acp",
94
- "permissionPolicy": "ask"
95
- },
96
- "pi": {
97
- "driver": "pi",
98
- "command": "pi-acp",
99
- "permissionPolicy": "ask"
257
+ "name": "Claude Code",
258
+ "workspace": "/home/lumia/projects"
100
259
  },
101
- "openclaw": {
102
- "driver": "openclaw",
103
- "command": "openclaw",
104
- "args": ["acp"],
105
- "permissionPolicy": "ask"
260
+ "hermes": {
261
+ "protocol": "acp",
262
+ "driver": "hermes",
263
+ "name": "Hermes",
264
+ "workspace": "/home/lumia/projects"
106
265
  }
107
266
  }
108
267
  }
109
- ```
268
+ ~~~
110
269
 
111
- 主要字段:
270
+ `workspace` 必须位于 `workspaceRoots` 之下;如果只通过 WebUI 配置,Gateway 会校验并保存这些字段。
112
271
 
113
- | 字段 | 说明 |
114
- |---|---|
115
- | `listen.host` | 默认 `127.0.0.1`;LAN 访问需显式改为内网地址或 `0.0.0.0` |
116
- | `listen.port` | HTTP/SSE 监听端口,默认 `8787` |
117
- | `authToken` | 必填 Bearer Token,支持 `env:VAR` |
118
- | `workspaceRoots` | 允许启动 ACP Session 的目录根列表 |
119
- | `agents` | daemon 本地 Agent 白名单 |
120
- | `driver` | `opencode`、`claude`、`codex`、`pi` 或 `openclaw` |
121
- | `permissionPolicy` | `ask` 或 `deny`,默认 `ask` |
122
- | `permissionTimeoutMs` | 权限或输入请求等待时间 |
123
- | `inheritEnv` | 额外允许传给 Agent 子进程的本机环境变量名 |
124
- | `env` | 显式环境变量,值支持 `env:VAR` |
125
-
126
- 默认入口:
127
-
128
- | Driver | 默认命令 | 说明 |
129
- |---|---|---|
130
- | `opencode` | `opencode acp` | OpenCode 原生 ACP Server |
131
- | `claude` | `claude-agent-acp` | `@agentclientprotocol/claude-agent-acp` |
132
- | `codex` | `codex-acp` | `@agentclientprotocol/codex-acp`,自带兼容 Codex 依赖 |
133
- | `pi` | `pi-acp` | adapter 再启动本机 `pi --mode rpc` |
134
- | `openclaw` | `openclaw acp` | OpenClaw 原生 Gateway ACP Bridge |
135
-
136
- OpenClaw Gateway 必须已运行并可被 `openclaw acp` 访问。可通过 OpenClaw 本机配置保存 Gateway
137
- 地址和凭据,也可在 `args` 中使用 `--url` 与 `--token-file`。不要把明文 Token 提交到仓库。
138
-
139
- Pi Driver 会同时探测 `pi-acp` 和底层 `pi`。如果 Pi 可执行文件不是默认名称,通过
140
- `env.PI_ACP_PI_COMMAND` 指定。
141
-
142
- `command` 和 `args` 只从 agentd 本机配置读取。HTTP 客户端不能覆盖它们。
272
+ Gateway 会在每个 Agent Session 的首次请求前自动注入一段 Agent Nexus 交互规范,提醒 Agent 在需要
273
+ 用户选择、确认、支付或补充信息时使用 ACP elicitation/A2A `input-required`,不要只输出普通文本问题。
274
+ 这段规范不需要为 OpenCode、Claude Code Hermes 手工重复配置。若某个 Agent 还需要额外规则,可在 Agent
275
+ 配置中增加 `instructions`;它会在内置规范之后追加,并限制为最多 32768 个字符。提示词注入只是行为约定,
276
+ Agent 仍必须实际支持相应的 ACP/A2A/MCP 用户输入机制,Gateway 不会把普通文本自动猜成等待状态。
143
277
 
144
- ## API
145
-
146
- ```text
147
- GET /health
148
- GET /v1/agents
149
- POST /v1/sessions
150
- GET /v1/sessions/:id
151
- POST /v1/sessions/:id/message
152
- POST /v1/sessions/:id/cancel
153
- GET /v1/sessions/:id/events
154
- ```
155
-
156
- 除 `/health` 外都要求:
157
-
158
- ```http
159
- Authorization: Bearer TOKEN
160
- ```
278
+ ### A2A
161
279
 
162
- 创建 Session 的请求只接受:
280
+ A2A 使用官方 `@a2a-js/sdk` 客户端,通过完整的 Agent Card URL 发现名称、能力和实际调用地址,
281
+ 支持 JSON-RPC / HTTP+JSON 传输、流式消息(SDK 自动回退为非流式)、任务状态、Artifacts 和取消。
282
+ 首选传输可设为 `auto`、`jsonrpc` 或 `http-json`;可配置无认证、Bearer 或自定义 Header。私有网段
283
+ 和局域网 URL 不会被禁止。
163
284
 
164
285
  ```json
165
286
  {
166
- "agentId": "claude",
167
- "workspace": "/data/repos/project"
287
+ "protocol": "a2a",
288
+ "name": "Research Agent",
289
+ "instructions": "需要用户确认时保持任务等待,并使用 Agent 的 input-required 能力。",
290
+ "agentCardUrl": "http://192.168.1.20:8080/.well-known/agent-card.json",
291
+ "preferredTransport": "auto",
292
+ "auth": {
293
+ "type": "bearer",
294
+ "value": "env:RESEARCH_AGENT_TOKEN"
295
+ },
296
+ "timeoutMs": 60000
168
297
  }
169
298
  ```
170
299
 
171
- 发送消息只接受:
300
+ 旧配置中的 `agentUrl` 仍按“服务根地址 + `/.well-known/agent-card.json`”方式发现 Card,无需手工
301
+ 迁移;在 WebUI 中保存一次后会写入新的 `agentCardUrl` 字段。
302
+
303
+ ## 配置
304
+
305
+ 推荐从首次启动生成的待初始化配置开始。完整示例见
306
+ [`nexus-agentd.example.json`](./nexus-agentd.example.json)。数值和数组字段会严格校验,错误配置
307
+ 会在启动或原子热重载前被拒绝,不再静默截断或忽略错误类型。
308
+
309
+ 常用资源限制:
172
310
 
173
311
  ```json
174
312
  {
175
- "message": "检查并修复测试"
313
+ "maxRequestBytes": 1048576,
314
+ "maxAttachmentBytes": 33554432,
315
+ "artifactStoragePath": "./artifacts",
316
+ "maxArtifactBytes": 536870912,
317
+ "maxArtifactStorageBytes": 4294967296,
318
+ "maxPublishedArtifacts": 4096,
319
+ "maxConcurrentArtifactPublishes": 4,
320
+ "artifactTtlMs": 86400000,
321
+ "requestTimeoutMs": 30000,
322
+ "promptTimeoutMs": 1800000,
323
+ "cleanupIntervalMs": 60000,
324
+ "maxSessions": 64,
325
+ "maxSseConnections": 128,
326
+ "maxConnections": 256,
327
+ "sessionTtlMs": 86400000
176
328
  }
177
329
  ```
178
330
 
179
- 额外字段会返回 `400`,因此客户端不能传入 command、argv shell payload。
180
-
181
- ## Session 与事件
331
+ 输入附件通过 Session 临时保存,默认单个文件最多 16 MiB、单个 Session 最多 32 MiB、最多 16 个文件;
332
+ HTTP 上传总上限由 `maxAttachmentBytes` 控制,默认 32 MiB,允许调整到 64 MiB。Session 释放时附件也会
333
+ 一起清理。ACP 会优先使用 Agent 声明支持的 image/audio/embeddedContext 能力,否则为 Agent 提供受限的
334
+ `file://` resource link;A2A 则以带文件名和媒体类型的二进制 Part 发送。
182
335
 
183
- 一个 Gateway Session 对应一个 ACP 子进程和一个 ACP Session。Session 完成后再次发送消息,
184
- 会续接同一 ACP Session;每轮输出单独保存,不与上一轮文本拼接。
336
+ 输出文件发布由 Gateway 自己的 `artifactStoragePath` 管理,默认单文件上限 512 MiB、链接有效期
337
+ 24 小时。上传和复制均使用流,不把文件编码进 JSON;公开 URL 使用 256 位随机 token,过期文件由
338
+ 后台清理。ACP/A2A 返回的内联二进制 Artifact 也会先落入该仓库,再在 Session 响应中改为 URL。
185
339
 
186
- 状态:
340
+ ### 多轮输入与确认
187
341
 
188
- ```text
189
- created
190
- running
191
- input_required
192
- permission_required
193
- completed
194
- failed
195
- canceled
196
- ```
342
+ ACP elicitation、ACP permission request 和 A2A `input_required` 都会让 Session 进入等待状态,并在
343
+ Session 响应的 `pendingRequest` 中返回等待提示和可选项。客户端只需重复调用同一个
344
+ `POST /v1/sessions/:id/message`:
197
345
 
198
- SSE 事件包括:
346
+ ~~~text
347
+ POST /v1/sessions/:id/message
348
+ {"message":"第一个"}
349
+ ~~~
199
350
 
200
- ```text
201
- session_state
202
- assistant_chunk
203
- thought_chunk
204
- plan
205
- tool_call
206
- tool_update
207
- terminal_output
208
- file_activity
209
- permission_required
210
- input_required
211
- completed
212
- failed
213
- canceled
214
- ```
351
+ Gateway 会复用原来的协议 Session/Task/Context,不会创建新任务。Agent 可以在下一轮再次进入
352
+ `input_required`,因此套餐选择、堂食方式、取餐时间和支付完成可以组成一条连续流程。需要表达业务
353
+ 步骤时,可在 `pendingRequest` 中提供可选的 `step`、`inputType` 和 JSON-safe `metadata`;这些字段
354
+ 不应放入密钥或其他敏感信息。支付完成消息仍必须由上游 MCP 根据订单/支付状态核验,不能只信任用户文本。
215
355
 
216
- `/events` 支持 `after` 查询参数和 `Last-Event-ID`,用于重放内存事件日志中的后续事件。
356
+ ACP Agent,Gateway 会在 Session 首次 prompt 前注入内置交互规范;对 A2A Agent,则把同一规范放在首个
357
+ 用户消息的前缀中。由于 A2A/ACP 的 system-message 能力在不同 Agent 实现中并不统一,这是一种兼容性更好的
358
+ 宿主提示方式。它不能替代 Agent 对 elicitation 或 `input-required` 的实现:Agent 必须真正发起协议级等待,
359
+ Gateway 才能暂停 Session 并在用户回复后继续。
217
360
 
218
- Session 当前保存在内存中。agentd 重启会终止 ACP 子进程,旧 Gateway Session 不可恢复。
361
+ API Key A2A 认证值支持 `env:VAR`。Console Password 哈希由 WebUI 管理,不要手工生成或把
362
+ 旧 `authToken` 复制到该字段。
219
363
 
220
- ## 权限与输入
364
+ 运行记录保存在配置文件同目录的 `nexus-agentd-runs.json` sidecar 中,默认最多保留 1000 条。
365
+ 记录文件使用 `0600` 权限和原子替换;进行中的任务若遇到 Gateway 重启,会在下次启动时标记为
366
+ “已中断/失败”,而不会一直显示为运行中。
221
367
 
222
- `permissionPolicy=ask` 时,ACP permission request 会进入 `permission_required`,Session 响应
223
- 包含问题和选项。AgentNexus 通过 `message` 返回:
368
+ ## API
224
369
 
225
- - 选项序号,例如 `1`
226
- - option ID
227
- - option name
228
- - `deny`、`cancel`、`拒绝` 或 `取消`
370
+ 匿名端点:
229
371
 
230
- ACP elicitation 会进入 `input_required`。简单单字段表单可直接回复文本、数字、布尔值或列表;
231
- 多字段结构化输入使用 JSON object。
372
+ ```text
373
+ GET /health
374
+ GET /v1/bootstrap/status
375
+ POST /v1/bootstrap/initialize
376
+ GET /v1/admin/auth/status
377
+ POST /v1/admin/auth/login
378
+ POST /v1/admin/auth/logout
379
+ ```
232
380
 
233
- `permissionPolicy=deny` 会选择协议提供的拒绝选项,或在没有拒绝选项时取消请求。
381
+ 管理员 Cookie 端点:
234
382
 
235
- ## Workspace 安全
383
+ ```text
384
+ GET /v1/admin/overview
385
+ GET /v1/admin/config
386
+ GET /v1/admin/agents
387
+ GET /v1/admin/runs
388
+ GET /v1/admin/runs/:id
389
+ PUT /v1/admin/agents/:id
390
+ DELETE /v1/admin/agents/:id
391
+ PUT /v1/admin/config/workspace-roots
392
+ PUT /v1/admin/config/runtime
393
+ PUT /v1/admin/password
394
+ GET /v1/admin/api-keys
395
+ POST /v1/admin/api-keys
396
+ PATCH /v1/admin/api-keys/:id
397
+ DELETE /v1/admin/api-keys/:id
398
+ POST /v1/admin/api-keys/:id/reveal
399
+ POST /v1/admin/api-keys/:id/regenerate
400
+ GET /v1/admin/files/roots
401
+ GET /v1/admin/files
402
+ GET /v1/admin/files/content
403
+ PUT /v1/admin/files/content
404
+ DELETE /v1/admin/files/content
405
+ POST /v1/admin/files/directory
406
+ POST /v1/admin/files/move
407
+ POST /v1/admin/files/publish
408
+ ```
236
409
 
237
- workspace 在启动 ACP 子进程前执行:
410
+ Bearer API Key 数据面:
238
411
 
239
- 1. `realpath(workspace)`。
240
- 2. `realpath` 每个 `workspaceRoots`。
241
- 3. 使用路径边界检查确认 workspace 位于允许根内。
412
+ ```text
413
+ GET /v1/agents
414
+ POST /v1/sessions
415
+ GET /v1/sessions/:id
416
+ POST /v1/sessions/:id/attachments
417
+ POST /v1/sessions/:id/message
418
+ POST /v1/sessions/:id/cancel
419
+ GET /v1/sessions/:id/events
420
+ GET /v1/sessions/:id/files
421
+ GET /v1/sessions/:id/files/content
422
+ POST /v1/sessions/:id/files/publish
423
+ ```
242
424
 
243
- 这会拒绝 `../` 逃逸、允许根之外的绝对路径和 symlink/junction 逃逸。workspace 必须已经存在。
425
+ `GET /v1/artifacts/:token/:expiresAt/:name` 是匿名下载端点;它只接受发布操作生成的不可猜测 token,并在 TTL
426
+ 到期后返回 404。该端点不支持目录列举,也不能据此访问原工作区。
244
427
 
245
- ## 网络建议
428
+ API Key 的 Agent scope 在 Agent inventory、Session 创建和后续 Session 操作上都会检查;Session
429
+ 还绑定创建它的 Key,其他 Key 即使拥有同一 Agent scope 也不能读取或控制该 Session。
430
+ 运行记录接口仅接受管理员 Cookie,数据面 API Key 无权读取。
246
431
 
247
- - 默认保持 `127.0.0.1`。
248
- - LAN 监听时使用强随机 Token 和主机防火墙限制 Koishi 来源 IP。
249
- - 不要直接暴露到公网;需要跨网络时在前面部署 HTTPS/mTLS 反向代理。
250
- - 使用权限受限的专用系统账号运行 agentd。
432
+ ## 局域网安全
251
433
 
252
- AgentNexus 自动部署时,Token 保存在 `~/.config/agent-nexus/nexus-agentd.env`,配置保存在
253
- `~/.config/agent-nexus/nexus-agentd.json`,权限均为 `0600`。系统服务优先使用 root 或免密
254
- sudo 创建;否则在可用时回退到用户 systemd,并在未启用 linger 时返回明确警告。
434
+ - 默认仍只监听 localhost;需要 LAN 时显式使用 `--host 0.0.0.0`,并用主机防火墙限制来源。
435
+ - LAN 上的纯 HTTP 为兼容 Cookie 默认不设置 `Secure`;跨不可信网络应放在 HTTPS/mTLS 反向代理
436
+ 或可信隧道后,并将 `secureAdminCookies` 设为 `true`。
437
+ - 管理写操作要求同源 `Origin`,Cookie 使用 `SameSite=Strict`;登录和无效 API Key 有失败限速。
438
+ - File Browser 的所有路径都在 realpath 后重新校验工作区边界;Session 发布还同时校验 API Key
439
+ scope 与 Session 所有权。公开链接应只发送给预期接收者。
440
+ - 不直接暴露公网。使用专用低权限系统账号运行 Gateway。
441
+ - 配置更新使用 `0600` 临时文件校验后原子替换;Secret 不进入普通响应和结构化错误日志。
255
442
 
256
443
  ## 验证
257
444
 
@@ -261,3 +448,7 @@ npm run typecheck
261
448
  npm run build
262
449
  npm pack --dry-run --json
263
450
  ```
451
+
452
+ ## License
453
+
454
+ [MIT](./LICENSE)