Power 生命周期
理解 City 持有的 Power 实例、动态调用上下文与执行租约。
Power 的所有权属于 City。city.powers.add(new MyPower()) 登记一个唯一实例;同一 Power ID
不能在一个 City 中重复注册,Agent 也不保存 Power 实例或 Registry。
两个生命周期节点
initialize(context):Power 加入 City 时执行一次,用于注册宿主 Action,并初始化 Power 自己拥有的长期资源。dispose(context):Power 被移除或 City 关闭时执行一次,用于释放这些长期资源。
class ProviderPower extends Power {
readonly name = "provider";
async initialize({ storage }: PowerLifecycleContext) {
await this.provider.open(storage.path);
}
async dispose() {
await this.provider.close();
}
}两个节点使用同一个稳定的 PowerLifecycleContext。Agent 加入或离开 City、Session 创建或结束、
Workspace 进入或离开都不会触发 Power 生命周期,也不存在通用的 connect/disconnect。
city.powers.add() 会明确返回初始化失败。失败实例不会进入执行 Registry,因此不能贡献 Action、Hook
或 System;City 同时在 city.powers.snapshots() 中保留 status: "error" 和 last_error。
宿主应隔离单个 Power 的失败并继续启动其他主体,而不是把可选 Power 当成整个应用的启动条件。成功重试
同一 Power ID 后,错误快照会被新的 ready 状态替换。
调用上下文
Action、Hook、System 和 Availability 每次调用都会获得 City 即时投影的 PowerContext。其中的
agent、workspace、可选 session/turn 都是当前调用可以直接使用的受限对象;Workspace 是本次
调用的项目资源,不是 Power 的生命周期或默认资源隔离键。
需要长期连接、Timer、调度器或后台 Worker 时,Power 应按真实领域所有权管理它们。例如浏览器
Provider 可以在首次 Action 时按 Agent 惰性创建,聊天渠道可以按账号管理,任务调度器
可以按任务定义管理。所有这些资源最终都必须由 dispose 收口。
执行租约
Session 在每个 Step 捕获不可变的 Power 执行视图。Power 被移除后,新 Step 立即不可见;已开始的
Step 可以继续使用捕获的实例,City 会等最后一个 execution lease 释放后再调用 dispose。
city.close() 会先停止 Session,再释放 Power 和 Workspace,并汇总释放错误。一个 Power 的
dispose 失败不会阻止其他 Power 清理。