- Add tools registration section in session.rs - Add update log table with all commits
8.5 KiB
8.5 KiB
Picobot 工具机制增强实现日志
实现记录
1. SchemaCleanr - 跨 Provider Schema 归一化
日期: 2026-04-07
Commit: d5b6cd2
背景
不同 LLM provider 对 JSON Schema 支持差异很大:
- Gemini: 最严格,不支持
minLength,maxLength,pattern,minimum,maximum等 - Anthropic: 中等,只要求解决
$ref - OpenAI: 最宽松,支持大部分关键词
实现方案
创建 src/tools/schema.rs,提供:
-
CleaningStrategyenumpub enum CleaningStrategy { Gemini, // 最严格 Anthropic, // 中等 OpenAI, // 最宽松 Conservative, } -
SchemaCleanr::clean()- 核心清洗函数- 移除 provider 不支持的关键词
- 解析
$ref到$defs/definitions - 将
anyOf/oneOf合并为enum - 将
const转换为enum - 移除
type数组中的null
-
SchemaCleanr::validate()- Schema 验证
使用方法
use picobot::tools::{SchemaCleanr, CleaningStrategy};
// Gemini 兼容清洗(最严格)
let cleaned = SchemaCleanr::clean_for_gemini(schema);
// Anthropic 兼容清洗
let cleaned = SchemaCleanr::clean_for_anthropic(schema);
// OpenAI 兼容清洗(最宽松)
let cleaned = SchemaCleanr::clean_for_openai(schema);
// 自定义策略
let cleaned = SchemaCleanr::clean(schema, CleaningStrategy::Conservative);
工具 Trait 增强
在 src/tools/traits.rs 的 Tool trait 中新增:
pub trait Tool: Send + Sync + 'static {
// ... 原有方法 ...
/// 是否只读(无副作用)
fn read_only(&self) -> bool { false }
/// 是否可以与其他工具并行执行
fn concurrency_safe(&self) -> bool {
self.read_only() && !self.exclusive()
}
/// 是否需要独占执行
fn exclusive(&self) -> bool { false }
}
这些属性为后续的并行工具执行提供基础。
测试
- 12 个单元测试覆盖所有清洗逻辑
- 运行
cargo test --lib tools::schema验证
2. file_read 工具
日期: 2026-04-07
Commit: a9e7aab
功能
- 读取文件内容(支持 offset/limit 分页)
- 返回带行号的内容,便于引用
- 自动处理二进制文件(base64 编码)
- 可选的目录限制(安全隔离)
Schema
{
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件路径" },
"offset": { "type": "integer", "description": "起始行号(1-indexed)" },
"limit": { "type": "integer", "description": "最大行数" }
},
"required": ["path"]
}
使用方法
use picobot::tools::FileReadTool;
// 基本用法
let tool = FileReadTool::new();
let result = tool.execute(json!({
"path": "/some/file.txt",
"offset": 1,
"limit": 100
})).await;
测试
- 4 个单元测试
cargo test --lib tools::file_read
3. file_write 工具
日期: 2026-04-07
Commit: 16b052b
功能
- 写入内容到文件
- 自动创建父目录
- 覆盖已存在文件
Schema
{
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件路径" },
"content": { "type": "string", "description": "写入内容" }
},
"required": ["path", "content"]
}
测试
- 5 个单元测试
cargo test --lib tools::file_write
4. file_edit 工具
日期: 2026-04-07
Commit: f3187ce
功能
- 编辑文件,替换 old_text 为 new_text
- 支持多行编辑
- 模糊匹配处理微小差异
- replace_all 选项批量替换
Schema
{
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件路径" },
"old_text": { "type": "string", "description": "要替换的文本" },
"new_text": { "type": "string", "description": "替换后的文本" },
"replace_all": { "type": "boolean", "description": "替换所有匹配", "default": false }
},
"required": ["path", "old_text", "new_text"]
}
测试
- 5 个单元测试
cargo test --lib tools::file_edit
5. bash 工具
日期: 2026-04-07
Commit: 68e3663
功能
- 执行 shell 命令
- 超时控制
- 危险命令检测(rm -rf, fork bombs)
- 输出截断
- 工作目录支持
Schema
{
"type": "object",
"properties": {
"command": { "type": "string", "description": "Shell 命令" },
"timeout": { "type": "integer", "description": "超时秒数", "minimum": 1, "maximum": 600 }
},
"required": ["command"]
}
测试
- 7 个单元测试
cargo test --lib tools::bash
6. http_request 工具
日期: 2026-04-07
Commit: 1581732
功能
- HTTP 客户端支持 GET/POST/PUT/DELETE/PATCH
- 域名白名单
- SSRF 保护(阻止私有IP、localhost)
- 响应大小限制和截断
- 超时控制
Schema
{
"type": "object",
"properties": {
"url": { "type": "string", "description": "请求 URL" },
"method": { "type": "string", "description": "HTTP 方法", "enum": ["GET", "POST", "PUT", "DELETE", "PATCH"] },
"headers": { "type": "object", "description": "请求头" },
"body": { "type": "string", "description": "请求体" }
},
"required": ["url"]
}
测试
- 8 个单元测试
cargo test --lib tools::http_request
7. web_fetch 工具
日期: 2026-04-07
Commit: 8936e70
功能
- 获取 URL 并提取可读文本
- HTML 转纯文本
- 移除 scripts, styles, HTML 标签
- 解码 HTML 实体
- JSON 格式化输出
- SSRF 保护
Schema
{
"type": "object",
"properties": {
"url": { "type": "string", "description": "要获取的 URL" }
},
"required": ["url"]
}
测试
- 6 个单元测试
cargo test --lib tools::web_fetch
工具清单
| 工具 | 名称 | 文件 | 功能 |
|---|---|---|---|
| calculator | 计算器 | src/tools/calculator.rs |
25+ 数学和统计函数 |
| file_read | 文件读取 | src/tools/file_read.rs |
带分页的文件读取 |
| file_write | 文件写入 | src/tools/file_write.rs |
创建/覆盖文件 |
| file_edit | 文件编辑 | src/tools/file_edit.rs |
文本替换编辑 |
| bash | Shell 执行 | src/tools/bash.rs |
带安全保护的命令执行 |
| http_request | HTTP 请求 | src/tools/http_request.rs |
API 请求 |
| web_fetch | 网页获取 | src/tools/web_fetch.rs |
HTML 内容提取 |
工具机制增强
SchemaCleanr
跨 LLM Provider 的 JSON Schema 归一化,支持:
- Gemini (最严格)
- Anthropic (中等)
- OpenAI (最宽松)
- Conservative (保守)
工具属性
fn read_only(&self) -> bool { false } // 是否只读
fn concurrency_safe(&self) -> bool { true } // 是否可并行
fn exclusive(&self) -> bool { false } // 是否独占
运行测试
cargo test --lib # 所有测试
cargo test --lib tools::schema # SchemaCleanr
工具注册
工具在 src/gateway/session.rs 的 default_tools() 函数中注册:
fn default_tools() -> ToolRegistry {
let mut registry = ToolRegistry::new();
registry.register(CalculatorTool::new());
registry.register(FileReadTool::new());
registry.register(FileWriteTool::new());
registry.register(FileEditTool::new());
registry.register(BashTool::new());
registry.register(HttpRequestTool::new(
vec!["*".to_string()], // 允许所有域名
1_000_000, // max_response_size
30, // timeout_secs
false, // allow_private_hosts
));
registry.register(WebFetchTool::new(50_000, 30));
registry
}
SessionManager 使用这些工具创建 AgentLoop 实例,所有工具自动对 LLM 可用。
更新日志
| 日期 | Commit | 变更 |
|---|---|---|
| 2026-04-07 | d5b6cd2 |
feat: add SchemaCleanr |
| 2026-04-07 | a9e7aab |
feat: add file_read tool |
| 2026-04-07 | 16b052b |
feat: add file_write tool |
| 2026-04-07 | f3187ce |
feat: add file_edit tool |
| 2026-04-07 | 68e3663 |
feat: add bash tool |
| 2026-04-07 | 1581732 |
feat: add http_request tool |
| 2026-04-07 | 8936e70 |
feat: add web_fetch tool |
| 2026-04-07 | b13bb8c |
docs: add implementation log |
| 2026-04-08 | 98bc973 |
feat: register all tools in SessionManager |
| cargo test --lib tools::file_read # file_read | ||
| cargo test --lib tools::file_write # file_write | ||
| cargo test --lib tools::file_edit # file_edit | ||
| cargo test --lib tools::bash # bash | ||
| cargo test --lib tools::http_request # http_request | ||
| cargo test --lib tools::web_fetch # web_fetch |