旧版编排迁移
编排 v2 在首次启动、打开可写持久化之前,会把 state.sqlite 快照到 statev2.sqlite。只有这份副本会接受 v2 迁移;原件仍可供 v1 使用。之后的启动会复用该副本,不再从 v1 刷新它。它会先创建 v2 的对话线程外壳事件(event),并在客户端(client)读取或继续该对话线程(thread)时,按需导入完整的用户与助手记录。v1 的投影(projection)表仍然是导入来源;如果某次导入需要调查,它们也提供只读的恢复来源。
导入的数据
外壳导入会保留项目(project)与对话线程标识、标题、提供方(provider)和模型选择、运行时模式(runtime mode)与交互模式(interaction mode)、分支、工作树(worktree)路径、创建与更新时间、归档与删除时间、结算覆盖及其时间戳、延后(snooze)时间戳、置顶时间戳与顺序,以及关联的拉取请求(pull request)。对于在这些字段纳入导入范围之前就已导入的对话线程,元数据修复路径会补齐延后、置顶顺序、unsettledAt 以及关联拉取请求字段。
记录导入从 projection_thread_messages 读取用户行和助手行。它保留消息标识、文本、受支持的附件(attachment)、时间戳、角色和顺序。一条仍在流式传输的消息会变成一个已中断的回合(turn)条目。
导入器不会转换提供方会话(session)身份、提供方的原生运行、检查点(checkpoint)与差异、活动与工具调用、批准记录,或提议的计划。因此 v2 不得把这些记录当作已迁移的历史来呈现。
首次继续
已迁移的对话线程没有活跃的提供方对话线程。首次继续会创建全新的提供方会话,并发送一份只由用户与助手消息构成的旧版交接。交接会在 32,000 字符的预算内选取最新的记录后缀,其中计入节标签和导入说明。这份预算与可移植的提供方交接是分开的。
客户端与服务器切换
客户端和服务器必须在 ORCHESTRATION_PROTOCOL_VERSION 上一致(当前为 2)。客户端运行时把 orchestrationProtocol=2 追加到套接字 URL 上,/ws 路由会在任何 RPC 或认证工作开始之前,用 HTTP 426(orchestration_protocol_incompatible)拒绝缺失或不匹配的版本。客户端以同样的方式检查环境(environment)描述符:缺少版本表示主机早于协议 2,版本不同则表示双方都需要更新。任一方向都会以 unsupported 阻止连接,消息中会指出应该更新哪台机器,而不是让连接在半升级状态下运行。参见 packages/client-runtime/src/connection/compatibility.ts 和 apps/server/src/ws.ts。
发散的迁移 ID
effect_sql_migrations 记录 migration_id 和 name,但迁移器只比较 ID:位于已记录最大值及以下的行会被跳过,且不检查名称。因此,如果数据库曾在某个 ID 下运行过本地迁移或分叉迁移,而此构建后来把该 ID 分配给了另一项迁移,它就永远不会在该 ID 上收到此构建的这项迁移。在修复受支持的 V2 预览账本之后,runMigrations 会拒绝这样一种历史:它将在 ID 55 或更高处跳过一项被请求的迁移,且该迁移没有预期的名称。更早的名称冲突仍然只是警告,以便兼容站点本地的迁移。此账本内没有对分叉而言安全的 ID 区间:任何小于或等于未来上游 ID 的 ID 都会永久掩盖它,因此分叉的表结构变更应放在单独的迁移表中,或完全置于迁移器之外。
恢复
没有受支持的整条对话线程导出 API。恢复时使用该环境的 userdata 目录一份未经改动的副本,并用 SQLite 的只读模式打开该副本。用户指南记载了针对 projection_threads 和 projection_thread_messages 的查询。切勿对着恢复副本启动服务器,因为启动过程可能会运行迁移并写入新状态。