Skip to content

02. Agent 运行时

翻译说明: 本页是与 英文源规格 一一对应的机器辅助翻译。代码、协议字段和标识符保持原文;如翻译与英文源事实有歧义,以英文版本为准。

1. Goal

应用决策:D002/D003/D008/D158/D189/D190/D193/D194

将 pi 包装到桌面层可以安全使用的产品运行时中。

核心包:

  • @earendil-works/pi-ai
  • @earendil-works/pi-agent-core

2. 运行时放置

Agent 循环在 Node/TypeScript pi sidecar 中运行,而不是在渲染器中运行。

text
packages/agent-runtime/*
apps/desktop/electron/* (supervisor)
crates/host-core (tool execution + permissions)

3. 核心对象

3. 1 PiRuntime (Node)

  • 初始化 models/providers
  • 创建 Agent
  • 绑定工具桥
  • subscribe/normalize pi 事件

3. 2 AgentHostFacade (Electron 主)

  • 会话路由
  • 过程监督
  • IPC 翻译

3. 3 主机工具桥(Rust)

  • 接收工具调用请求
  • 应用权限策略
  • 执行 builtin/plugin 工具
  • 返回标准化的工具结果

4. 运行时 API(包级)

ts
interface AgentRuntime {
 prompt(input: PromptInput): Promise<{ turnId: string }>
 abort(turnId?: string): Promise<void>
 getStatus(): RuntimeStatus
 dispose(): Promise<void>
 subscribe(handler: (event: NormalizedAgentEvent) => void): () => void
}

5. 提示流程

1.加载持久会话并拒绝丢失的会话 2. 解析该会话的 mode/provider/model 和项目绑定 (app/current 工作区默认值仅是旧版回退) 3. 解析该确切 provider/model 的完整 pi-ai 模型记录,并且 将持久会话思维水平限制为 pi 最接近的支持值; 未知的自由格式 id 使用显式通用后备 4. 验证 model/secret 可用性 5. 如果会话繁忙则拒绝 6. 保留用户消息 7. 快照本次有效的 shell ID 和方言 8.用解析的会话配置启动pi轮并生效 思维水平;请求设置接收一次有限的 pi-ai 瞬态重试 transport/provider 失败,而流式传输后出现暂时性失败 在回合失败之前开始接收一次同回合运行时重试 (D127、D186) 9. 将规范化的答案和思考事件传输到 UI 10. 在工具调用时,委托给具有持久性 sessionId 的 Rust 主桥; 主机解析会话绑定的工作空间根 11. 如果 pi 使用 stopReason: "error" 完成消息,则完成任何部分 带有结构化 UiMessage.error 的助手气泡,将其持久保存在 转录本,并发出一个规范化的生命周期 error 事件,其中包含 同一提供商 AppError;即使没有答案文本的失败仍然是 助手错误信息可见 12. 独立完成并保存成功的 answer/thinking 块

运行时为每个持久会话构造一个 pi Agent。 Plan 确实 不选择第二个模型、规划器服务、权限实施,或者 运行时。同一个 Agent 在执行一次操作后更改其计划状态和工具注册表 主机确认的转换。

5d。有界提供商流恢复和诊断(D186、ADR 0050)

提供程序请求设置使用一次 pi-ai 重试以及可中断的退避 上限为 8 秒。这涵盖了建立响应之前的故障; 它不会使整个代理进入无限重试循环。

当提供商在助手之后终止或关闭不完整的流时 已开始,运行时将事件分类为可重试 STREAM_FAILEDNETWORK_ERRORTIMEOUT 在发生时具有相同的有界路径 流式传输。运行时等待 750 毫秒,并进行可中止的退避,删除 从下一个模型上下文中调用失败的助手,并调用 continue() 一次。 现有的助手消息id被复用,因此部分响应为 替换为一个可见的气泡。第一次尝试的 turn_endagent_end 被压制;重试发出单个终端生命周期。一秒钟 失败是最终的,并发出正常的助手错误和生命周期 error 事件。身份验证、模型选择、速率限制、格式错误的请求、 并且上下文错误不使用此同回合重放路径。

提供程序故障在 AppError.details 中进行有界诊断 可用:phaserequeststream)、providerStatusproviderCodeproviderWaitMsstreamMsretryAttempt。提供商消息保留 已编辑并限制;凭证和不受限制的响应机构永远不会进入 事件或日志。

5e。静默回合恢复

以没有工具调用且没有可见辅助文本结束的回合是不可见的 对用户:推理永远不会呈现,因此结论只写在那里 没有到达。 255 个录制的会话中有 15 个以这种方式结束了一个回合,并且 用户唯一的办法就是输入“继续”。

运行时在 message_end 处检测到它:停止既不是错误也不是异常 中止,消息不请求任何工具(没有 toolCall 内容部分),并且 修剪后可见文本为空白。推理内容不免除回合 ——只思考的转变正是需要恢复的情况。

恢复镜像 §5d 并以相同的方式限制:每个用户最多重新运行一次 提示。无声助手已从模型上下文中删除 (continue() 拒绝以助理消息结尾的记录,空的则不 值得重新发送),一条简短的无输出指令被附加到系统中 提示继续该操作,并且重复使用气泡 ID,以便恢复 回合后不留空行。无声尝试的 turn_endagent_end 被抑制;重新运行会发出单个终端生命周期。

一次性指令依赖于代理的系统提示,而不是 prepareNextTurn 钩子,因为该钩子仅在实时运行中形成回合 并且本次运行已经结束。除非路径范围内的,否则它会在之后被删除 指令重新加载同时重写了提示,在这种情况下,较新的 重建胜利。

如果重新运行也没有声音,则回合结束时会出现明显的辅助错误 可重试的 EMPTY_MODEL_RESPONSE,它为转录本提供正常的重试 行动。在这两种情况下都不会保留空的助理消息。

决定D193;参见 E2E-098。

5. 1 上下文检查点保护(D158/D203、ADR 0030/0049/0061/0064)

完整的可见记录和模型上下文是不同的视图 同一个会话。持久检查点总结了旧模型上下文,同时 渲染器继续显示每个原始用户、助手和工具行。

PI-Desktop 复用 pi-agent-core 的 buildSessionContextconvertToLlmestimateContextTokensprepareCompactioncompact 原语。的 桌面运行时拥有运行时间以及结果如何穿过 Rust 存储 边界; OpenCode DCP 仅是 AGPL-3.0 行为参考,不是链接或 复制的依赖关系。

压缩遵循 Codex 的机制 (ADR 0064):它总是内联发生在 回合边界,模型可以通过new_context请求,每次compaction 添加一个成绩单行并提出一个警告 toast,并且没有 任何地方的预计算。

对于每个 pi 循环:

  1. pi 在助手消息和所有工具之后发出并等待 turn_end 该回合的结果已完成
  2. PI-Desktop 根据完整转录本和最新转录本重建上下文 有效的检查点并估计下一个请求预算 3.低于硬边界,并且没有待处理的模型请求,下一回合 收益不变
  3. 处于或高于硬边界,或者当模型名为 new_context 时, 压缩在下一个提供程序请求之前同步运行。在 摘要家庭、世代为必填项;运行时预检摘要 根据模型窗口进行输入并跳过不适合的请求。安 自动摘要失败首先尝试确定性保留尾部 检查点,而手动压缩仍然报告 CONTEXT_COMPACTION_FAILED
  4. 成功生成或确定性恢复首先追加 通过 host-core 检查点,然后安装其摘要 + 保留尾部为 下一个提供程序请求的运行时上下文;硬边界 检查点在持久化之前被重新估计,并且在之前再次估计 继续,并且不能授权下一个请求,除非它低于 硬预算

检查点生成和安装是单独的操作。 buildCheckpoint 运行准备、预算预检和摘要请求 无需保留任何内容或更改活动检查点;安装 重新估计,通过 host-core 附加,更新活动检查点,以及 发出 compaction_end。阻塞路径将两者背靠背组成。

在检查点中幸存下来的内容。 压缩后的模型上下文是 仅摘要以及最近的用户消息;助手和工具消息是 从模型上下文中删除并保留在可见的转录本中。圆周率 prepareCompaction 仍然选择切点,因此其回合边界和 保留分割回合处理,但运行时会折叠分割回合 前缀和最近的尾部返回到摘要输入中,因此摘要涵盖 整个紧凑的范围内,没有任何东西跨越边界而未被覆盖。这 保留的用户消息是从压缩范围中按最新优先顺序选择的 前一个检查点的留存用户,最多可达下面的留存限额;的 超过该限制的消息将被截断而不是丢弃 ([checkpoint truncated: this message crossed the retained context budget]), 并且选择将恢复为时间顺序。放弃助理 消息也会丢弃其工具调用,因此没有孤立的工具调用可以到达 提供商。保留的尾部用持久化之前的摘要重新估计 并且在继续之前,所以超大的请求仍然无法通过警卫。

两个压缩系列。 两者运行相同的生命周期 - 预算 重新估计、host-core 追加、compaction_end、成绩单行、警告:

  • summary(默认)从模型请求摘要;
  • fresh_window 不请求任何内容并安装一个空的检查点 保留尾部和固定标记文本,说明历史记录已重置,无需 正在总结中。

家庭从建筑选项中解决,然后 PI_DESKTOP_COMPACTION_STRATEGY。这不是一个设置,不存在 AppSettings 和 i18n,并且存在因此实现了无摘要机制 并且可测试。

面向模型的表面。 new_context 不带任何参数并开始一个新的 下一回合边界处的上下文窗口;它永远不会清除或重置环境 状态。当前回合的系统提示中附加了两条预算提醒, 每个检查点窗口最多一次,并在检查点被重置时重置 安装:当剩余预算降至 clamp(hardLimit * 0.15, 8k, 32k),要求模型开始平仓,并且 一个剩余 2,000 个令牌,告诉它写下必须幸存的一切。 这两个提醒都不会保留或显示在记录中。

硬边界是模型上下文窗口减去请求余量。 Headroom 是 16,384 个代币储备底线的最大值,模型最大输出 上限为上下文窗口的 25%,以及 5% 的安全裕度。预留楼层 本身被限制在窗口的一半处。传递给 pi 的切点目标是 从模型窗口得出,硬预算的 20% 被限制在 8,000–64,000 个代币,然后上限为硬预算的一半;它决定了在哪里 边界倒塌了,而不是幸存下来的东西。用户消息保留限制为 20,000 个代币,上限为硬预算的一半,因此仅靠保留无法填补 小窗口,没有留下摘要的空间。这些值都不是 可配置。

传入的用户提示先于第一个提供商参与预算 请求。如果在自动阈值或溢出期间正常压缩失败 恢复时,运行时会与之前的恢复检查点保持一个简短的恢复检查点 摘要(如果可用)和一个积极限制的最近尾部。的 完整的成绩单保持持久且可见,而下一个模型请求 仅接收恢复检查点和尾部。生命周期事件标记 这作为 fallback: "retained_tail" 因此渲染器可以显示警告 而不是虚假的成功。如果无法准备、持久或保留后备 低于安全预算,用户行和助理错误仍然持久并且 没有提供商请求开始。提供商报告的上下文溢出是最后一个 恢复层:从模型上下文中省略失败的助手,压缩一次, 并重试一次。第二次溢出仍处于终止状态。基岩的 prompt is too long: N tokens > M maximum 形式映射到此路径。

自动保护始终启用且用户不可配置。的 运行时仍然接受禁用它的构造时覆盖,由 测试;持久的 contextCompaction 设置将被忽略,因此会话无法 失去防护,无法恢复。手动 /compact 仍然存在 会话空闲时可用。检查点生成是可中止的并且 计为运行状态,直到持久持久性完成。

5b.运营模式及规划状态

  • 默认产品模式:Agent
  • 产品选择器是 Agent | Plan | Goal;内部对话页面 仍可能使用 page = "chat"
  • 模式是会话范围的,并与会话元数据一起保存
  • 思维水平是会话范围的,并通过会话元数据持续存在
  • 主机配置仅在会话空闲时可变。渲染器 保持 mode/provider/model/thinking/permission 控件在运行期间可编辑, 将最新选择视为下一回合状态,并刷新一个完整的 终端事件后的配置。
  • 更改 mode/provider/model/thinking 级别适用于下一回合,并且 当任何影响运行时的配置更改时重新创建 pi 运行时; 运行中的运行时不会观察到排队的渲染器选择。

实时计划状态的推导和预测为:

ts
type OperatingMode = "agent" | "plan" | "goal";
type ProposalKind = "plan" | "goal";
type PlanningState =
  | "inactive"
  | "planning"
  | "awaiting_approval";
type PlanExecutionState = "queued" | "running" | "completed" | "interrupted";

Plan 和 Goal 是两种 合约模式 (D198)。他们共用一个耐用的 批准表、一张投影 PlanningState、一张批准表面和一张 执行队列;提案上的 kind 判别器 (plan | goal) 选择 提示符、工件目录和面向用户的副本。 Agent 是唯一的 没有种类的模式,并且是唯一可以自由执行的模式。因为 投影是共享的,planningawaiting_approval 始终一起读取 可以知道会话处于哪种持久模式。

当用户选择 Plan 时,Agent / inactive 进入 Plan / planning 空闲时或 Agent 调用 EnterPlanMode 时。在 Plan 中,Agent 可以 检查、使用上下文控制、通过选定的权限模式运行 Bash, 并调用 SubmitPlan(title, markdown, question)。主机核心保留 在新的不可变中提交 Markdown 字节 .pi/plan/<unique-name>.md 工件,记录其相对 path/hash/size 和 在 plan_approvals 中构造 title/question,并将活动状态移至 awaiting_approval

仅批准 approvereject。批准提交 mode = agent, 显式权限模式、执行 ID 和 execution_state = queued 一个主机事务中的相同 plan_approvals 行。的 然后,同一个 Agent 使用 Agent 工具集进行新的模型转动。拒绝, 绝对过期、待处理的中断、过时的响应或持久性 失败关闭批准行并将活动状态返回为可编辑 Plan / planning 不授予执行工具。后来接受的 Plan 提示 是一个新的转折:早期的 SubmitPlan 调用仍然是历史不可变的 检查点,并且 Agent 必须调用 SubmitPlan 一次使用新的完整 Markdown 快照来创建新的工件。如果批准 已提交且 queued/running 执行被中断,持久模式 仍然是 Agent 并且不会重播执行。

手动模式和配置选择可以由渲染器上演,同时 轮运行,但主机持久性仅保持空闲状态。选择 Agent 是 故意的用户覆盖并且不综合计划或批准。每个 会话有 1 个活动轮次、1 个待批准轮次和 1 个 queued/running 执行;暂存时,第二个提示或执行被拒绝 仅在会话空闲后才提交配置。

Agent / inactive 进入 Goal / planning 两种方式相同,由用户选择 空闲时或通过 Agent 调用 EnterGoalMode。 Goal 有相同的工具 表面为 Plan,只不过其提交工具是 SubmitGoal(title, markdown, question) 及其工件被写入 .pi/goal/<unique-name>.md。提交的 Markdown 是一个目标合约—— 要达到的结果、证明已达到的验收标准以及 不得跨越的界限——不是实施步骤的列表。一个 当会话处于活动状态时,提交工具会被拒绝并显示 PLAN_KIND_MISMATCH 是另一种,当没有合约处于活动状态时,使用 PLAN_NOT_ACTIVE

Goal 批准所承诺的内容与 Plan 批准所承诺的内容完全相同:mode = agent, 显式权限模式、执行 ID 和 execution_state = queued 同一行。排队执行指令因种类而异。批准的计划是 重播为遵循的步骤;批准的目标指示 Agent 选择其目标 自己的方法,通过运行检查来验证每个验收标准 合同名称,在未满足标准和未经尝试的方法的情况下继续工作 仍然存在,只有当边界阻挡它时才提前停止,并以 逐个标准地报告所满足的内容和观察到的证据。

5c。思维能力与流契约

  • 规范级别为 offminimallowmediumhighxhigh、 和 max
  • Pi生成的模型目录对于推理支持具有权威性, 思维层面的映射、限制、输入模式、定价、标题和适配器 每个已解决的已知模型的兼容性。
  • 提供商配置不能覆盖已知模型语义。未知 自由格式的 id 仍然可以通过通用的纯文本、非推理的方式运行 模型,因此仅公开 off
  • 不支持的请求级别使用 pi 的最近支持级别规则:扫描 先向上,然后向下。非推理提供商总是决心 off
  • 有效电平传递给pi Agent;特定于提供商的请求 序列化仍然是 pi-ai 的责任。
  • Pi thinking 块变为 UiMessage.thinking 并且 message_update.deltaThinking。他们从不附加到 contentdeltaText
  • 恢复的助手历史重建单独的文本和思维块 在下一个回合之前。
  • 恢复的历史记录还可以从持久保存的工具 call/result 对中重建工具 工具行(off/minimal/low),因此重新创建了运行时 保持其完整的工作上下文——读取的文件内容、命令输出—— 而不是折叠成裸露的聊天文本(D127)。中断的刀具行 恢复为错误结果;辅助行丢失的工具行 获得合成的仅呼叫辅助运营商,以便 call/result 对保留 格式良好,适用于每个提供商 API。
  • 失败的助理消息仍然是持久的诊断记录条目,但 在以后的回合中永远不会恢复到 pi 模型上下文中。
  • 恢复的检查点可清除保留的助理消息中的提供商使用情况 用于预算。该用法测量了预压缩请求,并且不得 使摘要+尾部看起来与丢弃的上下文一样大。
  • 运行时重新创建和模型更改恢复最新的有效检查点。 仅当其边界保留在实时转录本中时,截断才会保留它; 仅当子级包含该边界时才分叉 copies/remaps。
  • 分叉会话接收新的会话 ID,并且没有共享运行时。它的第一个 提示创建一个新的 pi 运行时并仅从子进程恢复上下文 转录本,包括重新映射的工具 call/result 对。
  • 消息范围的助手 Fork/Edit 遵循相同的规则:子进程 转录可能会停止或替换所选的助理响应,但其 下一个提示无法重用源会话的 runtime/provider 缓存,因为 会话 ID 和重新映射的转录本身份是独立的 (D134)。

5f。子代理委托(D201、ADR 0062)

会话 Agent 可以将一项独立的工作交给委托人,并 收到一份书面报告。

目录。 定义是来自三个来源的 Markdown 文档:三个 agent-runtime 中内嵌的内置函数(explorercode-reviewertest-runner),host-core 在 <data>/agents/ (D202) 下拥有的用户注册表, 和 <workspace>/.pi/agents/*.md。优先级是 项目 > 用户注册表 > 内置,因此提交的项目文档会重新调整注册表定义或 内置而不重命名它。注册表文档通过 enabled 进行过滤, 它们在到达加载器之前的激活范围,因此定义范围为 另一个项目根本不在目录中。 Electron 主要加载目录 每次发射和通过 subagents / subagentProviders 在 sidecar 参数中,因此编辑定义 在下一个提示时生效。目录上限为 MAX_SUBAGENT_DEFINITIONS (16);格式错误或不可读的文档将成为 启动诊断并且永远不会使启动失败。

工具。 Task(agent, task, description?) 仅在 Agent 模式下构建,并且仅 当目录非空时。它的描述带有代表目录,并且 其参数在工具中进行验证:未知的 agent、空的 task、 无法解析的模型引脚和其工具均不可用的定义 返回一个工具错误来解释失败而不是抛出。 Task 所属 到 Agent 核心集而不是第 7.1 节的按需目录,因此会话 通过定义总是可以看到它。

委托循环。 SubagentRun 是同一 sidecar 中的第二个 pi Agent 使用定义的系统提示进行处理,其(可能已固定) provider/model,其声明的工具,与主机连接相同。它运行在 maxTurns(默认 24,最大 80)和相同的有界提供程序重试策略 作为家长。其状态为 completedtruncatedfailedaborted;所有四个都折叠到 Task 工具结果中,其文本是 报告(绑定到 MAX_SUBAGENT_REPORT_CHARS,12k)及其详细信息 agentstatusturnstoolCallsusage,以及失败时的 error

模型引脚。 Frontmatter 中的 model: <provider>/<model> 已解决一次 每次在 Electron main 中启动,其中凭证和 pi 目录都存在,针对 提供商 ID、供应商密钥或显示名称,上限为 MAX_SUBAGENT_PROVIDERS (8) 不同的提供商。省略了无法解析的引脚 故意从绑定地图中提取;运行时将缺失的条目变成一个工具 命名引脚时出错,并且永远不会回退到会话模型。一个定义的 thinkingLevel 被固定在具有相同的解析模型上 最近支持的规则如§5c。

**事件和上下文。**委托发出的每个事件都携带 信封上印有 parentToolCallIdagentName,Electron 主副本均印有 到持久化的行上。当运行时重建模型上下文时,它会跳过每个 parentToolCallId 行:家长只看过报告,并重播 代表行既会与此相矛盾,也会重新引入上下文成本 委托的存在是为了避免。

轮到所有权。 委托的生命周期永远不会轮到 Electron main 处理。终止仅作为 Task 工具结果可见,因此父级 回合仍然是唯一可以结束回合的事情。

周围的合约位于 03-tools-and-permissions.md §10.2(什么是 代表可以致电),04-data-storage.md §4.7a(持久归属), 04-ux/03-permission-ux.md §6a(多个待处理请求)以及 04-ux/08-component-spec.md §9.9(代表团如何解读)。

6. 提供商和模型

完整政策:11-provider-model-system.md12-provider-config-schema.md13-model-catalog-and-selection.md

覆盖策略:

  1. 由 pi-ai 公开的原生提供商(OpenAI、Anthropic、Google 以及其他可在 pin 版本上使用的提供商)
  2. 兼容OpenAI网关和长尾供应商的一流路径
  3. 具有协议配置文件的自定义提供商
  4. 可刷新模型目录 + 自由格式模型 ID(无封闭许可名单)

MVP UI 始终至少包括:

  • OpenAI
  • Anthropic
  • 谷歌 Gemini
  • OpenAI 兼容(通用)
  • 自定义提供商条目

运行时职责:

  • 解决 (providerId, modelId)
  • 解析并序列化完整的 pi-ai 模型记录,或将模型标记为 未知的通用后备
  • 由此解析模型推理能力和有效思维水平 相同的记录
  • 通过主机获取机密(切勿在日志中缓存原始机密)
  • 将供应商故障转换为提供商 AppError 代码
  • 将 tokens/events 流式传输到协调器
  • 支持abort/cancel中流

本地模型通过 OpenAI 兼容端点(Ollama、LM Studio、vLLM 等)获得支持。

7. 系统提示组成

text
[base product prompt in English]
+ [operating-state prompt: agent/plan/goal]
+ [workspace info]
+ [tool instructions]
+ [project instruction chain, when present]
+ [optional user custom instructions]

基本提示明确指出协作规则,因为省略它们 是产生无声会议的原因:“更喜欢简洁、可操作的答案” 只有相关的行,而推理模型将其执行为根本没有说什么。 所需的行为,每一项都是观察到的相反的失败:

  • 以用户书写的语言回答
  • 每个工具批次前一句话,且沉默时间不得超过一个工具 批量或 60 秒的工作
  • 用户提出的任何问题都会以可见文本的形式得到答复;推理未显示 给他们,并不算作答案
  • 最终消息是独立的
  • 工作是从头到尾进行的,而不是停留在分析上
  • 工具调用通过本机工具调用接口;写成散文的电话 (特别是 OpenAI 风格的 multi_tool_use.parallel 包装器)不运行,并且 当模型发出一个模型时,运行时会记录它

它还说明了与主机端预算相匹配的搜索偏好 16-工具结果限制:范围 ReadGrepGlob 用自己的参数代替手卷 Read/Grep/16-tool-result-limits.md/ findRead 仅接受现有的常规文本文件。当文件名是 不确定或必须列出目录时,Agent 会激活 Glob 通过 ToolSearch 获取当前提示,而不是猜测名称或阅读 目录。 Glob.path 是一个目录,而 Grep.path 可能是一个文件或一个 目录树。调用使用 Read.offset/limitGlob.path/limitGrep.path/include/outputMode/headLimitfilesWithMatchescount 避免 不需要的内容。工作区相对路径仍然是可移植的默认路径,带有 仅当本机工具不足时才在活动 shell 中使用有界命令。 rg 是可选的而不是假定的,并且代理不得重复搜索 他的答案已经在上下文中了。

7. 1 活动工具上下文和按需加载(D185、ADR 0048)

sidecar 构建了一个完整的工具注册表,但它不会序列化每个工具 将模式注册到每个提供商请求中。每个新用户提示都以 该模式的核心集:

  • Agent:ReadBashEditWrite(匹配 pi 的编码代理核心)
  • Agent:当子代理目录非空时,Task 也是如此 (§5f) — a 模型必须寻找的能力是它不会使用的能力,并且 每个请求委托值得一个额外的模式
  • Plan:ReadGlobGrepBrowserPreviewBash
  • 两种模式:ToolSearch(当至少存在一种延迟功能时)

在Agent模式下,GlobGrep加入BrowserPreview、插件工具、Skill, 以及延迟集中的插件开发助手。两种合约模式均保留 他们的 read/inspection 核心可用,而该类的提交工具 (SubmitPlanSubmitGoal)仅在规划状态期间公开,并且 仅适用于主动类型。延迟工具已注册,但其名称和 紧凑型 一行描述出现在 # On-demand tools 目录中;参数 模式则不然。目录是有限的,因此具有许多工具的插件无法 重新创建原来的提示膨胀。 该模型使用确切的名称或简短的功能查询调用 ToolSearch。 sidecar 激活最多四场比赛,通过返回他们的名字 pi-agent-core 的 addedToolNames,并用这些重建下一轮上下文 模式。具有本机延迟工具搜索的提供商可在以下位置接收定义: 该负载点;其他提供商通常会收到活动定义。

延迟激活会在每个新用户提示之前重置,因此之前的任务 无法使不相关的第一个请求携带不断增长的工具集。工具 注册表、主机权限路径、工具超时和工作区包含规则 保持不变。 ToolSearch 是 sidecar 的本地变量,不跨越 主机 RPC 边界。其激活标记保留在持久化工具中 结果,尽管重新启动,恢复的转录仍然是提供商有效的 在重用延迟功能之前,运行时仍然需要重新搜索。

对于用户可见的 HTML 可交付成果,默认系统提示要求代理 创建页面或创建第一个页面后激活 BrowserPreview 一次 使用工作区相对路径进行有意义的可视化编辑。代理重用 迭代时实时重新加载预览,而不是发出重复预览 来电。生成的、仅供测试的和非可视的 HTML 文件被排除在外。当 工具被延迟,ToolSearch 必须在预览调用之前激活它。

7. 2 Plan 提示要求

Plan 提示告诉相同的 Agent 了解请求,检查 相关 repository/specification/test 上下文,识别受影响的文件并 风险,包括重点验证和 migration/recovery 影响、表面风险 开放式问题。当任何初始或修订计划准备就绪时,必须调用 SubmitPlan 在当前回合中立即恰好一次,并完成一个 降价快照。已接受的新 Plan 提示没有事先等待批准; 记录中较早提交的内容是历史上不可变的检查点。 拒绝、过期或中断后,Agent 可能会在新一轮中修改,并且 必须遵循相同的 one-SubmitPlan 规则。它不得声称变更是 做了。主机写入不可变的 .pi/plan/*.md 工件; Agent 确实 本身不编写或编辑它,并且不接收请求更改流。

该提示可能会将 Bash 描述为受权限限制且可能会发生变异。它 不得将 Plan 描述为严格的只读安全边界。

7. 2a Goal 提示要求

Goal 提示告诉同一个 Agent 在任何事情之前协商目标合同。 自主工作。它要求实现什么而不是如何实现:结果、结果 验收标准和边界。它不能枚举实现 步骤,因为 Agent 在批准后自行决定这些步骤。每一次接受 标准必须能够在执行后由 Agent 客观地检查——命令 那必须过去,或者是可观察到的行为。 Agent 检查工作空间并 首先询问任何不明确的问题,然后立即准确地调用 SubmitGoal 当前回合中一次,包含一个完整的 Markdown 快照。

一次提交规则、历史检查点规则、关闭后修改规则、 no-chat-confirmation 规则和 host-writes-the-artifact 规则相同 作为 Plan,用 SubmitGoal.pi/goal/*.md 代替 Plan 等价物。提示还指出,一旦获得批准,合同即为 Agent 所遵循的标准:自主追求目标、选择 它自己的方法,只有当每个验收标准都得到验证或一个 边界挡住了它。

7. 2b 子代理提示组成(D201、ADR 0062)

代表的系统提示在 sidecar 中由三部分组成,其中 order:委托框架、定义的 Markdown 正文和工具 其宣称的工具所获得的指导。身体位于工作空间引导前方 所以项目自己的说明仍然具有最终决定权。

框架陈述了代表的处境的形状,这不是 从正文中可以推断:这是一项委托任务,委托人看不到 用户,提出问题或进一步委托,它完全具有列出的工具,并且 它的最终消息是主代理收到的唯一消息。只读 定义还被告知永远不要报告它无法进行的编辑; 一个具有写入能力的人被告知只能触摸该任务所涉及的文件。

指导块与会话提示使用的文本相同,仅在以下情况下包含: 该定义声明了匹配工具:search/read 范围为 Read/Grep/Glob,编辑 Edit/Write 的规则,命令 shell 合约 Bash 以及会话具有临时目录时的临时目录规则 代表可以写。附加项目指令链(§7.3) 最后,因此代表遵循与其会议相同的项目规则。

7. 3 项目指令链

Electron主流程首先解析全局 ~/.pi/agent/AGENTS.md,然后将指令文件投影到 运行时启动时的会话绑定项目根。对于每个项目目录 按以下顺序最多使用一个非空文件:AGENTS.override.mdAGENTS.mdCLAUDE.md,然后是 .claude/CLAUDE.md。条目由项目串联而成 root 到目标目录,因此最接近的文件最后出现并占用 优先。初始链的目标是项目根。在 Read 之前, WriteEditBrowserPreview 调用,sidecar 要求 Electron main 解析目标路径并用该路径替换活动指令部分 工具执行之前路径的完整链。这使得规则变得懒惰并且 防止代理移动到同级目录后保留同级目录规则 不同的文件树。

会话绑定的项目根与运行时启动元数据一起传递,并且 在每次提示或压缩请求之前由 Electron main 注册。的 sidecar 无法选择不同的根。在一次提示期间,路径解析 声明由项目根目录和目标目录缓存,因此重复文件工具 在同一目录中不要执行另一个 IPC 请求。索赔被放弃 在下一个提示下,允许进行编辑和新创建的指令文件 没有陈旧的跨消息缓存的效果。

路径特定的解决方案是尽力而为的,并且有 2 秒的截止日期。如果 解析器或其主机 RPC 不可用或超过该截止日期,该文件 工具继续运行运行时的 base/root 链,而不是等待 一般主机RPC超时。失败的解决方案永远不会留下以前的解决方案 已解决同级目录链处于活动状态。

所有发现都保留在会话项目根目录中。空的、不可读的、 跳过根目录外的文件。合并的 UTF-8 内容上限为 32 KiB 源路径标记在 # Project instructions 下。 sidecar 从不直接读取工作区指令。改变的根链 在下一个提示时重新创建空闲运行时;嵌套指令已解决 当相关文件工具运行时再次。 sidecar 计时线记录 instructionResolveMsinstructionCacheHitinstructionFallbackhostRttMs 分开,因此慢速预检不能被误认为是慢速预检 指挥机构。

设置为固定全局路径提供专门的管理。项目 查看项目列表菜单为其相应的项目提供了 AGENTS.md 编辑器 注册的项目根。其 IPC 不接受任意渲染器文件路径。 保存会影响下一个提示,而无需重新启动应用程序。

8. 并发

适用范围MVP 政策
同一会话单圈串联
不同的会议有限并行
工具默认情况下是顺序的
Task 通过一条助理消息进行呼叫并行,4 个插槽 (D201)

工具并发性通过 pi 执行模式来表示:每个目录工具都是 sequentialTask 单独为 parallel,并且 pi 按顺序运行批处理 一旦它包含一个顺序工具。因此,全 Task 批次是唯一的批次 扇出,并且所有其他订购保证均不变。代表问题 主机独立调用,以及 host-core 的每次会话一次突变准入 防止写入撕裂,但留下两个无序的相同路径突变,因此 sidecar 序列化针对相同标准化路径的 IPC/sequential 调用 在到达宿主之前;不同路径上的调用永远不会相互等待。 这就是保持每个路径编辑恢复规则的原因 03-tools-and-permissions.md §4d 在扇出下有意义。

选择另一个项目选项卡仅影响可见的 shell 工作区。它 不会处置、中止或重新启动属于另一个会话的运行时。

9. 中止语义

  • 停止模型流
  • 尝试取消可中断工具
  • 不自动回滚已完成的写入
  • 在 UI/storage 中标记回合已中止
  • 保留已过去的响应持续时间;当提供商最终使用不可用时, 估计可见思维以及每个 4 个 Unicode 代码点的答案输出 令牌并将其保留为 responseOutputTokens,因此停止轮吞吐量为 仍然可用并且明显近似
  • 渲染器智能停止转录撤消和结构化输入框恢复 中止后的协调;他们不会改变运行时取消或滚动 返回完成的工具效果

10. 明确的非目标

  • 没有 DOM 知识
  • 无法绕过 Rust 主机进行直接 FS 访问
  • events/logs 中没有秘密泄露

11. 实施状态(M5)

实现:流转OpenAI兼容协议路径 (通用逃生舱口,D024);每个会话强制执行一个活动回合 AGENT_BUSY;根据接受的提示返回真实的 turnId;供应商失败 映射到 PROVIDER_UNAUTHORIZED / PROVIDER_RATE_LIMITED / MODEL_NOT_CONFIGURED / STREAM_FAILED / TURN_ABORTED(可检测)。 桌面开发生命周期重建 packages/agent-runtime/dist 在 Electron 启动之前,因此生成的 sidecar 始终执行当前的 标准化和误差映射源。

跟踪差距(MVP 后积压):更丰富的系统提示组成 (§7) 和 provider/model 目录发现超出当前有线路径。

为本地优先开发而构建。