pi v0.87.0 版本更新介绍
发布日期: 2026-09-21
版本号: v0.87.0
v0.87.0 新增了规范化会话上下文与扩展边界能力,支持在不重写历史的前提下编辑模型上下文,并加入可操作的生命周期钩子;扩展方面新增基于全量转录的 context_with_system 事件,可在处理系统消息后对每次请求的系统消息做转换,还支持在 models.json 中按模型配置图片输入的缓存安全缩放限制。破坏性变更包括:移除继承的 shouldStopAfterTurn 代理选项,改用 finishTurn 并返回 action 为 end;SessionEntry 联合类型加入 ContextEditEntry,需要处理 context_edit 分支;SessionManager 成为 AgentSession 提供者上下文的唯一权威来源,直接赋值 session.agent.state.messages 不再替换后续请求历史;TurnEndEvent 扩展了必填边界字段,ExtensionEvent 联合新增 AgentBeforeSettleEvent,ExtensionRunner.emit 不再接受 turn_end;从 agent_settled 触发的延迟运行改为所有 settled 处理器结束后再执行。新增功能还有追加式的模型上下文编辑、turn_end 与 agent_before_settle 可操作边界、保留零条目的压缩输入,以及按模型的图片缩放配置。修复项涵盖:字符串上下文编辑替换产生无效消息内容、上下文不可见边界元数据与替换编辑导致新内容在首次请求前被摘要、编辑后上下文计量丢弃或错误复用助手用量、错误重试与长度恢复把被放弃的模型尝试保留在上下文、context 处理器过滤消息时丢失提示词与工具声明导致请求缺少内置工具、离线模式下 /bug 仍允许上传、空闲提示缓存预热在过期后重建、崩溃诊断缺少相关扩展提示、以 GIF 开头的文本文件被误判为图片、提示词模板 frontmatter 格式错误被静默忽略,以及继承的 OpenAI 兼容端点被强制使用严格工具 schema 等问题。 跳过了逐条对应英文原文的细节与链接;风险:总结压缩了部分迁移细节(如 finishTurn 返回 undefined 的语义),需要精确迁移时请对照原 changelog。
更新内容 (中文)
新特性
- 规范化会话上下文与扩展边界 —— 无需重写历史即可编辑模型上下文,并新增可操作的生命周期钩子。参见 ContextEditEntry 和 扩展事件。
- 全量转录上下文扩展 —— 使用
context_with_system对每条请求的系统消息进行转换。参见context_with_system。 - 按模型区分的图像输入限制 —— 针对附件、
read和工具结果图像,按模型配置缓存安全的图像缩放。参见 图像输入限制。
破坏性变更
- 移除了继承的
shouldStopAfterTurnagent 选项。请改用finishTurn并返回{ action: "end" }。finishTurn在turn_end之前运行,但其决策在之后生效,同时它也会收到错误响应和中止响应;对于这些硬性退出情况,将原有针对正常响应的判断条件改为返回undefined即可完成迁移。完整的前后对比示例参见@earendil-works/pi-agent-core的变更日志。 - 将
ContextEditEntry加入导出的SessionEntry联合类型。使用穷举 switch 处理条目的 TypeScript 消费方必须处理context_edit;省略时使用replacement: null,内容替换时使用其他值。 SessionManager成为AgentSessionprovider 上下文的权威来源。给session.agent.state.messages赋值不再替换后续请求的历史;请使用SessionManager.inMemory(cwd, { id }, entries)恢复,使用session.navigateTree()导航,或通过session.sessionManager追加并调用session.refreshContext()。- 扩展了
TurnEndEvent,新增必填的边界字段,并将AgentBeforeSettleEvent加入导出的ExtensionEvent联合类型。构造事件或对ExtensionEvent做穷举 switch 的消费方必须处理这些新结构。ExtensionRunner.emit()不再接受turn_end;宿主集成应使用emitBoundary(baseEvent, buildContext)派发可操作的边界。 - 从
agent_settled处理器请求的延迟运行会推迟到所有 settled 处理器执行完毕。处理器仍可观察到ctx.isIdle() === true,但不再在同一次通知派发中看到重入的agent_start。
新增
- 新增仅追加的模型上下文编辑。例如,
sessionManager.appendContextEdit(entryId, null)会从后续 provider 上下文中省略某条消息,而不改动原始历史、用量统计或 UI 历史。 - 新增可操作的
turn_end与agent_before_settle扩展边界。返回{ entries: [...event.entries, draft], continue: true }可按顺序持久化结构化条目,并在不改变 steering 和后续请求调度的前提下确保发起下一次 provider 请求。 - 新增 retain-none 压缩输入:
sessionManager.appendCompaction(summary, null, tokensBefore)会将压缩操作自身的 ID 存为其保留边界。 - 新增
context_with_system扩展事件,它在context处理器之后运行,作用于包含系统消息的完整转录,并将其结果原样发送。参见context_with_system。 - 通过
models.json中的inputLimits.images.resize新增按模型区分的图像缩放配置,应用于文件附件、图像读取和工具结果图像(#9631)。
修复
- 修复了字符串形式的上下文编辑替换会生成无效的 assistant 和工具结果消息内容,而非文本块的问题。
- 修复了上下文不可见的边界元数据与替换编辑,导致新追加或被替换的输入在首次 provider 请求之前就被摘要化的问题。
- 修复了编辑后上下文的用量核算问题:既会丢弃最近一次上下文编辑之后捕获的有效 assistant 用量,又会在后续压缩使其失效后仍复用该用量。
- 修复了选定的错误重试与最终长度/溢出恢复将被放弃的模型尝试保留在后续 provider 上下文中的问题;运行后的恢复省略操作现会被持久化,同时不隐藏原始转录历史、也不改变队列调度。
- 修复了对消息进行过滤或切片的
context处理器会丢弃提示词和工具声明的问题——经过扩展驱动的压缩后,这会导致请求缺少内置工具,或使 Codex 输出原始的工具调用文本。处理器不再看到系统消息;Pi 会在其运行后恢复提示词和工具状态。参见context(#9789、#9822)。 - 修复了
/bug在离线模式下允许上传同时保留本地 zip 导出的问题(#9841,由 @christianklotz 提交)。 - 修复了空闲提示词缓存预热在其定时器或扩展决策延迟时重建已过期缓存的问题。
- 改进了崩溃诊断,增加提示以标识栈追踪中出现的已加载扩展。
- 修复了以
GIF开头的文本文件被误判为图像,从而在read和 CLI@file输入中被省略的问题(#9755)。 - 修复了格式错误的提示词模板 frontmatter 被静默忽略而非作为资源警告上报的问题(#9830,由 @christianklotz 提交)。
- 修复了继承的未知 OpenAI 兼容 Chat Completions 端点在未显式声明支持时仍会收到严格工具 schema 的问题(#9816)。
更新内容 (原始)
New Features
- Canonical session context and extension boundaries — Edit model context without rewriting history and add actionable lifecycle hooks. See ContextEditEntry and extension events.
- Full-transcript context extensions — Use
context_with_systemfor per-request system-message transformations. Seecontext_with_system. - Per-model image input limits — Configure cache-safe image resizing per model for attachments,
read, and tool-result images. See Image Input Limits.
Breaking Changes
- Removed the inherited
shouldStopAfterTurnagent option. UsefinishTurnand return{ action: "end" }instead.finishTurnruns beforeturn_endbut applies the decision afterward, and it also receives error and aborted responses; migrate normal-response predicates by returningundefinedfor those hard exits. See the@earendil-works/pi-agent-corechangelog for a complete before-and-after example. - Added
ContextEditEntryto the exportedSessionEntryunion. TypeScript consumers with exhaustive entry switches must handlecontext_edit; usereplacement: nullfor omission and a content replacement otherwise. - Made
SessionManagercanonical forAgentSessionprovider context. Assigningsession.agent.state.messagesno longer replaces future request history; restore withSessionManager.inMemory(cwd, { id }, entries), navigate withsession.navigateTree(), or append throughsession.sessionManagerand callsession.refreshContext(). - Expanded
TurnEndEventwith required boundary fields and addedAgentBeforeSettleEventto the exportedExtensionEventunion. Consumers constructing events or exhaustively switching onExtensionEventmust handle the new shapes.ExtensionRunner.emit()no longer acceptsturn_end; host integrations dispatch actionable boundaries withemitBoundary(baseEvent, buildContext). - Deferred runs requested from
agent_settledhandlers until all settled handlers finish. Handlers still observectx.isIdle() === true, but no longer see a reentrantagent_startduring the same notification dispatch.
Added
- Added append-only model-context edits. For example,
sessionManager.appendContextEdit(entryId, null)omits one message from future provider context without changing raw history, usage, or UI history. - Added actionable
turn_endandagent_before_settleextension boundaries. Return{ entries: [...event.entries, draft], continue: true }to persist structural entries in order and ensure one next provider request without changing steering or follow-up scheduling. - Added retain-none compaction input:
sessionManager.appendCompaction(summary, null, tokensBefore)stores the compaction’s own ID as its kept boundary. - Added the
context_with_systemextension event, which runs aftercontexthandlers on the full transcript including system messages and sends its result verbatim. Seecontext_with_system. - Added per-model image resize profiles through
inputLimits.images.resizeinmodels.json, applied to file attachments, image reads, and tool-result images (#9631).
Fixed
- Fixed string context-edit replacements producing invalid assistant and tool-result message content instead of text blocks.
- Fixed context-invisible boundary metadata and replacement edits causing newly appended or replaced input to be summarized before its first provider request.
- Fixed edited-context accounting both discarding valid assistant usage captured after the latest context edit and reusing that usage after a later compaction made it stale.
- Fixed selected error retries and final length/overflow recovery retaining abandoned model attempts in future provider context; post-run recovery omissions are now persisted without hiding raw transcript history or changing queue scheduling.
- Fixed
contexthandlers that filter or slice messages dropping the prompt and tool declarations, which after extension-driven compaction left requests without built-in tools or made Codex emit raw tool-call text. Handlers no longer see system messages; Pi restores the prompt and tool state after they run. Seecontext(#9789, #9822). - Fixed
/bugallowing uploads in offline mode while preserving local zip exports (#9841 by @christianklotz). - Fixed idle prompt-cache warming rebuilding expired caches when its timer or an extension decision is delayed.
- Improved crash diagnostics with hints identifying loaded extensions that appear in the stack trace.
- Fixed text files beginning with
GIFbeing misclassified as images and omitted fromreadand CLI@fileinput (#9755). - Fixed malformed prompt template frontmatter being silently ignored instead of reported as a resource warning (#9830 by @christianklotz).
- Fixed inherited unknown OpenAI-compatible Chat Completions endpoints receiving strict tool schemas unless they explicitly advertise support (#9816).