byt3bl33d3r/figaro
GitHub: byt3bl33d3r/figaro
Figaro 是一个多 Agent 编排框架,能够在容器化桌面和远程设备上规模化调度 Claude Code agent 执行长期自动化任务。
Stars: 139 | Forks: 11
Figaro 编排了一群 Claude computer use agent,它们能在完整的桌面环境中自动化工作流。这些 agent 运行在容器化的 Linux 桌面内,或者可以连接到任何可通过 VNC 访问的机器——包括远程服务器、云端 VM 或物理工作站。所有桌面都会以直播流的形式展示在一个中央仪表板上,并由一个 supervisor agent 负责处理任务分配。一切都可以通过诸如 Telegram 等外部渠道以对话的方式进行管理。
Figaro 可以连接到任何可访问的桌面——包括本地机器、远程服务器、云端 VM 或运行 macOS、Windows 或 Linux 的物理工作站。通过 UI 界面添加桌面时只需提供连接 URL(`vnc://`、`rdp://`、`ssh://`、`telnet://`、`ws://` 或 `wss://`),随后 supervisor agent 即可通过屏幕截图、打字、点击和按键操作来观察并控制任何已连接的桌面。桌面直播流使用 Apache Guacamole(guacd + guacamole-common-js)来实现与协议无关的远程访问。
该系统专为耗时数分钟至数小时的长期运行任务而设计。所有服务均通过 [NATS](https://nats.io) 进行通信(使用 pub/sub + JetStream 来保障任务事件的持久化)。由 supervisor agent 负责处理任务优化与分配。
你也可以通过网关与 supervisor agent 聊天来管理一切事务——例如通过 Telegram。向它发送自然语言指令以创建任务、安排周期性作业、检查 worker 状态,或询问有关正在运行的任务的问题。supervisor 了解整个系统,并能够通过对话式接口将工作分配给各个 worker、通过 VNC 检查桌面情况,并报告反馈结果。
## 目录
- [快速开始](#quick-start)
- [高级设置](#advanced-setup)
- [连接外部桌面](#connecting-external-desktops)
- [计划任务](#scheduled-tasks)
- [自我修复](#self-healing)
- [自我学习](#self-learning)
- [Agent 记忆](#agent-memory)
- [网关](#gateway)
- [安全性](#security)
- [架构](#architecture)
- [服务](#services)
- [开发环境设置](#development-setup)
- [配置](#configuration)
- [NATS Subject 设计](#nats-subject-design)
- [消息流](#message-flows)
- [测试](#testing)
- [贡献指南](#contributing)
- [鸣谢](#credits)
## UI 实操截图
## 快速开始
```
curl -fsSL https://raw.githubusercontent.com/byt3bl33d3r/figaro/main/install.sh | bash
```
或者克隆代码并直接运行:
```
git clone https://github.com/byt3bl33d3r/figaro.git && cd figaro && ./install.sh
```
默认情况下,安装脚本使用 `prod-local` overlay,Figaro 将在 `http://localhost:8000` 上可用。
### 前置条件
- **Docker 和 Docker Compose** —— 在 Linux 上,安装脚本会自动通过 [get.docker.com](https://get.docker.com) 安装 Docker。在 macOS 上,你必须在运行脚本前手动安装 [Docker Desktop](https://docs.docker.com/desktop/setup/install/mac-install/)。
- Claude 凭证(`~/.claude.json` 和 `~/.claude/.credentials.json`)—— 需通过运行 `claude` 并登录来创建。在 macOS 上(假设你有 Claude Code 订阅),登录后,你可以使用以下命令导出凭证文件以便在容器中使用:
security find-generic-password -s "Claude Code-credentials" -w > ~/.claude/.credentials.json
### 可选项
- OpenAI API key(用于 `patchright-cli` 语音转写功能)
- Telegram bot token(允许通过 Telegram 与 supervisor agent 聊天,以进行任务提交、状态检查和通知)。通过 [@BotFather](https://t.me/BotFather) 创建一个 bot,并在你的 `.env` 中设置 `GATEWAY_TELEGRAM_BOT_TOKEN` 和 `GATEWAY_TELEGRAM_ALLOWED_CHAT_IDS`
## 高级设置
```
cp .env.example .env
# 为 VNC 密码存储生成加密密钥(必需)
echo "FIGARO_ENCRYPTION_KEY=$(openssl rand -hex 16)" >> .env
# 可选:设置 OPENAPI_API_KEY
# OPENAI_API_KEY=sk-proj-example
# 可选:设置 Telegram gateway 变量以用于通知和任务提交
# GATEWAY_TELEGRAM_BOT_TOKEN=your-bot-token
# GATEWAY_TELEGRAM_ALLOWED_CHAT_IDS=["your-chat-id"]
```
VNC 密码在 PostgreSQL 中使用 pgcrypto 进行静态加密。`FIGARO_ENCRYPTION_KEY` 用于对称加密,必须在启动 orchestrator 之前设置。`install.sh` 脚本会自动生成此项。
基础的 `docker/docker-compose.yml` 定义了所有共享服务,但**不会**暴露端口。请根据你的部署场景选择一个 overlay:
```
# 生产环境,仅 localhost(推荐)-- 端口绑定至 127.0.0.1
docker compose -f docker/docker-compose.yml -f docker/docker-compose.prod-local.yml up --build
# 开发环境 -- localhost 端口 + 一个用于测试 VNC 的桌面服务
docker compose -f docker/docker-compose.yml -f docker/docker-compose.dev.yml up --build
```
打开 `http://localhost:8000`。
这将启动 PostgreSQL、NATS(端口 8443)、guacd(Guacamole 守护进程)、orchestrator(端口 8000)、2 个 worker、2 个 supervisor 以及网关。supervisor 服务使用相同的 `figaro-worker` 二进制文件,并通过 `--supervisor` 标志启动。
### 扩容
```
docker compose -f docker/docker-compose.yml -f docker/docker-compose.prod-local.yml up --build --scale worker=4 --scale supervisor=3
```
### 卸载
```
docker compose -f docker/docker-compose.yml -f docker/docker-compose.prod-local.yml down # Stop services
docker compose -f docker/docker-compose.yml -f docker/docker-compose.prod-local.yml down -v # Stop and remove all data
```
## 连接外部桌面
Figaro 不仅局限于自带的容器化 worker。任何运行 VNC server 的机器都可以作为桌面连接进来。
### 从 UI 连接
在仪表板顶部点击“Add Desktop”。提供 worker ID、桌面 URL,并选择操作系统类型。支持的 URL scheme 有:
- `vnc://user:password@hostname:5901` —— 直接 TCP VNC 连接
- `rdp://user:password@hostname:3389` —— RDP 连接
- `ssh://user:password@hostname:22` —— SSH 连接
- `telnet://user:password@hostname:23` —— telnet 连接
- `ws://hostname:6080` —— WebSocket(兼容传统 noVNC)
- `wss://hostname:6080` —— 基于 TLS 的 WebSocket(兼容传统 noVNC)
凭证可以直接嵌入在 URL 中,也可以单独输入。已连接的桌面会显示在实时桌面网格中,supervisor agent 的 VNC 工具可以对其进行查看、截屏和交互。SSH 和 telnet 连接可通过 supervisor 的终端工具(`ssh_run_command`、`telnet_run_command`)进行访问。
### 从环境变量连接
在启动时通过 `FIGARO_DESKTOP_WORKERS` 环境变量预配置桌面:
```
FIGARO_DESKTOP_WORKERS='[{"id": "mac-studio", "novnc_url": "vnc://user:pass@192.168.1.50:5900", "metadata": {"os": "macos"}}]'
```
### Agent 升级路径
仅包含桌面的条目将作为占位符存在。当某个 worker agent 使用匹配的 ID 连接时,该桌面会自动升级为能够接收任务的完整 agent worker。当该 agent 断开连接时,桌面将恢复为仅查看模式,而不会消失。这意味着你可以预先注册桌面,并让 agent 以动态方式接入和断开。
当你想要将现有的物理机或 VM 连接到 Figaro 而又不想运行完整的容器化 worker 堆栈时,这非常有用。例如,你可以让 Figaro 指向你的 Mac Mini 的 VNC server,supervisor 就可以立即观察并与其屏幕进行交互。随后,你可以在这台机器上运行 `figaro-worker` agent,赋予其完整的任务执行能力——桌面条目会无缝升级,无需任何重新配置。如果你在那台机器上安装了 `patchright-cli`,它会变得特别实用:这是一个独立的浏览器自动化 CLI,使用与 claude-agent-sdk 相同的协议通信,因此你可以将它放到任何带有浏览器的机器上,瞬间提升你的浏览器自动化任务能力。
## 计划任务
Figaro 支持类似 cron 的周期性任务调度。计划任务可以通过 UI 进行管理,或者直接通过 Telegram 或在网关中配置的任何渠道与 Figaro 聊天来进行管理。
每个计划任务包含:
- **Prompt** —— 发送给 agent 的任务指令
- **Cron 表达式** —— 用于调度的标准 cron 语法(例如,`0 9 * * *` 代表每天上午 9 点)
- **起始 URL** —— worker 的浏览器在开始任务前应导航到的可选 URL
- **启用/禁用开关** —— 暂停和恢复任务而无需删除
- **手动触发** —— 无论计划时间或启用状态如何,立即执行
- **完成后通过网关通知** —— 任务完成或失败时,向配置的网关渠道(例如 Telegram)发送通知
- **自我学习** —— 每次运行后可选的自动 prompt 优化
计划任务会分配给 supervisor,再由 supervisor 委派给 worker。调度器每 60 秒检查一次到期任务,并将其分配给空闲的 supervisor(如果没有可用的 supervisor,则将其加入队列)。
### NATS API
```
figaro.api.scheduled-tasks # List all scheduled tasks
figaro.api.scheduled-tasks.get # Get a specific scheduled task
figaro.api.scheduled-tasks.create # Create a new scheduled task
figaro.api.scheduled-tasks.update # Update an existing scheduled task
figaro.api.scheduled-tasks.delete # Delete a scheduled task
figaro.api.scheduled-tasks.toggle # Enable or disable a scheduled task
figaro.api.scheduled-tasks.trigger # Trigger immediate execution
```
## 自我修复
当任务失败时,orchestrator 可以自动创建一个“修复”任务,用于分析失败原因并使用改进的方法进行重试。此功能专为浏览器自动化设计,因为在这类场景中失败往往是暂时性的——比如某个元素没有及时加载、页面布局发生了变化,或者 agent 导航到了错误的位置。
### 工作原理
1. worker 将错误发布到 `figaro.task.{id}.error`
2. orchestrator 根据优先级链评估是否进行修复:
- **任务级别:** 特定失败任务上的 `self_healing` 标志
- **计划任务级别:** 关联计划任务上的 `self_healing` 字段(如果有)
- **系统级别:** `FIGARO_SELF_HEALING_ENABLED` 环境变量(默认为:`true`)
3. 如果启用了自我修复且仍有重试次数(`< FIGARO_SELF_HEALING_MAX_RETRIES`,默认为:2),则会创建一个修复任务
4. 修复任务包含原始的 prompt、错误消息以及对话历史记录(最后 50 条消息)
5. supervisor 分析失败原因并决定:
- **可恢复**(未找到元素、时间同步问题、导航错误):使用改进的 prompt 委派给 worker。可能会先使用 VNC 工具检查桌面状态。
- **不可恢复**(凭证无效、服务宕机、根本方法错误):解释原因并且不进行重试。
6. 如果重试的任务也失败了且仍有重试次数,则会创建另一个修复任务(最多到 `max_retries`)
### 防止循环
- `source="healer"` 或 `source="optimizer"` 的任务永远不会被修复 —— 只有原始任务才会触发修复
- 重试链通过 `original_task_id` 和 `retry_number` 进行跟踪,以强制执行最大重试次数限制
### 配置
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `FIGARO_SELF_HEALING_ENABLED` | `true` | 启用失败任务的自动重试 |
| `FIGARO_SELF_HEALING_MAX_RETRIES` | `2` | 每个任务链的最大修复重试次数 |
## 自我学习
启用了 `self_learning` 的计划任务会在每次完成后自动优化其 prompt。系统会分析任务的实际执行情况,并重写 prompt 以便下次更加有效。
### 工作原理
1. worker 完成一项计划任务
2. orchestrator 检查:该任务是否有 `scheduled_task_id`、`source="scheduler"` 以及 `self_learning=True`?
3. 如果是,它会检索对话历史记录,过滤出关键消息类型(assistant、tool_result、result),并最多截取最后 50 条消息
4. 创建一个包含当前 prompt 和对话历史记录的优化任务,然后将其分配给空闲的 supervisor
5. supervisor 分析执行过程中发生的情况,并调用 `update_scheduled_task` 来保存改进后的 prompt
6. 下一次计划运行将使用改进后的 prompt
### 设计细节
- 优化运行以“即发即忘”的方式作为后台任务运行 —— 失败会被记录,但不会影响主任务的完成流程
- 优化在每次完成的计划任务运行后执行(无节流)
- supervisor 被指示仅更新 prompt 字段,保留计划、启用状态和起始 URL 设置不变
- 可以通过 UI 中的复选框针对每个计划任务开启或关闭自我学习
## Agent 记忆
Figaro 拥有一个持久化记忆系统,允许 agent 在多次任务执行之间存储和检索已学习的知识。记忆存储在 PostgreSQL 中,支持混合搜索(通过 ParadeDB 进行 BM25 全文搜索 + 通过 pgvector 进行语义相似度匹配),并通过 NATS 的 request/reply 在 agent 的 Python 沙盒中进行访问。
### 工作原理
supervisor 和 worker 都可以在其 `python_exec` 工具中通过内置的 `figaro` 模块访问记忆功能(`figaro.save_memory()`、`figaro.search_memories()`、`figaro.list_memories()`、`figaro.delete_memory()`)。Claude Code 内置的 Memory 工具已被禁用,以支持这种自定义实现。
supervisor 的工作流在两个节点集成了记忆功能:
- **委派之前:** 搜索记忆以获取相关的上下文(站点提示、用户偏好设置、过去的错误)并将其注入到 worker 的 prompt 中
- **任务完成后:** 将任何新的经验教训作为记忆保存,供未来的任务使用
### 记忆结构
每个记忆包含:
| 字段 | 描述 |
|-------|-------------|
| `content` | 自由文本的记忆内容 |
| `collection` | 用于组织的分类(`sites`、`users`、`errors、`workflows` 或 `default`) |
| `metadata` | 任意 JSON 键值对 |
| `embedding` | 用于语义搜索的 1536 维向量(OpenAI `text-embedding-3-small`) |
标准分类:
- **`sites`** —— 特定于站点的知识(URL、登录流程、导航模式、cookie 横幅)
- **`users`** —— 用户偏好和需求
- **`errors`** —— 失败模式和已知修复方法
- **`workflows`** —— 针对周期性任务的多步操作流程
### 搜索
记忆搜索使用 Reciprocal Rank Fusion (RRF),将 BM25 全文搜索和 pgvector 余弦相似度结合在一起。BM25 在融合中具有 2 倍的权重。如果未配置 OpenAI API key,则跳过 embedding,搜索将回退为仅使用 BM25。
记忆会根据 `(collection, content_hash)` 进行去重 —— 将相同内容保存到同一个 collection 中会更新现有记录。
### NATS API
```
figaro.api.memories.save # Save a memory (upsert by content hash)
figaro.api.memories.search # Hybrid BM25 + vector search
figaro.api.memories.list # List memories (optional collection filter)
figaro.api.memories.delete # Delete a memory by ID
```
### 配置
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `OPENAI_API_KEY` | -- | 用于生成 embedding 的 OpenAI API key(可选,未配置时退回仅使用 BM25 搜索) |
## 网关
网关是一项与渠道无关的消息服务,负责在外部通信渠道(Telegram,未来:WhatsApp、Slack 等)和编排系统之间路由消息。用户可以发送自然语言指令以创建任务、安排作业、检查状态或提出问题——这一切都通过对话式界面完成。
消息可以包含最大 20 MB 的附件(图像、文档等),这些附件将连同文本 prompt 一起转发给 supervisor agent。
### 语音消息转写
网关支持语音消息转写。当用户发送语音或音频消息时,它会自动转写为文本并作为常规任务进行处理——从用户的角度来看,无需进行任何特殊操作。
1. 用户通过 Telegram 发送语音/音频消息
2. 网关从 Telegram 下载音频文件
3. 通过 `ffmpeg` 将音频转换为原始 PCM 格式(16 位、16kHz、单声道)
4. PCM 数据以 100ms 的分块形式通过 WebSocket 流式传输到 Claude 的 STT endpoint(`/api/ws/speech_to_text/voice_stream`)
5. endpoint 返回转录片段,这些片段会被组装成最终的文本
6. 转写后的文本将走与键入消息完全相同的路径——发布到 NATS 进行任务创建和 supervisor 委派
身份验证使用从凭证文件(`~/.claude/.credentials.json`)读取的 Claude CLI OAuth token。该 token 会在每次请求时重新加载,因此可以自动处理凭证轮换。网关容器的 `PATH` 中必须提供 `ffmpeg`(已包含在 Docker 镜像中)。
### 配置
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `GATEWAY_TELEGRAM_BOT_TOKEN` | -- | Telegram bot token(通过 [@BotFather](https://t.me/BotFather) 创建) |
| `GATEWAY_TELEGRAM_ALLOWED_CHAT_IDS` | -- | 允许的 Telegram chat ID(JSON 数组) |
| `GATEWAY_STT_BASE_URL` | `wss://claude.ai` | STT WebSocket 基础 URL |
| `GATEWAY_STT_CREDENTIALS_PATH` | `~/.claude/.credentials.json` | 用于 OAuth token 的 Claude 凭证文件路径 |
## 安全性
Figaro 专为受信任的隔离环境而设计——例如私有 Docker 网络,以及在“生产”环境中通过 Tailscale、Headscale 或 Nebula 等加密 overlay 网络进行连接。有关已知安全权衡、攻击向量及其背后原因的完整列表,请参阅 [SECURITY.md](SECURITY.md)。
## 架构
```
+--------------------+
| NATS Server |
| (+ JetStream) |
| (+ WebSocket) |
+---------+----------+
+----------+-----------+-----------+--------------+
| | | | |
+----+----+ +---+----+ +---+-----+ +---+----------+ +-+----------+
| Worker | |Orchestr| |Supervis | | Gateway | | UI |
| (x N) | | ator | | or | | (channels) | | (SPA) |
+---------+ +---+----+ +---------+ +--------------+ +------------+
|
+----+---------------+
| guacd |
| (Apache Guacamole) |
+--------------------+
```
所有服务都通过 NATS 进行通信(使用 pub/sub + JetStream 来保障任务事件的持久化)。UI 通过 WebSocket(`nats.ws`)连接到 NATS,用于处理实时事件和变更(request/reply)。HTTP endpoints 被保持在最低限度:`GET /api/config`(NATS URL 发现)、`GET /api/guacamole/token`(加密的连接 token)和 `WS /guacamole/webSocket`(通过 guapy 实现的 Guacamole WebSocket 隧道)。
## 服务
### Orchestrator (`figaro/`)
FastAPI 应用程序,负责管理任务生命周期、worker 注册和调度。将构建好的 UI 作为静态文件提供服务。处理所有 NATS API 的 request/reply 操作(任务的 CRUD、计划任务、帮助请求、VNC/SSH/telnet 代理)。挂载了一个 guapy Guacamole WebSocket 服务器以实现桌面直播流。通过 Alembic 迁移将状态持久化到 PostgreSQL。
**技术栈:** Python 3.14、FastAPI、SQLAlchemy (异步)、asyncpg、asyncvnc、guapy、asyncssh、telnetlib3、Pillow
### Worker (`figaro-worker/`)
一个 Claude computer use agent,通过 claude-agent-sdk 执行浏览器自动化任务。该 agent 能像人类一样查看桌面并与之交互——进行截屏、移动鼠标、点击元素、输入文本以及在应用程序之间导航。它拥有自己的一套技能(自定义工具)并且可以运行 shell 命令。任务进度会流式传输到 JetStream。
worker 是一个独立的服务,可以在任何带有桌面环境的机器上运行。在 Docker 中,它运行在容器镜像提供的容器化 Linux 桌面(Fluxbox + TigerVNC + Chromium + noVNC)内,但它也可以直接运行在物理或虚拟机上——请参阅[连接外部桌面](#connecting-external-desktops)。
当使用 `--supervisor` 标志启动时,同一个二进制文件也可以作为 **supervisor** 运行。在 supervisor 模式下,agent 接收复杂的任务并将其委派给 worker。它可以通过 VNC 工具直接观察并控制任何已连接的桌面——进行截屏、打字、点击和按键——而无需委派完整的任务。它还可以通过 SSH 或 telnet 连接在 worker 上执行命令。使用由 NATS request/reply 支持的 SDK 原生自定义工具来实现委派和任务管理。支持基于非活动超时的阻塞式委派。
**技术栈:** Bun(编译为原生二进制文件)、`@anthropic-ai/claude-agent-sdk`、NATS
`legacy/` 目录中存在旧版的 worker 和 supervisor 的 Python 实现,以供参考。
### 网关 (`figaro-gateway/`)
与渠道无关的消息网关,负责在外部通信渠道和编排系统之间路由消息。目前支持 Telegram。实现了 `Channel` 协议,可通过最少的样板代码添加新渠道(WhatsApp、Slack 等)。
**技术栈:** Python 3.12+、`python-telegram-bot`、NATS
### UI (`figaro-ui/`)
React 单页应用程序,提供一个包含实时桌面网格(Guacamole 查看器)、事件流、用于任务提交的聊天输入框、计划任务管理和帮助请求处理的仪表板。所有通信均直接通过 WebSocket 连接到 NATS。桌面流式传输使用 `guacamole-common-js`,并支持自动重连和显示缩放。
**技术栈:** React 18、TypeScript、Vite、Zustand、Tailwind CSS、`guacamole-common-js`、`nats.ws`
### 共享 NATS 库 (`figaro-nats/`)
可重用的 Python 包,提供了一个带类型的 NATS 客户端封装(`NatsConnection`),支持 JSON 序列化、自动重连以及 Core NATS 和 JetStream 操作的方法。还提供了 subject 常量和 stream 配置。
**技术栈:** Python 3.12+、`nats-py`、Pydantic
### Patchright CLI (`patchright-cli/`)
基于 [Patchright](https://github.com/Kaliiiiiiiiii-Vinyzu/patchright)(用于隐蔽浏览器自动化的 Playwright 分支)构建的浏览器自动化 CLI 工具。采用基于会话的守护进程架构,并通过 Unix socket 进行通信。安装在 worker 容器内以提供浏览器自动化功能。
**技术栈:** Python 3.14、Patchright、OpenAI SDK(用于音频转写)
## 开发环境设置
### Dev Container(推荐)
代码库包含一个 VS Code Dev Container 配置,其中预装了所有依赖项:
- Python 3.14、Node.js、Bun、uv
- 用于本地测试的桌面环境 (VNC)
- 用于容器构建的 Docker-outside-of-Docker
- Claude Code CLI
在 VS Code 中打开代码库并选择“在容器中重新打开(Reopen in Container)”。
### 手动设置
每个服务都使用 [uv](https://docs.astral.sh/uv/) 进行 Python 依赖项管理:
```
# 共享 NATS 库(首先安装 -- 其他服务依赖于它)
cd figaro-nats && uv sync --frozen
# Orchestrator
cd figaro && uv sync --frozen
# Worker + Supervisor (Bun)
cd figaro-worker && bun install
# Gateway
cd figaro-gateway && uv sync --frozen
# UI
cd figaro-ui && npm install
```
### 单独运行服务
```
# Orchestrator (端口 8000)
cd figaro && uv run figaro
# Worker
cd figaro-worker && bun run dev
# Supervisor(相同的 binary,使用 --supervisor flag)
cd figaro-worker && bun run dev -- --supervisor
# Gateway
cd figaro-gateway && uv run figaro-gateway
# UI 开发服务器(端口 3000)
cd figaro-ui && npm run dev
```
### 数据库迁移
```
cd figaro
uv run alembic upgrade head # Apply migrations
uv run alembic revision --autogenerate -m "description" # Create new migration
```
## 配置
### 环境变量
| 变量 | 服务 | 描述 | 默认值 |
|----------|---------|-------------|---------|
| `FIGARO_HOST` | Orchestrator | 绑定地址 | `0.0.0.0` |
| `FIGARO_PORT` | Orchestrator | 监听端口 | `8000` |
| `FIGARO_DATABASE_URL` | Orchestrator | PostgreSQL 连接字符串 | -- |
| `FIGARO_NATS_URL` | Orchestrator | NATS server URL | `nats://localhost:4222` |
| `FIGARO_NATS_WS_URL` | Orchestrator | 用于 UI 的 NATS WebSocket URL | `ws://localhost:8443` |
| `FIGARO_STATIC_DIR` | Orchestrator | 构建的 UI 文件路径 | -- |
| `FIGARO_SELF_HEALING_ENABLED` | Orchestrator | 自动重试失败任务 | `true` |
| `FIGARO_SELF_HEALING_MAX_RETRIES` | Orchestrator | 每个任务链的最大修复重试次数 | `2` |
| `FIGARO_GUACD_HOST` | Orchestrator | Guacamole 守护进程主机名 | `localhost` |
| `FIGARO_GUACD_PORT` | Orchestrator | Guacamole 守护进程端口 | `4822` |
| `FIGARO_ENCRYPTION_KEY` | Orchestrator | 用于 Guacamole token 的 AES-256-CBC 密钥(未设置则自动生成) | -- |
| `FIGARO_VNC_PASSWORD` | Orchestrator | 用于 worker 桌面的 VNC 密码 | -- |
| `FIGARO_VNC_PORT` | Orchestrator | worker 上的 VNC 显示端口 | `5901` |
| `WORKER_NATS_URL` | Worker | NATS server URL | -- |
| `WORKER_ID` | Worker | 唯一的 worker 标识符 | -- |
| `WORKER_NOVNC_URL` | Worker | 用于 UI 的外部 noVNC URL | -- |
| `SUPERVISOR_NATS_URL` | Worker(supervisor 模式) | NATS server URL | -- |
| `SUPERVISOR_ID` | Worker(supervisor 模式) | 唯一的 supervisor 标识符 | 主机名 |
| `SUPERVISOR_MODEL` | Worker(supervisor 模式) | 要使用的 Claude 模型 | `claude-opus-4-6` |
| `SUPERVISOR_CLAUDE_CODE_PATH` | Worker(supervisor 模式) | Claude Code CLI 二进制文件路径 | -- |
| `SUPERVISOR_MAX_TURNS` | Worker(supervisor 模式) | 最大对话轮数 | -- |
| `SUPERVISOR_DELEGATION_INACTIVITY_TIMEOUT` | Worker(supervisor 模式) | 委派任务的闲置超时时间(秒) | `600` |
| `GATEWAY_NATS_URL` | Gateway | NATS server URL | -- |
| `GATEWAY_TELEGRAM_BOT_TOKEN` | Gateway | Telegram bot token | -- |
| `GATEWAY_TELEGRAM_ALLOWED_CHAT_IDS` | Gateway | 允许的 Telegram chat ID(JSON 数组) | -- |
| `GATEWAY_STT_BASE_URL` | Gateway | STT WebSocket 基础 URL | `wss://claude.ai` |
| `GATEWAY_STT_CREDENTIALS_PATH` | Gateway | 用于 STT OAuth token 的 Claude 凭证文件路径 | `~/.claude/.credentials.json` |
| `OPENAI_API_KEY` | Orchestrator | 用于记忆 embedding 的 OpenAI API key(可选) | -- |
| `VITE_NATS_WS_URL` | UI | NATS WebSocket URL | `ws://localhost:8443` |
### NATS 配置
NATS server 启用了 JetStream,WebSocket 在端口 8443 上运行(无 TLS),HTTP 监控在端口 8222 上运行。有关完整配置,请参阅 `docker/nats.conf`。
## NATS Subject 设计
### 注册与在线状态 (Core NATS)
```
figaro.register.worker # Worker registration
figaro.register.supervisor # Supervisor registration
figaro.register.gateway # Gateway registration
figaro.deregister.{type}.{id} # Graceful disconnect
figaro.heartbeat.{type}.{id} # Periodic liveness
```
### 任务 (Core NATS,点对点)
```
figaro.worker.{worker_id}.task # Assign task to specific worker
figaro.supervisor.{supervisor_id}.task # Assign task to specific supervisor
```
### 任务事件 (JetStream,TASKS stream)
```
figaro.task.{task_id}.assigned # Task assigned
figaro.task.{task_id}.message # Streaming SDK output
figaro.task.{task_id}.complete # Task completed
figaro.task.{task_id}.error # Task failed
```
### 帮助请求 (Core NATS)
```
figaro.help.request # New help request
figaro.help.{request_id}.response # Response to help request
```
### 广播 (Core NATS)
```
figaro.broadcast.workers # Updated workers list
figaro.broadcast.supervisors # Updated supervisors list
figaro.broadcast.task_healing # Task healing event
```
### API (NATS request/reply)
```
figaro.api.delegate # Delegate task to worker
figaro.api.workers # List workers
figaro.api.tasks # List tasks
figaro.api.tasks.get # Get task
figaro.api.tasks.create # Create task
figaro.api.tasks.search # Search tasks
figaro.api.supervisor.status # Supervisor status
figaro.api.scheduled-tasks # List scheduled tasks
figaro.api.scheduled-tasks.{get,create,update,delete,toggle,trigger}
figaro.api.help-requests.respond # Respond to help request
figaro.api.help-requests.dismiss # Dismiss help request
figaro.api.vnc # VNC operations (screenshot, type, key, click)
figaro.api.ssh # SSH operations (run_command)
figaro.api.telnet # Telnet operations (run_command)
figaro.api.memories.save # Save a memory
figaro.api.memories.search # Search memories (hybrid BM25 + vector)
figaro.api.memories.list # List memories
figaro.api.memories.delete # Delete a memory
```
### 网关 (Core NATS)
```
figaro.gateway.{channel}.send # Send message via channel
figaro.gateway.{channel}.task # Task from channel
figaro.gateway.{channel}.question # Ask question via channel
figaro.gateway.{channel}.register # Channel gateway registers availability
```
## 消息流
### 任务提交 (UI 到 Worker)
1. UI 向 `figaro.api.tasks.create` 发送 NATS 请求
2. Orchestrator 创建任务,认领一个空闲的 worker,并发布到 `figaro.worker.{id}.task`
3. worker 使用 Claude Agent SDK 执行任务
4. worker 通过 JetStream 流式传输消息(`figaro.task.{id}.message`)
5. worker 通过 JetStream 发布完成状态(`figaro.task.{id}.complete`)
6. orchestrator 更新数据库并将该 worker 设置为空闲
### 帮助请求流 (Human-in-the-Loop)
1. worker 或 supervisor 发布到 `figaro.help.request`
2. orchestrator 创建帮助请求并将其广播给 UI
3. 网关将帮助请求路由到相应的渠道(例如 Telegram)
4. 第一个响应者(UI 或渠道)进行回复
5. 响应被路由回发起请求的 agent
## 测试
### Python 服务
```
cd figaro && uv run pytest # Orchestrator
cd figaro-nats && uv run pytest # Shared library
cd figaro-gateway && uv run pytest # Gateway
```
代码检查和格式化:
```
uv run ruff check .
uv run ruff format .
```
### UI
```
cd figaro-ui
npm run test # Run tests
npm run test:watch # Watch mode
npm run build # TypeScript check + production build
```
### Worker (Bun)
```
cd figaro-worker && bun test
```
## 贡献指南
欢迎提交 Pull request!此代码库已禁用 Issues —— 如果你发现了错误或有功能请求,请先在 [Discussions](../../discussions) 中发起一个话题。一旦就方案达成一致,欢迎随时发起 PR。
## 鸣谢
- [OpenClaw](https://openclaw.ai) 提供了关于部分 agent 控制原语的设计灵感(例如循环控制、成本追踪等)
- [Apache Guacamole](https://guacamole.apache.org) & [Guapy](https://github.com/Adithya1331/guapy)
- [QMD](https://github.com/tobi/qmd) 提供的 agent 记忆 RAG 实现
标签:AI智能体, LLM, NATS, RPA, Unmanaged PE, VNC/RDP, 任务编排, 桌面自动化, 测试用例, 版权保护, 请求拦截