news 2026/9/10 7:20:48

oh-my-pi 的 rewind 工具:以会话树分支剪除探索上下文并保留调查报告

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
oh-my-pi 的 rewind 工具:以会话树分支剪除探索上下文并保留调查报告

oh-my-pi 的 rewind 工具:以会话树分支剪除探索上下文并保留调查报告

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

rewind 是 oh-my-pi 编码代理(coding-agent)中与 checkpoint 配套的会话管理工具。它的核心使命是:结束一个活跃的 checkpoint,通过会话树分支机制剪除此前的探索性上下文,同时把一份简洁的调查报告保留进后续对话。读完本文,你将掌握 rewind 的注册与可见性规则、输入输出契约、11 步完整执行流程、四种运行模式、副作用边界与全部错误场景,并能从 checkpoint.ts、agent-session.ts 等源码层面理解其实现原理。

工具定位:为什么编码代理需要 rewind

在长时间编码任务中,代理往往会在一个方向上进行大量探索:阅读源码、运行命令、尝试方案,然后发现此路不通。如果这些中间过程全部保留在上下文里,不仅占用 token 预算,还会干扰模型对后续任务的判断。oh-my-pi 给出的答案是 checkpoint/rewind 这一对工具:

  • checkpoint在探索开始前记录当前会话树位置与目标;
  • rewind在探索结束后,把上下文“回卷”到 checkpoint 处,同时保留一份非空的调查报告,作为此后对话的延续依据。

用文档原话概括,rewind 的职责是 "End an active checkpoint by pruning exploratory context and retaining a concise report"——结束活跃 checkpoint,通过剪除探索性上下文并保留一份简洁报告。它不恢复文件系统、不做 git 回滚,它只操纵会话树与会话上下文。

源码入口与协作组件

rewind 不是独立实现,而是横跨多个模块的协作功能。核心入口与协作关系如下:

角色文件职责
工具入口packages/coding-agent/src/tools/checkpoint.tsRewindTool类定义、参数 Schema、execute()校验与返回
模型侧提示词packages/coding-agent/src/prompts/tools/rewind.md面向模型的一句话描述:结束活跃 checkpoint,回卷上下文并用报告替换中间探索
执行编排packages/coding-agent/src/session/agent-session.tsAgentSession校验 pending rewind 状态、执行实际回卷、注入保留报告
会话树分支packages/coding-agent/src/session/session-manager.tsbranchWithSummary()分支持久化会话树并追加 summary/report 条目
上下文重建packages/coding-agent/src/session/session-context.tsbuildSessionContext()把持久化的branch_summary条目转换为模型可见的branchSummary消息
工具注册packages/coding-agent/src/tools/index.ts注册rewind工具并共享checkpoint.enabled门控

checkpointrewind在源码中被明确定义为一对互操作的类:checkpoint.ts 中CheckpointToolRewindTool共享CheckpointStateCompletedRewindState等接口定义。

注册与可见性规则

工具元数据

RewindTool的元数据定义在 checkpoint.ts:

  • approval = "read":只读审批级别,不需要写权限审批;
  • strict = true:严格模式,参数 Schema 约束严格;
  • loadMode = "discoverable":可发现加载,模型可在工具列表中检索到它;
  • 执行是单发的(single-shot):rewind 的副作用不通过流式进度更新暴露,而是延后到回合结束统一生效;
  • intent固定返回"rewinding",供意图路由使用。

checkpoint.enabled 门控

rewind 的可用性由checkpoint.enabled设置控制,默认值为false。注册逻辑位于 tools/index.ts:

if (name === "checkpoint" || name === "rewind") return ( session.settings.get("checkpoint.enabled") && ((session.taskDepth ?? 0) === 0 || requestedTools !== undefined) );

即:顶层会话(taskDepth === 0)在开启checkpoint.enabled后可见该工具;子代理默认不可发现,但可以通过显式的tools:/requested-tools 列表获得。

安全配对:checkpoint 与 rewind 自动互带

由于 checkpoint 和 rewind 是一对安全工具,只注册其中一个会导致代理“只能存档不能回卷”(或反之)而陷入困境。因此 tools/index.ts 实现自动互带:只要checkpoint.enabled开启,frontmatter 的tools:列表中显式请求了其中一个,另一个会被自动追加。该配对逻辑即使对受限会话(restricted session)同样生效。

xd:// 协议形态

在普通的tools.xdev会话中,可发现的内置工具可能以xd://rewind的形式呈现;而显式请求的工具则保持在顶层。这一约定与 oh-my-pi 其他内置工具的暴露方式一致。

输入输出契约

输入参数

rewind 只有一个必填参数,Schema 定义在 checkpoint.ts:

字段类型必填说明
reportstring调查发现(investigation findings)。execute()会先trim(),空结果被拒绝

输出

工具返回单个文本结果并附带结构化details

  • 文本正文:
    • Rewind requested.
    • Report captured for context replacement.
  • details
    • report: string—— 裁剪后的报告文本
    • rewound: true

关键点:工具返回值并不是最终的 rewind。AgentSession会等待turn_end,然后异步应用 rewind 副作用。也就是说,模型调用rewind得到的只是“请求已受理”的确认,真正的分支与上下文替换发生在该助手回合结束之后。

完整执行流程(11 步)

结合文档与 agent-session.ts 源码,rewind 从调用到生效的完整链路如下:

  1. 注册门控RewindTool.createIf()本身总是构造工具实例,但注册(tools/index.ts)强制检查checkpoint.enabled以及顶层/显式子代理可见性规则。

  2. 前置状态检查execute()在没有活跃 checkpoint 时区分两种状态(见 checkpoint.ts):

    • 存在已完成的 rewind 保留报告:抛ToolError("Checkpoint already completed; continue from the retained rewind report instead of calling rewind again.")
    • 不存在任何已完成的 rewind:抛ToolError("No active checkpoint. Create a checkpoint before calling rewind.")
  3. 报告裁剪校验:对params.report执行trim(),为空则抛ToolError("Report cannot be empty.")

  4. 返回受理结果:返回toolResult(),携带details.reportdetails.rewound = true

  5. 提取报告:成功的 rewind 工具结果返回后,AgentSession通过#extractRewindReport()details.report或第一个文本内容块中提取报告,存入#pendingRewindReport

  6. 回合结束触发turn_end#extractRewindReport()在消息序列中查找 pending 或成功的 rewind 结果,调用#applyRewind()

  7. 分支并记录 summary#applyRewind()首先调用sessionManager.branchWithSummary(checkpointEntryId, report, { startedAt }),在 checkpoint 分支点记录一条branch_summary。若该条目已无法解析,记录警告并改为从根节点分支(见 agent-session.ts)。

  8. 注入隐藏 rewind-report 消息:追加一条持久化的隐藏rewind-report自定义消息。其内容由 packages/coding-agent/src/prompts/system/rewind-report.md 渲染而来——告知下一回合 checkpoint 已完成、不要再调用rewind,并附带报告正文;details 中包含{ report, startedAt, rewoundAt }

  9. 重建上下文并替换消息:设置#lastCompletedRewind,从新活动分支重建 display/LLM 会话上下文,同时替换本回合的活动消息数组与agent.state.messages。探索分支与成功的 rewind 工具结果因此不会出现在下一次 provider 调用中。

  10. 重置关联状态:重置 advisor 会话状态(保留成本统计),从新分支同步 todo 状态,关闭因历史重写而失效的 provider 会话。

  11. 清理与恢复:清空#checkpointState#pendingRewindReport。此后若会话恢复(resume)或进行树导航,持久化的保留报告会重新水合#lastCompletedRewind

在源码层面,第 5~9 步分别对应 agent-session.ts(#extractRewindReport)与 agent-session.ts(#applyRewind)。值得注意的是#enforceRewindBeforeYield()(agent-session.ts):当处于活跃 checkpoint 且存在 pending rewind 报告时,代理被强制要求在让出(yield)前调用rewind,避免未完成 checkpoint 就结束回合。

四种运行模式 / 变体

模式触发条件行为
正常回卷(Normal rewind)checkpoint 条目存在会话历史从该确切条目分支
回退回卷(Fallback rewind)checkpoint 条目 ID 在当前会话树中缺失从根节点分支并记录警告(Rewind branch checkpoint missing, falling back to root
延后回合末应用(Deferred turn-end apply)正常流程工具结果只请求回卷,分支与上下文替换在助手回合结束后进行
恢复的 checkpoint(Resumed checkpoint)活跃持久化分支上存在未完成的成功 checkpoint 工具结果进程恢复后重新水合 checkpoint 状态,允许继续调用 rewind

其中“恢复的 checkpoint”依赖#rehydrateCheckpointRewindState()(agent-session.ts):它会扫描当前分支,区分两种历史情形——已完成的 rewind(恢复#lastCompletedRewind,重复调用会收到“already completed”错误)与 checkpoint 后中断(恢复#checkpointState,下次rewind可正常完成)。

副作用分析

会话状态(transcript、memory、jobs、checkpoints、registries)

  • 从 checkpoint 分支加保留的 summary/report 重建活跃对话历史;恢复文件或进程状态;
  • 追加隐藏自定义消息rewind-report,携带恢复指引与报告正文;
  • 记录#lastCompletedRewind,清空活跃 checkpoint 与 pending 报告,重置 advisors,从分支重同步 todo 状态,关闭因历史重写失效的 provider 会话;
  • 把持久化会话叶子(leaf)重新定位到 checkpoint 分支点,并追加新的会话条目。

文件系统

  • 新的branch_summarycustom_message条目通过SessionManager的常规追加持久化写入会话.jsonl文件;
  • 会话文件命名格式为<ISO时间戳-冒号与点被替换>_<uuidv7>.jsonl,位于会话目录;未显式覆盖时默认目录为~/.omp/agent/sessions/<encoded-cwd>/

用户可见提示 / 交互 UI

  • 工具结果在回合末应用之前即可见;
  • 持久化的branch_summary在上下文重建时变为模型可见的branchSummary消息;compaction 渲染时以用户角色的<summary>块呈现;
  • 隐藏的rewind-report自定义消息成为下一次 provider 调用的开发者角色保留指引。

后台工作 / 取消

rewind 的应用延后到turn_end,没有独立的 job 对象或取消句柄。

限制与上限

  • 门控:可用性受checkpoint.enabled限制,默认false
  • 子代理:需要显式的 requested-tools 条目;请求任一 checkpoint 工具会自动附带其姊妹工具;
  • 单 checkpoint 约束:一个会话最多一个活跃 checkpoint,没有命名、选择或区分多个 checkpoint 的路径;
  • 报告非空trim()后报告文本必须非空;
  • 恢复范围:rewind 只恢复活跃对话/会话树上下文,不存在文件、产物(artifact)、blob、进程或 git 恢复路径;
  • 持久化上限:持久化的报告/summary 内容受全局会话持久化上限MAX_PERSIST_CHARS = 500_000约束。

错误处理清单

错误消息抛出条件
Checkpoint already completed; continue from the retained rewind report instead of calling rewind again.活动分支已包含保留的完成记录时调用 rewind
No active checkpoint. Create a checkpoint before calling rewind.既无活跃 checkpoint 也无已完成的 rewind
Report cannot be empty.裁剪后的报告为空
(警告而非失败)Rewind branch checkpoint missing, falling back to rootapply 阶段 checkpoint 条目 ID 缺失,回退到根节点分支,不使已完成的工具调用失败

所有错误均通过ToolError抛出,实现在 checkpoint.ts 中可逐一对应。

边界与不恢复的内容

rewind 是非破坏性的:branchWithSummary()追加新的branch_summary条目并移动叶子,被放弃的条目仍留在.jsonl日志中,只是离开活动分支。明确不恢复的内容包括:

  • 文件系统或 git 状态;
  • packages/coding-agent/src/session/artifacts.ts 管理下的 artifacts;
  • packages/coding-agent/src/session/blob-store.ts 管理下的 blob-store 负载;
  • packages/coding-agent/src/session/history-storage.ts 中的 prompt 历史行;
  • packages/coding-agent/src/session/agent-storage.ts 中的 auth 或其他 agent 存储。

同时,不存在并发编辑对账机制:rewind 既不合并也不回滚代码或会话之外的并发外部状态。

源码级原理:从状态机看 checkpoint/rewind 配对

在 checkpoint.ts 中,两种核心状态被明确定义:

  • CheckpointState:记录checkpointMessageCount(checkpoint 时内存消息数,含追加后的工具结果)、checkpointEntryId(用于会话树分支的条目 ID)、startedAt时间戳;
  • CompletedRewindState:记录reportstartedAt(被回卷的 checkpoint 时间戳)、rewoundAt(回卷完成时间戳)。

checkpoint 的选择是隐式的:rewind总是瞄准单一的#checkpointState——它来自最后一次未完成的成功checkpoint调用,或从持久化状态重新水合。没有 checkpoint 列表、标签或 ID 参数。

branchWithSummary()的实现位于 session-manager.ts:若branchFromId非空且不在索引中则抛错;将叶子设置为分支点,然后记录一条type: "branch_summary"的条目,携带fromId(或"root")、summarydetails

而持久化条目进入模型视野的桥梁在 session-context.ts:当重建上下文遇到branch_summary且 summary 非空时,createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp)将其转换为branchSummary消息。这就是“被剪除的探索路径以摘要形式延续”的实现机制。

实战要点小结

  • 使用 rewind 前,必须先确保checkpoint.enabled = true(默认关闭),并在会话中先调用checkpoint记录目标;
  • report必须非空,建议用一句话概括探索结论与后续建议,因为它将成为新分支下模型可见的<summary>与开发者角色的保留指引;
  • 不要在同一 checkpoint 上重复调用rewind——第二次会得到 “already completed” 错误,应直接基于保留报告继续;
  • 若需要再次探索,需重新调用checkpoint(正如 rewind-report.md 所提示的:"Need explore again → newcheckpoint");
  • rewind 只回卷会话上下文,不恢复文件与 git 状态,涉及代码回退时应配合版本控制工具使用。

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 7:20:21

Python破解替换密码:从频率分析到映射推断的完整实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 7:19:08

OpenViking OVPack:.ovpack 数据包的导入导出与备份恢复完整实践

OpenViking OVPack&#xff1a;.ovpack 数据包的导入导出与备份恢复完整实践 【免费下载链接】OpenViking Self-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills. 项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking …

作者头像 李华
网站建设 2026/9/10 7:18:29

连续打卡17天:从新鲜感到惯性,一场关于自律的真实实验

2026年2月4日&#xff0c;Day17&#xff0c;我在打卡表上划掉今天的格子时&#xff0c;突然想把它单独拎出来写一篇。原因很简单&#xff1a;"第17天"这个数字卡在一个相当微妙的位置——比"连续一周"更有说服力&#xff0c;又远没有"满月""…

作者头像 李华
网站建设 2026/9/10 7:16:00

NLTK vs Spacy:自然语言处理实战对比与选型指南

1. 选型先想明白&#xff1a;NLTK和Spacy的设计逻辑决定了你的学习路径如果你今天问一个刚接触NLP的人该从哪套工具开始&#xff0c;十有八九会得到同一个答案&#xff1a;NLTK和Spacy。奇怪的是&#xff0c;这两个库放在一起总是让新人头疼——NLTK像是教科书附赠的瑞士军刀&a…

作者头像 李华
网站建设 2026/9/10 7:15:58

AI文本人性化实战:从机器味到人味的完整改写技能包

如果你最近也在留意“humanizer”这个热词&#xff0c;大概率是因为你开始觉得&#xff1a;AI写的东西越来越像“标准答案”&#xff0c;读着顺&#xff0c;却记不住&#xff0c;改起来更别扭。这个词的字面意思是“人性化”&#xff0c;但在实际使用场景里&#xff0c;它指的往…

作者头像 李华