@uiyzzi/pi-orca-mail
extensionmaintainedAuto-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-maildownloads/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