外观
subagent 工具的参数与动作。这些是 LLM 调用该工具时传入的内容;大多数用户会自然地询问或使用斜杠命令。
调用 { action: "guide", topic: "tool-reference" } 获取本参考,或调用 topic: "workflows" 获取工作流配方。使用 topic: "agents" 用于编写,使用 topic: "missions" 用于任务记录/调度,使用 topic: "watchdog" 用于看门狗控件。Guide 读取不会更改模式或授予权限。
执行示例
链式调用是通过 workflowScript 驱动的代码。使用 await runs.run(...) 进行顺序步骤,使用 await runs.all([{ key, agent, task }, ...]) 进行常规的并行扇出。runs.all 解析为有序数组,而非键映射,因此请使用索引、解构或 .map(...),而不是 results.<key>。不要从未被等待的 runs.run 启动中读取 .output。存储的 runs.run Promise 仅用于工作流引导下的高级滚动扇出模式,在那里每个 Promise 稍后都会通过直接 await、Promise.race 或 Promise.all 进行观察。不支持旧版的顶层 chain、tasks 与 parallel 输入。辅助函数必须是普通函数或显式的 Promise 链。嵌套的 async function 辅助函数、async 箭头函数与 async 方法会被拒绝,以便子启动跟踪在 Node 与 Bun 之间保持可移植。对于权限敏感的宿主调用,请使用由扩展所有的命名资源,例如 { workflow: "run-ci", args: { command: "npm test" } };原始的公共 workflowScript/workflowScriptPath 输入具有未知的资源来源,不能调用 runs.host。已解析的资源可在其权限上限内内部使用 runs.host(key, { kind: "command", command, timeoutMs, output?, role?, provider? });没有按步骤的 cwd,命令与相对输出路径使用工作流的 cwd。请改为在外层 subagent({...}) 请求上设置 cwd,或将受信任的目录更改放在命令中(例如 cd /path/to/worktree && npm test)。
使用 { action: "validate", workflowScript } 来检查静态可判定的语法与结构,而不启动子智能体。它会返回 { ok, errors },并在 ok 为 false 时失败工具调用。字面量子 baseRef 值会针对运行时 ref 策略进行检查。动态键与值仍受运行时检查;静态验证不会猜测它们。
使用 workflowScriptPath 而非 workflowScript,以从文件加载同一 JavaScript 语句主体。这两个字段互斥。相对路径相对于请求的 cwd 解析,绝对路径原样传递。宿主会在验证、调度或沙箱执行之前读取该文件。工作流沙箱仍没有文件系统访问。缺失、不可读与空文件会作为文件输入错误失败。
对于权限扩展的互操作性,请使用一个本扩展所有的命名资源加上有界的 args,而非调用者提供的工作流文本:
js
{ workflow: "review", args: { task: "Review the auth flow" } }
{ workflow: "run-ci", args: { command: "npm test" } }宿主在内部解析脚本与权限,并在工作流详情与回执中记录有界的来源。命名资源不能与 agent、task、workflowScript 或 workflowScriptPath 组合;用户/项目资源注册表不在本次首次切片中。
js
{ workflowScriptPath: "workflows/review.js", cwd: "/path/to/project" }
{ action: "validate", workflowScriptPath: "workflows/review.js" }
{ action: "schedule.create", every: "6h", workflowScriptPath: "workflows/review.js" }js
// 一个子智能体;显式返回子 Promise
{
workflowScript: `return runs.run("main", { agent: "scout", task: "Analyze the auth flow" })`;
}
// 顺序工作流
{
workflowScript: `
const scan = await runs.run("scan", { agent: "scout", task: "Analyze auth" });
return (await runs.run("implement", { agent: "worker", task: "Implement from: " + scan.output })).output;
`;
}
// 并行工作流
{
workflowScript: `
const results = await runs.all([
{ key: "backend", agent: "reviewer", task: "Review backend" },
{ key: "frontend", agent: "reviewer", task: "Review frontend" }
]);
return results.map(result => result.output);
`;
}并行顺序泳道
当若干独立泳道各自拥有有序阶段时,请在 workflowScript 中使用 runs.lanes(lanes)。该辅助函数组合既有的工作流子运行器;它不会增加顶层 lanes 参数或第二套持久化/清理系统。
js
{
workflowScript: `
const board = await runs.lanes([
{ key: "api", stages: [
{ key: "writer", agent: "worker", task: "Implement the API change" },
{ key: "challenge", resume: "previous", task: "Challenge the implementation" },
{ key: "review", agent: "reviewer", task: "Review the API lane" }
] },
{ key: "ui", stages: [
{ key: "writer", agent: "worker", task: "Implement the UI change" },
{ key: "review", agent: "reviewer", task: "Review the UI lane" }
] }
]);
return board.map((lane) => ({
key: lane.key,
state: lane.state,
failedStage: lane.failedStage,
stages: lane.stages.map((stage) => ({
key: stage.key,
state: stage.state,
ok: stage.ok,
runId: stage.runId,
outputReference: stage.outputReference,
verdict: stage.verdict
}))
}));
`;
}每条泳道的第一阶段由一次既有的 runs.all(...) 批次启动。后续阶段按泳道顺序运行。在后续阶段上设置 resume: "previous" 以继续之前保留的子智能体;该辅助函数要求该子智能体返回的 runId 并委托给既有的 resume 检查。阶段键是泳道本地的,生成的子智能体键为 <lane>.<stage>。
完整的纯 JSON 清单会在首次启动前进行验证(最多 32 条泳道、每条泳道 16 个阶段、共 64 个阶段,规范 JSON 上限 64 KiB)。失败、停止或分离的阶段仅阻塞其所在泳道,并将后续阶段标记为 skipped;显式的 structuredOutput.verdict === "blocked" 具有相同的效果。评审者的散文不会被解析。有界的 board 返回泳道/阶段键、状态、ok、运行 id、显式的输出引用、有界的错误以及可选的裁决,而非对话记录。条件式或滚动的工作流请使用原始的 runs.run(...)/runs.all(...)。
参数参考
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
agent | string | - | 一个直接子智能体或智能体管理目标。工作流子智能体在 runs.run 或 runs.all 内部设置。 |
task | string | 智能体默认 | 直接子智能体的任务;需要 agent,与 action 及工作流输入互斥。agent 也可以选择管理目标。 |
action | string | - | 离线工作流 validate、智能体管理(包括 guide、children.list 与 refine/refine.show/refine.rollback)、泳道证据(lane.status、lane.recordMerge、lane.recordSupersession)、任务记录(mission.create/list/show/update/resolve-decision/attach-run/close)、Inspect 动作(inspector.command/open/status/close)、Herdr 项目面板(project.open/status/close)、状态/控制、仅计划的 worktree.cleanup、调度、看门狗或 doctor 动作。 |
topic | overview | workflows | agents | missions | observability | tool-reference | configuration | models | watchdog | extension-api | overview | 用于 action: "guide" 的打包指南主题。 |
config | object/string | - | 用于管理创建/更新的智能体配置。 |
context | fresh | fork | profile | 全局或按智能体的默认,否则 fresh | 显式 fresh 或 fork 覆盖每个工作流子智能体。profile 要求所选智能体的声明 defaultContext,并忽略配置 defaultSubagentContext;缺失的智能体默认会失败。省略时,defaultSubagentContext 优先于每个智能体的 defaultContext;隐式 fork 在没有持久化的父会话和叶子节点时回退到 fresh。显式 fork 是严格的。打包的 worker、oracle 与 advisor 默认为 fork。 |
model | string | 智能体默认 | 首先调用 {action:"models"} 并复制一个精确的 provider/id;裸 id 仅在唯一时解析,且智能体名称不是模型 id。后缀(如 provider/id:high(off/minimal/low/medium/high/xhigh/max))会覆盖智能体的思考级别。thinking 字段仅用于 watchdog.configure,在派发时被忽略。 |
missionId | string | - | 将工作流挂接到一个已有的项目任务记录,而不是创建其默认的封闭任务记录。 |
mission | object/false | 自动创建 | 用 { title | summary, objective?, goal?, budget?, labels? } 覆盖默认的封闭任务记录。设置恰好一个非空的 title 或 summary;objective 与 labels 是可选的。goal 只能是 true,需要 budget.tokens,并启用续接通知。对于有意临时的工作流传递 false,它不会为该工作流或其子智能体创建任务记录,也没有 state 全局。显式的任务记录持久化失败是严格的。 |
handoffPath | string | - | 用于 action: "worktree.discard" 或泳道证据动作的聚合交接清单,或用于 action: "worktree.cleanup" 的可选显式元数据。 |
repo | string | 运行时 cwd | action: "worktree.cleanup" 的仓库路径;仅计划模式。已配置的工作树基础按其每个项目的子文件夹过滤候选,但不会发现它们。 |
planId | string | - | 为将来的 worktree.cleanup apply 动作保留;当前仅计划动作会拒绝它。 |
mode | steer | follow_up | auto | plan | apply | - | action: "steer" 的投递模式;worktree.cleanup 当前仅接受 plan。apply/移除保留给将来的更改。 |
laneId | string | - | 存储在交接清单中用于 lane.status、lane.recordMerge 或 lane.recordSupersession 的精确 runId。 |
merge | object | - | lane.recordMerge 的证明性合并证据;要求正 PR 编号、完整的已评审/合并 SHA、树等价与合并后检查状态、证明方与时间戳。 |
supersession | object | - | lane.recordSupersession 的证明性替换泳道证据;要求不同的替换泳道 id、证明方与时间戳。 |
focus | boolean | false | 为 action: "inspector.open" 聚焦新分割的宿主检查器面板,或为 action: "project.open" 聚焦新的 Herdr 项目面板;不是独立动作。inspector.command 是只读的,不会联系 Herdr 或写入绑定。除非你设置 focus: true,否则面板在后台打开。当 Herdr 报告 tab 或 workspace id 时,已保存的项目面板可以通过公共项目面板 API 进行聚焦。 |
view | fleet | transcript | - | 用于活跃舰队界面或对话记录尾部检查的可选 status 视图。 |
lines | number | 80 | action: "status", view: "transcript" 的最大对话记录行数;上限为 500。 |
agentScope | user | project | both | both | 智能体发现作用域。项目在冲突时胜出。 |
capabilities | boolean | false | 与 action: "list" 一起使用时,返回紧凑的无提示词行,以及每个智能体的已声明/默认路由能力的 details.agentCapabilities 机器可读记录。外部 CLI 行还包括其命令与被动的本地可用性。 |
async | boolean | 默认开 | 后台执行。工作流默认为后台。async:false 会阻塞父会话直到完成,并在父 Pi 进程内部以会话形式运行子智能体;这种前台子智能体永远不加载父会话的环境扩展,因此需要 MCP 工具(mcpDirectTools,或来自像 pi-mcp-adapter 这类环境适配器的 MCP 工具)或来自提供方扩展的模型的智能体必须作为后台子智能体运行,它们会在分离的运行器进程内部加载这些。 |
chatProgress | auto | off | live-card | auto | WorkflowScript 聊天投影。auto 仅对同一 Git 仓库(包括托管工作树)中被监视的前台工作流渲染聊天中的实时卡片;否则关闭。显式的 live-card 需要 async:false 与同一 Git 仓库。异步工作流没有内联实时卡片,因此请省略 chatProgress 或使用 auto/off;仅在父会话必须阻塞时使用 async:false。 |
isolation | none | worktree | - | 工作流子智能体隔离。none 在共享 cwd 中运行,不需要 Git。worktree 需要托管的 Git 工作树。不要将其与矛盾的 worktree 值组合。 |
baseRef | string | HEAD | HEAD 或受支持的命名 ref,如 refs/heads/release、refs/tags/v1 或 origin/main。完整的 40/64 字符提交 ID 以及像 HEAD~1 这样的修订表达式不受支持。该 ref 必须在工作树分配时解析为提交;省略的值默认为那时解析的 HEAD。源检出是否干净仍会被检查。对于 workflowScript,请将其设置为外层请求上的默认值,或在单独的 runs.run/runs.all 子智能体上以覆盖它。 |
timeoutMs / maxRuntimeMs | number | 配置 timeoutMs,否则前台 30 分钟/单智能体异步 | 可选的运行级最大运行时(毫秒)。省略时,全局的 timeoutMs 配置提供默认值;若仍缺失,前台与纯单智能体异步运行回退到 30 分钟,而复合异步运行(链式、并行任务、工作流)在顶层保持无界。该运行级截止时间的到期是终态的,且不会触发 fallbackModels。 |
toolTimeoutMs | number | 快速工具默认 | 可选的正数硬性单次工具调用截止时间(毫秒)。优先级:调用值 → 智能体 frontmatter → 配置 → PI_SUBAGENT_TOOL_TIMEOUT_MS。计时器从 tool_execution_start 开始,在匹配的 tool_execution_end 上清除,并在工具仍打开时以 timedOut: true 终止运行。省略时,已知快速的内置工具默认为 5 分钟;长时间运行的工具收到关注通知,但没有硬性默认值。它永远不会延长运行截止时间;contact_supervisor、intercom 与 bg_wait 被豁免。 |
checkpointBeforeDeadlineMs | number | 无 | 仅限异步单智能体运行。运行器会在运行截止时间前的这么多毫秒请求子智能体"检查点并停止"(完成当前工具调用,报告变更的文件、构建/测试状态、剩余工作、提交/PR 状态;不再开启新工作)。该尽力而为的 steer 使用下一个工具边界处的常规引导生命周期,因此回执在状态与事件中可见;常规的截止时间终止仍然适用。优先级:调用值 → 配置 checkpointBeforeDeadlineMs。当截止时间在检查点前剩下不到 1 秒时,解除武装。 |
toolBudget | object | 无 | 可选的子智能体工具调用预算 { soft?, hard, block? }。在 soft 时,子智能体会被轻推以完成。在 hard 之后,已配置的工具被阻止;block 默认为 read、grep、find 与 ls,而 "*" 阻止每一次工具调用。最终的助手文本永远不会被阻止。 |
usageBudget | object | 无 | 可选的仅根已报告用量预算 { tokens?: { soft?, hard }, costUsd?: { soft?, hard } }。软限制仅为状态。硬限制在对账已报告用量后阻止后续的子智能体启动;已在运行的子智能体不会被停止,也不会进行预留。 |
cwd | string | 运行时 cwd | 覆盖工作目录。对于 machine,是该机器上的目录。 |
machine | string | - | 外部 cli 智能体的 Herdr 保存机器(标签或配置档 id);见 agents.md。 |
maxOutput | object | 200KB,5000 行 | 最终输出截断限制。 |
artifacts | boolean | true | 写入调试产物。 |
includeProgress | boolean | false | 在结果中包含完整进度。 |
share | boolean | false | 将会话导出上传到 GitHub Gist。 |
sessionDir | string | 派生 | 覆盖会话日志目录。 |
acceptance | string/object/false | 推断 | 配置证据门槛。见验收门槛。 |
gate | string | - | 一个宿主运行的验证命令,是 acceptance: { level: "verified", verify: [{ id: "gate", command }] } 的简写。也在单独的 runs.run/runs.all 条目上有效。拒绝 acceptance,仅 false 除外(视为省略),并拒绝保留的 resume。 |
写作者的预算指南
作为保守的编排策略,请勿在实现 worker、修复 worker、拥有编辑权的评审者或其他具备变更能力的子智能体上设置硬性 toolBudget 或紧张的 usageBudget。默认的工具预算会阻止读/搜索工具而非变更工具,并且已报告的用量没有预留模型,因此无论是工具调用计数还是令牌/费用总额都不能衡量交付切片是否可构建或是否可安全交接。硬性上限仍适合明确只读的 scout、评审者与验证器。
通过狭窄的任务和留出足够余量的外层 timeoutMs 或 maxRuntimeMs 来约束写作者工作。一个已过期的超时并不是"安全变更"的边界,且仍可能在工具工作期间向子智能体发出信号。在当前工具返回后请求一个检查点,记录变更的文件、构建/测试状态以及提交或 PR 状态;对于异步单智能体运行,设置 checkpointBeforeDeadlineMs,否则手动引导。
Fork 上下文详情
显式 context: "fork" 在父会话未持久化、当前叶子节点缺失,或分支的子会话无法创建时快速失败。相比之下,全局 defaultSubagentContext: "fork" 与智能体级的 defaultContext: fork 是偏好:当父会话没有持久化的会话文件或当前叶子节点时,启动会立即使用 fresh,而不是失败并需要重试。全局 defaultSubagentContext: "fresh" 以全新上下文开始。显式 context: "fresh" 始终优先于这两种偏好。
当继承的对话记录包含已签名的 Anthropic thinking/redacted_thinking 块时,pi-subagents 会从 fork 的子会话中剥离这些私有于提供方的块:思考签名绑定于生成它的会话,无法被重放到分支中。子会话保留其请求的思考级别,并在第一回合中全新地推理;清理继承的对话记录并非降级。显式 context: "fork" 永远不会悄悄降级为 fresh。
在省略 context 的工作流运行中,每个 runs.run 子智能体在设置时遵循全局 defaultSubagentContext,然后是其自身的 defaultContext。在没有全局设置的情况下,一个 fresh 默认的 scout 可以与 fork 默认的 worker 并排运行。如果父会话文件或当前叶子节点尚不可用,则隐式 fork 默认的子智能体会以全新上下文运行。当你有意希望每个子智能体使用同一种上下文时,传递显式 context: "fork" 或 context: "fresh"。
工作流引导
runs.steer(key, message, options?) 定向到已被 runs.run 或 runs.all 启动的稳定键。它不接受原始的运行 id。选项包括 mode?: "steer" | "follow_up" | "auto"、index?: number 与 ackTimeoutMs?: number。该 Promise 返回 { key, state, requestId?, deliveryStatus?, targets?, error? },其中 state 为 queued、delivered、missed 或 failed。
工作流跟踪会记录该尝试与回执。始终使用 await 等待、返回,或将其包含在被等待的标准 Promise 组合器中。未被等待的引导调用会在副作用安定后拒绝工作流完成。Promise.race 仍是滚动原语。前台子智能体通过其进程内会话进行引导(当传输接受输入时,steer 与 auto 报告 delivered;follow_up 在被接受到 Pi 队列时报告 queued)。异步子智能体使用文件控制收件箱,并报告子智能体的关联消费,而非仅仅是收件箱接受。在两种情况下,引导恢复都被禁用。
对于高级滚动扇出,仅当每个 Promise 稍后都会通过直接 await、Promise.race 或 Promise.all 进行观察时,才将已启动的 runs.run Promise 保留在普通 JavaScript 数据中。Promise.race 给出下一个完成的子智能体,runs.steer 可以挑战仍在运行的带键兄弟节点,而 Promise.all 收集其余部分。未暴露单独的 runs.start、runs.next 或 runs.collect API。
js
{
workflowScript: `
let pending = [
{ key: "writer", promise: runs.run("writer", { agent: "worker", task: "Draft the fix" }).then((result) => ({ key: "writer", result })) },
{ key: "reviewer", promise: runs.run("reviewer", { agent: "reviewer", task: "Review likely risks" }).then((result) => ({ key: "reviewer", result })) }
];
const first = await Promise.race(pending.map((child) => child.promise));
pending = pending.filter((child) => child.key !== first.key);
const target = pending[0];
const receipt = await runs.steer(target.key, "Use this early review:\n" + first.result.output, { mode: "auto" });
const rest = await Promise.all(pending.map((child) => child.promise));
return { first: first.key, rest: rest.map((child) => child.key), receipt };
`;
}输出模式详情
当保存的输出可能较大且父会话仅需要一个指针时,请使用 outputMode: "file-only"。返回的文本是一个紧凑的引用,例如 Output saved to: /abs/report.md (48.2 KB, 2847 lines). Read this file if needed.。失败运行与保存错误仍会为调试返回正常的内联输出。
在 workflowScript 中,当后续脚本步骤需要持久的文件引用时,为每个子智能体提供显式的输出路径。仅具有只读工具的子智能体不需要直接的文件系统访问以用于 output:它在其最终响应中返回完整的产物,并且运行器会持久化它。具有变更能力的子智能体保留直接写入指令。
output 字段是 API 绑定;任务文本中提到的文件名(例如 Write your findings to exactly this path: report.md)仅是指令,不会覆盖运行时路由。当后续的工作流步骤或父会话需要持久文件时,请在 runs.run/runs.all 上设置 output 并返回该子智能体的 outputReference、outputPathMapping 或 artifactPaths;工作流 JavaScript 返回的任意字面量字符串不会被重写。省略的子输出可以使用从托管聚合派生的兄弟路径。
工作流通过其默认或显式的任务记录获得 await state.get(key) 与 await state.set(key, value)。使用它们在同一 missionId 挂接的后续工作流之间共享持久的 JSON 值。每次 set 都会获取状态文件锁,并将其键与磁盘上的最新状态合并。缺失的键返回 undefined,完整的状态文件具有严格的 256 KiB 限制。mission:false 的工作流没有 state 全局。
保留的子智能体
当前父会话中已完成的工作流子智能体作为保留子智能体保持可寻址。{ action: "children.list" } 列出最多最近 10 个,附带其运行 id 与显式的 resumable 或 not resumable 状态。仅恢复报告为 resumable 的行;如果没有可恢复的行,请启动一个同角色的回退挑战并将其标记为回退。后续工作流通过传递 resume 而非 agent 来继续一个可恢复的子智能体:
js
{
workflowScript: `
let writer = await runs.run("implement", { agent: "worker", task: "Implement the accepted contract" });
for (const pass of [1, 2]) {
if (!writer.runId) throw new Error("writer did not return a retained run id");
writer = await runs.run("followup-" + pass, { resume: writer.runId, task: "Revisit pass " + pass + ": " + writer.output });
}
return writer;
`;
}每个工作流键标识一个结果泳道。请为每个不同的保留恢复过程使用一个新的稳定工作流键;仅当启动参数完全相同时才重用同键调用,不兼容的参数会被拒绝。
在 workflowScript 内部,await runs.run(key, { resume, task }) 等待恢复的子智能体完成,并返回其完成输出与新的 runId。每次恢复可以返回一个新的保留运行 id,因此循环必须从最近返回的 runId 继续。顶层的 { action: "resume" } 保持分离,并返回一条后台运行的回执。
对于工作流脚本之外的简单实现挑战,仅当 children.list 报告该保留的 writer 为 resumable 时,通过 subagent({ action: "resume", id: "<retained-writer-run>", message: "Reconsider the implementation and make any better current-scope change." }) 发送该挑战。如果没有可恢复的保留 writer,请启动一个同角色的回退挑战并记录为何它是回退。仅当脚本必须在下一步之前等待恢复的 writer 输出时,才使用工作流 runs.run({ resume })。不要将 steer 用作已完成的保留子智能体的唯一挑战动作;带 mode: "follow_up" 的 steer 仅将文本排队以等待下一次 resume。
resume 与 agent 互斥。恢复的子智能体保留其存储的智能体、模型与工具契约。gate 在保留的 resume 条目上被拒绝,因为 resume 使用保留的子智能体契约。
管理动作
指南
{ action: "guide" } 从已安装版本读取打包的 README.md。传递 topic 以读取其打包的 docs/<topic>.md 文件。有效的主题为 overview、workflows、agents、missions、observability、tool-reference、configuration、models、watchdog 与 extension-api。未知主题会列出有效值且不会更改文件。使用 /subagents-guide [topic] 获取斜杠等效命令。
默认情况下,智能体定义不会加载到上下文中。管理动作允许 LLM 在运行时发现、检查、创建、更新与删除智能体。未知动作会返回安全的下一步(status 与 list),并可能建议一个接近的非破坏性动作。仅对接近完整的一个字符拼写错误才会命名破坏性动作,且建议永远不会执行动作。
ts
{ action: "list" }
{ action: "list", agentScope: "project" }
{ action: "list", capabilities: true }
{ action: "get", agent: "scout" }
{ action: "models" }
{ action: "models", agent: "reviewer" }
{ action: "get", agent: "code-analysis.scout" }
{ action: "create", config: {
name: "Code Scout",
package: "code-analysis",
description: "Scans codebases for patterns and issues",
scope: "user",
systemPrompt: "You are a code scout...",
systemPromptMode: "replace",
inheritProjectContext: false,
inheritGlobalContext: false,
inheritSkills: false,
model: "anthropic/claude-sonnet-4",
fallbackModels: ["openai-codex/gpt-5.6-luna:low", "anthropic/claude-haiku-4-5"],
tools: "read, bash, mcp:github/search_repositories",
extensions: "",
skills: "parallel-scout",
thinking: "high",
acceptance: { level: "none", reason: "lightweight lookup" },
acceptanceRole: "read-only",
output: "context.md",
reads: "shared-context.md",
progress: true
}}
{ action: "update", agent: "code-analysis.scout", config: { model: "openai/gpt-4o" } }
{ action: "update", agent: "code-analysis.scout", config: { acceptance: "" } } // 清除 frontmatter 默认值
{ action: "update", agent: "code-analysis.scout", config: { acceptanceRole: false } } // 恢复推断的名称回退
{ action: "delete", agent: "scout" }
{ action: "eject", agent: "reviewer" }
{ action: "eject", agent: "reviewer", agentScope: "project" }
{ action: "disable", agent: "reviewer" }
{ action: "enable", agent: "reviewer", agentScope: "project" }
{ action: "reset", agent: "reviewer" }规则:
capabilities: true将action: "list"改为紧凑的单行,并添加details.agentCapabilities: { agents, restrictedCount, capabilityCeilingSources? }。每个智能体行包括来源、别名、运行器类型/能力、工具、MCP 直接工具、变更工具、模型/思考/回退、默认 async/超时、输出路径/模式、技能/扩展,以及当前能力上限是否允许执行。外部 CLI 行包括runner.command、runner.available,以及在被动 PATH/PATHEXT/X_OK 查找无法找到命令时的有界runner.unavailableReason。它永远不会包含智能体的系统提示词。行显示已声明/默认的能力与命令可发现性,而非身份验证、版本兼容性或成功启动;启动预检仍为权威来源。create使用config.scope,而非agentScope。config.name是本地 frontmatter 名称;可选的config.package将运行时名称注册为{package}.{name},并保存为单独的name与packagefrontmatter。config.aliases接受逗号分隔的字符串、字符串数组或false以清除别名。别名解析为规范智能体名称以供执行,并显示在list/get中。update与delete使用运行时名称,且仅当同一运行时名称存在于多个作用域时才使用agentScope。- 要清除可选字符串字段(包括
package),请将其设为false或""。
eject、disable、enable 与 reset 见 agents.md。
精化覆盖层
refine、refine.show 与 refine.rollback 管理单个智能体的项目本地精化覆盖层。/subagents-refine <agent> 是 refine 的斜杠等效命令。行为与存储见 agents.md。
调度控件
将 schedule.create 与 workflowScript 或 workflowScriptPath 一起使用,而非直接的子智能体。at 接受像 +10m 这样的延迟或带时区的 ISO 时间戳;every 接受固定间隔。sessionOnly:true 将恢复/执行绑定到创建会话文件;省略/false 是项目范围的。周期性的 quiet:true 会使成功的自动触发保持可见而不开启父会话回合;失败、停止或暂停的运行仍会唤醒父会话。一次性的 at 与手动的 schedule.run 保持喧闹,除非该次启动传递 quiet:true。示例与 list/show/history/pause/resume/run/run-due/delete 见任务记录与调度。日历选择器(on、timezone)与调度任务记录挂接被推迟。baseRef 仅在工作树分配时解析,并且仍要求源检出干净。
泳道合并证据与清理资格
泳道证据动作在显式的更新边界更新现有的并行交接清单。它们不验证 GitHub 状态、不运行 Git 命令,也不删除工作树。请将清单路径与它的精确 runId 作为 laneId 传递:
ts
subagent({
action: 'lane.recordMerge',
laneId: '<manifest-run-id>',
handoffPath: '/path/to/handoff.json',
merge: {
prNumber: 123,
reviewedHead: '<40-character-sha>',
mergeCommit: '<40-character-sha>',
treeEquivalent: true,
postMergeChecks: 'recorded',
attestedBy: 'operator',
attestedAt: '2026-08-27T16:23:00.000Z'
}
});
subagent({
action: 'lane.recordSupersession',
laneId: '<manifest-run-id>',
handoffPath: '/path/to/handoff.json',
supersession: {
supersededBy: '<replacement-lane-id>',
attestedBy: 'operator',
attestedAt: '2026-08-27T16:23:00.000Z'
}
});
subagent({
action: 'lane.status',
laneId: '<manifest-run-id>',
handoffPath: '/path/to/handoff.json'
});清单存储以下"失败闭合"的资格状态之一:active(拥有的子智能体仍在运行)、terminal-eligible(完整的合并证据与已记录的合并后检查)、带有原因的 terminal-blocked、superseded-eligible(显式的替换证明)或 unknown(缺失或格式错误的证据/清单)。每次证明都会存储其所覆盖清单事实的摘要;后续组、工作树或补丁的更改会将该证据降级为 terminal-block,直至再次记录。终态更新会根据当前子智能体状态与证据重新计算先前存储的 active 状态。冲突的已评审 head 与不匹配的泳道 id 会被拒绝为陈旧。既有的工作流回执保持不可变。
lane.status 渲染存储的状态以及一份可复制粘贴的 worktree.cleanup 计划调用。它永远不会运行该调用。所有清理计划/apply 与 apply 时的 Git/所有权重新验证属于来自 #1622 的 worktree.cleanup;远程分支删除与扩展侧的 GitHub 验证仍不在范围内。
状态与控制动作
失败泳道的恢复与执行模式边界
子智能体工作流、子启动、提示词运行时、扩展加载或子工具设置中的失败属于泳道基础设施阻塞器,而非默默更改执行模式的权限。请停止并报告精确的失败、运行/状态以及仓库/cwd/工作树/分支/ref 状态。在进行同协议重试或询问所有者之前,请验证工作树干净或捕获部分差异。仅通过明确的同协议动作重试或修复 subagent 路径。
对于待办泳道以及其他由子智能体管理的工作流,外部/前台/CLI 回退需要显式的所有者批准。不要悄悄切换到 interactive_shell、pi -ne、Codex/Claude/Cursor CLI、前台智能体或其他外部模式。当用户显式请求可见的前台/CLI 工作,或任务超出受管子智能体协议的范围时,interactive_shell 仍然有效。Pi 核心可能打印通用的 pi -ne 扩展加载提示;该仓库外提示不是协议批准的回退。已配置的原生模型/提供方回退仍受其自身契约的约束。
ts
subagent({ action: 'status' });
subagent({ action: 'status', view: 'fleet' });
subagent({ action: 'status', id: '<run-id>' });
subagent({ action: 'status', id: '<run-id>', view: 'transcript', index: 0, lines: 80 });
subagent({ action: 'status', id: '<nested-run-id>' });
subagent({ action: 'interrupt', id: '<run-id>' });
subagent({ action: 'interrupt', id: '<nested-run-id>' });
subagent({ action: 'stop', id: '<run-id>' });
subagent({
action: 'resume',
id: '<run-id>',
message: 'follow-up question after it pauses or finishes'
});
subagent({ action: 'resume', id: '<run-id>', index: 1, message: 'follow-up for child 2' });
subagent({ action: 'resume', id: '<nested-run-id>', message: 'follow-up for a nested child' });
subagent({ action: 'steer', id: '<run-id>', message: 'guidance for the running child' });
subagent({
action: 'steer',
id: '<run-id>',
mode: 'follow_up',
message: 'check this after the current turn'
});
subagent({
action: 'steer',
id: '<run-id>',
index: 1,
mode: 'auto',
message: 'guidance for child 2'
});
subagent({ action: 'doctor' });status
status 在回退到前缀匹配之前,先解析精确的前台 id、顶层异步 id 与嵌套运行 id。
view: "fleet"是一个可选的只读活跃运行界面,带有对话记录命令;它不会增加引导或停止控件。view: "transcript"显示所选运行的实时output-<index>.log或持久化的会话对话记录的尾部,lines上限为 500。- 嵌套状态显示根/父路径、嵌套子智能体、已知时的会话/产物路径以及嵌套控制命令。
- 在子智能体可安全扇出模式下,当没有本地前台运行时,裸的
status需要一个 id,以便子智能体无法枚举不相关的顶层异步运行。 - 裸的
interrupt仍仅定向到可见的顶层运行;中断一个嵌套运行需要其显式的嵌套 id。
resume
resume 通过从其存储的会话文件启动一个新的子智能体,来恢复一个暂停、已完成或失败的异步/前台子智能体。已停止的运行仍不可恢复,并且它不会中断一个活跃的顶层异步子智能体。对于已确认的活跃异步指引,请使用 steer。
- 多子智能体异步运行以及被记住的前台 single、parallel 或 chain 运行可以通过传递
index来选择子智能体以恢复。 - 当嵌套运行的活跃路由或持久化的嵌套会话元数据可用时,可以通过嵌套 id 恢复嵌套运行。
- 已完成的外部任务运行可以在已注册提供方暴露
followUp(input)时,使用相同的resume动作作为提供方的跟进。正在运行的外部任务父智能体会失败闭合,并带有等待完成的指引。不受支持的提供方会以更新/重新加载消息失败。 - 恢复会从旧的会话上下文启动一个新的子会话;它不会恢复活跃的会话,并且它要求所选子智能体具有持久化的
.jsonl会话文件。 - 直接恢复对规范会话文件采用独占的跨进程租约,直至新的子智能体完成。同时进行的尝试会在 Pi 派生前失败,并识别拥有的恢复运行;仅在能证明陈旧时才会回收死亡所有者的租约。
stop
stop 结束一个当前会话的顶层异步运行。它被刻意设计得比 interrupt 更强:
- 它不是可恢复的暂停;已停止的运行应作为新运行重新启动。
- 前台与嵌套目标会被拒绝。
- 直接 id 调用会立即执行。
- 没有 id 的
/subagents-stop会在 TUI 可用时打开一个带确认的选择器。使用↑/↓或j/k在选择器中移动。 - 在非 TUI 上下文中,斜杠命令会打印精确的
subagent({ action: "stop", id })与/subagents-stop <id>命令。 - 传递子 id 以停止多子异步运行或工作流中的一个子智能体,而其余继续运行:
/subagents-stop <run-id> <child-id>(等同于subagent({ action: "stop", id, childId }))。子 id 来自状态输出、异步状态快照或/subagents-inspect-rpc回复。只有挂起或正在运行的子智能体可被停止;其他情况的请求会被拒绝,而不是被扩大为运行级停止。 - 非活跃的调度可以出现在选择器中,但它们被标记为调度,并通过
schedule.pause路由,而非stop。
steer
steer 最多等待三秒钟以获取关联回执,并返回一个带有 delivered、scheduled、pending、partial、recovered 或 failed 以及每个子智能体状态的请求 id。回执还具有 deliveryStatus: "delivered" | "queued"。对于异步运行,投递意味着子智能体已消费关联的用户输入;前台投递意味着进程内 Pi 传输已接受它。二者都不意味着模型遵从。挂起的已索引子智能体返回 scheduled。
可选的 mode 默认为 steer,并保留当前的中断行为。follow_up 等待下一个回合边界。auto 使用与 steer 相同的原生 steer 投递路径,而不会在错过确认后自动暂停并复活。保留的恢复简报队列可容纳 20 条消息,并在已满时返回明确的错误;这不是实时的跟进队列绑定。实时的跟进确认报告队列接受,而非消费。异步运行稍后会记录关联的消费或在结算时失败未消费的请求;前台跟进没有稍后的关联回执。发送给已完成的保留工作流子智能体的 follow_up 会成为其下一次 resume 的第一条简报;它本身不会恢复子智能体。
仅顶层 single 运行可以在确认截止时间后中断,并在再 15 秒的暂停/复活上限后恢复;持久化的多子智能体与嵌套运行永远不会自动中断。恢复仅在确认源已暂停、有效的持久化会话存在,且截止时间、回合与工具预算仍保留后启动替代。它保留原始子智能体契约与剩余的限制;否则源保持暂停,并带有明确的失败。延迟接受会被记录,但不能取消已提交的恢复。
持久化的 steering 账本保留 20 个请求,并替换旧的 steerCount/lastSteerAt 字段。
/subagents-steer <run-id> [--child <child-id>] <message> 斜杠命令是非 TUI 会话与 RPC 主机的宿主桥接。--child 接受状态输出与检查回复中显示的稳定子智能体身份(工作流键、子运行 id 或 step:<index>),并在引导前将其解析为子索引;未知或歧义的子 id 会失败闭合。标志仅在运行 id 与消息尾部之间解析——一旦消息开始,-- 标记就是消息文本。该桥接始终禁用暂停并复活恢复(steeringRecovery: false),与扩展 RPC 的 nonRecoveringSteer 保证匹配,以便调用者保留对其所定向的精确子智能体的控制权。
验收门槛
每个运行都会解析一个有效的验收策略。调用者可以为推断的默认值省略 acceptance,或在单次运行、顶层并行任务条目、链式步骤、静态并行任务以及动态扇出模板上进行设置。
优先使用内联 JSON 对象。JSON 编码的对象字符串仅在输入规范化期间被容忍;非法字符串会失败闭合。true 是非法的。受支持的证据种类为 changed-files、tests-added、commands-run、validation-output、residual-risks、no-staged-files、diff-summary、review-findings 与 manual-notes。例如:{level:"checked",evidence:["commands-run","changed-files"],review:{required:true}}。证据级别以 verified 结束;独立评审是一个独立的门槛,而非更强的证据级别。
ts
{
agent: "worker",
task: "Implement the fix",
acceptance: {
level: "verified",
criteria: ["Patch the bug without widening scope"],
evidence: ["changed-files", "tests-added", "commands-run", "residual-risks", "no-staged-files"],
verify: [{ id: "focused", command: "npm test", timeoutMs: 120000 }]
}
}单命令门槛
当一个宿主运行的命令就是整个验证合同时,请使用 gate 简写,而非完整的 acceptance 对象:
js
{
workflowScript: `return runs.run("impl", { agent: "worker", task: "Implement the fix", gate: "npm test" })`;
}gate 会规范化为带该单个命令的已验证验收,因此运行器在宿主上执行它并将结果记录为证据。验证结果会针对每个被追踪的工作区状态与有效的环境进行记忆化,因此未变更的树不会重新运行同一命令。当你需要多个命令、超时或自定义标准时,请使用显式的 acceptance.verify。gate 拒绝 acceptance,仅 false 除外(视为省略),并拒绝保留的 resume 条目。对于 worktree: true,门槛会在子智能体的托管工作树内运行。
级别与推断
验收证据级别为 auto、none、attested、checked 与 verified。acceptance: "auto" 为默认值。
评审是使用 acceptance.review 配置的独立门槛:
- 异步、有风险与动态的写作者上下文会推断已检查证据加上
review: { required: true }。 - 评审者/只读调用默认推断无验收;显式的验收请求仍然适用。
- 普通的写作者任务推断已检查证据,不带评审。
智能体 frontmatter 或 subagents.agentOverrides 可以为模糊任务设置 acceptanceRole: "read-only" | "writer"。显式的任务变更或无编辑意图优先于该角色,而省略的元数据保留现有的评审者/scout/worker 名称启发式。该角色仅影响验收推断,不会改变工具访问。
边界情况:
- 裸字符串
"none"会被拒绝;请改用{ level: "none", reason: "..." }。 acceptance: false仅作为禁用门槛的过时简写被接受。- 对于评审者/只读调用,请省略
acceptance。 - 显式的值
"reviewed"不是策略级别:它仅保持被模式识别,以便语义预检可以在不派生子智能体的情况下解释该错误。若要要求对写作者结果进行评审,请使用acceptance: { level: "checked", review: { required: true, agent: "reviewer" } }并单独编排评审者。 - 对于
agentContract: { version: 1 },省略、"auto"与false表示该运行没有验收请求;显式验收与执行分开报告。
证据状态
验收来源与子智能体的散文分开存储。evidenceStatus 在总体状态等待评审或已完成评审时保留证据进度:
claimed:子智能体完成但未提供结构化证据。attested:子智能体返回了结构化验收报告。checked:运行时结构检查通过,例如必需证据与无暂存文件。verified:已配置的运行时验证命令通过。子智能体报告的命令成功不计入。review-required:必需的证据通过,但尚未提供独立评审者的结果。reviewed:独立评审者的结果存在且无阻塞项。rejected:证明、结构检查、验证或评审失败。
验收报告
对于 attested 或更严格的级别,子智能体提示词包含一个标准化的验收部分,并请求一个带围栏的 acceptance-report JSON 块。评审者/只读推断解析为 none,因此它不会添加此部分;显式验收仍然如此。对于 outputSchema,设置 acceptance.report: "on" 以要求在最终的 structured_output 调用中使用相同的报告,或 "off" 以保留带围栏的报告路径。省略 report 会保留默认行为。没有 outputSchema 的运行绝不会因该选项而获得独立的结构化输出工具。
解析器会规范化已知的枚举同义词、snake_case 报告键与包装、下划线围栏标记、无歧义的标量数组、字符串布尔值以及标准 id 分隔符。未知或歧义的键与枚举值会以字段级诊断失败。显式空的 changedFiles 与 testsAddedOrUpdated 数组会被记录为不适用;缺失字段以及空的必需命令或验证证据仍会失败。
验收围栏会从正常输出产物中移除,而原始子对话记录保持完整,每个子智能体的元数据存储完整的验收账本与已解析的报告。显式失败的门槛会使运行失败。推断出的门槛保持可观察,而不会使运行失败。
Herdr 项目面板
Herdr 项目面板是由本 Pi 会话打开的对等 Pi 会话:
ts
subagent({ action: 'project.open', cwd: '/path/to/repo', message: 'Start in this project.' });
subagent({ action: 'project.status', cwd: '/path/to/repo' });
subagent({ action: 'project.close', cwd: '/path/to/repo' });保存的面板绑定仅是面板级别的。父会话可以刷新状态、当 Herdr 报告 tab 或 workspace id 时聚焦保存的面板,或在 Herdr 验证所有权与 agent_status: "idle" 后关闭它。它不能检查、引导或停止该对等会话内的子智能体。陈旧或不透明的 Herdr 元数据保持未知,并失败闭合。
内联状态会统计当前会话的活跃工作以及 Herdr 项目面板的数量。请使用 Herdr 本身或项目面板 API 来聚焦或关闭项目面板。
Orca 进度标签页(实验性观察者)
Orca 进度标签页是一个全局的、可选择启用的观察者,而非智能体运行器。请在扩展配置中启用它:
json
{ "orcaProgressTabs": { "enabled": true } }前台与后台子智能体通过其常规的原生 Pi 或 external-cli 路径继续运行。对于每次顶层子智能体调用,观察者会请求 Orca 在拥有的工作树中创建一个后台终端标签页,并将进度镜像到其中。并行与链式子智能体共享该标签页,并按子智能体标题分隔。标题接收持久的工作树本地序号,包括跨不同的工作流调用。对于同一工作树的创建按该序号序列化,因此标签页按顺序(1,然后 2,然后 3)出现在右侧,而不是竞争。模型/启动重试重用同一观察者。附加到正在运行的异步根不会创建重复的子标签页。终端控制序列在查看器接收端跨读取边界被移除。每个镜像上限为 1 MiB,并在达到上限或流背压时截断。运行完成后,其查看器返回到终端 shell,而不是结束终端会话,因此标签页与滚动历史保持开启,直到用户关闭它们。成功的原生 Pi 运行以及已知会话,会附加一条安全引用的移除命令,用于精确的已验证会话路径;不成功与无会话的运行仅附加其终态。
观察者支持 macOS 与 Linux,在 Windows 上被禁用。它要求 PATH 上有可执行的 orca(或 PI_SUBAGENT_ORCA_BINARY),以及识别 cwd 的运行中 Orca 运行时。可用性与标签页创建是尽力而为的:失败永远不会使子智能体失败、停止或延迟。在可能的情况下,观察者会在 <worktree>/.pi/subagents/views/orca/ 下写入一份被动的清单;该清单仅作为显示元数据,而非生命周期或控制源。将 orcaProgressTabs.enabled 设为 false 可保证不会创建任何 Orca 命令或标签页。
智能体配置档 runner.type 支持原生 Pi(默认)、external-cli 与 external-job。Orca 故意不是配置档运行器,也不拥有子智能体的执行、完成、取消、产物或结果交付。外部任务提供方可以选择性地暴露 followUp(input),以便已完成的提供方作业可以通过 subagent({ action: "resume", id: "<run>", message: "..." }) 继续其父会话。
外部 CLI 智能体配置档
智能体配置档可以选择启用本地一次性命令,而非 Pi 子智能体。外部运行器不增加安装依赖,但已配置的可执行文件必须在运行时存在。它们仅异步,通过 stdin 接收一条合并的系统/任务提示词,并使用不带 shell 的 argv 数组:
yaml
runner:
type: external-cli
command: node
args: ['./scripts/local-reviewer.mjs']
promptDelivery: stdin
async: true受支持:状态产物、stdout/stderr 日志、超时与停止。完整的 stdout与 stderr 被写入日志文件,而内存中的最终 stdout 响应与 stderr 错误被限制为其最后 64 KiB。
刻意不支持:原生 Pi 子选项,例如模型覆盖、结构化输出、验收/智能体契约、工具预算、快速模式、fork 上下文、技能或原生 Pi 工具,除非运行器显式实现了它们。前台/澄清、steer/resume/interrupt-as-pause、嵌套子智能体以及回退模型同样不支持。
会话分享
传递 share: true 以将会话导出为 HTML,通过你的 gh 凭据上传到秘密 GitHub Gist,并返回 https://shittycodingagent.ai/session/?<gistId> URL。
ts
{ workflowScript: `return runs.run("main", { agent: "scout", task: "..." })`, share: true }默认禁用。会话数据可能包含源代码、路径、环境变量、凭据或其他敏感输出。你需要安装并完成身份验证的 gh。
