Files
HomeAgent/third_party/homeagent-sdk/example/files/README.md

85 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# files 插件讲解
文件系统操作插件,提供文件的读写编辑和目录浏览能力。
## 工具清单
| 工具 | 功能 | 源码 |
|------|------|------|
| `files_read` | 读取文件内容,支持 offset/limit 分段 | `handleRead` |
| `files_write` | 写入文件,支持 4 种模式 | `handleWrite` |
| `files_edit` | 精确字符串替换编辑 | `handleEdit` |
| `files_ls` | 列出目录内容 | `handleLs` |
## 核心设计
### 沙箱路径隔离
`resolvePath()` 方法将用户传入的路径解析为沙箱内的绝对路径。关键逻辑:
```go
// 相对路径以沙箱根目录为基准拼接
if !filepath.IsAbs(userPath) {
userPath = filepath.Join(p.filesDir, userPath)
}
// 检查是否越界
base := filepath.Clean(p.filesDir)
if base != "/" && !strings.HasPrefix(abs, base+string(filepath.Separator)) && abs != base {
return "", fmt.Errorf("path outside sandbox")
}
```
当沙箱根设为 `/` 时放行所有路径;设为特定目录时拒绝访问外部。配置项 `plugin.files.dir` 控制此值。
### 分段读取
`files_read` 支持 `offset`(行号,1-indexed)和 `limit`(行数上限),用于大文件分段查看:
```go
// plugin.go:handleRead
lines := strings.Split(text, "\n")
offset := 0 // 从 args["offset"] 解析,1-indexed 转 0-indexed
limit := totalLines - offset
// ...
end := offset + limit
selected := lines[offset:end]
```
如果未读完会在末尾追加提示 `[Showing lines X-Y of Z. Use offset=N to continue.]`。
### 四种写入模式
`files_write` 通过 `mode` 参数区分:
- **overwrite**(默认):`os.WriteFile` 覆盖写入,自动创建父目录
- **append**:`os.OpenFile` 以 `O_APPEND|O_CREATE|O_WRONLY` 打开,追加内容
- **insert**:将文件按行分割,在指定行号前插入新内容,再写回
- **create**:先检查文件是否已存在,存在则报错,不存在才创建
### 精确编辑
`files_edit` 接收 `edits` 数组,每个元素有 `old` 和 `new`。要求每个 `old` 在原文中**恰好出现一次**,防止 LLM 误替换:
```go
count := strings.Count(content, oldText)
if count == 0 { /* 报错未找到 */ }
if count > 1 { /* 报错存在多处匹配 */ }
content = strings.Replace(content, oldText, newText, 1)
```
### 目录列表
`files_ls` 按字母序排序,目录加 `/` 后缀,同时显示文件大小。默认上限 500 条。
## 配置项
| Key | 默认值 | 说明 |
|-----|--------|------|
| `plugin.files.dir` | `/` | 文件操作沙箱根目录 |
## 注意事项
- 所有路径操作前都经过 `resolvePath` 沙箱检查
- 错误结果统一用 `errorResult()` 返回 `{isError: true, content: msg}` 格式,LLM 可据此判断
- `files_write` 的 insert/append 模式不检查文件是否存在(不存在则报错),overwrite/create 模式自动创建父目录