byt3bl33d3r/figaro

GitHub: byt3bl33d3r/figaro

Figaro 是一个多 Agent 编排框架,能够在容器化桌面和远程设备上规模化调度 Claude Code agent 执行长期自动化任务。

Stars: 139 | Forks: 11

Figaro Logo

License: MIT Code LLM Generated (with a lot of human oversight)

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 实操截图

Figaro Dashboard

## 快速开始 ``` 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 Scheduled Tasks

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, 任务编排, 桌面自动化, 测试用例, 版权保护, 请求拦截