一句话结论
OpenPI 的 Direct Subagent、Background Terminal、Workflow 都已实现“完成后投递给父会话”,但分别维护三套 pending map、消费、重试、持久化与 wake 语义。
建议抽取一个薄的 completion inbox contract:生产者仍拥有终态和 artifact,inbox 只负责 owner 路由、generation/epoch、防重复消费、投递收据和 wake policy。不要把三套执行状态机合并。
固定证据
对比固定在:
- OpenPI
main@2a69d3f32994da4123f1312b7fa84ef3d6119be1
- OMP
main@151dc754e8cd9314721aa6c78a168a205a4b0e4c
OMP 当前:
OpenPI 当前:
- Direct Subagent 使用内存 pending map;auto-delivery 与 explicit wait 谁先 drain 谁消费,delivery throw 会恢复批次:subagent delivery
- Background Terminal 使用另一套 pending map + idle batcher,并在 idle 时
followUp/triggerTurn、busy backlog 时 nextTurn:terminal pending, wake policy
- Workflow 有第三套 durable delivery plane:稳定 delivery id、per-run receipt、retry、restart restore;transport 成功但 receipt 落盘失败时采用 at-least-once recovery:workflow delivery contract, receipt/retry
为什么值得讨论
三条实现分别解决了真实竞态,但合同逐渐漂移:
- 只有 Workflow completion 可跨 process restart 恢复;
- Direct Subagent 会主动重新唤醒 parent,Terminal 对 busy backlog 选择 nextTurn;
- stable identity、attempt、receipt、dead-letter、owner-lost 的表达不同;
- Session switch / branch / resume 后 stale completion 的判定没有统一 epoch vocabulary;
- 修过的一类竞态需要在三条路径重新证明。
共享的应是 transport/inbox 不变量,不是 producer lifecycle。
OpenPI 应保留的优势
- WorkflowDetails、SubagentSnapshot、TerminalSnapshot 仍是各自 canonical execution facts;
- inbox 不从 UI label 推断完成;
- producer 自己决定何时 terminal、artifact 在哪里、取消如何结算;
- wake policy 可按 producer 和 client capability 配置,不统一成“一完成就强制起 turn”;
- fail closed:不确定 owner/epoch 时保留可检查状态,不误投。
建议的最小 envelope
示意:
type CompletionEnvelope = {
deliveryId: string;
ownerSessionId: string;
ownerEpoch: number;
producer: "subagent" | "workflow" | "background";
producerId: string;
terminalRef: unknown;
wake: "follow-up" | "next-turn" | "producer-policy";
}
具体 API 需先确认 Pi 是否已有 completion/yield queue seam;若有,应扩展 Pi seam,而不是 OpenPI 自建第二个 Session mailbox。
必须明确的语义
- exactly-once 是“模型可见消费”还是 transport acceptance?崩溃窗口下能否真正保证?
- transport 成功、receipt 失败时是 at-least-once,并如何让模型识别 replay?
- explicit wait/status 与 automatic delivery 如何原子争抢消费权?
- owner Session switch、fork、resume、dispose、revive 时 epoch 如何变化?
- 无 live owner 是 dead-letter、durable pending,还是迁移到新 owner?
- client 不支持 agent-initiated turn 时如何降级为 next-turn/card?
- 一批 completion 部分成功时如何只重试未确认 sibling?
非目标
- 不统一三类执行状态机;
- 不把 producer result 内联进 inbox storage;
- 不声称分布式 exactly-once;
- 不让 completion 自动决定 Goal/Task 完成;
- 不强制所有 producer 采用相同 wake 行为;
- 不把 delivery success 当 execution success。
完成条件
与现有 Issue 的关系
一句话结论
OpenPI 的 Direct Subagent、Background Terminal、Workflow 都已实现“完成后投递给父会话”,但分别维护三套 pending map、消费、重试、持久化与 wake 语义。
建议抽取一个薄的 completion inbox contract:生产者仍拥有终态和 artifact,inbox 只负责 owner 路由、generation/epoch、防重复消费、投递收据和 wake policy。不要把三套执行状态机合并。
固定证据
对比固定在:
main@2a69d3f32994da4123f1312b7fa84ef3d6119be1main@151dc754e8cd9314721aa6c78a168a205a4b0e4cOMP 当前:
AgentSession用自己的 agent id 注册 delivery sink,避免所有 completion 被硬路由到第一个 top-level Session:owner-routed contract/new、switch、handoff 后旧 epoch 会被丢弃,即使 job id 被复用:epoch contract, format/enqueue fenceOpenPI 当前:
followUp/triggerTurn、busy backlog 时nextTurn:terminal pending, wake policy为什么值得讨论
三条实现分别解决了真实竞态,但合同逐渐漂移:
共享的应是 transport/inbox 不变量,不是 producer lifecycle。
OpenPI 应保留的优势
建议的最小 envelope
示意:
具体 API 需先确认 Pi 是否已有 completion/yield queue seam;若有,应扩展 Pi seam,而不是 OpenPI 自建第二个 Session mailbox。
必须明确的语义
非目标
完成条件
与现有 Issue 的关系