@cobia/pi-onward

pi 出错或空回复时,按阶段策略恢复并调用扩展命令或具名动作

Packages

Package details

extension

Install @cobia/pi-onward from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@cobia/pi-onward
Package
@cobia/pi-onward
Version
0.5.2
Published
Nov 12, 2026
Downloads
2,075/mo · 865/wk
Author
cobia
License
MIT
Types
extension
Size
129.9 KB
Dependencies
1 dependency · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./src/extension/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi 出错或空回复时,按规则和阶段自动续跑,也可以调用其他插件的命令或动作

📦 安装

pi install npm:@cobia/pi-onward

安装后重新打开 Pi,或执行 /reload,再输入 /onward 检查插件是否加载

🚀 开始使用

1. 配置恢复规则

pi-onward 没有默认规则。复制包里的 example.json 到 ~/.pi/agent/onward.json,再按自己的需求修改

示例会在额度不足时停止,在临时服务错误或网络错误时重发任务提示词,在空回复时提示继续;连续失败达到示例中的停止阶段后,交由用户处理。规则、次数和间隔都可以调整,写法见规则与阶段

只想在当前项目使用时,也可以放到 <项目>/.pi/onward.json;项目需要先获得 Pi 信任,详见作用域与位置

2. 加载并检查

在 Pi 中执行:

/reload
/onward status
/onward show rules

确认状态为已启用、规则已加载后,照常发送任务。Pi 完成自身的重试和恢复后,如果仍以错误或空回复结束,onward 会按配置执行恢复动作

💬 日常使用

自动恢复

onward 处理两类失败:Pi 明确以错误结束,或者正常结束但没有文字、工具调用。规则按顺序匹配,第一条命中的规则生效;再根据连续失败次数选择该规则的一个阶段。每个阶段只执行一个具名动作

内置动作 作用
pi.message 追加一条自定义消息,继续当前任务
pi.command 等当前轮次完全结束后,调用已加载的扩展命令
onward.stop 停止当前恢复过程,保留动作结果供查看

pi.message 和 pi.command 随 onward 一起提供,无需另外安装。pi.* 是 onward 对接 Pi 的动作命名空间,并非 Pi 官方 API

查看状态与开关

用 /onward 打开菜单,或直接执行:

/onward status
/onward off
/onward on

status 显示命中的规则、当前阶段、连续失败次数、已启动续跑次数和动作结果;查询不会改变恢复状态,也不会把这些信息发给模型

off、on 默认修改全局配置并立即生效,同时取消当前恢复。项目级开关优先于全局;只修改当前项目时,使用 /onward --scope project off 或 on。启用开关不会立即发起模型请求

onward.stop 只结束本轮恢复;需要持续停用自动恢复时,使用 /onward off

状态栏

状态栏采用 emoji onward · 失败次数 的短格式,例如 ⏳ onward · 失败3。数字表示本轮连续失败次数,规则、动作名和完整原因通过 /onward status 查看

Emoji 含义
⏳ 等待间隔、提议等待启动或动作待执行
⏩ 已启动续跑
🚀 正在执行动作
🎉 动作完成
📤 命令已分派,业务结果由目标插件报告
🔀 已接受接管
🛑 本轮恢复停止,例如规则停止、未命中规则或达到次数上限
🚫 恢复已取消
💥 动作失败,同时显示“动作失败”
🎲 结果未知,同时显示“结果未知”

空闲时隐藏状态栏;终止结果保留到当前恢复状态被清除。异常提示示例:🎲 onward 结果未知 · 失败3

续跑消息与任务提示词

pi.message 的 prompt 默认为 继续,可以使用以下变量,也可以与正文拼接:

变量 内容
{failures} 本轮连续失败次数,包含当前失败
{rule} 当前命中的规则名称
{error} 当前错误信息;空回复时为“空回复”
{taskPrompt} 本轮已接收的任务提示词文本

例如,在阶段的 action 中填写:

{
  "use": "pi.message",
  "with": { "prompt": "请重新尝试:\n{taskPrompt}" }
}

上次输入为 检查并修复登录接口 时,会追加 请重新尝试: 换行后接该任务文本。"prompt": "{taskPrompt}" 直接重发任务文本,"prompt": "继续{taskPrompt}" 则在前面加上“继续”。这些写法都会追加一条新消息,保留历史回复

模板只替换一次:任务文本或错误信息中包含的 {error}、{taskPrompt} 等文字保持原样,未知变量也保持原文

{taskPrompt} 使用真正进入会话的用户消息,包含输入扩展改写、Pi 技能及提示词模板展开后的结果。人工或 RPC 消息被接收后才更新任务来源和恢复计数;被拦截、尚未消费或已取消的输入不会成为新任务。自动续跑保留原任务;新会话首次由扩展发起任务时,以该消息为任务来源

重载、恢复会话或切换分支时,onward 根据当前分支的来源记录重建任务。来源记录不重复保存提示词正文,也不进入模型上下文。重发只复用文字,不复制图片附件或整个请求上下文;缺少任务文本、来源记录或无法确定排队消息来源时,使用 {taskPrompt} 的动作会明确失败并停止本次恢复

调用其他插件

目标命令由 Pi 加载后,就可以通过 pi.command 调用,目标扩展无需修改、无需注册 onward 动作:

{
  "use": "pi.command",
  "with": {
    "name": "example-command",
    "args": "-- 继续执行当前任务"
  }
}

example-command 是占位名称,替换成实际已加载的扩展命令,不带开头的 /。args 按目标命令的格式填写,原样传递,不经过 shell、不替换 onward 模板,也不需要模型执行。/model 等 Pi 内置交互命令不属于扩展命令,不支持这个入口

结果“已分派”表示命令已交给 Pi,业务是否成功由目标插件报告。onward 不能强制取消已经进入目标命令处理器的操作,也不会自动重放命令。通用命令的跨会话、跨进程防循环由目标插件负责,maxHandoffs 不限制这类调用

计数与停止

连续失败次数属于整轮恢复,换错误或换规则不会清零。一次失败以 Pi 完成本轮重试后的最终结果为准,不包含 Pi 内建重试期间的每个 HTTP 请求

  • 正常模型回复(包括工具轮)结束本轮恢复。
  • 已接收的人工新任务、Esc、关闭自动恢复、Pi 重载、切换分支和配置修改会取消未执行动作;Esc 保留本次失败的诊断状态。
  • 扩展自动发送的续跑消息保留当前恢复过程和失败计数。
  • 没有匹配规则、超过 maxFailures、动作要求停止,或动作完成后没有安排新请求时,本轮停止。
  • 动作失败、超时、抛出异常或返回非法结果时,不自动进入下一阶段;超时、异常及非法返回标记为“结果未知”,不自动重放可能已经产生副作用的动作。

终止状态会保留动作结果,等待新的人工任务

📝 配置文件

用 /onward show 查看已加载配置、每项来源和文件位置。修改顶层参数可以直接使用命令:

/onward set maxFailures=10 actionTimeout=45s
/onward unset maxHandoffs
/onward --scope project set maxFailures=5
/onward --scope project show

规则和动作写在 JSON 的 rules 中;set 只修改恢复上限、动作时限和全局 quietStartup,开关用 on、off

作用域与位置

优先级:内置默认值 < 全局 < 项目

作用域 适用范围 配置文件
global 同一系统用户下的 Pi 会话 ~/.pi/agent/onward.json
project 启动 Pi 的工作目录 <工作目录>/.pi/onward.json

设置 PI_CODING_AGENT_DIR 时,全局配置跟随 Pi 的用户目录。项目配置只读取启动目录下这一份,不向父目录查找

项目配置只在 Pi 已信任当前项目 时读写。未受信任时不读取文件、不参与合并,也不允许 /onward --scope project 修改;全局配置照常生效,show 会说明项目层已跳过。检查项目内容后,可用 Pi 的 --approve 为本次启动授权,或用 /trust 保存决定并重新加载。仅有 onward.json 不一定触发 Pi 的自动信任提示

  • --scope global|project 写在动作前。不指定范围时,修改写全局,show 显示合并结果;指定范围后只查看或修改那一层。
  • 普通字段逐项覆盖,unset 删除本层值并恢复继承。
  • 项目级 rules 整份替换全局规则,不拼接;不写则继承,写 [] 则不使用全局规则。
  • quietStartup 只能写在全局;不写时跟随 Pi。配置错误、动作注册问题和规则遮挡提醒仍会显示。

配置示例

下面的规则在第 1、2、3 次服务错误后重发任务文本,第 4 次失败时停止:

{
  "$schema": "https://raw.githubusercontent.com/cobia68/pi-labs/main/packages/pi-onward/onward.schema.json",
  "enabled": true,
  "maxFailures": 20,
  "maxHandoffs": 3,
  "actionTimeout": "30s",
  "rules": [
    {
      "name": "server",
      "when": { "failure": "502|503|Connection error" },
      "stages": [
        {
          "minFailures": 1,
          "delay": "3s..15s",
          "action": {
            "use": "pi.message",
            "with": { "prompt": "{taskPrompt}" }
          }
        },
        {
          "minFailures": 4,
          "action": {
            "use": "onward.stop",
            "with": { "reason": "连续失败,请检查服务状态" }
          }
        }
      ]
    }
  ]
}

$schema 用于编辑器补全和校验;实际配置是否可用以 /onward show 为准。希望失败后调用其他插件时,把对应阶段的 action 换成命令动作或已加载的具名动作

字段 默认值 含义
enabled true 是否启用自动恢复
maxFailures 20 一轮恢复最多处理的连续失败数;超过后停止
maxHandoffs 3 结构化恢复链最多跨会话接管的次数;0 禁止接管
actionTimeout "30s" 单次动作执行时限,等待 delay 不计入
quietStartup 跟随 Pi 是否隐藏正常启动提示,仅限全局
rules [] 按顺序匹配的恢复规则

规则与阶段

一条规则由匹配条件 when 和恢复阶段 stages 组成:

  • when.failure 是大小写不敏感的正则。空回复用空字符串匹配,所以 ^$ 只匹配空回复,.+ 只匹配普通错误,.* 匹配所有失败。
  • when.provider、when.model 匹配整串名称,只有 * 是通配符;多个条件必须同时满足。不写 when 时匹配任何失败,通常放在最后作为兜底。
  • 规则可以用 enabled: false 停用;按顺序选择第一条启用且匹配的规则。
  • minFailures 是连续失败次数下限,包含当前失败。第一阶段必须为 1,之后严格递增;每次选择已经达到下限的最后一个阶段。
  • 每个阶段引用一个 action,结构为 { "use": "动作名", "with": { "参数": "值" } },with 可省略;不会隐式切换到其他动作。

例如,要先续跑 10 次、再停止,可在 minFailures: 1 设置消息动作,在 minFailures: 11 设置停止动作,并让 maxFailures 至少为 11

delay 默认为 0s,使用序号 连续失败次数 - minFailures + 1 选择间隔。达到阶段阈值的那次失败使用第一个间隔;换规则不会重置连续失败次数:

写法 等待时间
"10s" 每次 10 秒
"5s,15s,35s,1m" 5、15、35、60、60… 秒;列表用完后重复最后一项
"3s..15s" 3、6、9、12、15、15… 秒;以起始值递增,到上限后保持

修改何时生效

  • 通过命令修改:/onward on/off/set/unset/reset 写入配置后,立即在当前运行中生效,无需重载 Pi;成功的修改会取消当前恢复。
  • 直接编辑文件:使用 Pi 的 /reload 或重启加载;会话开始时也会重新读取配置。其他已打开的 Pi 会话需要各自重新加载。
  • 查询配置:show、status、actions 只读当前运行状态,不重读配置文件、不清零计数。

set 先检查全部参数,有一项不合法就一项都不改。文件无法读取时不改文件;reset 即使无法修改文件,也会取消本轮恢复并清零计数

写入失败时,本次运行仍立即应用该层修改,show 标记“未保存”;修改另一层不会丢掉它们。再次修改同一层时,先重读文件,合并尚未保存的设置和删除操作,再一起尝试落盘,保留未涉及字段的手工编辑。Pi 的 /reload、切换会话或重启会清除未保存修改,重新以磁盘内容为准

未知字段、非法正则、空阶段、阶段阈值错误或重复规则都会使整份配置无效。已启用规则引用未加载的动作、冲突的动作或非法参数时,也不会启用部分配置。未被引用的动作注册失败只报告警告;动作参数由提供者的 JSON Schema 校验,运行模式在调用前检查

🧰 命令速查

以下命令在 Pi 中执行,支持 Tab 补全;--help 只显示帮助,不执行修改

命令 作用
/onward 打开状态和配置菜单,默认修改全局配置
/onward actions 查看已加载的具名动作及注册失败原因
/onward off 停用自动恢复并取消当前恢复过程
/onward on 启用自动恢复,不立即请求模型
/onward reset 删除本层开关、恢复上限和 quietStartup,保留规则及其他手写内容;重置运行状态
/onward set 字段=值 … 修改上限、动作时限或全局 quietStartup,全部参数先校验
/onward show [rules] 查看已加载配置、来源、规则和文件位置;rules 只列规则
/onward status 查看当前阶段、失败数、已启动续跑数及动作结果
/onward unset 字段 … 删除指定配置项,采用下层值或默认值
/onward --help 查看完整用法;单个动作的帮助用 /onward <动作> --help

修改或查看指定层时,把 --scope 写在动作前,例如 /onward --scope project set maxFailures=5。status、actions 不接受 --scope

解析规则

命令顺序固定,支持以下四种形式:

/onward
/onward --help
/onward --scope <global|project>
/onward [--scope <global|project>] <动作> [动作参数] [--help]

前两种打开默认菜单或显示总帮助,第三种打开对应作用域的配置菜单。带作用域查看帮助时必须明确动作,例如 /onward --scope project set --help;/onward --scope project --help 报错

  • 一条命令只能占一行,以空格或 Tab 分隔,允许首尾及连续空白。动作、字段、作用域和 rules 均区分大小写,不支持缩写、引号或转义。
  • --scope 只能出现一次,只接受 --scope global、--scope project,不接受 --scope=project 或动作后的作用域选项。
  • --help 只能出现一次,且必须是最后一个独立参数;不支持 -h、help 动作和 -- 结束符。
  • status/actions/on/off/reset 不接受位置参数;show 只接受可选的 rules;set、unset 分别要求至少一个赋值或字段名。
  • set 的每个参数必须是完整的 字段=值,恰好一个等号、两侧非空;不能拆成 字段 = 值。unset 只接受裸字段名。重复字段均报错,即使值相同。
  • 帮助只豁免 set/unset 完全没填参数的情况。已填写的参数仍须合法:set --help 显示帮助,set maxFailures=0 --help 报错。
  • 结构错误从左到右只报告第一个;结构通过后汇总未知字段、重复字段、非法值及作用域限制。帮助和报错都不写配置、不重载文件、不改变恢复状态。

Tab 补全沿用同一套校验:当前参数可以尚未输入完整;前面已由空格或 Tab 结束的参数若有错误,先修正才会提供后续候选。输入 --help 后不再补全

❓ 常见问题

已启用,但没有自动恢复

先用 /onward show rules 确认有启用的规则,再用 /onward status 查看停止原因。没有匹配规则、配置无效、用户主动取消或已有排队消息时不会插入恢复。空回复是正常结束但没有文字和工具调用,正常工具轮不会触发空回复规则

修改配置后仍使用旧值

用 /onward show 检查字段来源,项目配置可能覆盖全局配置。命令修改立即作用于当前运行;手工编辑文件后用 Pi 的 /reload。如果显示“未保存”,先处理写入问题再重试,重载会丢弃这部分内存修改

提示没有可用的任务提示词

{taskPrompt} 需要已接收的任务文本和可确认的来源。缺少来源记录或排队消息来源不明确时,onward 会停止,避免重发错误任务。重新发送人工任务后再继续;只需要发送固定文本时,可以把 prompt 写成 继续