Skip to content

任务记录与调度

·
  • pi-subagents
  • v0.67.0
  • Pi
本页为 pi-subagents 官方文档的非官方中文翻译,请以官方英文文档为准。 原文 · 许可证

委派工作的持久化记录:任务记录(mission)把运行包装起来以便事后恢复,调度则按定时器启动工作。

任务记录 ​

任务记录是围绕运行(run)的持久化包装。名词对应关系如下:

  • 项目/代码库(Project/codebase)—— 工作发生的地方。
  • 任务记录(Mission)—— 委派工作存在的原因与事后恢复方式。
  • 运行(Run)—— 一次实际的子智能体执行。
  • 回执(Receipt)—— 外部产出的证明或链接,例如 PR、CI 检查、部署或发布。

默认情况下,常规的工作流启动会创建一个外层任务记录,其下的详细 JSON 记录位于 ~/.pi/agent/missions/projects/<project-hash>/,用于关联目标、运行 id、生命周期状态、决策、产物路径与投递回执。工作流子任务不会创建独立的任务记录。每次工作流子任务的尝试都存储在外层任务记录中,带有稳定的工作流键、已知时的运行 id、使用的智能体、任务元数据、时间戳、会话与产物路径以及最新的状态心跳。

旧默认路径 <project>/.pi/subagents/missions 下创建的记录仍保留在磁盘上。可通过把该项目的 missions.directory 指向该路径,或把记录复制到新的 agent 目录项目存储来继续使用。不存在自动迁移。

行为规则:

  • 自动持久化的失败不会阻塞运行,并以 details.missionWarning 报告。显式 missionId 与 mission 请求在启动前仍然严格校验。
  • 人类可读的回执以 Mission: <id> (<status>) 结尾,JSON/结构化输出文本保持不变,details.missionId 为权威字段。
  • 对有意临时的工作流传入 mission: false。它既不为该工作流也不为其子任务创建任务记录,且没有 state 全局。
  • 设置 missions.enabled: false 可禁用自动创建任务记录;显式的 mission 字段与动作仍然有效。
  • 带有任务记录的工作流可以使用 await state.get(key) 与 await state.set(key, value) 持久化 JSON 状态。缺失的键返回 undefined。键名格式与 runs.run 键相同。每次 set 都会获取状态文件锁,读取最新文件,合并键,然后原子地写入 <mission-directory>/<mission-id>/state.json。完整文件大小不能超过 256 KiB。每个工作流在首次 get 时缓存该文件。mission:false 的工作流没有 state 全局。

显式 mission 对象必须且只能有一个非空的 title 或 summary。objective 与 labels 可选。若提供 goal,其值必须为 true,且需要 budget: { tokens: <positive integer> }。

ts
const created = subagent({
  action: 'mission.create',
  mission: { title: 'Ship auth refresh', objective: 'Implement and validate token refresh' }
});
subagent({
  workflowScript: `return runs.run("main", { agent: "worker", task: "Implement the approved auth refresh plan" })`,
  missionId: '<mission-id>'
});

// 或者在一次启动中创建并关联
subagent({
  workflowScript: `return runs.run("main", { agent: "worker", task: "Implement the approved plan" })`,
  mission: { title: 'Ship auth refresh' }
});

目标型任务记录 ​

设置 goal: true 与令牌预算,把开放的任务记录变为活跃的续接驱动器:

ts
subagent({
  action: 'mission.create',
  mission: {
    title: 'Ship auth refresh',
    objective: 'Implement and validate token refresh',
    goal: true,
    budget: { tokens: 400000 }
  }
});

每次父轮结束后,空闲的目标型任务记录会发送一条"需要关注"通知,包含其标题、剩余令牌预算与下一个就绪动作。该动作取自 state.nextReadyAction、state.nextAction、status: "ready" 的状态项、未决决策,或关联的运行状态。工作流可以写入 state.nextReadyAction 来告知下一条通知具体什么工作已就绪。当最新关联的工作流带有可续接的保留子任务时,通知会将其命名为 resume 目标。不可续接的保留子任务会在 children.list 中保留并附上原因,但目标通知不会把它们呈现为 resume 目标。本扩展不会自行启动或重新规划目标工作。

关联运行的令牌总量存储在每次运行上,并汇总入任务记录的 usage。处于活跃状态的关联运行会抑制通知。达到令牌预算后,目标状态变为 budget-exhausted,通知停止,但任务记录不被关闭,也不报告成功。

使用 mission.update 与 { goal: { paused: true } } 或 { goal: { paused: false } } 暂停与恢复通知。设置 { goal: false } 禁用目标模式。mission.close 也会结束循环。

管理任务记录 ​

使用 mission.list、mission.show、mission.update、mission.resolve-decision、mission.attach-run、mission.close。

  • 使用 mission.update 在工作进行中记录决策、产物、标签、摘要与投递回执。添加决策会把活跃或已完成的任务记录门控为 needs_decision;计划中与等待中的任务记录在决策可见期间保留其生命周期状态。通过 mission.resolve-decision、missionId、决策的 id 以及 summary 中的解决方案来消除该决策。当最后一条未决决策被消除后,被门控的任务记录恢复为 active。
  • mission.show 包含每个工作流子任务的最新状态、阶段、更新时间、会话路径元数据与心跳。该账本是恢复用记录,不调度也不重启子任务。
  • 回执是 PR、CI、部署或发布的持久化链接,每条都包含 kind、status、title、url,以及可选的 description。它们只记录投递状态;pi-subagents 不会合并代码、轮询 CI 或执行部署。
  • 当任务记录完成时,使用 mission.close 并传入终态状态与摘要。
  • 压缩或重启后,先从 mission.list/mission.show 恢复:mission.show 会在可用时刷新关联的异步状态,然后使用关联的运行 id 进行常规的 status、steer、resume、stop 动作。
  • 带 missionScope: "global" 的 mission.list 读取 Pi agent 目录下的用户本地指针索引。项目记录仍为权威源;缺失记录会被报告为陈旧,而非隐藏其他项目。

跨项目工作 ​

把同项目的任务保留在普通子智能体上。对其他项目中小的、有边界的工作使用显式 cwd。

对另一项目中大规模或长期运行的工作,使用 project.open 打开一个项目自有的 Herdr 面板,并给该项目的 Pi 会话一个狭窄的 mission/result 契约(参见 extension-api.md)。项目面板拥有自己的子智能体;不要把它建模为普通的子嵌套,也不要指望现有的无头运行会移入该面板。

任务记录存储配置(missions.directory、retainTerminal、globalIndex)位于 configuration.md。

调度 ​

持久化的调度默认启用,按项目存储于 .pi/subagents/schedules/<id>/。

创建一个一次性调度:

ts
subagent({
  action: 'schedule.create',
  id: 'evening-review',
  name: 'Evening review',
  at: '+30m',
  baseRef: 'refs/heads/release',
  workflowScript: `return runs.run("main", { agent: "reviewer", task: "Review the current diff." })`
});

创建一个固定周期的工作流:

ts
subagent({
  action: 'schedule.create',
  id: 'backlog',
  every: '6h',
  catchUp: 'latest',
  workflowScript: '...'
});

固定间隔支持 m、h、d、w 单位,并按计划时间推进,不会因完成时间漂移。

创建一个静默的周期工作流,其成功完成保持可见但不会唤醒父会话:

ts
subagent({
  action: 'schedule.create',
  id: 'nightly-sweep',
  every: '24h',
  quiet: true,
  workflowScript: '...'
});

使用 schedule.list、schedule.show、schedule.history、schedule.pause、schedule.resume、schedule.run、schedule.run-due、schedule.delete 管理调度。

行为规则:

  • 运行始终以异步方式启动,携带全新上下文,并禁用自动创建任务记录;任务记录的关联在该首片中延后处理。
  • 可选的顶层 baseRef 选择托管工作树使用的安全 Git 引用(默认 HEAD);它随调度持久化,并在每次触发时转发。源码检出目录仍需保持干净。
  • 定义、有界的历史、仅追加的事件以及每次运行的回执都以模式 0600 存储。
  • overlap 当前固定为 skip;catchUp 支持 latest(默认)与 none。
  • 一次成功的 schedule.run 满足下一次自然触发;失败的手动启动不会跳过该次触发。
  • quiet 仅在周期(every)调度上持久化。成功的自动触发保持可见但不进入父轮;失败、停止或暂停的结果仍会唤醒会话。一次性 at 调度与 schedule.run 保持喧闹,除非该次启动显式传入 quiet: true。
  • schedule.run-due 允许外部启动器启动到期的项目工作,而无需把 pi-subagents 变为守护进程。
  • 日历型循环、cron、队列/替换型 overlap 以及调度 TUI 检查器被刻意延后到下一片。
  • 旧的 schedule、schedule-list、schedule-status、schedule-cancel 动作已在硬切换中移除。

通过 configuration.md 中的 scheduledRuns 配置键禁用或限定调度。