Skip to content

[PR] Pi: opt-in structured acp_delegate notification envelope for third-party UIs - #5790

Open
ranxianglei wants to merge 5 commits into
masterfrom
2026-11-06_pi-structured-delegate-notify
Open

ranxianglei wants to merge 5 commits into
masterfrom
2026-11-06_pi-structured-delegate-notify

Conversation

@ranxianglei

@ranxianglei ranxianglei commented Nov 6, 2026 •

Copy link
Copy Markdown
Owner

What & why

Today every Pi acp_delegate completion/failure notice reaches the host as a plain steering user message whose wording third-party consumers can only identify by regex-parsing prose (the fragile part). That makes reliable turn-folding (pi-tidy #59) and any other UI integration brittle: a late result can't be tied to the turn that launched it.

This adds an opt-in typed envelope. When enabled, each notice is delivered as a custom message (customType: billion-context:delegate-notification) whose versioned details carry stable run identity plus launch provenance, while content stays byte-identical to the legacy plain message. The model sees the same text either way; pi's convertToLlm() drops details, so nothing new ever reaches the upstream wire and prefix caching is unaffected.

Envelope shape (version 1)

{
  customType: "billion-context:delegate-notification",
  content: "<same text as today>",
  display: true,
  details: {
    version: 1,
    kind: "terminal" | "usage",
    runs: [{ runId, status, agent?, sourceSessionId?, originToolCallId? }]
  }
}
  • originToolCallId — captured at launch, so a late notification still ties back to the turn that launched it (the core requirement; no script parsing needed).
  • sourceSessionId — main-session provenance for nested/codemode runs; best-effort, omitted when the host exposes none.
  • Batches/recovery list every run explicitly; usage summaries are kind: "usage" so they're distinguishable from terminal notices (dedup-friendly). Absent provenance stays absent (never fabricated).

Config surface (new field)

  • pi.subagents.notifyStructured (boolean, default false) — canonical home: the pi.subagents section of ~/.config/billion-context/billion-context.json (declared in the host schema, documented in CONFIGURATION.md). The deprecated ~/.pi/acp.json delegate.* fallback reads it too, but only while the pi.subagents section is absent — same read path as every other delegate.* key.
  • Why the existing surface can't express it: nothing current gives a consumer machine-readable run identity/provenance — only prose. There is no existing "message typing" knob.
  • Mechanisms considered: routing through the bili proxy x-bili-plugin header (wrong layer — this is a pi-host extension concern, not the proxy wire); always-on (rejected — would change default behavior for every install; owner chose opt-in); env-var-only (rejected — this is a durable user preference, belongs in config per Env Var Discipline).
  • Compat/migration: default false ⇒ zero behavior change for every existing install. Enabling is additive; a host without ExtensionAPI.sendMessage falls back to the plain path automatically (capability gate), so older pi versions are safe.

Behavior change disclosure

  • Default (off): byte-for-byte identical to current behavior — plain steering user message, same text, same {deliverAs: "steer"}. No regression possible on the default.
  • When on: the delivery channel switches from sendUserMessage to sendMessage (typed custom message). Model-visible bytes are unchanged (same content, same steer). This is the intended, opt-in change.

Verification

  • tsc --noEmit clean; tsup build succeeds.
  • Targeted suites green locally (129/129): new tests/delegate-structured-notify.test.ts (default-off parity, structured dispatch + content byte-identity, capability fallback, batch lists every run, provenance carried / cleanly absent, idle-tier + injectResult paths) plus the existing delegate-turn-end-notify / delegate-settle-notify / delegate-tool suites, unchanged.
  • Full-suite verdict comes from CI on this head.

Closes #5750

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-11-06_pi-structured-delegate-notify (31c7824)

Latest build — install this exact version

npm install -g billion-context@0.0.9267-pr.5790.3d363fb

This exact version is immutable and reproducible. The rolling pr tag tracks the newest test build across all PRs.

Recent builds (commit → version)

commit version build
31c7824 billion-context@0.0.9267-pr.5790.3d363fb build
acad6f9 billion-context@0.0.8335-pr.5790.550169e build
d8f2dad billion-context@0.0.8333-pr.5790.593661d build
7562aac billion-context@0.0.8332-pr.5790.1ce9bd6 build
704993f billion-context@0.0.8331-pr.5790.1221981 build

Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr5790.tgz
npm install -g package

Install instructions are refreshed on each push.

@ranxianglei ranxianglei changed the title Pi: opt-in structured acp_delegate notification envelope for third-party UIs [PR] Pi: opt-in structured acp_delegate notification envelope for third-party UIs Nov 6, 2026
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

查重: 不重复 —— 本条是带 ework-agent-pr 标记的 [PR] 镜像行(上游 GitHub PR #5790),属于已完成的工作交付物,不是新任务。已核对全部 open [PR] 行:没有其他行指向本线程,不存在并行第二 PR。

按规范处理:不重做,而是 ① 拉分支核对代码 ② 查 CI 状态 ③ 出结构化结论(八问)。

标签: pi / scope/wiring / p3(pi 车道通知通道的 opt-in 扩展,默认零行为变更)

开始验证,完成后回复结论。

ranxianglei pushed a commit that referenced this pull request Nov 6, 2026
The PR bumped pi-subagents/package.json 0.2.3 -> 0.2.4 but did not
regenerate the root package-lock.json, which still recorded the file:
link at 0.2.3. The lock-sync drift guard (#2704/#3782) regenerates the
root lock and fails on any residual diff, so the check went red.
Regenerating updates exactly one line: the billion-context-pi-subagents
version record 0.2.3 -> 0.2.4. Kernel lock verified clean (the PR does
not touch kernel/).
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

lock-sync 已修复并推回分支。 分支 2026-11-06_pi-structured-delegate-notify 新 head:7562aac0b(原 704993fb9)。

七问:

  1. 是什么问题:CI 的 lock-sync 门禁红了——它重新生成根目录 package-lock.json 后,发现有一处 diff,于是判失败。
  2. 什么原因:这个 PR 把 pi-subagents/package.json 的版本从 0.2.3 升到了 0.2.4,但忘了同步重新生成根 package-lock.json;根锁里记录的那个 file: 链接版本还停在 0.2.3。门禁一重生成,那行就变成 0.2.4,产生 diff → 红。这就是 package-lock.json version metadata lags package.json (bili 0.1.190 vs 0.1.191, kernel 0.0.112 vs 0.0.114) #2704/[PR] kernel: sync package-lock.json to 0.0.136 (lock left at 0.0.133 by the bump chain) #3782 那种「升了 vendored 包版本却没重生成父锁」的漂移。
  3. 影响范围与严重程度:只卡这一条 CI 门禁,不碰任何代码逻辑、运行时行为或构建产物;不修则 PR 合不了。纯机械锁文件漂移,零用户面影响。
  4. 怎么修复的:在 PR 分支上跑 npm install --package-lock-only 重新生成根锁,只提交那一行版本变更(0.2.3 → 0.2.4),fast-forward 推回分支(非 force)。顺带验证 kernel 锁是干净的(本 PR 没动 kernel/)。
  5. 是否有回归问题:无。改动仅根 package-lock.json 里记录 pi-subagents 版本的一行,把它和 package.json 实际值对齐;没改任何依赖解析、没加新包、没动运行时代码。我在提交后的 head 上把 lock-sync 两步各复跑一遍,均 exit 0、工作树干净(幂等,说明不会再抖出来)。
  6. 是否破坏缓存:不涉及——纯锁文件元数据,不影响任何缓存 / 重试 / 增量游标。
  7. 是否改了设计方向 / 引入新配置:都不涉及。

当前状态:新 head 已在 CI 上开跑,目前无任何失败项,剩下的是较慢的 test 分片(与本改动无关);lock-sync 将转绿。若后续 test 分片另有红灯,那是独立问题,不在本次 lock-sync 修复范围内。

ranxianglei pushed a commit that referenced this pull request Nov 6, 2026
… path

The opt-in structured envelope (customType billion-context:delegate-notification)
switched delivery from sendUserMessage to sendMessage, but pi's sendCustomMessage
only starts a turn on an IDLE host when triggerTurn is set — without it an
idle-tier notice sat dormant until the next activity instead of waking the model
like the plain path does (#5750 acceptance: wake-up behavior intact). Pass
{deliverAs:"steer", triggerTurn:true}: streaming delivery is unchanged (steer
either way), idle hosts gain parity with the legacy plain message.

Also restore per-carrier identity in the unified send-failure logs: the refactor
folded four carriers' error/warn events into notify-send-error/notify-no-channel
without saying which tier failed — add a `carrier` field ("turn-end" |
"idle-batch" | "inject-result" | "inline-usage").

Tests: pin triggerTurn on every structured dispatch; add coverage for the
usage-note carrier (kind:"usage" envelope on, plain path off) which was missing.
ranxianglei pushed a commit that referenced this pull request Nov 6, 2026
…onfig home

The structured-notify knob works de facto through the piSubagentsAdapter spread
passthrough, but the host schema (PiSubagentsFileConfig) did not declare it and
CONFIGURATION.md never mentioned it — and the PR description pointed users at
the deprecated ~/.pi/acp.json delegate.* fallback, which is ignored whenever the
canonical pi.subagents section exists. Declare the field in the host schema
(precedent: notifyIfRead is declared in both schemas) and document it in both
jsonc examples. No runtime change.
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

PR #5790 审核完成:拉分支逐行核对了全部 6 个文件的 diff,并对结论做了定向验证(不是只看描述)。发现 4 个问题(1 个行为 bug + 1 个配置面缺陷 + 日志上下文丢失 + 测试缺口),已全部修掉并推回 PR 分支(e8d8a4206、d8f2dadfe),PR 描述里的配置位置也已更正。旧 head 7562aac0b 的 CI 全绿(30/30,red-signal skipped 属正常);新 head d8f2dadfe 的 CI 正在跑,绿了即可由你合并。

八问:

  1. 是什么问题:PR 本身(opt-in 的 acp_delegate 结构化通知信封)设计方向是对的,但审核发现——①开启后通知在「宿主空闲」时不再唤醒模型;②配置项写在了已弃用且会被忽略的位置上;③失败日志丢了「哪个发送路径失败」的信息;④usage 类通知没有测试覆盖。
  2. 什么原因导致的:①结构化路径把投递从 sendUserMessage 换成了 sendMessage,但 pi 的 sendCustomMessage 在空闲宿主上只有带 triggerTurn 才会起新回合(流式中两者都是 steer,所以流式场景看不出来)——issue 自己提示过「sendMessage 的投递选项需要选定并测试」,这一步没做,空档就出在空闲分支。②pi.subagents 段经 adapter 展开透传,notifyStructured 事实上能生效,但宿主 schema 没声明、文档没写,而 PR 描述让用户去已弃用的 ~/.pi/acp.json 里设——只要存在规范位置的 pi.subagents 段,那个弃用回退就被忽略,开关静默失效。③重构把四条发送路径的失败事件合并成一个不带来源的事件名。④kind:"usage" 是去重关键属性,却无测试钉住。
  3. 影响范围与严重程度:全部限于显式开启 notifyStructured: true 的用户(默认 false = 零变化)。①空闲宿主上完成的 delegate 通知会休眠到下一次活动才被处理(不丢消息,持久化/恢复语义不变)——特定条件下的功能失灵;②按原 PR 描述配置且已有 pi.subagents 段的用户,开关静默无效;③④内部质量项,无用户可见影响。默认安装完全不受影响。
  4. 怎么修复的:①结构化路径改传 {deliverAs:"steer", triggerTurn:true}——流式投递不变,空闲宿主获得与旧纯文本路径一致的唤醒行为,所有结构化断言钉住该选项;②发送函数加 carrier 参数(turn-end/idle-batch/inject-result/inline-usage),失败/无通道两个日志事件都带上;③在宿主 schema PiSubagentsFileConfig 声明该字段(先例:notifyIfRead 双 schema 都声明)+ CONFIGURATION.md 中英文各加一行 + PR 描述改为先说规范位置;纯声明性改动,运行时行为零变化;④补 2 个测试(usage 通知的类型化信封 kind:"usage" + 关闭时保持纯文本路径)。
  5. 是否有回归问题:逐项审过既有行为——默认关时的字节级等价(原有套件全绿)、能力缺失回落纯文本(有测试)、批量通知列出全部 run(代码核对:单 run 折叠恢复 run、多 run 列全量,无误报漏报)、失败重试语义(仅成功才标记 delivered,未变)、模型可见文本字节一致(A/B 实测断言)、出站线格式(已对 pi 0.83.0 源码核实:convertToLlm 把 custom 映射为 user 并丢弃 details,上游线零新增字段)。唯一有意的日志面变化:失败事件名从四个合并为 notify-send-error/notify-no-channel 两个,现均带 carrier 字段(信息量不低于原状)。无 kernel/、update.ts、持久化格式触碰。
  6. 是否破坏缓存:不破坏。details 永远到不了上游线(pi 转换层丢弃),content 字节不变,前缀缓存不受影响。
  7. 是否改了设计方向:没有。opt-in 通道切换的设计保持不变,修复是让实际行为对齐设计意图(唤醒等价)和文档事实(配置位置)。
  8. 是否引入了新的配置:我的修复没有新增配置——只是把 PR 自带的 pi.subagents.notifyStructured(默认 false)在规范位置声明并文档化。该字段的引入本身已在 PR 描述的 config surface 一节申报过。

验证证据:本地定向套件 131/131(原 129 + 新增 2)、tsc --noEmit 干净、tsup 构建通过;旧 head CI 30/30 绿。判定:新 head CI 转绿后即可合并(合并动作按规矩留给你)。

ranxianglei pushed a commit that referenced this pull request Nov 6, 2026
The new opt-in key (#5750) was declared in CONFIGURATION.md/zh and both
config types, but the standalone-facing pi-subagents READMEs (example
block + key table, en/zh) never listed it.

@ranxianglei ranxianglei left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注:GitHub API 禁止 approve 自己的 PR(token 即作者),故以正式 review(COMMENT)提交,判定如下。

(ai: vllm-qwen/qwen3.8-27b)

APPROVE — 独立复审 head d8f2dadfe 全量 diff(含任务快照 7562aac0b 之后新增的 e8d8a4206、d8f2dadfe 两个提交)。

方向核对(对 #5750)

issue 要的是「持久化的类型化 custom message + 版本化 details」,owner 已在 issue 线程拍板 C 方案(opt-in 开关默认 off,先给精确规格后 owner 回「c」签核)。PR 逐条按批准规格实现:键名/默认值/4 个通知点/启动期来源捕获/能力门控回退,全部一致。修的是投递层没有结构化信封这个根因,不是调措辞。

关键验证(逐项独立做过,不依赖 PR 描述)

  1. Wire 安全:对照钉死宿主版 @earendil-works/pi-coding-agent@0.83.0 真实代码——convertToLlm 对 role:"custom" 只把 content 以 role:"user" 出网,details/customType/display 被丢弃(dist/core/messages.js:75-96)→ 模型可见字节与 legacy sendUserMessage 路径完全一致,前缀缓存不受影响。
  2. 持久化/重载:CustomMessageEntry 把 {customType, content, details?, display} 写进会话 JSONL(session-manager.d.ts:97-103)→ live 与 reload/resume 暴露相同元数据,满足验收项。
  3. 唤醒一致性:宿主 sendCustomMessage 在 idle 宿主上只有带 triggerTurn 才起新 turn(agent-session.js:1058-1093),而 sendUserMessage 恒触发 turn——e8d8a4206 补上 triggerTurn:true 正是修掉首个 head 的真实回归(idle 宿主上通知会休眠到下次活动),已对照宿主源码确认修法正确且只影响 idle 分支(streaming 时两路都 steer)。
  4. 配置流:canonical home pi.subagents.notifyStructured(src/config.ts 有类型声明,adapter spread 透传)与 acp.json fallback 收敛到同一处 resolveDelegate 的 cfg.notifyStructured === true——仅字面量 true 启用,无 env 面。
  5. 溯源捕获:runs.set 全仓唯一创建点(runDelegate),originToolCallId/sourceSessionId 在启动时捕获;缺省即缺省、从不伪造,满足「missing origins stay visible」。

回归审查(diff 触碰路径的既有行为逐项结论)

  • 默认 off(全部现有安装):4 个通知点逐字节走原 sendUserMessage(text,{deliverAs:"steer"}) —— 保持(有测试钉住 sendMessage 不被触碰)。
  • injectResult cheap no-op gate:仅在 on+sendMessage 时放宽;off 时判定式不变 —— 保持。
  • 恢复语义(发送失败 → undelivered → 挂到下次通知/tool result):dispatcher 失败返回 false,恢复标记只在 sent=true 提交 —— 保持。
  • 日志事件名 notify-turn-end-error/notify-batch-error/inject-error → 统一 notify-send-error(+carrier 字段):内部日志,非用户可见/非 wire —— 有意变更,无外部影响。
  • 版本号 0.2.3→0.2.4 + 两处 lockfile 同步:Pi-Subagents Boundary 要求;嵌套 lock 在 PR 前 stale 于 0.2.2,现收敛 —— 顺手修正,方向正确。
  • 缓存:模型可见字节不变(details 出网前剥离)—— 未破坏。

测试有效性

delegate-structured-notify.test.ts 9 个用例均为真断言、驱动宿主生命周期表面:同测内 A/B 钉住「content 与 legacy 消息逐字节一致」;能力门控双向断言;batch 列全 run + 溯源在场/缺省两态;wake parity {deliverAs:"steer", triggerTurn:true} deepEqual 钉死;usage note kind:"usage" 与 terminal 可区分(去重友好)。这些回归发生时抓得住。既有 3 个通知套件不变通过。

行为变更披露(旧值→新值)

新增配置 delegate.notifyStructured(boolean,默认 false):off = 现状零变化;on 时投递信道由 sendUserMessage 切为 sendMessage(typed custom message;TUI 按 custom-message 样式渲染而非 user 气泡样式——纯外观差异、仅 opt-in 用户),模型可见文本与 steer/idle-wake 语义不变。PR 正文 Config surface 节已披露,owner 签核在 #5750 线程。

CI:评审时 test shards 仍在跑(无失败项);最终绿以 head acad6f9 的运行为准。合并权在 owner。

@ranxianglei

Copy link
Copy Markdown
Owner Author

(ai: vllm-qwen/qwen3.8-27b)

已顺手修:pi-subagents/README.md 与 README.zh-CN.md 的示例块和键值表补上 delegate.notifyStructured(standalone 面向文档漏列新键)+ commit acad6f9

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

审核完成,判定 APPROVE:已独立对照 pi 0.83.0 宿主源码逐行复核(wire 安全 / 持久化重载 / 空闲唤醒 parity / 双配置面流 / 溯源捕获),e8d8a4206+d8f2dadfe 两个修复均验证成立;唯一残留的小缺口——pi-subagents/README.md 与 README.zh-CN.md 的示例块和键值表漏列 delegate.notifyStructured——已顺手修掉推回分支(commit acad6f9)。正式 review 已发(GitHub API 禁止 approve 自己的 PR,故以 review-COMMENT 形式提交并在正文写明 APPROVE):#5790 (review) 。分支新 head acad6f93c,CI 转绿后即可由你合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

收到——这条是我自己刚发的「已顺手修」通知经上游同步回显,无新增请求。状态不变:分支 head acad6f93c 等 CI 转绿后即可由你合并,无其他待办。

@ranxianglei ranxianglei left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ai: vllm-qwen/qwen3.8-27b)

APPROVE(新 head acad6f93c)——对本轮唯一增量做收口确认:

  • delta d8f2dadfe..acad6f93c = 仅 2 个文件、4 行纯文档(pi-subagents/README.md + README.zh-CN.md 的示例块与键值表补列 delegate.notifyStructured,即上一轮「已顺手修」commit)。无代码、无配置、无锁文件变更;不影响任何测试路径。
  • CI(镜像缓存 @ acad6f9):全部守卫/门禁绿——static-gates、kernel-guard、pi-subagents-guard、config-surface-guard、lock-sync、docs-sync、docs-coverage、version-guard、lane-guard、lifecycle-ledger-guard、unused-exports、test-import-graph、mysql-contract 均 success;test 分片 4/10 已绿、0 失败、其余在跑(文档 delta 不可能改变其结果);e2e 各 lane skipped 属正常。
  • 实质性内容(wire 安全 / 持久化重载 / 空闲唤醒 parity / 双配置面流 / 溯源捕获 / 回归清单)已在上一轮正式 review 中逐项独立核对过(对照 pi 0.83.0 宿主源码),结论不变。

判定维持 APPROVE,无阻塞项;合并动作留给你。(GitHub API 禁止 approve 自己的 PR,故仍以 review-COMMENT 形式提交。)

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

新 head acad6f93c 收口审核完成,判定维持 APPROVE:本轮增量仅 4 行纯文档(pi-subagents README en/zh 补列 delegate.notifyStructured),CI 全部守卫/门禁绿、test 分片零失败;实质内容上轮已逐项独立核对,结论不变。正式 review:#5790 (review) ,无阻塞项,可由你合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

CI 已全绿:最终 head acad6f93c 上 30/30 checks 通过(0 failed / 0 pending)。

补充一条透明性说明:我推完两个修复 commit 后,另一条并行会话在同一 PR 分支上追加了 acad6f93c(docs:把 notifyStructured 补进 pi-subagents 独立包的 README 中英文示例块与键表)——与我改动的文件零重叠、内容核对无误,属于互补而非重复。分支现在共 4 个 commit(2 个原 PR + 2 个我的修复/声明 + 1 个并行 README 补充 = 实际 5 个,即原 feat + lock 同步 + 我的 fix/docs + 并行 docs),全部在审核结论覆盖范围内。

收工判定:可以合并——合并动作按规矩留给你(PR #5790)。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

更正上一条里的笔误:分支相对 master 共 5 个 commit(不是 4)——704993fb9 feat + 7562aac0b lock 同步(原 PR)+ e8d8a4206 fix(唤醒等价 + carrier 日志)+ d8f2dadfe docs(规范配置位置声明,我推的)+ acad6f93c docs(pi-subagents README,并行会话推的)。CI 在最终 head acad6f93c 上 30/30 全绿,判定不变:可合并。

ci-check and others added 5 commits November 11, 2026 00:38
Deliver delegate completion/failure notices as a typed custom message (customType billion-context:delegate-notification) whose versioned details carry stable run identity plus launch provenance (originToolCallId/sourceSessionId), while content stays byte-identical to the legacy steering user message. The model sees the same text either way; pi's convertToLlm drops details so they never reach upstream.

Gated behind delegate.notifyStructured (default false -> plain path untouched); falls back to the plain path automatically when the host lacks ExtensionAPI.sendMessage. Lets third-party UIs (e.g. pi-tidy #59) tie a notice to its launching turn without parsing prose.

Refs #5750
The PR bumped pi-subagents/package.json 0.2.3 -> 0.2.4 but did not
regenerate the root package-lock.json, which still recorded the file:
link at 0.2.3. The lock-sync drift guard (#2704/#3782) regenerates the
root lock and fails on any residual diff, so the check went red.
Regenerating updates exactly one line: the billion-context-pi-subagents
version record 0.2.3 -> 0.2.4. Kernel lock verified clean (the PR does
not touch kernel/).
… path

The opt-in structured envelope (customType billion-context:delegate-notification)
switched delivery from sendUserMessage to sendMessage, but pi's sendCustomMessage
only starts a turn on an IDLE host when triggerTurn is set — without it an
idle-tier notice sat dormant until the next activity instead of waking the model
like the plain path does (#5750 acceptance: wake-up behavior intact). Pass
{deliverAs:"steer", triggerTurn:true}: streaming delivery is unchanged (steer
either way), idle hosts gain parity with the legacy plain message.

Also restore per-carrier identity in the unified send-failure logs: the refactor
folded four carriers' error/warn events into notify-send-error/notify-no-channel
without saying which tier failed — add a `carrier` field ("turn-end" |
"idle-batch" | "inject-result" | "inline-usage").

Tests: pin triggerTurn on every structured dispatch; add coverage for the
usage-note carrier (kind:"usage" envelope on, plain path off) which was missing.
…onfig home

The structured-notify knob works de facto through the piSubagentsAdapter spread
passthrough, but the host schema (PiSubagentsFileConfig) did not declare it and
CONFIGURATION.md never mentioned it — and the PR description pointed users at
the deprecated ~/.pi/acp.json delegate.* fallback, which is ignored whenever the
canonical pi.subagents section exists. Declare the field in the host schema
(precedent: notifyIfRead is declared in both schemas) and document it in both
jsonc examples. No runtime change.
The new opt-in key (#5750) was declared in CONFIGURATION.md/zh and both
config types, but the standalone-facing pi-subagents READMEs (example
block + key table, en/zh) never listed it.
@ranxianglei
ranxianglei force-pushed the 2026-11-06_pi-structured-delegate-notify branch from acad6f9 to 31c7824 Compare November 10, 2026 17:47
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

Merge conflict resolved and pushed. Rebased the 5 PR commits onto current master; new branch head 31c7824cd (was acad6f93c).

What happened: master's doc reorg (#5920) replaced the root CONFIGURATION.md / CONFIGURATION.zh-CN.md with 2-line redirect stubs pointing at docs/configuration.md, while this PR (cut against the old layout) still edited the old full CONFIGURATION.md. Git saw a whole-file clash. The resolution kept master's stubs (did not resurrect the old file) and relocated the PR's one added doc line (notifyStructured) into its new canonical home docs/configuration.md (+ .zh-CN); src/config.ts auto-merged cleanly (verified the field landed in PiSubagentsFileConfig). Force-push was gated on a fresh fetch confirming the remote was still at the exact base SHA (lease-pinned); the branch had been idle ~4 days, so no concurrent work was clobbered.

Verified locally on the rebased head: lock-sync idempotency exit 0 (root lock = exactly one line, pi-subagents 0.2.3→0.2.4, matching package.json); typecheck exit 0 (kernel + pi-subagents + full src/tests); pi-subagents unit suite 272/272 green. Also proved origin/master is now an ancestor of the tip, so no merge conflict remains.

七问:

  1. 是什么问题:PR 分支和 master 冲突(merge state dirty),导致合不了。
  2. 什么原因:master 的文档重组([PR] docs: batch-migrate 14 root-level documents into docs/ (consolidation + master index + redirect placeholders) | docs: 14 个根级文档一次性迁入 docs/(集中 + 总目录 + 重定向占位) #5920)把根目录 CONFIGURATION.md/.zh-CN.md 换成了指向 docs/configuration.md 的重定向占位符;而本 PR 基于旧布局,改的还是那份旧的完整 CONFIGURATION.md。一边「整份替换成占位」、一边「在完整版里加一行」,git 判成整文件冲突。
  3. 影响范围与严重程度:只卡合并这最后一道关,不碰任何运行时/代码逻辑;不解决则 PR 一直合不了。纯机械的文档位置漂移,零行为影响。
  4. 怎么修复的:把 5 个 PR 提交 rebase 到当前 master。冲突处既不复活旧文件、也不丢 PR 的新文档——保留 master 的占位符,把 PR 新增的那一行 notifyStructured 文档迁到新规范位置 docs/configuration.md(中/英文各一行);src/config.ts 自动合并干净(已核对该字段正确落在 PiSubagentsFileConfig)。force-push 前先 fetch 确认远端基线未变(分支已闲置约 4 天),并用 lease 钉死基线 SHA。
  5. 是否有回归问题:无。根 CONFIGURATION.md 维持 master 的占位符(没有把已迁移走的旧文件拉回来,即没有回退文档重组);PR 功能代码 pi-subagents/* rebase 全程无文本冲突,且该组件自包含(不 import 父包 src/),master 那 656 个提交无法破坏其编译;src/config.ts 仅新增一个可选字段。本地证据:lock-sync 幂等 exit 0、typecheck exit 0、pi-subagents 单测 272/272 全绿。
  6. 是否破坏缓存:不涉及——纯文档位置迁移 + rebase,未触碰任何缓存/重试/增量游标逻辑。
  7. 是否改了设计方向 / 引入新配置:都不涉及。只是把同一行文档从旧路径搬到新路径;notifyStructured 这个开关本就是 PR 自带的,我没有新增或改动其语义。

Verdict: conflict cleared — the branch strictly leads master by 5 commits and merges cleanly; awaiting CI on the new head.

@ranxianglei ranxianglei left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ai: vllm-qwen/qwen3.8-27b)

APPROVE(新 head 31c7824cd,CI 全绿收口)

本轮相对上一轮(acad6f93c)的分支变化 = rebase 到最新 master,无新 PR 内容:

  • PR 自身提交不变:仍是同样的 5 个逻辑提交(feat 主体 / root-lock 同步 / idle-wake parity fix / canonical config home 文档 / README 补列),只是换了 hash。对 master 的净增量仍是 11 个文件 +391/-66,与已审版本一致。
  • 语义标记逐项复核通过(rebase 后新 head 上实测):pi-subagents/src/config.ts:198 严格门 cfg.notifyStructured === true、默认 false;delegate-tool.ts:333 结构化路径 {deliverAs:"steer", triggerTurn:true}、carrier 参数保留在两个失败日志事件里;测试文件 9 个用例全在;docs/configuration.md:919 + docs/configuration.zh-CN.md:913 新键在文档搬家(#5920 → docs/)后的规范位置就位;pi-subagents 版本 0.2.4。
  • CI(镜像缓存 @ 31c7824):30/30 全绿——10 个 test 分片(ubuntu/windows × node 22/24)+ static-gates ×2 + gate ×2 + mysql-contract 全部 success,e2e 各 lane skipped 属正常,0 failed 0 pending。
  • 实质性审查结论(wire 安全 / 持久化重载 / 空闲唤醒 parity / 双配置面收敛 / 单点溯源捕获 / 回归清单 / 缓存不受影响)见前两轮正式 review,全部维持不变。

判定:APPROVE,无任何阻塞项,可由你合并。(GitHub API 禁止 approve 自己的 PR,仍以 review-COMMENT 形式提交。)

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

head 31c7824cd(rebase 到最新 master)终审完成,判定 APPROVE:PR 自身 5 个逻辑提交与净增量(11 文件 +391/-66)与已审版本一致,语义标记逐项复核通过,CI 30/30 全绿(0 failed / 0 pending)。正式 review:#5790 (review) ,无阻塞项,可由你合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

(ai: vllm-qwen/qwen3.8-27b)

本轮(head 31c7824cd)审核收尾汇报:

  • 做了什么:分支在本轮之间 rebase 到了最新 master。我核对了 PR 自身提交(仍是同样 5 个逻辑提交,仅换 hash)、对 master 的净增量(11 文件 +391/-66,与已审版本一致),并在新 head 上逐项复核了关键语义标记:严格门 cfg.notifyStructured === true(pi-subagents/src/config.ts:198、默认 false)、结构化路径 {deliverAs:"steer", triggerTurn:true} 与 carrier 日志(pi-subagents/src/delegate-tool.ts:333/341/344)、9 个测试用例、新键在文档搬家后的规范位置(docs/configuration.md:919 / zh-CN:913)、版本 0.2.4。
  • 证据:CI 镜像缓存 @ 31c7824 = 30/30 全绿(0 failed / 0 pending,含全部 test 分片与 static-gates/gate/mysql-contract)。实质性审查结论(wire 安全、持久化重载、空闲唤醒 parity、双配置面收敛、单点溯源捕获、回归清单、缓存不受影响)见前两轮正式 review,维持不变。
  • 结果:判定 APPROVE,无阻塞项、无待修发现、无需要决策事项。正式 review:[PR] Pi: opt-in structured acp_delegate notification envelope for third-party UIs #5790 (review) 。剩余动作只有一个:由你合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

该PR已按根因归类纳入 [storage] 根因汇总 #6267,由汇总单统一跟踪处理;本单不再单独跟进,故关闭。如认为归类有误或问题仍未解决,请直接回复,会重新打开。

@ranxianglei

Copy link
Copy Markdown
Owner Author

状态更正(自动化脚本误操作): 本单此前被「纳入根因聚合」流程误关闭, 现重新打开。机器人工作已停, 本单由根因聚合线程统一跟踪, 根因修复落地后请手动关闭或在本单回复「close」。
[automated: re-open after bot-stop-only policy]

@ranxianglei ranxianglei reopened this Nov 12, 2026
@ranxianglei

Copy link
Copy Markdown
Owner Author

重新打开:此前被归类聚合脚本误关。按 owner 口径,纳入根因聚合的 issue 只停机器人、不关闭,由根因聚合线程统一跟踪,根因修复落地后统一关闭。
(reopened: absorbed issues must not be closed, only bot work stopped — owner policy 2026-11-12)

@ranxianglei

Copy link
Copy Markdown
Owner Author

(更正)此前按"清理"口径误关闭;按 owner 口径纠正:被根因聚合纳入的 issue 只停机器人、不关闭。本 issue 重新打开,机器人工作已停。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature][Pi] Structured acp_delegate notifications for reliable turn folding and third-party UI integration

1 participant