工具执行系统
wesgine 的工具执行系统管理 Agent 可用工具的注册、发现、分类与调用。
工具六源四层归属
| 来源 | 归属层 | 生命周期 |
|---|---|---|
| Tier E 内置工具(read/write/exec/grep…) | Layer 2 Kernel | 编译时固定 |
Tier C SDK 闭包(cell.Tools().Register) | Layer 3 Cell | 随 Cell |
MCP proxy(cell.MCPs().Upsert) | Layer 3 Cell | 随 Cell |
| Adapter 派生(kb/email/cron/headless-browser…) | Layer 3 Cell | 随 Cell |
| Sub-agent as Tool | Layer 3 Cell | 随 Cell |
Per-run 临时 Tool(RunParams.Tools) | Layer 4 Actor | 单次 Run |
Exec 工具
前台执行
- ctx 结束后必须调用
KillProcessGroup()清理整个进程组(INV-EXEC-11) - 防止逃逸的 grandchild 存活
输出读取
- 无条件消费管道直到 EOF(INV-EXEC-DRAIN-01)
- 禁止
bufio.Scanner读命令输出——1MB 上限遇无换行大输出会死锁 - 使用
ReadSlice循环 +cappedWriter限内存
超时清理
- 进程退出后 stdout 排空最多等 5s(INV-EXEC-12)
- 超时强制
CloseOutput()解除 scanner 阻塞
进程安全(INV-EXEC-PROC-01)
一个原语生成子进程:proc.Command(ctx, ...)
// 正确
cmd := proc.Command(ctx, "go", "build", "./...")
// 禁止
cmd := exec.Command("go", "build", "./...")
cmd := exec.CommandContext(ctx, "go", "build", "./...")
proc.Command 确保:
Setpgid: true(建进程组)- cancel 时
SIGKILL整个组 WaitDelay给Wait()封顶
治理链
三步管道
Hardline → Sandbox → Zone
| 步骤 | 职责 |
|---|---|
| Hardline | 灾难命令拦截(18 条正则,不可覆盖) |
| Sandbox | 数据边界(DenyPaths / NetworkPolicy) |
| Zone | 效果分类 + GovernMode 决策 |
Zone 分类
| Zone | 含义 |
|---|---|
| Green | 纯读取 → Allow |
| Yellow | 写入 → GovernMode 决策 |
| Red | 危险 → 条件审批 |
Hardline 不限于 exec
对所有工具检查 command/cmd/script/shell JSON 字段(INV-GOV-01),覆盖 MCP 代理工具。
网络命令检测
NetworkPolicy=deny/internal_only 时按命令位置检测 curl/wget/nc/ssh 等(INV-GOV-02)。
工具 Handle API
cell.Tools() → ToolHandle
.Register(tool) // SDK 闭包注册
.List() // 工具列表(JSON Schema)
.Descriptions() // 工具描述(纯文本)
反模式
| 禁止 | 正确做法 |
|---|---|
裸 exec.Command | proc.Command(ctx, ...) |
bufio.Scanner 读命令输出 | ReadSlice 循环 + cappedWriter |
改写 proc.Command 返回的 Cancel/WaitDelay | 不要碰 |
| Hardline 只检查 exec 工具 | 所有工具检查 command 字段 |