工作区管理
Wesclaw 的工作区(Workspace)是 Agent 运行时产生文件的持久化存储。每个 Actor 拥有独立的工作区目录,确保数据隔离。
Workspace Handle
cell.Workspace() 是工作区管理的入口 Handle,与 cell.Memory() 对等:
// 六个核心操作
cell.Workspace().List(ctx, opts) // 列出文件
cell.Workspace().Download(ctx, opts) // 下载文件
cell.Workspace().Upload(ctx, opts) // 上传文件
cell.Workspace().Delete(ctx, opts) // 删除文件
cell.Workspace().Stats(ctx, opts) // 使用统计
cell.Workspace().GC(ctx) // 垃圾回收
文件操作 API
列出文件
GET /cells/{id}/workspace/files?actor=alice&path=/reports&depth=2
| 参数 | 类型 | 说明 |
|---|---|---|
actor | string | 可选,指定 actor(admin token 才生效) |
path | string | 可选,目录路径前缀 |
depth | int | 可选,目录深度 |
下载文件
GET /cells/{id}/workspace/file?actor=alice&path=/reports/summary.pdf
返回文件的原始内容(二进制流)。
上传文件
POST /cells/{id}/workspace/upload?actor=alice&path=/reports/new-report.pdf
Content-Type: application/octet-stream
<file binary data>
请求体为文件的原始字节。
删除文件
DELETE /cells/{id}/workspace/file?actor=alice&path=/reports/old-report.pdf
批量删除
DELETE /cells/{id}/workspace/delete-by-prefix?actor=alice&prefix=/temp/
按路径前缀批量删除文件。
ArtifactDir(持久产出目录)
ArtifactDir 是 Agent 运行时产出文件的持久化目录。
路径推算
{CellDataDir}/workspace/{actor}/
- 路径由引擎从
(CellDataDir, Actor, AgentID)推算 - 不从 AppRunRequest 外部传入(INV-IO-01)
关键约束
| 不变量 | 说明 |
|---|---|
| INV-IO-01 | ArtifactDir 由引擎推算,不从外部传入 |
| INV-IO-02 | write/edit/apply_patch 输出必须落入 ArtifactDir 或 HostPaths |
| INV-IO-04 | ArtifactDir 物理在 Cell 目录下,满足 AX-1 隔离 + Export 可移植 |
与系统提示词的关系
ArtifactDir 是 Cell 内部产物持久化目录,不出现在系统提示词的"项目"列表中。
ScratchDir(临时计算目录)
ScratchDir 用于 Run 执行期间的临时文件。
路径
{CellDataDir}/.scratch/{runID}/
生命周期
Run 开始 → 创建 .scratch/{runID}/
Run 执行 → Agent 在此目录读写临时文件
Run 结束 → 引擎自动 GC(os.RemoveAll)
关键约束
| 不变量 | 说明 |
|---|---|
| INV-IO-06 | Scratch 在 Run 结束后由引擎 GC |
| — | Scratch 永不包含在 Cell Export 中 |
Cell Export 中的 Workspace
默认行为
Cell Export 默认包含 workspace 目录:
// 导出 Cell
reader, err := hyp.Cells().Export(ctx, cellID)
// → tar.gz 包含 workspace/
// 排除 workspace
reader, err := hyp.Cells().Export(ctx, cellID, ExportOpts{
SkipWorkspace: true,
})
包含与排除
| 目录 | Export 行为 |
|---|---|
workspace/ | ✅ 默认包含(可通过 SkipWorkspace 排除) |
.scratch/ | ❌ 永不包含 |
skills/ | ✅ 包含 |
knowledge/ | ✅ 包含 |
使用统计与 GC
使用统计
GET /cells/{id}/workspace/stats?actor=alice
返回工作区的文件数量、总大小等统计信息。
垃圾回收
POST /cells/{id}/workspace/gc
触发工作区垃圾回收,清理无效或过期的文件。
按前缀批量删除
DELETE /cells/{id}/workspace/delete-by-prefix?actor=alice&prefix=/temp/
删除指定前缀下的所有文件,适用于清理临时产出。
HostPaths
HostPaths 是宿主机上允许 Agent 访问的路径。
与 Workspace 的区别
| 特性 | Workspace (ArtifactDir) | HostPaths |
|---|---|---|
| 位置 | Cell 目录内 | 宿主机任意位置 |
| 引擎管理 | ✅ 完全管理 | 仅验证边界 |
| MkdirAll | 引擎负责 | ❌ 引擎不创建 |
| Chmod | 引擎负责 | ❌ 引擎不修改 |
| GC | 引擎负责 | ❌ 引擎不清理 |
| Export | ✅ 包含 | ❌ 不包含 |
HostPaths 约束
引擎对 HostPaths 中的路径只验证边界,不做其他操作(INV-IO-07)。
PrimaryRoot
PrimaryRoot 是 Agent 认知的"主工作上下文"。
确定规则
优先级:显式声明 > AllowPaths[0] > ArtifactDir
通过 CellSpec.AgentDefaults.Workspace.PrimaryRoot 声明。
约束
- 必须在
AllowPaths ∪ {ArtifactDir}内 - 出现在系统提示词中,标为 active project
- 影响 exec CWD 优先级(INV-IO-03)
目录权限模型
exec CWD 优先级
显式 cwd 参数 > PrimaryRoot > ScratchDir > ArtifactDir
文件写入边界
Agent 的文件写入操作(write/edit/apply_patch)只能落入:
- ArtifactDir:
{CellDataDir}/workspace/{actor}/ - HostPaths:CellSpec 中声明的宿主机路径
禁止写入 /tmp、Scratch、任何 Cell 外路径(INV-IO-02)。
最佳实践
- 理解目录层次:知道 ArtifactDir(持久)和 ScratchDir(临时)的区别
- 不要手动操作 Cell 内部文件:通过 Workspace API 管理
- 定期清理:使用 GC 或按前缀删除清理过期文件
- Export 前考虑大小:大量 workspace 文件会增加 Export 体积
- HostPaths 最小化:只声明必要的宿主路径