# 内置工具

工具审批行为及运行中切换请参见[工具权限模式](permissions.zh.md)。

OpenProgram 自带一批注册为工具的函数，模型在聊天里直接调用。这一页按 `openprogram/programs/tools/` 目录逐个列出：每个工具做什么、需要什么 key 或本地依赖。大多数工具零配置；需要 key 的集中在网络检索和图像两类。

## 文件与代码

| 工具 | 做什么 | 需要什么 |
|---|---|---|
| `read` | 读文件内容 | 无 |
| `write` | 新建或整体覆盖文件 | 无 |
| `edit` | 文件内字符串替换 | 无 |
| `apply_patch` | Codex / OpenClaw 格式的多文件结构化 patch | 无 |
| `list` | 列目录内容 | 无 |
| `glob` | 按文件名模式找文件 | 无 |
| `grep` | 内容搜索，优先 ripgrep，缺 rg 回退 Python re | 无（装 `rg` 更快） |
| `semble_search` / `semble_find_related` | 语义 + 词法代码搜索，返回排好序的代码块 | 每个受支持的 release 已包含；source developer 通过锁定的项目环境安装 `search` extra |
| `lsp_diagnostics` / `lsp_references` / `lsp_definition` | 从 language server 拿类型检查错误、真实调用点、真实定义位置，见[Language server 工具](lsp.zh.md) | Python 装 `pyright`，TypeScript 装 `typescript-language-server`（缺哪个工具就报哪条安装命令） |

### 文档版本

对于 Word、PowerPoint、PDF、图片等二进制文件，模型可以先生成独立的临时结果，再调用 `write(file_path="/absolute/final.docx", source_path="/absolute/staged.docx")` 写入最终文件。`source_path` 与文本 `content` 只能指定一个。来源必须是本地普通文件，最大 64 MiB。覆盖已有目标前须先读取；二进制读取返回文件信息，并建立与文本读取相同的内容变更检查。

在会话中写入时，系统将修改前后的完整字节保存到这一轮的文件历史。重新打开会话或重启应用后，记录仍然存在。撤销和重新应用使用保存的版本；文件后来被修改且发生冲突时，不会覆盖后续内容。新建文件也能撤销，不要求项目文件夹是 Git 仓库。

完整版本保留格式和嵌入媒体，但当前 Review 不比较文档排版，也不显示 Word 修订标记。直接覆盖最终文件的普通 shell 命令不会成为本轮精确修改记录。过去未记录的版本无法根据文件卡片或命令输出补建；脚本应生成独立结果，再通过 `write` 写入最终文件。

后续历史提交失败时，之前已发布的版本仍完整保留。写入后尚未记录结果就中断时，文件历史显示结果未确认，并禁止精确恢复；不推断成功，也不把它当作没有修改。历史损坏会阻止继续记录写入，不会覆盖为空记录。首次尝试失败后，重新读取当前文件再重试。版本随所属轮次保留，并沿用现有历史保留策略。新增本地文档生成器复用 `source_path` 发布接口，无需另建版本存储。

通过项目文件编辑器进行的手动修改也会保留修改前后的完整字节，独立于会话历史。每次成功写入立即发布；同一编辑器的连续修改最多合并为五分钟的一条版本，结束分组或发现外部修改时另建版本。恢复历史版本会新增记录，并检查当前文件版本后再覆盖。项目磁盘断开时仍可读取已保存的历史；写入和恢复需要项目位置可用。项目位置变化后，恢复使用登记的新位置。文档 API 接受不超过 64 MiB 的二进制内容，但这并不代表每种二进制格式都已提供编辑界面。


项目文件默认打开预览。加载时居中显示资源准备和文档打开状态；加载期间关闭文件会取消待加载的编辑器，初始化失败后可以重试。支持的 UTF-8 文本文件可以选择“编辑”，修改会自动保存，也可以按 Ctrl/Cmd+S 立即保存。预览与编辑之间切换会保留编辑器的撤销记录。“历史”可查看保留版本修改前后的内容，并恢复选定版本。保存失败或磁盘文件被其他程序修改时，草稿会保留，可以重试、导出或明确选择丢弃。关闭文件会等待待保存修改完成；保存失败时标签保持打开。聊天附件使用同一预览窗口，以只读方式打开。

PDF 预览支持翻页、缩放和文本搜索；搜索前 500 页，更长的文档会明确显示这个范围。PSD 预览显示 8 位 RGB 文件保存的合成图和图层名称，TIFF 预览显示首页。这些解码器最多接收 64 MiB，并限制渲染图像大小。常见图片默认打开预览，音频和视频使用浏览器播放控件，编解码器支持取决于浏览器。损坏或不支持的文件仍可下载原文件。查看历史版本时使用该版本保留的字节。解码器资源保存在本地，打开对应格式时才加载。这些预览模式不编辑 PDF、PSD、TIFF、音频或视频文件。

Office 支持是演示文稿、文档和表格共用的可选本地组件，默认 App 和运行环境不附带它。未安装时打开 Office 文件会显示“安装”和“取消”，只有选择“安装”才开始下载。下载约 699 MiB，包含 ONLYOFFICE 资源、字体、许可证和源码材料，文件在本机处理。安装先校验固定版本压缩包和全部资源，再选择完整版本；失败可以重试，已有安装保留。安装成功后自动打开当前文档，无需重启 App。取消后仍可下载原文件，也可通过“安装选项”重新选择。通过远端访问应用时，本地 Office 编辑器不可用。PDF 预览不依赖这个组件。文件窗口支持 DOCX、PPTX、XLSX、ODT、ODP 和 ODS 的预览与编辑，默认打开预览。选择编辑后会等待原生编辑器进入可写状态，修改随后自动保存。切换预览、标签、分栏或历史时保留当前编辑器及其原生撤销记录。关闭前会等待尚未提交的输入和文件写入；写入失败时保留文档供重试。历史版本只读预览，恢复版本会新建一条保留记录。旧 DOC、PPT、XLS 可以明确转换为新路径下的 DOCX、PPTX、XLSX，原文件保留，已有目标不会被覆盖。附件保持只读，编辑器无法加载时仍可下载原文件。这些窗口不提供 Office 内容修订差异视图。

静态 PNG、JPEG 和 WebP 支持编辑，可裁剪、旋转、绘图、添加形状和文字。修改通过文档历史控制器自动保存；切换预览、历史、标签或页面时保留原生撤销与重做记录。写入失败会保留可编辑草稿供重试，关闭前等待导出完成。转换为 PNG 会创建独立文件，已有目标不会被覆盖。动画 PNG/WebP 和 16 位 PNG 保持只读。编辑最多接收 64 MiB、1600 万像素，单边不超过 16384 像素；不支持或损坏的文件仍可下载原文件。图片编辑导出渲染后的像素，不承诺保留嵌入元数据。附件和历史预览保持只读。

同一个“历史”界面汇总该项目相对路径下的手动修改和已确认的模型修改。模型版本直接读取原会话 checkpoint 保留的修改前后字节，不另建会话副本。恢复所选版本只修改这一个文件，检查当前版本后新建一条手动历史记录。归档会话保留文件历史；彻底删除会话后，其模型版本不再可读。手动历史独立保留。旧会话历史分批索引，点击“继续加载历史”处理下一批；尚未完成或无法核实的历史会明确标注。旧路径只有能够确认项目归属时才会汇总。项目移动不改变新记录的文件历史身份；磁盘离线时可读取保留版本，恢复需要项目位置可用。

## 执行

| 工具 | 做什么 | 需要什么 |
|---|---|---|
| `bash` | 同步执行 shell 命令，返回 stdout / stderr / 退出码 | 无 |
| `process` | 管理后台 shell 会话（长跑服务、可轮询输出） | 无 |
| `execute_code` | 在独立子进程里跑 Python 片段 | 无 |

`execute_code` 返回 stdout、stderr 和已观察到的退出码。非零退出或超时返回错误结果，部分输出仍可用于检查失败原因。只有零退出码表示成功。每次调用使用新的 Python 子进程。

### 独立命令的执行目录

`bash` 每次调用都启动新的 shell。可通过可选参数 `workdir` 指定本次调用的起始目录，例如 `bash(command="npm test", workdir="apps/web")`。这是工具调用写法；普通 Python 导出的对象是 AgentTool，而不是直接执行 shell 的函数。

本地相对路径从当前绑定的 worktree 解析；未绑定时使用宿主进程目录，也支持绝对路径。路径按字面值处理，不展开 `~`、环境变量或 shell 表达式。省略 `workdir` 保留原来的 worktree／后端默认目录。某次命令里的 `cd` 或 `export` 不影响下一次调用；`workdir` 也不改变 worktree 绑定或文件工具的路径基准。

目录不存在、不是目录或未获授权时，不执行请求的命令，不自动创建目录，也不回退到其他位置。指定目录本身不授予访问权限。启用本地沙箱策略时，显式目录须符合原工作区的读写策略，包括符号链接和已有额外授权目录；执行仍受原沙箱边界约束。配置的沙箱不可用时，显式 `workdir` 不会绕过它继续执行。

SSH 和 Docker 在后端文件系统中按 POSIX 路径解释显式目录，不使用宿主文件系统解析远端路径。远端相对路径需要绝对 POSIX worktree 绑定。受保护的目录切换在目录不可用时阻止后续整个命令列表，Docker 不会通过 `-w` 自动创建指定目录。启用宿主沙箱策略时，在后端原生路径授权可用之前，显式远端 `workdir` 会被拒绝。省略该参数保留现有后端行为。

结果包含选择的本地起始 `cwd`；对于未独立观测规范位置的远端路径，显示 `requested_cwd`。这不是命令结束后的目录，也不表示 shell 状态持续。长时间运行的进程仍由独立的 `process` 工具管理；`bash` 不操作桌面集成终端。

## 网络

| 工具 | 做什么 | 需要什么 |
|---|---|---|
| `web_search` | 关键词 → 相关 URL 列表，多后端可选 | 见下方后端表 |
| `web_fetch` | 拉取 URL 并转成可读文本 | 无（装 `trafilatura` 抽取更干净） |
| `playwright_browser` | Playwright 驱动无头 Chromium（open / navigate 等动作） | 每个受支持的 release 已包含 Playwright Chromium |
| `agent_browser` | 经 npm `agent-browser` CLI 驱动浏览器，snapshot 返回可访问性树 | 开发者增加的替代 backend，不用于补齐产品 Browser 功能 |

`web_search` 后端与 key（arXiv 与 DuckDuckGo 免 key，始终可用）：

| 后端 | 环境变量 |
|---|---|
| DuckDuckGo / arXiv | 无 |
| Brave | `BRAVE_API_KEY` |
| Exa | `EXA_API_KEY` |
| Firecrawl | `FIRECRAWL_API_KEY` |
| Google PSE | `GOOGLE_PSE_API_KEY` + `GOOGLE_PSE_CX` |
| Jina | `JINA_API_KEY` |
| Kagi | `KAGI_API_KEY` |
| MiniMax | `MINIMAX_CODE_PLAN_KEY`、`MINIMAX_CODING_API_KEY` 或 `MINIMAX_API_KEY` |
| Moonshot (Kimi) | `KIMI_API_KEY` 或 `MOONSHOT_API_KEY` |
| Perplexity | `PERPLEXITY_API_KEY` |
| SearXNG | `SEARXNG_URL`（自托管实例地址） |
| Serper | `SERPER_API_KEY` |
| Tavily | `TAVILY_API_KEY` |
| You.com | `YDC_API_KEY` 或 `YOU_API_KEY` |
| Ollama | 本地 Ollama（需 `ollama signin`），或用 `OLLAMA_API_KEY` 走 Ollama Cloud |

聊天中的 Web Search 开关控制本条消息是否可使用 `web_search`；关闭后，即使是自动工具模式也会排除此工具。开启后直接提供搜索工具定义，Tools 关闭时也可调用。开启仍遵守 Agent 禁用工具和权限设置。Tool profile 按会话保存，切换标签和刷新后保留。

新增搜索 key 在后续调用中生效，无需重启。默认后端不可用时使用其他可用后端；显式指定不可用后端则报错，错误说明原因（例如缺少的 key）并列出当前可用的后端。Jina 搜索需要 `JINA_API_KEY`。DuckDuckGo 读取其无 JavaScript 结果页，返回第一页结果（约十条）；遇到机器人验证或无法解析的页面时报错，而不是返回空结果。`combine="race"` 返回首个非空成功结果；`providers` 中无法运行的后端会被跳过，全部无法运行时错误逐个列出原因；`combine="rrf"` 保留截止时间前完成的结果。全部失败返回错误，与成功但无结果区分；已开始的请求按各自传输超时结束。

## 图像与 PDF

| 工具 | 做什么 | 需要什么 |
|---|---|---|
| `image_generate` | prompt → PNG 存盘 | 任一后端：OpenAI（`OPENAI_API_KEY`）、Gemini（`GEMINI_API_KEY` 或 `GOOGLE_API_KEY`）、fal（`FAL_KEY`） |
| `image_analyze` | 描述图片 / 回答关于图片的问题（本地路径或 URL） | 任一视觉模型 key：OpenAI / Anthropic / Gemini（复用已配置的 provider key） |
| `pdf` | 从 PDF 抽取文本，支持 offset / limit 翻页 | 完整 release 已内置（`pypdf`） |

图像工具在所选 Provider 不可用、调用失败或图片无法保存时返回错误结果。`mixture_of_agents` 在模型引用未知、所有参考调用失败或汇总失败时也返回错误结果。部分参考调用失败但得到有效回答，或成功回答的文本包含 Error 字样时，结果仍然是成功。普通 Python 的 `execute(...)` 调用保持字符串返回值。

## 会话与协作

协作分四个域，一词一义，见
[agent 协作](../reference/design/runtime/agent-collaboration.zh.md) §1。

| 域 | 工具 | 做什么 | 需要什么 |
|---|---|---|---|
| 计划 | `todo_create` / `todo_update` / `todo_list` | 会话规划清单：手写的计划清单（建条目、设状态/负责人/依赖、按状态分组列出）。写一条不会启动任何东西 | 无 |
| 执行 | `list_jobs` / `job_output` | 列出本会话的后台任务，等待或查看结果。结果读取检查派发会话和祖先任务的所有权 | 无 |
| 实体 | `agent` | 新建一个 agent 并取回回复，或用 `to=` 给已存在的 agent 派受管任务。`run_in_background=true` 不阻塞、直接返回 job_id；`start_from` 决定新 agent 从哪起（`clean` / `inherit` / `SID:MSG_ID`）；`archive_when_done=true` 让它在任务结束、结果回流之后自动归档 | 无 |
| 实体 | `list_agents` | agent 列表：有哪些 agent、它们的名字、地址、体量和忙闲（`scope="archived"` 看已归档的） | 无 |
| 实体 | `archive_agent` | 把活干完的 agent 归档：它从 `list_agents` 消失，并拒收后续 `send_message` / `agent(to=)` 投递；`read_conversation` 照读它的历史，`agent(start_from="SID:MSG_ID")` 照 fork。归档不中断在跑的工作、不删数据，所以任何会话都能归档任何 agent；归档单向，没有反归档 | 无 |
| 通讯 | `send_message` | 跟已存在的 agent 说话，按 `"SID:HEAD"` 或名字寻址。不产生任务、不产生 job_id、没有东西可取消，所以任何 agent 都能发 | 无 |
| 通讯 | `read_conversation` | 把任意 agent 的历史读成纯文本（含工具调用），可指定轮次范围和字数预算 | 无 |

协作消息额度耗尽后，`job_output` 仍可用；读取已有结果不消耗该额度。新的 Agent 投递仍须遵守相应上限。取消任务使用它的执行控制；API 取消使用 `execution.command`，设置 `action="execution.cancel"` 并传入当前执行版本。当前工具目录没有 `job_stop`。

| 工具 | 做什么 | 需要什么 |
|---|---|---|
| `program` | 调用任意已注册的 `Agent` method | 无 |
| `mixture_of_agents` | 并行问N个模型再综合;默认从模型注册表选,每个provider取一个 | 模型注册表里至少2个provider |
| `ask_user_question` | 向用户提 1–N 个带选项的问题 | 需要交互前端；输入基础设施不可用、问题数组无效或无交互上下文时返回工具错误 |
| `enter_plan_mode` / `exit_plan_mode` | 进入 / 退出计划模式 | 无 |
| `canvas` | 往 markdown 文件的具名块里增量写入；`set` 的 `content=""` 清空正文，省略内容则返回错误 | 无 |
| `memory_*` | 读取持久记忆工作区——`memory_search`（按语义找）、`memory_grep`（找确切字符串）、`memory_get`（读一个文件、章节或段落）、`memory_browse`（看有什么）、`memory_status`（规模与版本），以及 `memory_update` 用来更正某一处。没有记录对话的工具：那件事在后台完成。每个实例只有一份工作区，所有agent、所有对话（含聊天渠道）共用（见[聊天渠道](../integrations/channels.zh.md#谁能和你的机器人说话)）。 | 无 |
| `worktree_*` | git worktree：`worktree_create`（也可直接从 PR 开 worktree，传 `pr="123"` / `"#123"` / GitHub PR 链接，走 `gh`）/ `merge` / `discard` / `list` / `keep` | git |
| `cron` | 登记周期性 agent 任务 | 无 |
| `list_mcp_resources` / `read_mcp_resource` / `list_mcp_prompts` / `get_mcp_prompt` | 把 MCP 的 resources / prompts 原语暴露给模型（`mcp_meta` 目录） | 已配置的 MCP server（见 [MCP](mcp.zh.md)） |
| `tool_search` | 按需加载延迟工具；下一次模型请求包含其完整 schema | 无 |

已注册的 `canvas` 与 `agent_browser` 对明确的校验、依赖和进程失败设置错误标记。成功的 Canvas 正文与 CLI stdout 即使以 `Error:` 开头也保持成功。普通 Python `execute()` 调用仍返回字符串。
