@uiyzzi/pi-orca-mail

extensionmaintained

Auto-inject Orca orchestration mail into pi agents — no blocking check --wait needed

by · v0.2.6 · published 1w ago

$ pi install npm:@uiyzzi/pi-orca-mail
downloads/mo
0
stars
0
last push
1w ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

No downloads in the last 12 weeks.

README

pi-orca-mail

Orca 编排 Run 信箱的自动推送桥。pi agent 不再需要 orca orchestration check --wait 阻塞轮询——worker_done / escalation / question 到了自动变成用户消息注入上下文。

与 Orca push-on-idle 的分工

Orca 自带的 push-on-idle 只投递直发终端 handle 的邮件;Run 信箱(worker 生命周期汇报)它从不推送,coordinator 只能轮询。本插件只补这个缺口:

邮件投递者
直发终端 handle 的邮件Orca push-on-idle(本插件不碰,避免双投)
Run 信箱的 worker_done / escalation / question本插件

行为

环境行为
Orca 外(无 ORCA_TERMINAL_HANDLE完全不生效。不注册任何 handler,零 timer、零进程、零损耗
Orca 终端内,无 active coordinator run休眠。每 30s 探测一次 run-list,不跑 check、不产生错误
有 active coordinator run后台跑阻塞式 check --run <id> --wait --types worker_done,escalation,question,status(扩展进程内,不占 agent turn),邮件到达即注入

注入分两条路:

  • agent 空闲pi.sendMessage({display: false}, {triggerTurn: true}) 开新 turn:XML 信封进上下文但不在 TUI 渲染
  • agent 忙碌context 事件钩子,把邮件拼进进行中的 LLM 请求(这是相对 Orca push-on-idle 的本质优势:推送只在 idle 跳变触发)。若邮件在 turn 最后一次 LLM 调用期间到达(不会再有 context 事件),agent_end/agent_settled 事件唤醒桥直接投递——事件驱动,无轮询,不会卡到下一个 turn

TUI 可视面由 transcript entry 承担:每批邮件镜像为一条 pi.appendEntry + registerEntryRenderer 横幅(📬,展开可见 body),纯 TUI 展示、不进 LLM 上下文。

同时在系统提示词追加一小段说明,告诉 LLM:信箱是推送式的,不要自己 poll;要回复用 orca orchestration reply --id <msg_id> --body "..."

注入的信封是纯 XML(与 pi 自身的 <bd_context><project_context> 等注入块同风格),body 实体转义,worker 文本不会破坏信封:

<orca-mail count="1" source="pi-orca-mail">
<note>Auto-injected orchestration mail. Do not poll the mailbox …</note>
<message type="worker_done" id="msg_a1b2" from="term_abc" at="2026-07-31T15:24:14Z">
<subject>Wave 3 done</subject>
<body>
PR #61 created, tests pass.
</body>
</message>
</orca-mail>

正确性

  • 服务器即队列:本地最多持有一个 batch。未 ack 的 batch Orca 会原样重放,桥不建本地缓冲
  • 只 ack 已投递:ack 随下一轮 check --ack <id> 发出;投递失败(agent 刚好变忙)转 held 等钩子
  • 重放去重:ack 丢失导致服务器重投时,按 deliveryId 跳过重复注入,只补 ack
  • run 消失即休眠:run 结束 / 身份降级(legacy_read_only 等)不报错刷屏,回到休眠探测
  • 信箱争用静默重试waiter_exists(重载会话时新旧桥短暂重叠持有互斥 waiter)不报错,退避后自动恢复
  • 客户端类型过滤:Orca 的 --types 只是唤醒条件,batch 会带上信箱里全部未读(含 heartbeat)。桥在本地丢弃非监听类型;被全部滤掉的 batch 仍会在下一轮带上 ack,避免服务器无限重放
  • HELD 不死等agent_end/agent_settled 唤醒 held 批次直接投递,不会因 turn 结束而滞留到下个 turn
  • 退避重试:真正的 CLI 失败保留 slot,15s 后重试,通知节流每分钟最多一条

架构

src/index.ts   胶水:pi 事件 ↔ 桥(唯一懂 pi 的地方)
src/bridge.ts  状态机:EMPTY → HELD → INJECTED → EMPTY(纯逻辑,依赖全注入)
src/runner.ts  IO:run-list 探测 + spawn `check --run --wait`、解 JSON
src/env.ts     检测:ORCA_TERMINAL_HANDLE 硬信号
src/format.ts  渲染:mail → 注入文本 + 系统提示词片段

开发

npm install
npm test     # tsc + node --test(31 个用例)
npm run lint

本地装进 pi:

pi install ./packages/orca-mail

License

MIT