PicoBot/README.md
xiaoxixi b13450498b refactor: remove sleep tool and wake-aware steering machinery
Drop the model-callable sleep tool and its TurnWakeup publisher/handle state. Async background completions and user input already inject through steer-at-safe-boundary or the queued continuation Turn, so the sleep path only misled agents into busy-waiting on non-actionable queue wakes. Cancellation still normalizes running tool blocks to Cancelled.
2026-08-13 18:08:07 +08:00

31 KiB
Raw Blame History

PicoBot

PicoBot 是一个用 Rust 编写的个人 AI 助手运行时。它在本地启动 Gateway接入 CLI TUI、飞书/Lark 等聊天渠道,把会话、消息、记忆和定时任务持久化到 SQLite并为 Agent 提供文件、Shell、HTTP、Web、MCP、Skill、记忆、浏览器和子 Agent 等工具能力。

它更像一个可扩展的“个人助手操作系统”渠道负责收发消息SessionManager 负责会话和上下文AgentLoop 负责模型与工具循环Storage 负责可靠落盘。

完整的组件边界、并发不变量、启动/关停顺序和扩展指南见 架构文档

适合做什么

  • 在终端里和本地 AI 助手持续对话。
  • 从脚本或命令行发送一条任务,等待完整的模型/工具循环后只输出最终结果。
  • 在 TUI 或浏览器中实时查看正文、思考过程和工具执行状态,并在完成后收敛到持久化历史。
  • 在浏览器中查看日志、任务和记忆,修改运行配置与助手档案。
  • 在 WebUI 顶栏查看当前会话的累计输入/输出 Token、上下文窗口和占用比例。
  • 复杂任务可创建 session 级 Todo 计划,把不同子项并行委托给多个子 Agent聊天页侧栏实时显示进度。
  • 将同一套 Agent 能力接入飞书/Lark并可选用单张卡片实时更新回复。
  • 让 Agent 使用本地文件、Shell、搜索、HTTP、浏览器、MCP 工具完成任务。
  • 把长期偏好、事实和历史摘要存成可检索记忆。
  • 用 Cron 定时执行任务,并把结果发回目标渠道。
  • 通过 Skills 为 Agent 注入项目知识和专用操作指南。

快速开始

1. 准备环境

需要:

  • Rust toolchain项目使用 edition 2024。
  • 一个可用的 LLM Provider API Key。

2. 构建项目

cargo build

3. 准备配置

PicoBot 按以下顺序加载配置:

  1. ~/.picobot/config.json
  2. 当前目录 ./config.json

Gateway 首次启动时会把模板释放到 ~/.picobot/config.example.json。模板源文件在 resources/templates/config.example.json

最小配置示例:

{
  "providers": {
    "openai": {
      "type": "openai",
      "base_url": "https://api.openai.com/v1",
      "api_key": "<OPENAI_API_KEY>",
      "extra_headers": {}
    }
  },
  "models": {
    "gpt-4o": {
      "model_id": "gpt-4o",
      "temperature": 0.7,
      "max_tokens": 4096,
      "input_type": ["text", "image"]
    }
  },
  "agents": {
    "default": {
      "provider": "openai",
      "model": "gpt-4o",
      "max_tool_iterations": 99,
      "token_limit": 128000
    }
  },
  "workspace_dir": "~/.picobot/workspace"
}

.env 会在启动时由 PicoBot 自己解析,不依赖 dotenv。环境变量按以下顺序分层越靠后优先级越高

  1. config.json 所在目录的 .env,作为所有 workspace 共用的基础配置。
  2. workspace_dir/.env,用于当前 workspace 的覆盖值。
  3. 启动 PicoBot 时进程中已有的环境变量,例如 Docker Compose 的 environment,优先级最高且不会被文件覆盖。

合并后的值既用于替换配置里的 <OPENAI_API_KEY> 等占位符,也会写入 PicoBot 进程环境,供 MCP Server 和工具子进程继承。workspace_dir 的位置由配置目录层和进程环境决定workspace 自己的 .env 不能反过来修改 workspace_dir

4. 启动 Gateway

cargo run -- gateway

默认监听 127.0.0.1:19876。Gateway 启动后会把进程工作目录切到 workspace_dir,默认 SQLite 数据库也会写到该 workspace 下的 picobot.db

监听地址可通过配置文件或命令行覆盖。命令行参数优先于 config.json

{
  "gateway": {
    "host": "0.0.0.0",
    "port": 19876
  }
}
picobot gateway --host 0.0.0.0 --port 19876

Docker Compose 默认让容器内 Gateway 监听所有 IPv4 接口。监听地址、宿主机发布地址和端口均可通过环境变量调整:

PICOBOT_GATEWAY_HOST=0.0.0.0 \
PICOBOT_PUBLISH_HOST=192.168.1.10 \
PICOBOT_GATEWAY_PORT=19876 \
docker compose up -d

PICOBOT_GATEWAY_HOST 是容器内进程的监听地址;PICOBOT_PUBLISH_HOST 是 Docker 在宿主机上发布端口的地址。对局域网开放时应保持 gateway.require_pairing=true,并由防火墙限制可信网段。

5. 启动 CLI 客户端

另开一个终端:

cargo run -- chat

CLI 默认连接 ws://127.0.0.1:19876/ws。TUI 首次使用先运行 picobot pair,再执行 picobot chat --pair-code <CODE>;客户端令牌会以 0600 权限保存到 ~/.picobot/tui_auth_token。如需指定地址,可使用 --gateway-url

5.1 一次性执行

run 通过 Gateway 发送一条消息,复用正常的 SessionManager、AgentLoop 和工具调用流程,收到 Turn 终态后打印最终回复并退出:

picobot run "检查这个项目并总结测试结果"
printf '使用浏览器打开 example.com 并返回页面标题\n' | picobot run

默认情况下 stdout 只包含最终回复,便于管道和脚本消费。--verbose 把阶段和工具状态写到 stderr--json 输出包含 session、turn、状态、正文、usage 和错误的一行 JSON--timeout 设置最大等待秒数。超时或按下 Ctrl-C 时,客户端会先向当前会话发送 /stop

连接本机回环地址时不需要人工配对:run 自动读取 ~/.picobot/web_admin_tokenGateway 只有在真实 TCP 对端也是回环地址时才允许该凭据访问 /ws。每次调用使用独立的临时 chat scope不会替换正在运行的 TUI 连接。连接远程 Gateway 时仍使用 ~/.picobot/tui_auth_token 中已有的配对令牌。

5.2 健康检查

启动 Gateway 前可检查 PicoBot 核心命令、已启用功能的依赖、stdio MCP 命令和浏览器运行环境:

picobot health
picobot health --json

缺少核心或当前配置要求的依赖时退出码为 1rg / fd 等有回退实现的加速项只会标记为 DEGRADED。运行中的 Gateway 也提供 /health 斜杠命令Agent 可调用同名 health 工具,三者共享同一套只读检查逻辑。

5.3 使用 WebUI

Gateway 启动后直接打开:

http://127.0.0.1:19876/

新浏览器默认不能直接进入。请在运行 Gateway 的同一台设备上生成一次性配对码:

picobot pair

在浏览器配对页输入输出的 8 位代码即可。配对码 5 分钟内有效且只能使用一次;浏览器凭据由 HttpOnly Cookie 保存。需要撤销全部浏览器和 CLI 客户端时运行 picobot pair --revoke-all,再用新代码重新配对。

Docker 部署必须在 Gateway 容器内签发配对码,使请求来自容器自身回环地址并能读取映射目录中的管理密钥:

docker compose exec picobot picobot pair --gateway-url http://127.0.0.1:19876

不要从宿主机经发布端口直接调用签发接口;容器会把该连接识别为非回环来源并拒绝。picobot 已加入正式镜像的 PATH,可在容器 shell 中直接调用。

WebUI 随二进制嵌入,不需要 Node.js、npm 或单独部署静态文件。界面采用本地实现的 Microsoft Fluent 2 视觉系统,提供语义化中性色表面、品牌蓝交互状态、统一组件层级和完整的浅色/深色主题,并提供:

  • 在线聊天、会话创建/切换、历史回放、流式 Markdown、独立思考区、实时工具状态、可折叠历史工具调用卡片以及基于 Gateway 实时命令清单的 / 斜杠命令补全。
  • 文件选择、拖放和剪贴板图片上传;消息中的附件可预览或下载。附件按服务端路径引用,原文件移动或删除后历史附件可能不可用。
  • “配置 → 外观”提供浅色/深色模式和六套 Fluent 品牌色;选择即时生效并保存在当前浏览器中,首次访问时明暗模式跟随系统偏好。
  • Cron 定时任务、最近运行记录和后台子任务状态。
  • 当前聊天 session 的可展开 Todo 侧栏;计划变化时自动展开,其他 session 的变化显示未读提示。
  • Knowledge/Timeline 记忆的分类与全文检索。
  • 本地滚动日志的尾部查看、过滤和自动刷新。
  • config.json~/.picobot/USER.md~/.picobot/AGENTS.md 编辑。

配置接口会掩码 API Key、secret、password 和 token保留 ******** 再保存不会覆盖原密钥。运行配置采用原子写入,保存后可执行 picobot reload 或发送 /reload 热重载;USER.mdAGENTS.md 的修改用于后续构建的 Agent 上下文。

WebUI 默认启用设备配对鉴权,管理 API 与 /ws 都拒绝未配对客户端;静态配对页、公开健康检查和配对提交接口除外。唯一的 WebSocket 例外是本机 picobot run:请求必须同时来自真实回环对端并持有权限为 0600~/.picobot/web_admin_token,该管理令牌不能绕过任何管理 API 的设备鉴权。配对令牌只以 SHA-256 哈希写入 ~/.picobot/web_auth.json。鉴权不提供传输加密;如果通过 --host 0.0.0.0、反向代理或端口转发暴露 Gateway仍必须使用 TLS。可通过 gateway.require_pairing=false 显式关闭配对,但不建议在非隔离环境使用。

WebUI 开发

WebUI 源码位于 webui/,使用 Svelte 5、Vite 和无样式的 Bits UI 可访问组件原语。Fluent 2 外观由 webui/src/styles.css 中的本地语义令牌与 Svelte 组件实现,不加载 CDN 或外部 UI 运行库;明暗模式和品牌色分别保存在浏览器 picobot-themepicobot-accent 项中,并由 theme-init.js 在应用挂载前恢复。运行发布版 PicoBot 不需要 Node.js从源码编译或修改前端时需要 Node.js 20+

cd webui
npm ci
npm run check
npm run build

直接运行 npm run build 会在被忽略的 webui/dist/ 生成独立检查产物。正常执行 cargo build 时,build.rs 会监听前端源码和构建配置,只有它们发生变化时才调用 Vite将生产资源生成到 Cargo OUT_DIR 并嵌入二进制;node_modules 缺失或 package-lock.json 变化时会先自动运行 npm ci。前端产物不提交到仓库。

6. 作为 systemd 用户服务运行Linux

安装会把当前 PicoBot 可执行文件注册为 picobot.service 并设置为登录后自动启动;安装本身不会立即启动 Gateway

picobot service install
picobot service start

服务管理命令:

picobot service status
picobot service restart
picobot service stop
picobot service uninstall

修改配置后无需重启 systemd service

picobot reload

该命令连接正在运行的 Gateway先解析并校验新配置再停止接收新工作等待当前交互 Turn、Scheduler job 和后台子 Agent 到达安全边界后切换运行代。也可在聊天中发送 /reload,或让根交互 Agent 在用户明确要求时调用 reload_config 工具;子 Agent 与定时任务不能触发重载。监听地址、workspace 和数据库路径涉及进程级资源,不能热重载;修改这些字段时命令会保留旧配置并提示使用 picobot service restart。重载会主动断开 WebSocketTUI/WebUI 随后可重新连接并从持久化历史恢复。受认证客户端可通过 GET /api/config/reload/status 查询 generation、切换阶段和最近错误。

unit 位于 ~/.config/systemd/user/picobot.service,以执行 service install 时的当前目录作为初始工作目录。服务异常退出时由 systemd 自动重启;stoprestart 会通过 SIGTERM 触发 Gateway 的有界优雅关停。

TUI 会把一个随机客户端标识保存到 ~/.picobot/tui_client_id,因此关闭并重新打开客户端后会恢复同一组 dialog 和最近使用的会话。界面支持流式正文、独立思考与工具状态、历史回放、会话列表与归档筛选、命令补全、Unicode/中文编辑、括号粘贴、多行输入和文件传输。

常用快捷键:

快捷键 操作
F1 / Ctrl+H 打开帮助
Tab / Ctrl+S 切换焦点 / 聚焦会话列表
Ctrl+N 新建会话
Ctrl+R / Ctrl+A / Ctrl+D 重命名 / 归档 / 删除所选会话
Ctrl+L / Ctrl+O 清空历史 / 显示归档会话
Enter / Shift+Enter 发送 / 换行
Ctrl+F / F2 添加附件 / 下载历史中最近的附件

WebUI/TUI 上传文件默认保存到 ~/.picobot/media/cli_chat,单文件上限 25 MiB可通过 gateway.file_transfer 调整目录、上限和待发送上传的有效期。消息只保存文件路径,不保证文件被移动或删除后仍能下载。 | PageUp / PageDown | 滚动对话历史 | | 连按两次 Ctrl+C | 退出客户端 |

运行时数据流

用户消息进入 PicoBot 后,会被转换为统一的 inbound message经由 MessageBus 交给 SessionManager。SessionManager 选择当前 dialog、组装上下文并创建活动 TurnAgentLoop 消费 Provider 原生流、执行工具并发出结构化事件TurnController 将它们归约成可丢中间帧的完整快照。DeliveryCoordinator 把快照投影给 TUI、WebUI 或 Channel最终消息在 SQLite 原子提交成功后才进入 Completed

详细时序和失败语义见 架构文档:消息与控制数据流

同一 session 始终只运行一个 Turn不同 session 可以并发。Turn 执行期间新发的普通消息默认 steering 当前工作:系统在完整工具批次后或最终回复边界把它作为真实用户消息加入下一次模型调用;使用 /queue <message> 可明确等当前 Turn 完成后再处理,使用 /stop 可中断当前 Turn 并清空等待输入。Steering mailbox 和 session 队列都有界且带可靠回退。活动 Turn 使用 latest-wins 快照,慢展示端只跳过中间状态,不反压模型。普通出站消息按 (channel, chat_id) 分 lane 保序,两条投递路径共享目标写锁。

核心边界:

模块 职责
channels 接入外部渠道,只做收发,不直接处理会话或 LLM
bus 异步消息队列,承载 inbound、outbound、control 三类消息
session 管理会话生命周期、dialog 操作、上下文、记忆召回、压缩和持久化
agent 执行无状态 LLM/tool 循环,处理模型响应和工具调用
providers OpenAI 兼容接口和 Anthropic Messages API 的原生流解析与回放
delivery 活动 Turn 的展示过滤、latest-wins 节流、终态投递与 TurnSink 生命周期
tools Agent 可调用工具集合
storage SQLite schema、CRUD、消息和任务持久化
scheduler 领取定时任务,执行普通/巡检 Agent并按投递策略记录或发送结果
work 管理 session 级单 active plan、并行子项状态和 WebSocket 变更事件
skills 加载 Skill并把 Skill 指南注入系统提示
mcp 连接 MCP Server将远端工具包装成普通 Tool
task_supervisor 统一管理 Gateway 后台任务的取消和有界关停

核心能力

渠道

渠道 说明
cli_chat Ratatui 终端客户端,通过 WebSocket 连接 Gateway
feishu 飞书/Lark 消息、反应、文件上传下载和媒体引用

飞书默认只接受 allow_from 中的用户,且群聊消息必须明确 @ 机器人(可通过 channels.feishu.require_mention=false 关闭)。回复会使用飞书原生引用/话题语义保持在原消息位置。默认只发送终态结果;设置 channels.feishu.live_updates=true 后会创建一张卡片并持续编辑,live_update_interval_ms 默认 500ms运行时限制在 2505000ms。外部渠道始终不会收到模型 reasoning。

会话

Session ID 使用三段式:

<channel>:<chat_id>:<dialog_id>

同一个 channel:chat_id 下可以有多个 dialog。当前支持的 dialog 操作包括创建、列表、切换、重命名、归档、删除、清空历史、压缩、导出、查看信息和停止任务。

常用 slash commands

命令 说明
/new 创建新 dialog
/sessions 列出最近 dialog
/switch <dialog_id> 切换 dialog
/rename <title> 重命名当前 dialog
/delete 删除当前 dialog 并创建新 dialog
/compact 手动压缩上下文
/info [--json] 查看当前 dialog、累计 Token 与上下文窗口信息;可选 JSON 输出
/dump 导出当前 dialog 为 Markdown
/mcp 查看 MCP 服务器和工具状态
/health 检查 PicoBot 运行依赖
/queue <message> 等当前 Turn 完成后再把消息作为下一 Turn 处理
/stop 停止当前任务并清空队列
/todo [done|cancel] 查看、完成或取消当前 session 的任务计划
/reload 校验并重新加载 Gateway 配置
/?, /help 查看帮助

记忆

PicoBot 有两类记忆:

类型 用途 生命周期
Knowledge 偏好、事实、项目规则、长期可复用信息 长期保留,手动删除
Timeline 长对话压缩后的历史摘要 默认保留 90 天

每轮处理用户消息时MemoryManager 会按用户输入召回 Knowledge并作为运行时上下文附加到本轮用户消息。当前召回上限固定为 5memory.recall_limit 已支持解析但尚未接入 worker。上下文压缩产生的摘要会保存为 Timeline后续可通过 timeline_recall 工具检索。Scheduler 默认创建一个每日维护巡检,按 memory.timeline_retention_days 清理过期 TimelineKnowledge 不会被自动删除。

工具

基础工具集:

工具 说明
calculator 数学表达式和统计计算
file_read / file_write / file_edit 文件读写和编辑;file_read 读取受支持图片时可将图片直接提供给多模态模型
file_search / content_search 文件名和内容搜索
bash 在 workspace 中执行 Shell 命令
http_request / web_fetch HTTP 请求和网页文本抽取
get_skill 列出或读取本地 Skill
memory_store / memory_recall / timeline_recall / memory_forget 长期记忆操作
reload_config 在用户明确要求时校验并重新加载 Gateway 配置
delegate 向具名 Agent 委托单个或批量任务;foreground 等待结果,background 异步执行。批量 foreground 会并发运行并按请求顺序聚合
agent_task 查询/列出/读取结果/取消已持久化的具名 Agent run仅编排启用时注册
emit_signal 后台 run 向主 Agent 发送结构化内部信号queue/steer 投递;仅带 signal 契约的 run 注册)
todo 为复杂、多轮任务创建并更新当前 session 的持久化计划
send_message 向指定渠道或当前会话发送消息,可附带文件/截图WebUI/TUI 当前 Turn 的附件并入最终回复
chat_manager 查看渠道、会话和历史消息
cron_add/list/remove/enable/disable/update 管理定时任务
routine_maintenance 安全清理超过保留期的 Timeline不删除 Knowledge
health 检查核心、配置相关和可选运行依赖
browser 可选 agent-browser 浏览器自动化;默认按 dialog 临时使用,长期任务可用 persistent_id 复用个人 Profile
browser_profiles 创建、设置语义标签、列出或删除浏览器持久 ID 及其 Profile 目录
MCP tools 从配置的 MCP Server 动态发现并注册

Skills

Skill 是包含 SKILL.md 的目录。加载优先级从高到低:

  1. {workspace}/skills
  2. ~/.picobot/skills
  3. ~/.agents/skills

同名 Skill 会按高优先级覆盖低优先级。内置 Skill 位于 resources/skills,首次运行时会安装到 ~/.picobot/skills

配置速查

顶层配置字段:

字段 说明
providers LLM Provider 配置
models 模型参数与输入能力
agents Agent 使用哪个 provider/model
agent_orchestration 具名子 Agent 定义目录与编排上限
gateway HTTP/WebSocket、数据库、调度器、后台任务限制
client CLI 客户端默认 Gateway URL
channels 渠道配置,目前主要是飞书/Lark
memory 记忆召回、归并和 Timeline 保留策略
mcp MCP Server 配置
browser 可选浏览器自动化配置
workspace_dir 文件工具、Shell、数据库和 workspace skills 的工作目录

重要默认值:

配置 默认值
gateway.host 127.0.0.1
gateway.port 19876
gateway.require_pairing true
gateway.max_concurrent_background_tasks 10
gateway.scheduler.enabled true
client.gateway_url ws://127.0.0.1:19876/ws
memory.recall_limit 5(当前运行时固定为 5
memory.timeline_retention_days 90
mcp.tool_timeout_secs 180
browser.enabled true
channels.feishu.live_updates false
channels.feishu.live_update_interval_ms 500
channels.feishu.require_mention true
channels.feishu.max_image_bytes 10485760
channels.feishu.max_file_bytes 26214400
channels.feishu.media_dir_max_bytes 536870912
channels.feishu.request_timeout_secs 30

具名子 AgentPhase 1

PicoBot 在 Gateway 候选运行代构造时从配置目录下的 definitions_dir 加载 *.md(子 Agent 编排是内在机制,始终启用)。相对路径按 config.json 所在目录解析,且 canonical path 不得逃逸该目录角色文件、Provider profile、工具、Skill 和委托边任一无效都会拒绝启动或热重载。支持具名 foreground(单/批量)与 Root 发起的具名 background(单任务或 tasks[] 批量):每个 run 独立落库、预留 completion 槽、完成后由主 Agent 的 continuation Turn 单独汇总(空闲时完成即返回),可配合 emit_signalqueue/steer推送内部信号。子 Agent 发起的 background 尚未开放(旧匿名 general 已移除)。

---
id: researcher
description: 搜索、阅读并整理技术资料
llm_profile: research
tools:
  - file_read
  - file_search
  - content_search
delegates:
  - reviewer
limits:
  timeout_secs: 900
  max_iterations: 24
---
# Role

你是一名严谨的研究 Agent只返回与任务有关的结论和证据。

每个具名 Agent 的工具集完全由其 Markdown tools 列表决定(管理员显式授权),不再有工具侧的可派发门槛;也可内联 provider/model 直接指定模型(或沿用 llm_profile 引用顶层 agents keydelegate/emit_signal/get_skill/agent_task 为运行时注入工具,不能写进 tools(分别由 delegates/signal/skills 字段派生),get_skill 例外作为启用 scoped skill 的开关。每个定义可用 enabled: false 单独禁用(保留在磁盘但不加载)。主 Agent 可委托给任意具名子 Agent子 Agent 能否继续委托由 delegates 决定——不写该字段时默认仅可委托内置 general-purpose,写 [] 表示不可继续委托,写 ["*"] 表示可委托任意子代理写列表则按列表指定self 与祖先在运行时始终被拒绝。WebUI「子 Agent」页可直接增删改定义、启停并选择工具/Skill/Provider/Model 与委托范围。

更完整的配置字段说明见 resources/skills/about-picobot/references/config.md

agent-browser 安装与使用

PicoBot 不再使用 Fantoccini、ChromeDriver 或 WebDriver。上层仍暴露一个稳定的 browser 工具,底层通过 agent-browser 0.33.0 的 JSON CLI 驱动原生 Rust daemon 和 Chrome CDP。先安装 CLI 与浏览器:

# 推荐npm 只负责安装预编译 CLI
npm install -g agent-browser@0.33.0
agent-browser install

# Linux 需要同时补齐系统库时
agent-browser install --with-deps

# 或直接通过 Rust 工具链安装
cargo install agent-browser --version 0.33.0 --locked
agent-browser install

# macOS 也可使用 Homebrew
brew install agent-browser
agent-browser install

已有 Chrome/Chromium 时可在配置中设置 browser_executable_path,或通过 AGENT_BROWSER_EXECUTABLE_PATH 指定。Docker 镜像已固定安装 agent-browser 0.33.0 与 Debian Chromium不包含 ChromeDriver。启用示例

{
  "browser": {
    "enabled": true,
    "command": "agent-browser",
    "headless": true,
    "browser_executable_path": null,
    "max_sessions": 4,
    "idle_timeout_secs": 900,
    "command_timeout_secs": 120,
    "max_output_chars": 50000,
    "content_boundaries": true,
    "allowed_domains": [],
    "allow_private_hosts": false,
    "artifact_dir": "~/.picobot/media/browser",
    "persistence": {
      "profile_dir": "~/.picobot/browser/profiles"
    }
  }
}

浏览器没有全局“持久模式”开关,而是按每次调用分流:不传 persistent_id 时使用当前 dialog 的普通临时浏览器涉及长期工作、需要保留登录或站点状态时Agent 可以自主调用 browser_profiles(create,label=...) 生成 picobot-profile-<uuid>,并在该工作的后续每个 browser action 中持续传入同一个 ID。也可以用 set_label 随时修改语义化标签。PicoBot 不设置默认 ID也不会按 dialog 自动选择持久 Profile。同一 ID 跨 dialog 共享 agent-browser session 和串行锁,不同 ID 使用各自的 session、锁与 Chrome Profile因而可以并发操作。Cookie、localStorage、IndexedDB、Service Worker、缓存和标签随各自目录持久化。

browser_profiles 支持 createset_labellistdeletelist 返回 ID、标签、目录和 active 状态,浏览器仍始终用不可变 ID 选择重命名标签不会破坏现有调用。Profile 根目录位于 ~/.picobot 内,现有 Docker picobot_data 卷会一并持久化。agent-browser 无法同时保证 Profile 复用与 allowed_domains 域名隔离配置非空白名单后普通临时浏览器仍可用持久身份的创建和使用会被拒绝health 会给出可选能力警告。

缺少 agent-browser 或 Chrome 不阻止 Gateway 启动,但实际调用会失败并给出安装提示,picobot health 也会提前报告。修改后建议先运行 health再启动或重载 Gateway。旧的 webdriver_urlchrome_path 配置已删除,出现这两个字段时配置校验会明确失败。实际使用仍由 Agent 调用 browseropensnapshot 获取 @e1 等引用 → click / fill / type → 页面变化后重新 snapshot。截图保存到受控产物目录,通过统一工具输出管线交给多模态模型,并默认附到本轮最终回复给用户查看,不再生成 Base64 工具文本;仅需模型内部检查时可显式设置 present_to_user=false

详细开发分层、进程协议、并发/安全边界和故障语义见 agent-browser 集成设计

WebSocket API

Gateway 暴露:

Method Path 说明
GET /health 健康检查和版本信息
GET /api/auth/status 当前设备配对状态
POST /api/auth/pair 用一次性代码配对设备
POST /api/auth/code 本机 CLI 签发配对码;要求回环来源和管理密钥
GET /ws WebSocket 聊天协议;要求配对 Cookie 或 Bearer token

Inbound 消息类型:

Type 主要字段
user_input content,可选 channelchat_idsender_id
clear_history 可选 chat_idsession_id
create_session 可选 title
list_sessions include_archived
load_session session_id
get_session_history session_id,可选 limit(服务端限制为 12000
rename_session 可选 session_idtitle
archive_session 可选 session_id
delete_session 可选 session_id
get_slash_commands
ping

Outbound 消息类型包括活动 Turn 使用的 turn_updated,以及 assistant_responseerrorsession_establishedsession_createdsession_listsession_loadedsession_historysession_renamedsession_archivedsession_deletedhistory_clearedslash_commands_listpongcommand_executedsystem_notificationturn_updated 每次携带完整快照和单调 revision客户端只替换当前 session 的活动 Turnassistant_response 保留给独立完整消息。历史消息可包含 reasoning、turn/iteration、completion status 和结构化工具元数据,但不会暴露 Provider 私有回放状态。

测试

# 单元测试
cargo test --lib

# 离线集成/协议测试
cargo test --test test_scheduler
cargo test --test test_request_format

# 模型 API 集成测试需要 tests/test.env 中有真实 API key
cp tests/test.env.example tests/test.env
cargo test --test test_integration -- --ignored
cargo test --test test_tool_calling -- --ignored

会真实调用模型 API 的测试标记为 #[ignore];离线集成测试默认执行。

项目结构

src/
  agent/          LLM loop、上下文压缩、系统提示、媒体处理、子 Agent
  bus/            inbound、outbound、control 消息队列
  channels/       CLI chat 和飞书/Lark 集成
  client/         Ratatui 终端 UI
  config/         配置加载、环境变量替换、路径展开
  delivery/       活动 Turn 快照投影、节流与 TurnSink 生命周期
  gateway/        Axum HTTP/WebSocket server 和 GatewayState 装配
  mcp/            MCP 客户端连接和工具包装
  memory/         记忆管理和记忆类型
  observability/  Agent/tool telemetry observer
  providers/      OpenAI 兼容和 Anthropic provider
  scheduler/      定时任务运行时
  work/           Session 级任务计划与并行子项状态机
  session/        会话生命周期、dialog 命令、持久化集成
  skills/         Skill 加载和内置 Skill 安装
  storage/        SQLite schema 和 CRUD
  tools/          Agent 工具实现
  task_supervisor.rs  Gateway 后台任务的生命周期管理
resources/
  skills/         构建时嵌入的内置 Skills
  templates/      首次运行释放的配置和用户模板
tests/            单元测试和 ignored 集成测试
docs/             面向维护者和 Agent 的架构与开发文档

关键依赖

Crate 用途
axum, tokio, tokio-tungstenite Gateway 和 WebSocket runtime
sqlx SQLite 持久化
reqwest LLM 和 HTTP 客户端
ratatui, crossterm, termimad 终端 UI
rmcp MCP 客户端
cron, chrono-tz 定时任务
jieba-rs 中文记忆检索分词
zstd, tar 内置 Skill 打包和释放

进一步阅读