内容
# AstrBot Codex Router
将 AstrBot 管理员的任务型请求路由到本机 Codex CLI,并让普通用户继续使用 AstrBot Agent。
> 本插件由 **gpt5.6sol(GPT-5.6-SOL)** 设计、编写与调试。
当前版本:`0.3.1`
项目仓库:<https://github.com/qianan-qwq/astrbot_plugin_codex_router>
## 功能概览
- 直接复用 AstrBot 的管理员名单,不维护第二套插件白名单。
- 仅管理员的任务型请求会进入 Codex。
- 普通用户的消息不被插件拦截,直接沿用 AstrBot Agent。
- 通过 MCP bridge 调用本机 Codex CLI,而不是发送普通 API completion。
- Codex 在后台异步运行,AstrBot 不会因长任务阻塞或触发 180 秒 MCP 超时。
- 完成后尝试主动把结果发送到原会话。
- 持久化每个会话最近的任务 ID。
- 管理员可发送 `完成了吗?`、`结果呢`、`有结果了吗` 查询最近任务。
- Codex 不可用时,只有原管理员发起者会收到是否改用 AstrBot Agent 的确认。
- 提供 AstrBot Pages 可视化管理界面,可查看管理员、工具状态并调整超时和闲聊规则。
## 路由规则
| 用户类型 | 消息类型 | 处理方式 |
| --- | --- | --- |
| AstrBot 管理员 | 修改、检查、运行、安装、调试、文件、代码等任务型请求 | 本机 Codex CLI |
| AstrBot 管理员 | 配置的普通闲聊短句 | AstrBot Agent |
| 普通用户 | 任意请求 | AstrBot Agent |
| 原管理员发起者 | `完成了吗?`、`结果呢` 等状态查询 | 返回当前会话最近的 Codex 任务状态或结果 |
| 其他用户 | 状态查询 | 保持 AstrBot 默认行为 |
## 工作原理
```mermaid
flowchart LR
U[用户消息] --> A{AstrBot 管理员?}
A -- 否 --> N[AstrBot Agent]
A -- 是 --> Q{任务型请求?}
Q -- 否 --> N
Q -- 是 --> R[Codex Router]
R --> M[MCP codex-bridge]
M --> C[本机 Codex CLI]
C --> F[结果文件]
F --> P[后台轮询]
P --> S[原会话通知或状态查询]
```
插件本体只负责权限判断、请求路由、任务追踪和结果投递。`bridge/server.py` 负责启动 Codex CLI、保存任务状态,并通过 MCP 提供以下工具:
- `request_codex_task`
- `list_codex_tasks`
- `get_codex_task_result`
- `get_codex_bridge_status`
- `list_codex_models`
- `test_codex_upstream`
## 运行要求
- AstrBot,已在 `4.26.6` 上验证。
- AstrBot 已启用 MCP 功能。
- 本机存在可用的 Codex CLI。
- 执行 AstrBot 的 Python 环境中能够导入 `mcp.server.fastmcp`。
- Windows、Linux 或 macOS。当前版本重点验证了 Windows。
先在终端确认:
```powershell
codex --version
```
如果命令无法执行,请将 `bridge/config.json` 中的 `cli_command` 改为 Codex 可执行文件的绝对路径。
## 安装插件
### 方法一:从 ZIP 安装
1. 下载 Release 中的插件 ZIP。
2. 在 AstrBot 插件管理页面选择从本地 ZIP 安装。
3. 启用 `astrbot_plugin_codex_router`。
4. 按下文配置 bridge 和 MCP。
5. 完整重启 AstrBot。
### 方法二:手动安装
将仓库目录放到:
```text
AstrBot/data/plugins/astrbot_plugin_codex_router
```
目录中应直接包含 `main.py`、`metadata.yaml`、`_conf_schema.json`、`pages` 和 `bridge`。
## 配置 Codex Bridge
复制示例配置:
```powershell
Copy-Item bridge/config.example.json bridge/config.json
```
然后修改 `bridge/config.json`。
### 关键字段
| 字段 | 说明 |
| --- | --- |
| `workspace_root` | bridge 的默认工作区 |
| `model` | Codex 模型;留空时使用 Codex CLI 自己的默认模型 |
| `executor` | 本插件推荐使用 `cli` |
| `cli_command` | `codex` 命令或可执行文件绝对路径 |
| `cli_args` | 传给 Codex CLI 的参数 |
| `cli_workspace` | Codex 实际执行任务的工作目录 |
| `fallback_cli_workspace` | 主工作区不存在时使用的目录 |
| `cli_async` | 应保持为 `true` |
| `cli_timeout_seconds` | 单个 Codex CLI 进程的最长运行时间 |
### Windows 示例
```json
{
"workspace_root": "C:\\AstrBotWorkspace",
"model": "",
"executor": "cli",
"cli_command": "C:\\path\\to\\codex.exe",
"cli_args": [
"exec",
"--skip-git-repo-check",
"--sandbox",
"workspace-write"
],
"cli_workspace": "C:\\AstrBotWorkspace",
"fallback_cli_workspace": "C:\\AstrBot\\data",
"cli_async": true,
"cli_sync_wait_seconds": 0,
"cli_timeout_seconds": 1200
}
```
## 配置 AstrBot MCP
在 AstrBot 的 MCP 配置中加入:
```json
{
"mcpServers": {
"codex-bridge": {
"active": true,
"command": "C:\\path\\to\\AstrBot\\backend\\python\\python.exe",
"args": [
"C:\\path\\to\\AstrBot\\data\\plugins\\astrbot_plugin_codex_router\\bridge\\server.py"
]
}
}
}
```
如果已有其他 MCP 服务,只添加 `codex-bridge` 节点,不要覆盖原有节点。
重启后,AstrBot 日志中应出现:
```text
Connected to MCP server codex-bridge
MCP services initialization completed
```
## 插件配置
### `codex_timeout_seconds`
后台追踪 Codex 结果的时间,默认 `1200` 秒,范围 `30` 到 `3600` 秒。
### `confirm_timeout_seconds`
Codex 不可用时,等待管理员确认改用 AstrBot Agent 的时间,默认 `180` 秒。
### `small_chat_threshold`
以 `|` 分隔的普通闲聊短句。完全匹配这些短句时不会调用 Codex,例如:
```text
你好|在吗|hi|hello|嗯|好的|谢谢|ok|收到
```
## 管理员权限
插件不会创建独立白名单。权限只读取 AstrBot 根配置中的管理员列表,也会优先调用事件的 `is_admin()` 判断。
这意味着:
- 在 AstrBot 中新增管理员后,不必再修改插件配置。
- 从 AstrBot 管理员列表移除用户后,该用户立即失去 Codex 路由权限。
- 普通用户不会收到“无权使用 Codex”之类的提示,消息会直接进入 AstrBot Agent。
## 使用示例
管理员发送:
```text
检查当前 AstrBot 的运行状态
```
AstrBot 会先返回:
```text
Codex 已接手并在后台运行。任务 ID:...
完成后会自动把结果发回当前会话。
```
查询进度:
```text
完成了吗?
结果呢
有结果了吗
```
Codex 不可用时可回复:
```text
用 AstrBot
```
改用 AstrBot Agent,或回复 `取消` 放弃。
## WebChat 说明
QQ、Telegram 等支持主动消息的平台通常可以在任务完成时直接收到结果。
WebChat 的主动显示取决于当前前端是否保持后台消息订阅。即使页面没有即时刷新,结果仍会保存到 WebChat 历史数据库。此时可以:
1. 发送 `完成了吗?` 或 `结果呢`,插件会直接读取最近任务。
2. 刷新当前 WebChat 会话,查看已保存的结果。
## 安全说明
Codex CLI 可能读取或修改本机文件。请认真选择沙箱参数。
推荐默认使用:
```text
--sandbox workspace-write
```
只有确实需要修改工作区之外的 AstrBot 文件,并且理解风险时,才使用:
```text
--sandbox danger-full-access
```
不要把 API Key、访问令牌或带有私密路径的 `bridge/config.json` 提交到 GitHub。仓库的 `.gitignore` 已默认排除该文件。
## 数据文件
插件运行时数据位于 AstrBot 的插件数据目录:
```text
AstrBot/data/plugin_data/astrbot_plugin_codex_router/task_sessions.json
```
bridge 的任务记录位于:
```text
bridge/inbox
bridge/results
```
这些运行数据不会包含在发布 ZIP 中。
## 故障排查
### 找不到 `request_codex_task`
- 检查 MCP 配置路径。
- 确认 bridge Python 能导入 `mcp.server.fastmcp`。
- 完整重启 AstrBot。
- 查看日志中是否出现 `Connected to MCP server codex-bridge`。
### `Codex CLI command not found`
- 在终端运行 `codex --version`。
- 将 `cli_command` 改为绝对路径。
- Windows 下优先使用实际 `codex.exe`,避免 `npx` 子进程在超时后无法及时退出。
### 任务一直显示 `running`
- 检查 `bridge/results` 中对应任务文件。
- 增大 `cli_timeout_seconds`。
- 直接运行相同 Codex CLI 命令,检查登录状态和网络连接。
- 不要把 `cli_async` 设为 `false`,否则长任务可能阻塞 MCP 调用。
### WebChat 没有弹出完成消息
- 发送 `完成了吗?`。
- 刷新会话历史。
- 检查数据库中是否已经保存结果。
### 普通用户也进入了 Codex
- 检查 AstrBot 管理员列表是否包含该用户 ID。
- 检查平台事件的 `is_admin()` 返回值。
- 确认没有其他插件重复注册 Codex 路由。
## 仓库结构
```text
astrbot_plugin_codex_router/
|-- main.py
|-- metadata.yaml
|-- _conf_schema.json
|-- README.md
|-- CHANGELOG.md
|-- LICENSE
|-- bridge/
| |-- server.py
| `-- config.example.json
`-- pages/
`-- Codex Router/
|-- index.html
|-- app.js
`-- style.css
```
## 开发与验证
Python 语法检查:
```powershell
python -m py_compile main.py bridge/server.py
```
前端脚本检查:
```powershell
node --check "pages/Codex Router/app.js"
```
配置检查:
```powershell
python -c "import json; json.load(open('_conf_schema.json', encoding='utf-8'))"
```
## 作者与许可
- 作者:**gpt5.6sol(GPT-5.6-SOL)**
- 许可证:MIT
- 项目定位:AstrBot 管理员到本机 Codex CLI 的异步任务路由器
使用本项目即表示你理解 Codex CLI 具备本机文件操作能力,并愿意自行承担所配置权限带来的风险。