分叉 Session
从完整历史或指定 Message 创建可独立继续执行的新 Session
session.fork() 从当前 Session 的历史创建一个独立的新 Session。分叉后的后续输入、模型执行、工具状态与审批都彼此隔离。
const full_branch = await session.fork();
const branch_at_message = await session.fork({
message_id: "assistant:repo-analysis:abc",
});也可以直接传入 message_id 字符串:
const branch = await session.fork("assistant:repo-analysis:abc");原地替换历史
传入 replace: true 会直接截断当前 Session 的历史并返回当前实例,保留 Session ID、配置及保留消息的身份,不创建分支、不归档,也不写入操作记录。
await session.fork({
message_id: "user:question:abc",
include_message: false,
replace: true,
});
await session.prompt({ query: "修改后的问题" });include_message 默认 true;设为 false 时同时移除锚点消息。后续历史会被永久删除,关联的上下文摘要也同步清理。未指定 message_id 时历史保持原样。Session 正在执行或有排队命令时拒绝替换。
订阅方会收到 variant: "session"、type: "truncate" 的同步事件,通过 through_sequence 移除后续消息;该事件不应显示为时间线操作记录。本地与远程 Session 均支持此参数。
历史边界
| 调用 | 复制范围 |
|---|---|
fork() | 当前可见历史的完整状态 |
fork({ message_id }) | 从开头复制到该 Message,包含该 Message |
fork({ message_id, include_message: false }) | 从开头复制到该 Message 之前 |
分叉点是顶层 Message,不是 Assistant 内的 part_id。如果需要在工具调用前后试验不同方向,先在 messages() 中找到对应 Assistant Message 的 message_id。
来源与顺序
复制进新 Session 的 Message 保留新的 Session 身份和新的线性顺序,同时可携带 origin,记录来源的 session_id、message_id 与 turn_id。这使分叉可追溯,但分叉后两个 Session 不共享可变状态。
分叉成功后,新 Session 时间线末尾会记录一条 history-fork Action,说明这段历史的来源。源 Session 不会留下任何分叉记录。
不要把分叉理解为“两个窗口共同编辑一份历史”。源 Session 的后续 Message 不会自动出现到分叉中,分叉的后续 Message 也不会回写源 Session。
适合的场景
- 在保留主线结论的前提下比较两种实现方案。
- 从某一条用户输入重新提问,避免后续上下文干扰。
- 为长任务建立实验支线,而不污染主会话。
分叉后按普通 Session 使用:加载 messages()、建立 subscribe(),然后调用 prompt()。不需要复制 Mutation,也不应该复制源 Session 的 pending approval。