# PicoBot 工具说明

## send_message — 向指定渠道发送消息

向指定会话发送消息，可附带文件或图片。

### 参数

| 参数 | 必填 | 说明 |
|------|------|------|
| `target_chat_id` | 是 | 目标会话 ID，格式 `<channel>:<chat_id>` 或 `<channel>:<chat_id>:<dialog_id>` |
| `content` | 是 | 消息文本内容 |
| `files` | 否 | 文件路径列表 |
| `origin` | 否 | 消息来源标识，不填则自动使用当前 session_id |

`files` 支持绝对路径和 workspace 相对路径，媒体类型由文件扩展名/MIME 自动判断。目前 schema 不支持手工指定 `file_types`。

目标可以是当前会话，例如把浏览器截图或生成文件直接交付给正在聊天的用户。WebUI/TUI 中，同一 active Turn 的附件会并入本轮最终回复：先显示工具调用与结果，再显示自然回复和内联图片，不生成 `[message from ...]` 自引用前缀。后续模型回放只读取 assistant 附件的文本清单，不会把图片放入 assistant 内容块。

### 示例

```json
{
  "target_chat_id": "feishu:oc_abc123",
  "content": "这是生成的音乐文件",
  "files": ["/workspace/music.mp3"]
}
```

发送流程会先把消息写入目标 Session，再调用 `MessageBus::deliver_outbound` 等待真实渠道投递结果（上限 120 秒）。投递失败会作为工具失败返回，不应把“已入队”报告成“已送达”。

---

## chat_manager — 会话管理

查看和管理会话及消息。

### 参数

| 参数 | 必填 | 说明 |
|------|------|------|
| `action` | 是 | 操作: `list_sessions`, `list_channels`, `list_messages` |
| `session_id` | 部分 | `list_messages` 时必填 |
| `count` | 否 | 返回数量（默认 20，最大 100） |
| `offset` | 否 | 跳过前 N 条，用于翻页 |
| `before_time` | 否 | Unix 时间戳（秒），返回该时间之前的消息 |
| `after_time` | 否 | Unix 时间戳（秒），返回该时间之后的消息 |

---

## Cron 定时任务工具

Cron 不是一个带 `action` 的统一工具，而是七个独立工具；仅在 `gateway.scheduler.enabled=true` 时注册。

| 工具 | 主要参数 | 说明 |
|------|----------|------|
| `cron_add` | `schedule`, `prompt`, `channel`, `chat_id`; 可选 `name`, `agent_id`, `delivery_policy` | 创建任务 |
| `cron_list` | 可选 `status=all|enabled|disabled` | 列出任务 |
| `cron_runs` | `job_id`; 可选 `run_id`, `limit` | 查询结构化运行和投递记录，包括静默结果 |
| `cron_update` | `job_id`; 可选 `name`, `prompt`, `schedule`, `channel`, `chat_id`, `agent_id`, `delivery_policy` | 更新指定字段；`agent_id:null` 切回 Root |
| `cron_remove` | `job_id` | 无活动 Run 或 pending delivery 时永久删除任务 |
| `cron_enable` | `job_id` | 启用并重新计算下次运行时间 |
| `cron_disable` | `job_id` | 禁用但保留任务 |

`schedule` 支持：

```json
{"type":"at","at":1750000000000}
{"type":"every","every_ms":3600000}
{"type":"cron","expr":"0 0 9 * * *","tz":"Asia/Shanghai"}
```

时间戳和间隔单位为毫秒；Cron 表达式为 6 段（秒、分、时、日、月、周）。过去时间的 At 不能创建、更新或直接重新启用。定时 Agent 不复用聊天历史，`prompt` 必须包含完整上下文；`agent_id` 省略时使用 Root，否则使用当前 AgentCatalog 中的命名 Agent。

每次运行必须恰好一次调用 `complete_scheduled_run(outcome,message)`，outcome 只能是 `ok`、`alert`、`failed`、`refused`。普通最终文本不会被解释为结果，缺少结构化终结会 fail-closed。投递完全由 Scheduler 决定：`always` 投递所有结果，`on_alert` 只抑制 `ok`，`never` 只保留记录。Scheduled Agent 不能自行发送最终通知；子 Agent 委托会同步完成，也不会产生后台 Inbox/Signal。

---

## memory_store — 存储记忆

写入长期记忆（Knowledge 类别）。

| 参数 | 必填 | 说明 |
|------|------|------|
| `key` | 是 | 记忆唯一键，同 key 覆盖旧值 |
| `content` | 是 | 记忆内容 |
| `importance` | 否 | 重要性 (0.0–1.0) |

## memory_recall — 搜索知识记忆

关键词全文搜索 Knowledge 记忆。

| 参数 | 必填 | 说明 |
|------|------|------|
| `query` | 是 | 空格分隔的关键词列表 |
| `since` | 否 | 起始时间戳（unix 毫秒） |
| `until` | 否 | 结束时间戳 |
| `limit` | 否 | 返回数量（默认 10） |

## timeline_recall — 搜索时间线

搜索压缩后的历史会话摘要。

| 参数 | 必填 | 说明 |
|------|------|------|
| `query` | 是 | 关键词 |
| `session_id` | 否 | 限定会话 |
| `since` | 否 | 起始时间 |
| `until` | 否 | 结束时间 |
| `limit` | 否 | 返回数量 |

## memory_forget — 删除记忆

按 key 删除记忆。

| 参数 | 必填 | 说明 |
|------|------|------|
| `key` | 是 | 要删除的记忆键 |

## routine_maintenance — 日常维护

清理超过 `memory.timeline_retention_days` 的 Timeline 记忆；不会删除 Knowledge。Gateway 在 Scheduler 启用时幂等创建一个每日运行的默认维护巡检，用户禁用或修改后不会在重启时被覆盖。

---

## get_skill — 获取 Skill

查询 skill 内容。

| 参数 | 必填 | 说明 |
|------|------|------|
| `action` | 否 | 操作: `get`(默认), `list` |
| `skill_name` | get时必填 | Skill 名称 |

---

## delegate — 子 Agent 委托

创建子 Agent 处理独立任务。

| 参数 | 必填 | 说明 |
|------|------|------|
| `target` | 具名 Agent 必填 | 目标 Agent ID；主 Agent 可委托给任意具名子 Agent，子 Agent 按自身 Definition 的 `delegates` 白名单决定 |
| `task` | 单任务必填 | 明确、独立、可验收的子任务 |
| `context` | 否 | 子 Agent 所需的显式事实；不会继承完整主会话历史 |
| `mode` | 否 | `foreground`（默认）或 `background`；批量并发不是第三种 mode |
| `tasks` | 批量必填 | 子任务数组；foreground 并发执行、结果保持请求顺序 |
| `allowed_tools` | 否 | 只能收窄具名 Definition 的工具集，不能扩权 |
| `plan_item_id` | 否 | 绑定当前计划子项；批量数组中的每项可分别绑定 |

子 Agent 的工具集完全由其定义文件（`~/.picobot/agents/*.md`）的 `tools` 列表决定，可直接内联 `provider`/`model` 指定模型。具名 background（`target` + `mode=background`，单任务或 `tasks[]` 批量）经 durable run/inbox 接纳：每个 run 先落 `agent_runs` 并预留 inbox completion slot，完成后由主 Agent 的 continuation Turn 处理结果，不再直接发 Channel 通知；批量并发执行、每个 run 独立返回（无用户输入积压时完成即返回）。子 Agent 发起的 background 尚未开放。后台运行可以在任务中调用 `emit_signal` 发送结构化内部信号（队列或 steer 投递），Steer 信号会在当前 Turn 的安全边界注入主 Agent；`agent_task.cancel` 会把该 run 未消费的普通信号标记 superseded。

## agent_task — 具名 Agent Run 查询与控制

仅在 `agent_orchestration` 启用时注册。查询或控制已持久化的具名 foreground run；授权来自调用者身份（ROOT 限本 session，具名 Agent 限自身子树），run ID 本身不是凭证。

| 参数 | 必填 | 说明 |
|------|------|------|
| `action` | 是 | `get` 查询单个 run；`list` 列出 session 的 run；`get_result` 读取终态完整结果；`cancel` 取消未终态 run |
| `run_id` | get/get_result/cancel 必填 | 目标 run ID |
| `cursor_created_at` / `cursor_id` | 否 | list 分页游标，必须成对出现 |
| `limit` | 否 | list 上限，默认 20 |

## todo — Session 任务计划

仅用于明确的复杂、多轮或并行任务。`create` 创建当前 session 唯一的 active plan；`view` 查看；`append` 增加子项；`update` 修改子项状态；`close` 完成或取消计划。普通闲聊和单步操作不应创建计划。子 Agent 始终不能使用 `todo`；只有 Definition 声明委托边的具名 Agent 会获得运行时注入的 `delegate`，且只能 foreground 委托允许目标。

---

## browser — 浏览器自动化

默认注册；设置 `browser.enabled=false` 后不注册。PicoBot 上层包装统一 action 和结构化媒体，底层逐次调用 agent-browser `--json`。调用时不传 `persistent_id`，每个 dialog 使用各自的普通临时 session，默认空闲一小时后自动关闭；长期工作需要保持浏览器进程或保留登录和站点状态时，Agent 可自主用 `browser_profiles(create,label=...)` 创建身份，并在后续相关 action 中持续传入同一个 ID。持久 session 不会因空闲自动关闭。PicoBot 没有全局持久化开关或默认持久 ID，也不按 dialog 自动选择持久身份；同一 ID 跨 dialog 共享 session 和串行锁，不同 ID 使用独立 session/锁并可并发。CLI daemon 通过 Chrome CDP 工作，不使用 Fantoccini、ChromeDriver 或 WebDriver。

| action | 说明 |
|--------|------|
| `open` | 打开 URL |
| `snapshot` | 获取页面结构快照 |
| `click`, `click_at` | 点击元素或坐标 |
| `fill`, `type`, `press` | 输入文本或按键 |
| `get_text`, `get_title`, `get_url` | 读取页面信息 |
| `screenshot` | 保存到 `browser.artifact_dir`，交给模型并默认附到最终用户回复；支持 `full_page`、`annotate`，可用 `present_to_user=false` 仅供模型检查 |
| `focus`, `hover`, `scroll`, `wait` | 常见交互和等待 |
| `close` | 关闭浏览器会话 |

典型流程：`open` → `snapshot` 获取 `@e` 引用 → 交互 → 页面变化后重新 `snapshot`。`path` 只接受 `.png` 文件名，不能逃逸产物目录。`open` 默认拒绝非 HTTP(S)、userinfo、回环、私网、本地域名及 DNS 解析到私网的地址；配置 `allowed_domains` 后，agent-browser 同时限制导航、子资源、WebSocket、EventSource 与 WebRTC。页面输出是不可信内容，默认开启 content boundary 元数据和 50,000 字符上限。

## browser_profiles — 持久浏览器身份管理

与 `browser` 一同注册。`create` 生成新的持久 ID 和 Profile 目录，并可接受 1–80 字符的语义标签；`set_label` 按精确 ID 重命名标签；`list` 返回每个合法 Profile 的 ID、标签、目录和 active 状态；`delete` 必须传入 `create/list` 返回的精确 ID，并删除该 ID 的完整 Chrome Profile、标签与登录态。删除活动 Profile 时会等待其操作完成并尝试关闭浏览器。标签只用于识别，不能代替 ID 选择；该工具不能接收任意目录。非空 `browser.allowed_domains` 下普通临时浏览器仍可用，但持久身份不能创建或使用。

依赖缺失时必须把错误和处置命令返回给用户，不能声称已浏览，也不能在工具内部静默安装：CLI 不存在时安装 `agent-browser@0.33.0`；Chrome 不存在时运行 `agent-browser install`；Linux 共享库不完整时运行 `agent-browser install --with-deps`。用 `picobot health` 复查，再用 `agent-browser doctor` 获取详细上游诊断。用户明确不需要浏览器时才建议 `browser.enabled=false`。

## health — 依赖检查

无参数时返回可读报告；`json=true` 返回结构化报告。核心必需项、当前配置启用后必需的依赖、可选功能分别标记。`fd` 与 Debian/Ubuntu 的 `fdfind` 是同一个首选文件搜索程序；只有传统 `find` 会产生降级警告。浏览器启用时会检查 CLI、可执行路径，并通过隔离的完整 offline doctor 分别验证浏览器安装、真实 headless 启动和环境。该工具只读，与 CLI `picobot health [--json]`、`/health` 斜杠命令以及 WebUI“配置 → 健康检查”复用同一个 `HealthService`。

---

## MCP 工具

如果 `config.mcp.servers` 配置了 MCP 服务器，Gateway 启动时会连接服务器、发现工具，并把 MCP 工具包装后注册到 ToolRegistry。注册名固定为 `mcp_<服务器名>_<工具名>`，例如 `mcp_filesystem_read_file`；配置 `tool_settings` 仍使用 MCP 原始工具名 `read_file`。使用 `/mcp` 查看当前连接状态和工具列表。MCP 协议不声明副作用或并发安全性；可在服务器配置的 `tool_settings` 中为各工具设置本地受信任的 `read_only`、`exclusive` 属性。未设置的工具顺序执行；“可并发”由 `read_only && !exclusive` 自动推导。

---

## file_read / file_write / file_edit / file_search / content_search — 文件操作和搜索

文件读写编辑、文件名搜索和内容搜索。相对路径从 workspace cwd 解析；默认注册的文件工具也接受绝对路径，因此 workspace 不是硬沙箱。详细参数以各工具的 `parameters_schema` 为准。

## bash — 执行命令

默认从 workspace cwd 执行 bash 命令。参数为 `command` 和可选 `timeout`；默认 60 秒、最大 600 秒，输出最多约 50,000 字符。命令继承 Gateway 进程权限，可以访问 workspace 外路径；危险模式拦截不是完整沙箱。

## pty — 持久终端会话

用于交互式程序和需要保持状态的长运行命令。`action` 支持 `spawn`、`write`、`read`、`kill`、`list`；`write/read/kill` 需要 `session_id`。Gateway 进程退出时 PTY manager 会清理子进程。

## http_request / web_fetch — HTTP 和 Web 工具

`http_request` 支持 GET/POST/PUT/DELETE/PATCH、headers 和字符串 body；`web_fetch` 提取 HTML/JSON 的可读文本。两者校验 URL 与 DNS 解析结果，阻止回环、私网、link-local 和本地域名，并禁用自动重定向，以降低 SSRF 风险。

## calculator — 计算器

数学表达式计算和统计函数。

| action | 说明 |
|--------|------|
| `evaluate` | 计算表达式 |
| `sum` | 求和 |
| `average` | 平均值 |
| `median` | 中位数 |
| `mode` | 众数 |
| `stdev` / `variance` | 标准差/方差 |
| `min` / `max` | 最小值/最大值 |
| `log` | 对数 |
| `factorial` | 阶乘 |
| `round` | 四舍五入 |
| `percentage_change` | 变化百分比 |
| `percentile` | 百分位数 |
