迁移指南

本文档帮助从 wesgine v0.2 迁移到 v1.0。v1.0 是一次破坏性重构,引入了 Hypervisor + Cell 两层架构。


v0.2 到 v1.0 核心变化

架构变化

维度v0.2v1.0
入口wesgine.New()wesgine.NewHypervisor() + Cells().Create()
租户模型单实例Hypervisor + 多 Cell
数据库单个 wesgine.dbhypervisor.db + per-Cell 三层 DB
外设装配engine 级 AttachCellSpec 声明式
治理策略engine 级per-Cell,govern-v2 唯一治理链
Provider全局共享共享 + per-Cell 私有
用户身份OwnerIDActor(一等字段)

名称变更

v0.2v1.0说明
OwnerIDActor一等字段,空值返回 ErrActorRequired
WorkDirCell EnginePaths + DenyPaths路径边界由 Cell 声明
ScopeOwnerScopeAgentCell 已是租户域,无需 owner scope
eng.Memory()cell.Memory()所有 Handle 迁移到 Cell
eng.Runtime()cell.Runtime()同上
wesgine.New()wesgine.NewHypervisor()Boot 入口变更
boot.Boot()已删除使用 engine.StartEngine()
QuickCell()已删除使用 GetOrCreate()

API 变更清单

Boot API

// v0.2
eng, err := wesgine.New(ctx, wesgine.Config{
	DataDir: dataDir,
	WorkDir: "/workspace",
})

// v1.0
hyp, err := wesgine.NewHypervisor(ctx, wesgine.HypervisorConfig{
	DataDir: dataDir,
})
hyp.Start(ctx)
cell, err := hyp.Cells().GetOrCreate(ctx, wesgine.CellSpec{
	ID: "main",
	Timezone: "Asia/Shanghai",
})

Run API

// v0.2
events := eng.Runtime().Run(ctx, wesgine.RunRequest{
	OwnerID:   "alice",
	SessionID: "s1",
	Messages:  msgs,
	WorkDir:   "/workspace",
})

// v1.0
events, err := cell.Runtime().Run(ctx, wesgine.AppRunRequest{
	Actor:     "alice",       // ★ 必填一等字段
	SessionID: "s1",
	Messages:  msgs,
	Model:     "gpt-4o",     // ★ 必填
})
// 注意:v1.0 返回 (events, error) 两个值

Memory API

// v0.2
eng.Memory().Save(ctx, entry)
eng.Memory().List(ctx, query)

// v1.0
cell.Memory().Save(ctx, entry)          // → SaveToLayer(write)
cell.Memory().List(ctx, listOpts)       // ?layer= 按层查询
cell.Memory().CountByLayer(ctx, actor)  // 每层条数

Handle 迁移

所有 25 个 Handle 从 engine 级迁移到 Cell 级:

// v0.2
eng.Memory()
eng.Sessions()
eng.Knowledge()
eng.Skills()
eng.MCPs()  // 注意:v0.2 是 eng.MCP()

// v1.0
cell.Memory()
cell.Sessions()
cell.Knowledge()
cell.Skills()
cell.MCPs()  // handle 名统一复数化

Provider 配置

// v0.2
config.ProviderConfig{
	APIKey: "sk-abc123",  // 明文
}

// v1.0
config.ProviderConfig{
	APIKeyRef: config.SecretRef{
		Source: "inline",
		Value:  "sk-abc123",
	},
}

外设装配

// v0.2
eng.AttachChannel(channelConfig)
eng.AttachEmail(emailConfig)

// v1.0
// 通过 CellSpec 声明式装配
spec := wesgine.CellSpec{
	Channels: []channel.ChannelConfig{...},
	Email:    []email.Config{...},
	MCPs:     []mcp.ServerConfig{...},
	Cron:     []cron.JobSpec{...},
}

数据迁移步骤

步骤概览

1. 停止 v0.2 引擎
2. 备份数据目录
3. 运行迁移脚本
4. 验证数据完整性
5. 启动 v1.0 引擎
6. 验证功能正常

1. 停止并备份

# 停止 v0.2
systemctl stop wesgine

# 备份整个数据目录
cp -r /var/lib/wesgine /var/lib/wesgine.v0.2.bak

2. 运行迁移

每个消费产品提供迁移子命令:

# wesclaw
wesclaw migrate v0.2-to-v1.0

# wescode
wescode migrate v0.2-to-v1.0

# wescraft
wescraft migrate v0.2-to-v1.0

迁移脚本执行以下操作:

步骤操作说明
1归档旧 DBwesgine.db → legacy-YYYYMMDD.db.bak
2创建目录结构cells/{cellID}/ scaffold
3搬迁 skillsskills/ → cells/{cellID}/skills/
4搬迁 knowledgeknowledge/ → cells/{cellID}/knowledge/
5创建 hypervisor.dbCell 注册表

3. 验证迁移

# 检查目录结构
tree /var/lib/wesgine/ -L 3

# 验证 hypervisor.db
sqlite3 /var/lib/wesgine/hypervisor.db "SELECT * FROM wes_cells;"

# 检查 Cell 数据完整性
sqlite3 /var/lib/wesgine/cells/main/sessions.db "PRAGMA integrity_check;"

4. 启动 v1.0

# 更新 systemd unit
sudo cp wesgine.service /etc/systemd/system/
sudo systemctl daemon-reload

# 启动
sudo systemctl start wesgine

# 验证
curl http://localhost:9091/health
curl http://localhost:9091/admin/cells

消费方代码迁移

wesclaw

// v0.2
eng, _ := wesgine.New(ctx, config)
runner := chat.NewRunner(eng, ...)

// v1.0
eng, _ := engine.StartEngine(ctx, engine.Config{DataDir: dataDir})
cell, _ := eng.Hypervisor.Cells().GetOrCreate(ctx, spec)
// chat handler 使用 cell.Runtime().Run(ctx, req)

wescode

// v0.2
eng, _ := wesgine.New(ctx, wesgine.Config{WithWorkDir: wsRoot})

// v1.0
cellID := workspaceCellID(wsAbs) // "ws-a1b2c3d4"
eng, _ := engine.StartEngine(ctx, engine.Config{DataDir: dataDir})
cell, _ := eng.Hypervisor.Cells().GetOrCreate(ctx, wesgine.CellSpec{
	ID: cellID,
	// HostEnvironment, OnStarted 等 json:"-" hook 在 GetOrCreate 前绑定
})

Teleclaw(HTTP 二进制模式)

// v0.2:X-Cell-ID header
request.setHeader("X-Cell-ID", cellID);
String url = baseUrl + "/sessions";

// v1.0:URL path
String url = baseUrl + "/cells/" + cellID + "/sessions";
// 不再使用 X-Cell-ID header

常见问题

Q: 迁移后旧数据还在吗?

旧数据被归档为 legacy-YYYYMMDD.db.bak,不会被删除。但 v1.0 引擎不读取旧格式数据——必须通过迁移脚本转换。

Q: 可以同时运行 v0.2 和 v1.0 吗?

不可以。两个版本使用不同的数据库格式,不能共享数据目录。建议在独立目录中测试 v1.0。

Q: OwnerID 字段还能用吗?

不能。OwnerID 已被彻底删除,替换为 Actor 一等字段。空 Actor 会返回 ErrActorRequired。

Q: Storage 配置字段去哪了?

CellSpec.Storage 已删除。存储路径由引擎从 (DataDir, CellID) 自动推导,不需要显式配置。

Q: boot.Boot() 和 QuickCell() 还能用吗?

都已删除。使用 engine.StartEngine() + Cells().GetOrCreate() 替代。

Q: ScopeOwner 怎么迁移?

改为 ScopeAgent。Cell 已是租户隔离域,不需要 owner scope。

Q: 为什么 Run() 现在返回两个值?

v0.2 的 Run() 返回 <-chan Event,v1.0 改为 (<-chan Event, error)。错误必须传播,不能忽略:

events, err := cell.Runtime().Run(ctx, req)
if err != nil {
	return err  // 必须处理
}

Q: AllowPaths 怎么迁移?

AllowPaths 仍在 AppRunRequest 上,不要与 HostToolAllow(工具名白名单)混淆。


回滚方案

如果迁移失败需要回滚:

# 1. 停止 v1.0
sudo systemctl stop wesgine

# 2. 恢复备份
sudo rm -rf /var/lib/wesgine
sudo mv /var/lib/wesgine.v0.2.bak /var/lib/wesgine

# 3. 恢复旧 systemd unit
sudo cp wesgine-v0.2.service /etc/systemd/system/wesgine.service
sudo systemctl daemon-reload

# 4. 恢复旧二进制
sudo cp wesgine-v0.2 /opt/wesgine/bin/wesgine

# 5. 启动 v0.2
sudo systemctl start wesgine

重要:回滚后,v1.0 期间产生的数据会丢失。建议在迁移前做完整备份,并在测试环境充分验证后再迁移生产。


迁移检查清单