- updateText 移除文本宽度硬编码下限 160,真正根据内容自适应 - showRefining/showThinking 简化为调用 updateText,复用自适应逻辑 - 面板最小宽度由 minPanelWidth(180pt) 兜底 - 打包 VoiceInput-20260425.dmg
127 lines
7.2 KiB
Markdown
127 lines
7.2 KiB
Markdown
---
|
||
name: run-command-guide
|
||
description: run_command 工具使用指南。介绍前台与后台模式、后台模式处理长时间命令的标准流程(command_id + sleep(wait_runcommand_id))、与 terminal 的边界、以及互斥参数约束。
|
||
---
|
||
|
||
# run_command 使用指南
|
||
|
||
## 核心原则
|
||
|
||
- `run_command` 是 **一次性执行** 的终端命令,适合查询文件信息(`ls`、`file`、`grep -n`)、触发 CLI 工具、做简单的数据转换或运行非交互脚本。它**不能**用于启动交互式程序(如 `python` REPL、`vim`、`top`)。
|
||
- 每次调用必须提供 `timeout`(单位秒,必须大于 0),系统会在超时后强制打断命令并返回当前输出。
|
||
- 输出内容有字符数限制(默认 10000 字符),超过时会被截断或遭拒,因此尽量控制命令输出量,必要时拆分多个命令或保存到文件再读取。
|
||
- `run_command` 是当前“单条命令”默认入口:短命令走前台,长命令优先走后台模式。
|
||
- 只有在需要会话状态(`cd`/`source`/`export` 后多步连续)或常驻服务时,才优先使用 `terminal_*`。
|
||
|
||
## 长时间任务默认策略(重要)
|
||
|
||
以下场景默认优先 `run_command(run_in_background=true)`:
|
||
- `npm run build` / `cargo build` / `mvn package`
|
||
- `pip install ...` / `npm install ...` / `brew install ...` / `apt install ...`
|
||
- 单次 `git clone`、单次数据导入/导出、单次压缩打包
|
||
|
||
标准流程:
|
||
1. 后台发起命令并拿到 `command_id`
|
||
2. 先继续处理其他任务
|
||
3. 需要最终结果时调用 `sleep(wait_runcommand_id=command_id)`
|
||
4. 或等待系统完成通知
|
||
|
||
## 执行模式:前台 vs 后台
|
||
|
||
### 前台模式(默认,`run_in_background=false`)
|
||
|
||
- timeout 上限 30 秒。命令在工具完成前会阻塞整个模型线程,返回后即可马上读取 `output`、`return_code` 等字段。
|
||
- 适合“快照式”场景:查看目录、检查某个文件、运行一条短命令并立刻需要结果。
|
||
- 要求命令在 30 秒内完成,否则会中断并返回 `status: "timeout"`。
|
||
|
||
### 后台模式(`run_in_background=true`)
|
||
|
||
- timeout 最长 3600 秒。命令在后台继续执行,工具会等约 5 秒收集当前输出并返回,然后 **立即释放控制权**,让你继续处理其他任务。
|
||
- 返回值里会包含 `command_id`,`status` 可能是 `running_background`。你会拿到已经产生的输出片段,但最终结果要靠系统通知或手动等待。
|
||
- 成功或失败完成后,系统会自动发送一条 `system` 消息(内容类似 `后台命令已完成(completed)`,并附带 `command_id`、`command`、`output` 摘要)通知你。不要再依赖 `wait_sub_agent`/手动轮询。
|
||
- 适合长时间任务(构建/安装/批处理)或你想“先发起再继续别的工作”。
|
||
- 返回的 `command_id` 需要保留,用于后续通过 `sleep(wait_runcommand_id=...)` 等待结果或根据通知定位输出。
|
||
|
||
## 何时不要用 run_command(改用 terminal)
|
||
|
||
- 需要 `cd` 后连续执行多条命令
|
||
- 需要 `source venv/bin/activate` 后持续执行
|
||
- 需要常驻服务(如 `npm run dev`)或持续追踪输出(如 `tail -f`)
|
||
- 需要长期复用同一 shell 上下文
|
||
|
||
## 等待后台命令完成:command_id + sleep(wait_runcommand_id)
|
||
|
||
1. 调用后台命令后记录 `command_id`(形如 `cmd_<时间戳>_<8位hash>`);
|
||
2. 当你确实需要知道最终输出/返回码时,调用 `sleep(wait_runcommand_id=command_id)`;
|
||
3. `sleep` 工具会阻塞直到命令完成,返回值的 `result` 字段就是后台命令的最终 payload,`success`/`return_code` 等都可以直接使用;
|
||
4. `sleep` 默认会验证该 `command_id` 是否属于当前对话;跨会话调用会报错。
|
||
|
||
注意:即使你不调用 `sleep`,后台命令完成后也会有系统通知,只要收到消息就可以去交叉检查输出或 `sleep` 结果。
|
||
|
||
## `sleep` 工具的互斥参数规则
|
||
|
||
- `sleep` 工具支持三种等待方式:`seconds`(纯等待)、`wait_sub_agent_ids`(等待子智能体)、`wait_runcommand_id`(等待后台 `run_command`)。
|
||
- **只能选择其中一个等待参数**,否则会报错 “sleep 的等待参数互斥”;
|
||
- 如果你需要短暂停顿而非等待任务完成,传 `seconds` 并可选填 `reason`;
|
||
- 需要等待后台命令完成时仅填写 `wait_runcommand_id`,其余两个参数必须为 `null`/不传。
|
||
- `wait_runcommand_id` 返回:
|
||
```
|
||
{
|
||
"success": true,
|
||
"mode": "wait_runcommand_id",
|
||
"command_id": "...",
|
||
"result": {...}, # 与 run_command 结果结构一致
|
||
"message": "后台 run_command 等待完成"
|
||
}
|
||
```
|
||
|
||
## 常见坑与注意事项
|
||
|
||
1. **忘记设置 `timeout` 或给值 ≤ 0**:前台/后台都会立即报错。后台模式还有限制(>0 且 ≤3600)。
|
||
2. **误以为后台模式会自动输出最终结果**:后台只返回 `running_background` 的片段,必须通过系统通知或 `sleep(wait_runcommand_id=...)` 才能拿到完整状态。
|
||
3. **没有保存 `command_id` 即失去追踪**:`command_id` 是等待、复查、排错的唯一标识符,出错后可直接用它查询后台管理器。
|
||
4. **在 wait/run_command 之间同时传多个 `sleep` 参数**:会被客户端拒绝,报错明确指出互斥约束。
|
||
5. **命令输出过大(超过 10000 字符)**:会被截断并提示降低输出量,可考虑写入文件再用 `read_file` 读取,或分步执行。
|
||
6. **尝试运行交互式程序**:`run_command` 明确禁止,命令会在 `_validate_command` 阶段失败。
|
||
7. **后台命令属于别的对话**:`sleep(wait_runcommand_id=...)` 会报 “该后台命令不属于当前对话”,只能在原 conversation 中等待。
|
||
8. **误把会话型任务交给 run_command**:当任务依赖 shell 上下文时请切换 `terminal_*`。
|
||
9. **误以为 `sleep` 会自动拼接 system message**:`sleep` 只是等待,系统通知仍旧按背景轮询插入,你收到 `system` 消息即可确认状态。
|
||
|
||
## 示例
|
||
|
||
### 前台快速查询
|
||
|
||
```python
|
||
run_command(command="ls -a docs | head", timeout=5)
|
||
# 立即得到输出和 return_code
|
||
```
|
||
|
||
### 后台安装并等待
|
||
|
||
```python
|
||
# 发起后台安装
|
||
bg = run_command(
|
||
command="python -m pip install -r requirements.txt",
|
||
timeout=600,
|
||
run_in_background=True
|
||
)
|
||
command_id = bg.get("command_id")
|
||
|
||
# 可先去做别的事情,或立即等待最终状态
|
||
sleep(wait_runcommand_id=command_id, reason="等待 pip 安装完成")
|
||
# 返回 result["result"]["output"], return_code 等最终内容
|
||
```
|
||
|
||
### 结合系统通知与 sleep
|
||
|
||
- 系统会插入类似 `后台命令已完成(completed)` 的 `system` 消息,包含 `command_id`。
|
||
- 如果你优先希望第一时间处理输出,可以在收到消息后再 `sleep(wait_runcommand_id=command_id)` 来确认成功状态(即使已有通知,也可再次 `sleep` 获得 `result` 结构)。
|
||
|
||
## 总结
|
||
|
||
- 单条命令默认使用 run_command:前台用于快照,后台用于长任务。
|
||
- 后台结果需要 `command_id + sleep(wait_runcommand_id=...)` 或系统通知来确认最终状态。
|
||
- 会话型/常驻型任务请使用 terminal。
|
||
- `sleep` 的等待参数互斥,务必只传一个。
|
||
- 避免交互式命令、超出字符/超时限制,必要时将输出先写到文件再读。
|