OpenCode V2 模式变更日志深度解读:事件溯源 Session 的持久化契约、分页语义与工具 Schema 演进
【免费下载链接】opencodeThe open source coding agent.项目地址: https://gitcode.com/GitHub_Trending/openc/opencode
本篇指南以 specs/v2/schema-changelog.md 为骨架,完整梳理 OpenCode 项目实验性 V2 会话架构(feat/opencode-embedded-api分支)自 2026-06 以来每一次数据库表结构、持久化事件、HTTP 路由与生成 SDK 契约的变更。读完后,你可以准确回答三类问题:V2 Session 的"事件溯源 + 投影"模型到底如何存储与回放数据、GET /api/session/:sessionID/history等公开接口的分页与耗尽语义是什么、以及当 V2 事件 Schema 发生不兼容迭代时应如何重置实验数据而不影响 V1 规范数据。
文档定位与适用范围
原文档开篇即给出自身职责边界:所有 V2 数据库、持久化事件、投影消息、HTTP 与生成 SDK 的 Schema 变更都必须记录在此处,且每条记录要说明"契约为何变化、消费者或已存数据是否需要兼容性处理"。影响 Schema 的提交,其 commit message 也应包含同样的摘要。
理解本文档的前提有三点(原文档明确声明,后文所有条目都在此前提下解读):
- 分支前提:文档覆盖的是
feat/opencode-embedded-api分支自origin/dev分叉后引入的"有意义的契约变更"。纯文件移动和内部重构一律省略——除非它们改变了存储数据、回放行为、公开 HTTP/SDK 形态,或模型侧工具契约。 - 实验性前提:V2 Session 数据在发布前始终被声明为"可丢弃的实验状态(disposable experimental state)"。当跨不兼容事件 Schema 迭代升级时,正确的做法是重置实验性 V2 数据,而不是做数据迁移。
- V1 不变前提:每一次重置(reset)都明确声明"保留规范的 V1
session、message、part行"。V2 与 V1 是双轨存储,重置只作用于 V2 侧。
从源码结构看,这条双轨策略有明确落点:V2 会话服务的核心接口定义在 packages/core/src/session.ts 中,而 V2 的 HTTP 路由(标注为 "Experimental session routes.")集中定义在 packages/protocol/src/groups/session.ts。
近期关键变更(2026-06-05 至 2026-06-26)
1. Finite Session History:有限历史分页读接口
2026-06-26 的最新条目为 V2 会话新增了有限的(finite)历史分页读 API:
- 新增
GET /api/session/:sessionID/history,并生成 Promise、Effect 和 legacy JavaScript 三种客户端方法(方法名分别为listHistory、listHistoryEffect、listHistoryLegacy,见 packages/client/src/generated/client.ts)。 - 在**可选的排他聚合序列(exclusive aggregate sequence)**之后分页返回公开的持久化 Session 事件,并带显式的
hasMore耗尽信号。 - 允许聚合序列出现间隙(gaps)、单页上限 100 个事件,且原有的
sessions.events()"回放 + 尾随(replay-and-tail)"流保持不变。 - 无数据库迁移、无持久化事件版本变更——它只是对已有事件 manifest 的有限读接口。
源码印证:
- 路由声明在 packages/protocol/src/groups/session.ts 中(
session.history端点,响应结构为data: DurableEvent[]+hasMore: boolean,OpenAPI identifier 为v2.session.history),与 SSE 流端点GET /api/session/:sessionID/event(v2.session.events)并列。二者的定位差异正是 changelog 所述:"history 是一次性有限页,新提交的事件会出现在后续页中",而event端点是"回放某序列之后的持久化事件,然后持续尾随新事件"。 - 服务层接口定义在 packages/core/src/session.ts 的
history方法(入参after?: number+ 必填limit,返回{ events, hasMore })与events方法(返回Stream)上,两者并存、互不替代。 hasMore的计算逻辑在 packages/core/src/event.ts:hasMore: rows.length > input.limit——即取limit + 1行探测是否还有后续,超过上限即置位耗尽信号。
设计含义:消费端可以用after游标(取本页最后一个事件的聚合序列 +1)做纯轮询式拉取历史,无需维持长连接;实时性要求高的场景则继续使用 SSE 流。两个接口共享同一份持久化事件日志,语义上"有限页 ⊂ 回放+尾随流"。
2. Simplify Session Input Promotion(2026-06-22)
围绕"用户输入如何进入模型视野"的事件模型做了简化:
- 保留
session.next.prompt.admitted.1作为待处理 Session 输入的持久化、客户端可见记录("已受理但未投给模型")。 - 用已有的
session.next.prompted.1事件替换session.next.prompt.promoted.1:当输入变为模型可见时只发prompted事件。 - 保留 prompt 端点、受理回执(admission receipt)、幂等性、
steer/queue投递顺序,以及原子化的用户消息投影。 - 配套重置实验性 V2 事件、投影、输入、Context Epoch 与同步工作区状态,同时保留 V1 三张规范表。
这与 06-04 的"Event-Sourced Session Input Cutover"呼应:输入生命周期被拆成**受理(admitted)与晋升(prompted)**两个独立持久化操作,steer语义在安全的 provider-turn 边界晋升,queue语义按 FIFO 保持待处理,直到回合自然结束。
3. Reset Unpublished Compaction Event(2026-06-22)
将未发布的session.next.compaction.ended.1事件的 payload 替换为当前 checkpoint payload,并移除其遗留解码器;随后重置实验性事件、序列、Session 输入、投影消息、Context Epoch、同步工作区行和 Session 工作区链接。V1 数据照常保留。这体现了 changelog 一贯的操作模式:未发布(unpublished)事件的 payload 可以在不升版本的情况下直接改写,但已发布事件只能追加式兼容。
4. Make Session Interruption Process-Local(2026-06-22)
把session.next.interrupt.requested.1从实验性持久化 Session 事件 union 和生成的 SDK 中整体移除——中断语义改为进程内(process-local)行为。理由在 packages/protocol/src/groups/session.ts 的session.interrupt路由描述中可以得到印证:"Interrupt active execution owned by this OpenCode process. Idle interruption is a no-op."。兼容性说明明确:V1 数据无需迁移,包含已退役事件的实验性 V2 历史直接可丢弃。
5. Execute Automatic Session Compaction(2026-06-05)
自动会话压缩从"延期项"变为已实现,是 V2 上下文管理里信息量最大的一条:
- 触发时机:在 provider turn 之前,用"完整估算请求 + 模型感知的绝对 headroom"判断是否触发自动压缩。
- 摘要契约:保留既有结构化摘要契约;新压缩的历史会更新此前的摘要(摘要链式演进)。
- 存储方式:token 有界的近期历史以纯序列化文本存进 checkpoint,而不是回放 provider 原生消息。
- 持久化边界:压缩"开始"是持久化的、进度 delta 只是 live-only;只有当持久化的完成摘要出现时才切换历史(history cutover)。
- 完成事件:携带当前 checkpoint payload,包含稳定的消息身份、原因(reason)、摘要与近期上下文。
- 续跑:加载替换后的 Context Epoch,在压缩完成后继续原本挂起的回合。
- 不可失数据:完整持久化历史永远保留,压缩只改变"活跃模型表示"。
- 明确延期:provider 溢出恢复、显式手动压缩、确定性旧工具结果裁剪。
对应实现位于 packages/core/src/session/compaction.ts 与 packages/core/src/session/context-epoch.ts。
事件溯源输入切换(2026-06-04 Event-Sourced Session Input Cutover)
这是 changelog 中篇幅最重的单条变更,理解它是理解整个 V2 存储模型的关键:
受影响 Schema
session_input、session_message、event、event_sequence表,以及可丢弃的工作区 beta 存储。- 新的同步事件
session.next.prompt.admitted.1与(后来被退役的)session.next.prompt.promoted.1。 - 实验性
SessionV2.prompt(...)、HTTP 与生成 SDK 的受理回执。
变更内容
- 用事件溯源的 prompt 受理/晋升序列替换inbox 本地的受理序列。
- 投影 Session 消息获得稳定的
msg_*资源 ID,与创建者事件 ID(evt_*)区分开。 - 每一个"创建投影 transcript 资源"的事件都携带显式
msg_*资源 ID;assistant 步骤通过assistantMessageID在 assistant 拥有的各事件间传播同一身份。
兼容性处理(可操作要点)
- 重置保留 V1 的
session、message、part行。 - 已同步的工作区属于可丢弃 beta 状态,由重置删除。
- 启动新构建前,先丢弃由未发布构建创建的、adapter 管理的外部工作区资源——因为 SQL 迁移无法通过运行时 adapter 删除外部资源,且启动后重新发现残留资源可能回放不兼容的 beta 历史。
- 精确的 prompt 重试在 Session、prompt 与投递模式三者一致时,协调到同一个稳定的
msg_*身份(幂等)。
分支早期历史(Earlier Branch History)
可回放 Session 事件精炼与游标流
受影响 Schema:packages/core/src/session/event.ts中已有的session.next.*事件族、packages/core/src/session/message.ts中已有的 V2 投影消息 union、以及sessions.events({ sessionID, after? })返回的显式持久化事件 union 与内部回放游标。
变更
- 保留既有 Session 生命周期事件族与投影消息 union,而非在本分支引入它们。
- 停止同步文本 delta、推理 delta 与工具输入 delta——这些片段(fragment)被明确声明为 ephemeral。
- 为回放安全的消费者新增显式持久化事件 union。
- 新增由持久化 Session 事件序列支撑的"回放 + 尾随"聚合游标。
- 在写入 JSON 存储前编码、回放时解码同步事件 payload,使 Schema 转换显式地发生在持久化边界。
动机:嵌入式 Session 执行需要基于持久化日志的断线重连安全回放流,外加按时间顺序的派生读模型;片段流对在线渲染器有用,但不得推进持久化游标,也不得膨胀同步存储。
兼容性:session.next.*事件族早于本分支存在,本分支只是精炼其 V2 持久化与回放契约;持久化回放游标是每聚合的事件序列,ephemeral delta 在重连后有意缺失。
持久化 Step 结算归属(Durable Step Settlement Ownership)
session.next.step.ended与session.next.step.failed的同步事件版本升到2:step 结算绑定到显式的 assistant 消息 ID。- 原因:provider 本地的 call 标识符可能在多个回合间重复。
- 因为持久化 payload 变化,同步事件必须升版本。
持久化 Session 输入收件箱(Durable Session Input Inbox)
- 新表
session_input(迁移20260603141458_session_input_inbox.ts),pending 索引由20260603160727_jittery_ezekiel_stane.ts更新;新增SessionInput.AdmittedSchema 与Prompted.delivery字段。 - 收件箱持久化字段:自增 inbox 序列、唯一消息 ID、Session ID、编码后的 prompt、
steer/queue投递模式、可选的晋升事件序列、创建时间;索引按 Session、晋升状态、投递模式与受理序列组织。 - 原因:prompt 受理与模型可见晋升必须是两个独立的持久化操作;steer 必须在安全 provider-turn 边界晋升,queued prompt 按 FIFO 保持 pending。
- 兼容性:迁移创建 inbox 表并替换首个 pending 索引为感知投递模式的索引;精确 prompt 重试幂等,复用消息 ID 但输入不同会失败(对应源码中的
PromptConflictError,定义见 packages/core/src/session.ts)。
持久化 Session 投影顺序(Durable Session Projection Order)
session_message.seq(来自20260603040000_session_message_projection_order.ts)及一系列事件/消息索引。- 重置发布前的 Session 消息投影,为新生成的同步事件加
seq;新增事件聚合序列、聚合类型序列索引,以及消息序列、类型序列与兼容时间戳索引。 - 原因:投影历史、回放、压缩查找与分页必须跟随持久化聚合顺序,而不是时间戳或调用方生成的 ID;Runner 与 HTTP 读路径需要覆盖具体查询形态的 covering index。
- 兼容性:发布前的投影因"可能在没有持久化创建者事件的情况下被写入"而可丢弃,迁移直接重置而不阻塞启动;时间戳索引保留给遗留/过渡查询形态。
结构化工具注册表与规范输出(Structured Tool Registry And Canonical Output)
- Core 自有的类型化工具注册表契约、规范工具输出内容与结构化结算 Schema;
@opencode-ai/llm中标记化的工具文件源(inline 数据 / 远程 URL / 托管文件 URI,替代一个含义模糊的 URI 字符串)。 - 变更:对模型输入按注册工具参数 Schema 校验;对 handler 成功结果按 success Schema 校验后再做可选的纯模型输出降级;从类型化 success Schema 生成可选的 output JSON Schema;对运行中、完成与失败的工具都持久化规范结构化输出与内容。
- 兼容性:属追加式实验性 V2 运行时契约;工具结果在 provider 续跑前必须持久化结算;遗留文本/JSON/内联媒体结果仍可转换,未解析的 URL 与文件源必须在 provider 降级前被物化或显式拒绝。
托管工具输出文件(Managed Tool-Output Files)
- 工具结果与完成的 Session 工具状态上新增可选
outputPath/outputPaths;普通read、grep输入接受绝对托管输出路径。 - 超大模型侧工具文本被溢出(spill)到 OpenCode 共享工具输出目录下的全局唯一文件,有界预览中包含该文件的绝对路径,从而普通
read、grep、bash都能检查完整内容。 - 设计权衡:模型上下文必须有界但不能丢完整输出;文件系统的解析只接受托管目录中直接生成的
tool_*文件,权限白名单恰好覆盖该目录(与 packages/core/src/tool-output-store.ts 的托管输出存储对应)。 - 托管输出按有界期限保留,暴露为普通宿主文件系统路径。
Location 作用域的只读与检索契约
- 核心文件系统读、目录列举、根解析、命名引用输入;
LocationSearch.FilesInput、LocationSearch.GrepInput与有界结果 Schema;read、glob、grep工具参数与成功 payload。 - 变更:有界文件读、分页目录列举、有界 glob 结果、带行预览的有界 grep 匹配;命名项目引用仅限只读操作;遍历前解析并固定(pin)已批准的规范检索根;宽泛 V2 glob/grep 发现默认排除隐藏路径段。
- 兼容性:属追加式 V2 工具契约;隐藏文件发现有意比无条件的 ripgrep
--hidden遍历更窄。
Location 工作区身份(Location Workspace Identity)
Location.Ref.workspaceID从无类型字符串变为WorkspaceV2.ID品牌类型;V2 Location HTTP 中间件保持location[workspace]嵌套与 workspace header 两种路由输入,但解码到同一品牌身份。- 兼容性:满足 workspace ID Schema 的既有 workspace 字符串继续被接受;生成的 OpenAPI 体现 workspace 前缀约束。
结构化变更权限与文件叶子(Structured Mutation Authority And File Leaves)
- 新增
LocationMutation.ResolveInput、计划目标、外部目录授权与类型化路径错误;新增write与精确edit工具 Schema 及内部文件变更提交服务。 - 变更:相对变更路径在活跃 Location 内解析;内部绝对路径直接接受,外部绝对路径必须显式
external_directory批准后才能进入叶子批准;命名引用只读、拒绝用于变更;写机制执行前立即重验路径权限(防 symlink/路径切换)。 - 动机:变更工具需要显式的能力升级与符号链接/路径交换检查,而不是假装路径 API 提供了系统调用级沙箱。
- 兼容性:追加式 V2 变更契约;更丰富的 V1 模糊编辑行为有意延期。
V2 权限请求与已保存规则(V2 Permission Requests And Saved Rules)
PermissionV2.Request、AssertInput、ReplyInput、源元数据、标记错误与生命周期事件;V2 权限列表/回复/已保存规则的 HTTP 路由与生成 SDK Schema。- 变更:Location 作用域的挂起权限请求,支持
once、always、reject三种回复;可附带来源工具消息与 call ID;作者编写的有序规则与已保存批准作为评估的两个独立输入保留;为read、glob、grep、edit、external_directory、bash、todowrite、webfetch建立动作与资源约定。 - 原因:嵌入式工具调用需要 Core 自有的授权边界,能够经 HTTP 挂起与恢复。
- 兼容性:追加式实验契约;策略作者应关注规范资源形态;来源工具元数据在"每个注册表调用都携带持久化 assistant 拥有者"之前保持可选。
初始 Core V2 内置工具 Schema、Bash 警告与后续工具
- 内置工具集:
read、glob、grep、write、精确edit、bash、websearch——Core 自有的 Location 作用域内置工具,带显式参数与 success Schema;bash 输出与超时、搜索结果数与预览、读取大小、目录页、websearch 结果/上下文控制全部有界。apply_patch(顺序提交、add-only 语义、预检后不可中断)、skill({ name: string }选择,返回 V1 形态的<skill_content name="...">输出)、todowrite(SessionTodo.Info替换列表)、question(有序QuestionV2.Prompt+ 有序答案数组)、webfetch(text/markdown/html显式格式、有界超时、可选托管输出元数据)都是同样的"追加式 Location 作用域 V2 内置工具"模式,且都不需要数据库迁移或公共 HTTP API 迁移。 - Bash Advisory Warnings:bash 成功 payload 新增可选
warnings——尽力而为的命令参数扫描发现外部绝对路径时返回建议性警告字符串,但结构化的外部workdir批准仍然强制执行。理由很诚实:"shell 子进程拥有宿主用户的文件系统、进程与网络权限,token 扫描无法诚实地提供隔离"。消费端渲染 bash 成功时应容忍可选警告字符串。 - Bash 背景执行延期(2026-06-03):移除
bash工具的可选background参数与进程内背景结算形态;保留内部BackgroundJob原型。原因是模型没有注册的背景任务观察/取消工具,进程内状态不构成充分的远程契约;只有当持久化状态观察、完成投递与显式取消语义齐备时才重新引入。 - Bash Description 输入移除(2026-06-18):删除 V1 必填、V2 可选的
description参数,shell 展示从命令本身或通用 shell 标签派生。既有持久化 tool call 可能仍含description,但新工具定义不再暴露或要求它;执行行为不变。
V2 Session HTTP 与生成 SDK 契约
- V2 Session 的 list、prompt、context、message-list、compact、wait 路由,以及 V2 Location 查询路由字段与生成的 OpenAPI/JavaScript SDK。
- prompt 端点接受可选
id(幂等)、delivery(steer/queue)与resume(持久受理但不立即执行)字段;消息游标保持不透明(opaque);SDK 客户端同时保留遗留扁平location与嵌套location[...]查询参数两种路由形态。 - 兼容性要点:prompt 受理现在返回受理后的 user 形态消息;一个消息 ID 被不同输入复用时返回冲突错误。
分页与目录(Catalog)契约修正
持久化 Session 消息分页(2026-06-03)
- 内部
SessionV2.messages()游标输入与GET /api/session/:sessionID/message返回的不透明游标 payload 中移除墙钟time;游标内投影消息id解析到存储的session_message.seq,分页边界与排序一律按每 Session 持久化seq,而非time_created + id。 - 原因:投影 V2 消息的时间顺序由同步 Session 事件顺序定义;墙钟时间戳可能碰撞或回拨,不是安全的分页边界;list 端点必须与已经按持久化序列排序的回放和上下文加载保持一致。
- 兼容性:无需数据库迁移(
session_message.seq与会话作用域索引已存在);HTTP 游标保持不透明,既有游标仍可用(它们本就携带投影消息id,解码时忽略多余的time);无需 OpenAPI 或生成 SDK 变更。
公共 Provider 与模型目录 DTO(2026-06-03)
GET /api/provider、GET /api/provider/:providerID、GET /api/model的响应替换为显式公共 DTO(生成的ProviderV2PublicInfo与ModelV2PublicInfo)。- 从公共响应中移除:provider 请求头与请求体、API 设置、自定义启用数据、模型请求覆写、变体请求覆写。
- 原因:内部目录记录可能包含凭据或 provider 特定的请求材料,不得跨越公共 HTTP 序列化边界。公共 V2 目录响应有意暴露更少字段;内部 Schema 仍对运行时可用。
回放元数据与投影所有权
持久化推理与托管工具回放元数据(2026-06-03)
- 持久化
session.next.reasoning.started/ended事件新增可选providerMetadata;session.next.tool.success/failed事件新增可选持久化result并投影进结算工具消息状态。 - 投影的 tool-call 元数据与可选结算结果元数据分开保存;只在历史 assistant 模型与续跑所选模型一致时回放 provider 原生推理与工具元数据。
- 原因:provider 续跑需要后续回合携带签名/加密的推理元数据;provider 执行的托管工具结果必须幸存投影,使回放能把托管调用与结果内联保留在 assistant 内容中;恢复结算不得抹掉重建有效续跑请求所需的 provider 原生 call 元数据。
- 兼容性:新增持久化事件字段均为可选,先前记录的实验事件仍可解码;OpenAI Responses 把重建的 provider 执行托管结果降级为存储项引用而非拒绝 assistant 历史;Bedrock Converse 签名、Gemini
thoughtSignature、OpenAI 兼容 Chatreasoning_content现在都能经规范续跑 part 往返。
投影 assistant 所有权与全值 Part(2026-06-03)
- 投影 assistant 文本 part 保留稳定 ID;持久化工具投影更新通过显式拥有者 assistant 消息 ID 路由,而不是仅靠 provider 本地 call ID;回放**全值(full-value)**的文本与工具输入终点 checkpoint,片段 delta 仍为 ephemeral。
- 原因:provider 本地工具 call ID 可能跨回合重复;持久化投影重建不能依赖重连后消失的 ephemeral 片段。
- 兼容性:早期无稳定文本 ID 的实验投影 assistant 行不假设回放兼容;当前 V2 历史一律从持久化全值 checkpoint 重建。
上下文纪元(Context Epoch)演进三部曲
这三条是 V2 系统上下文管理的完整演进链,建议按顺序阅读:
1. Add Durable Session Context Snapshots(2026-06-04)
- 新表
session_context_epoch:每 Session 一个活跃不可变基线字符串、结构化 JSON 快照与基线序列。 - 在首个安全 provider-turn 边界惰性初始化一个持久化 Context Epoch 快照;纪元内每个 provider turn 通过
LLMRequest.system下发其精确基线字符串;重启或生产者变化后逐字复用存储基线,而不是重新采样特权初始上下文;后续观察与可覆写的编解码结构化快照(而非渲染文本哈希)比较;受理的按时间顺序上下文作为一等systemSession 消息暴露。 - 兼容性:未发布的 Context Epoch Schema 合并进单个数据库迁移;基线与结构化快照是运维状态而非同步事件历史。
2. Admit Chronological Session Context Updates(2026-06-04)
- 新同步事件
session.next.context.updated.1(携带持久化 System 消息 ID 与精确合并后的模型可见文本);session_context_epoch.revision用于事务性结构化快照推进;一等systemSession 消息投影。 - 每个安全 provider-turn 边界用一个一致观察调和 Location 作用域 Context Source;存储基线保持不可变,变化源渲染作为按时间顺序的
Message.system(...)历史受理;结构化快照与渲染 System 消息事件原子推进;源被移除时发出此前存储的模型意义移除渲染;拒绝会把本地工具调用与其结果割裂到不同 provider 协议两侧的按时间顺序 system 更新,Anthropic 原生 system 更新位置不受支持时使用包装 user 回退。 - 兼容性:同步事件日志只保留模型实际看到的文本,不保留内部结构化快照。
3. Replace Session Context Epochs Lazily(2026-06-04)→ Simplify Session Context Rebaselining(2026-06-22)
- 惰性替换阶段:模型切换或压缩完成后标记活跃 Context Epoch 为待替换,
session_context_epoch.replacement_seq(可空)持久化触发聚合序列,使同目标回放不会重开已结算的替换;新基线在下一个安全边界惰性渲染覆写;组装活跃 provider 历史时排除旧纪元的按时间顺序 System 消息。 - 2026-06-22 的简化是对其回滚式重构:删除
session_context_epoch.agent、replacement_seq、revision三列;每个 provider turn 只采样一次有效 agent 与模型(选择变化对下一 turn 生效);压缩完成后直接重建基线而非维护挂起替换状态;后压缩基线无法完整渲染时保留旧基线及其按时间顺序更新;依赖进程内 Session 执行 lane,而非 Context Epoch 写者间的乐观并发状态。 - 兼容性:既有 Context Epoch 行原地迁移(丢弃废弃的选择与挂起替换列);模型与 agent 切换不再通过强制新基线丢弃早前的按时间顺序 System 上下文更新。
配套的 2026-06-05 两条补齐了生产侧:Register Ambient System Context Producers(Location 作用域的稳定键上下文生产者注册表替换 Session 专属加载器;独立注册环境/日期与 ambient 指令生产者并按稳定贡献键顺序并发评估;每个安全边界直接发现并读取全局与向上项目AGENTS.md;任一上下文源不可用时阻塞首纪元初始化;Session 移动时清空活跃纪元并在目标 Location 初始化完整基线;以权威 Session Location 对纪元初始化做 fence,防止并发的旧 Location runner 重建陈旧的特权上下文)与Admit Selected-Agent Skill Guidance(session_context_epoch.agent记录基线所属有效 agent;选定 agent 的技能指导经权限过滤后与 Location 级 System Context 组合再进纪元受理;技能正文仍留在权限检查的skill工具后,缺失技能错误不再枚举未过滤目录;agent 切换后请求纪元替换,并跨 agent 阻止在替换上下文不可用期间的 provider turn)。
其余契约条目速览
- Location 作用域 V2 Questions(2026-06-03):新增
QuestionV2.*域 Schema、question.v2.asked/replied/rejected事件、GET /api/question/request与POST /api/session/:sessionID/question/request/:requestID/reply|reject路由。嵌入式 V2 工具执行需要 Location 拥有的挂起问题服务,其挂起回复可经 HTTP 结算。无需数据库迁移——挂起问题有意是内存态 Location 状态。 - Core 自有 Todo 更新事件(2026-06-03):从 Core session-todo 所有权注册全局
todo.updated事件,向 Core V2 工具暴露既有 todo 项形态;todo 表与公共事件形态不变,无迁移。 - 条件文件变更陈旧错误(2026-06-03):内部新增
FileMutation.StaleContentError标记错误——已批准的精确编辑在提交时不再匹配字节时,携带变更目标路径的类型化错误。V2 精确编辑必须失败,而不是在权限批准后陈旧覆盖并发协作写入;纯内部追加契约,无数据库/HTTP/SDK 变更。 - Provider 流看门狗策略延期(2026-06-03):不施加通用的 provider 流不活跃或绝对超时,移除内部超时错误与硬编码看门狗服务;超时、重试、看门狗、持久化失败报告与 drain 链释放策略整体延期到可配置的设计切片。理由:V1 本就没有通用处理器不活跃看门狗,不同 provider 与自主负载的运行时特征不同,硬编码默认值为时过早。
- 键控合并持久化尾信号(2026-06-03):把进程全局无界聚合 ID PubSub 替换为"每活跃尾 + 聚合一个滑动容量 1 的 dirty 信号";历史 SQLite 回放前订阅注册、尾关闭时移除;每次 dirty 边之后重查持久化行并只按持久化聚合序列推进。唤醒通知是建议性边而非持久化事件 payload;慢消费者不应为一次 SQLite 查询就能恢复全部已提交行而保留无界冗余唤醒 ID。
sessions.events({ sessionID, after? })语义不变。 - 嵌入式本地工具恢复对齐(2026-06-03):Session 省略显式 agent 时,权限按默认
buildagent 评估(与 provider-turn 执行一致);组装 provider 请求前,把上一个进程遗留、仍投影为running的本地工具用既有session.next.tool.failed形态与Tool execution interrupted消息持久化失败。原因:无 agent 的嵌入式 Session 以前按build执行却用空权限规则集评估,首个本地工具可能永远等待一个本地表面不存在的批准面;进程在本地工具运行中丢失会留下悬空 tool call,使后续 provider 续跑无效——恢复必须结算持久化投影而不重放被放弃的副作用。 - Pre-PR V2 安全评审(2026-06-03):对聚合 ID 与解码同步 payload 不一致的回放封套加 fence,回放首次采纳无主聚合时持久化 owner 声明;续跑前持久化结算被放弃的本地与 provider 执行工具;
apply_patch的 add hunk 采用 create-only 语义、预检后顺序提交不可中断、急切拒绝畸形 patch 语法;skill内置物化前等待初始插件启动;provider/model 公共 API URL 剥离凭据、query 与 fragment;V2 请求体在生成的 OpenAPI 与 SDK 类型中保持必填。兼容性要点:pre-launch 的session.next.*数据库仍是可丢弃实验状态;V1 把抓取图片作为附件返回,而首个 Core V2 类型化结算是纯文本的,因此 V2 继续拒绝抓取的图片等非文本文件,直到附件结算被显式设计。
阅读与实操建议
- 消费 V2 历史数据:轮询式用
GET /api/session/:sessionID/history(after排他序列 + 页上限 100 +hasMore耗尽信号);实时渲染用 SSE 的GET /api/session/:sessionID/event。两者读同一份持久化日志,序列间隙是合法的。 - 升级跨不兼容事件 Schema 迭代:按 changelog 的一致性结论操作——重置实验性 V2 事件/投影/输入/纪元/同步工作区状态,启动前清理 adapter 管理的外部工作区资源,V1
session/message/part行不动。 - 写 V2 工具或权限策略:以"追加式、有界、Core 自有"为基调——每个工具都有显式参数与 success Schema,变更操作必须走
external_directory显式授权与提交前重验,bash 的宿主权限只能靠建议性警告提示而不可宣称隔离。 - 提交影响 Schema 的变更:在本 changelog 增加一条记录,写清受影响 Schema、变更、原因与兼容性,并在 commit message 中附同样摘要——这是该文件自身声明的维护纪律。
【免费下载链接】opencodeThe open source coding agent.项目地址: https://gitcode.com/GitHub_Trending/openc/opencode
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考