@cr1ms0n/pi-subagent 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.11.0 - 2026-09-22
4
+
5
+ ### Probability-ranked Jev failover
6
+
7
+ - Retain validated candidate probabilities and advance to the next eligible model after a recognized availability failure, only before any current-invocation tool execution begins. Unknown activity and task-quality failures do not authorize restart.
8
+ - Select one task-based tool subset for all attempts, resolve thinking per candidate, and verify each attempted model/tool set without another Jev request.
9
+ - Bound all extension-level extra attempts by `max_retries`, candidate exhaustion, the original deadline and cumulative execution budgets. Preserve Pi's internal retries and the trusted unranked SDK fallback contract.
10
+ - Record original and actual models, bounded attempt history and earlier output pointers across status, plan and reload. Preserve failure state and usage without publishing failed structured output or duplicating selector receipts.
4
11
 
5
12
  ## 0.10.0 — 2026-09-21
6
13
 
package/README.md CHANGED
@@ -1,124 +1,34 @@
1
- [English](README.md) | [简体中文](README.zh-CN.md)
2
-
3
1
  # Pi Smart Subagents
4
2
 
5
- Run isolated child agents in [Pi](https://pi.dev/), with Jev selecting an execution model and individual tools for each task.
3
+ [English](README.md) | [简体中文](README.zh-CN.md)
6
4
 
7
- Published on npm as `@cr1ms0n/pi-subagent`. This is an independent community fork of Luke Parke's `@parke.dev/pi-subagent` 0.8.0 from [LukasParke/pi-extensions](https://github.com/LukasParke/pi-extensions/tree/main/packages/pi-subagent), not an official upstream release. The original MIT license and copyright are preserved.
5
+ Run isolated child agents in [Pi](https://pi.dev/), with Jev selecting a model and tools for each task.
8
6
 
9
- The upstream extension provides the child-process engine, named agents, background tasks, worktrees and usage accounting. This fork adds mandatory Jev model/tool selection and verifies the child's selected capabilities before sending it the task.
7
+ An independent community fork of Luke Parke's `@parke.dev/pi-subagent` from [LukasParke/pi-extensions](https://github.com/LukasParke/pi-extensions/tree/main/packages/pi-subagent). It retains the upstream engine's named agents, parallel and background tasks, worktrees and usage accounting, and adds Jev routing with child capability verification.
10
8
 
11
9
  ---
12
10
 
13
11
  <a id="quick-start"></a>
14
- ### Install and quick start
15
-
16
- Use Node.js 22.19.0 or newer and an installed Pi CLI with a working model provider. Pi 0.86.0 is the verified host baseline for enforcing built-in, extension and late-registered tool allowlists. A host that cannot verify the selected capabilities is refused rather than granted more tools.
17
-
18
- **1. Install the published package.**
19
-
20
- Install the exact `0.10.0` release. The earlier `0.9.0` release uses the older `apiKeyEnv` configuration contract and does not accept `apiKey`:
21
-
22
- ```bash
23
- pi install npm:@cr1ms0n/pi-subagent@0.10.0
24
- ```
25
-
26
- Pi loads the package directly. Do not enable another copy of this extension or `@parke.dev/pi-subagent` together with it: they register the same tools. The package provides `subagent`, `subagent_wait`, `/subagents`, `/subagent-cost` and `/btw`.
27
-
28
- **2. Store your TypeSafe credential in private configuration.**
29
-
30
- Set `jevRouting.apiKey` in your user-level `~/.pi/subagent.json`, as shown below. If you are upgrading from `0.9.0`, move the existing value from `jevRouting.apiKeyEnv` to `jevRouting.apiKey` and remove the old field before starting new dispatches. Do not paste the key into chat or repository files. The file stores the key in plaintext: restrict file access and protect backups. See [credential setup](docs/REFERENCE.md#credential-setup) for migration and security details. Provider authentication for the child models is configured separately in Pi.
31
-
32
- **3. Configure your candidate models.**
33
-
34
- Add this block to `~/.pi/subagent.json`, preserving unrelated settings. Replace the example model ID with an exact `provider/model-id` available in your Pi installation and write your own model characteristics. Remove any legacy `modelPolicy` block; it is not migrated automatically.
35
-
36
- ```json
37
- {
38
- "jevRouting": {
39
- "selectorModel": "jev-latest",
40
- "apiKey": "<your-typesafe-api-key>",
41
- "timeoutMs": 15000,
42
- "models": [
43
- {
44
- "model": "<provider/model-id>",
45
- "description": "Describe this model's strengths and the tasks you want it to handle."
46
- }
47
- ]
48
- }
49
- }
50
- ```
51
-
52
- Replace the `apiKey` placeholder with your TypeSafe key and remove any old `apiKeyEnv` field. There is no environment fallback or automatic migration. Candidate descriptions may be written in Chinese. See the [configuration reference](docs/REFERENCE.md#configuration) for optional thinking defaults, profile defaults and limits.
53
-
54
- Jev selection can incur TypeSafe charges. It receives the delegated task text, model IDs/descriptions, candidate tool names/descriptions and required constraints. It does not automatically upload repository files or conversation history; text you include in the task can still disclose sensitive information. `action: "plan"` also calls Jev, and a later execution selects again.
55
-
56
- **4. Start Pi and delegate a read-only task.**
57
-
58
- Start Pi, or reload/restart it after switching extension code. Once `0.10.0` is loaded, each new dispatch re-reads the configuration; changing `apiKey` does not require a shell environment update.
12
+ ### Installation
59
13
 
60
14
  ```bash
61
- pi
62
- ```
63
-
64
- Ask the parent agent to use `subagent` with a request such as:
65
-
66
- ```json
67
- {
68
- "task": "Read README.md and summarize what this package does.",
69
- "description": "Summarize the README",
70
- "profile": "explore",
71
- "tools": ["read"],
72
- "max_turns": 4,
73
- "timeout_ms": 120000,
74
- "max_retries": 0
75
- }
15
+ pi install npm:@cr1ms0n/pi-subagent
76
16
  ```
77
17
 
78
- Omit `model` and `fallback_models`. Jev chooses from your configured model list and permitted tools; a routing failure stops the new dispatch without a fallback. Existing-run management remains available without a routing credential.
79
-
80
18
  ---
81
19
 
82
20
  <a id="delegation"></a>
83
- ### Delegation
84
-
85
- - **Model and tool routing:** this fork asks Jev to match each task to your model descriptions and select tools individually. Local permission checks and child startup verification enforce the result.
86
- - **Named agents and parallel work:** the upstream engine supports reusable personas and concurrent child processes. This fork routes each new child through Jev; agent files do not pin its model or tool selection.
87
- - **Background tasks:** the upstream engine supports status, interruptible waiting, cancellation and steering. The fork's display includes the selected model, with tool details in expanded results.
88
- - **Isolated edits:** the upstream worktree flow lets you inspect, apply or discard changes without sharing one writable checkout between parallel agents.
89
- - **Structured results and budgets:** the upstream engine validates structured output parent-side and preserves partial work. This fork keeps retries on the selected model/tool set and accounts for selector tokens separately.
21
+ ### Usage
90
22
 
91
- For a background task, set `async: true`, then collect it using `subagent_wait` or `action: "wait"`. Aborting or timing out a wait does not cancel the child. Use `action: "cancel"` to stop it. Open `/subagents` to inspect runs and `/subagent-cost` to see usage.
23
+ Before your first task, configure your TypeSafe API key and candidate models in `~/.pi/subagent.json`. See the [configuration example](docs/REFERENCE.md#jev-routing).
92
24
 
93
- The [reference](docs/REFERENCE.md#quick-usage) includes parallel work, synthesis, resume/fork, structured output, budgets and the worktree diff/apply/discard loop. The [TUI guide](docs/UX.md) describes the inspector and keyboard controls.
94
-
95
- ---
96
-
97
- <a id="permissions-and-costs"></a>
98
- ### Permissions and costs
99
-
100
- | Profile | Tool selection | Project-file writes |
101
- | --- | --- | --- |
102
- | `explore` | Jev-selected locally permitted read-only tools plus available Pi context controls | No |
103
- | `review` | Same read-only policy | No |
104
- | `general` | Jev-selected locally permitted tools plus available Pi context controls | Possible with selected write-capable tools |
105
-
106
- Single tasks default to `general`; parallel tasks default to `explore`. An explicit `tools` list is a ceiling. Available Pi context-management controls are added locally even with `tools: []`. An empty tool selection never means all tools.
107
-
108
- Profiles are tool-selection policy, not an OS sandbox. Children inherit the parent environment and can read files accessible to the same user, including the private config. Worktrees isolate the checkout only. Review the [security model](docs/SECURITY.md) before delegating untrusted work.
109
-
110
- The ledger separates root, subagent, routing and combined usage. TypeSafe reports routing tokens, not currency, so selector cost is **unreported**, not free. `max_cost` limits provider-reported child execution cost; it does not cap TypeSafe fees. See [cost accounting](docs/COST-ACCOUNTING.md) for delivery, retry and branch semantics.
111
-
112
- New extension-managed dispatch supports the Pi backend only. Native Codex/Claude requests are rejected. The [low-level SDK](docs/REFERENCE.md#using-the-runner-as-a-library) is a separate explicit-spec API: it does not automatically call Jev, and embedding code owns its model/tool choices.
113
-
114
- ---
25
+ Then ask Pi, for example:
115
26
 
116
- <a id="development"></a>
117
- ### Development
27
+ > Use a read-only subagent to review this project's directory structure and summarize the main modules.
118
28
 
119
- The source is a standalone TypeScript package with peer dependencies, no build step and no bundled test runner or typecheck script. Follow [development and verification](docs/DEVELOPMENT.md) for the checks this checkout supports. A syntax transform is not a semantic typecheck, and `npm pack --dry-run --ignore-scripts --json` verifies package contents without publishing.
29
+ Jev chooses the model and tools. Open `/subagents` to inspect tasks and `/subagent-cost` to view usage.
120
30
 
121
- The [architecture contract](docs/ARCHITECTURE.md) documents ownership and invariants. [Release maintenance](docs/RELEASING.md) covers selective source updates and the separate, explicitly authorized npm publication process.
31
+ See the [usage reference](docs/REFERENCE.md#quick-usage) for parallel tasks, background work, worktrees and structured results, or the [TUI guide](docs/UX.md) for keyboard controls.
122
32
 
123
33
  ---
124
34
 
package/README.zh-CN.md CHANGED
@@ -1,132 +1,42 @@
1
- [English](README.md) | [简体中文](README.zh-CN.md)
2
-
3
- # Pi Smart Subagents
4
-
5
- 在 [Pi](https://pi.dev/) 中运行独立子代理,由 Jev 为每项任务选择执行模型和具体工具。
6
-
7
- npm 包名为 `@cr1ms0n/pi-subagent`。本项目是 Luke Parke 的 `@parke.dev/pi-subagent` 0.8.0 的独立社区分支,上游来自 [LukasParke/pi-extensions](https://github.com/LukasParke/pi-extensions/tree/main/packages/pi-subagent),并非上游官方发行版。原始 MIT 许可证和版权声明均予以保留。
8
-
9
- 上游扩展提供子进程引擎、命名代理、后台任务、工作树和用量统计。本分支增加了强制 Jev 模型与工具选择,并在发送任务前核验子进程实际采用的模型和工具权限。
10
-
11
- ---
12
-
13
- <a id="quick-start"></a>
14
- ### 安装与快速开始
15
-
16
- 需要 Node.js 22.19.0 或更高版本,以及已安装、已配置可用模型提供方的 Pi CLI。Pi 0.86.0 是已验证的宿主基线,能够执行内置工具、扩展工具和延迟注册工具的允许列表。若宿主无法核验所选能力,扩展会拒绝启动,不会扩大工具权限。
17
-
18
- **1. 安装已发布的软件包。**
19
-
20
- 安装精确的 `0.10.0` 版本。较早的 `0.9.0` 使用旧的 `apiKeyEnv` 配置契约,不接受 `apiKey`:
21
-
22
- ```bash
23
- pi install npm:@cr1ms0n/pi-subagent@0.10.0
24
- ```
25
-
26
- Pi 会直接加载这个软件包。不要同时启用本扩展的其他副本或 `@parke.dev/pi-subagent`,它们会注册同名工具。本包提供 `subagent`、`subagent_wait`、`/subagents`、`/subagent-cost` 和 `/btw`。
27
-
28
- **2. 将 TypeSafe 凭据保存到私有配置。**
29
-
30
- 在用户级 `~/.pi/subagent.json` 中设置 `jevRouting.apiKey`,格式如下。如果从 `0.9.0` 升级,请在启动新任务前将 `jevRouting.apiKeyEnv` 中的现有值移到 `jevRouting.apiKey`,并删除旧字段。不要把密钥放进聊天或仓库文件。配置文件以明文保存密钥,需要限制文件访问权限并保护备份。迁移与安全说明见[凭据配置](docs/REFERENCE.md#credential-setup)。子模型所需的提供方认证需要另行在 Pi 中配置。
31
-
32
- **3. 配置候选模型。**
33
-
34
- 将下面的配置加入 `~/.pi/subagent.json`,保留其他已有设置。把示例模型 ID 替换为当前 Pi 中可用的精确 `provider/model-id`,并自行描述模型特点。如果存在旧的 `modelPolicy` 配置,需要将其移除;扩展不会自动迁移。
35
-
36
- ```json
37
- {
38
- "jevRouting": {
39
- "selectorModel": "jev-latest",
40
- "apiKey": "<your-typesafe-api-key>",
41
- "timeoutMs": 15000,
42
- "models": [
43
- {
44
- "model": "<provider/model-id>",
45
- "description": "Describe this model's strengths and the tasks you want it to handle."
46
- }
47
- ]
48
- }
49
- }
50
- ```
51
-
52
- 将 `apiKey` 占位符替换为自己的 TypeSafe 密钥,并移除旧的 `apiKeyEnv` 字段。扩展不会回退读取环境变量,也不会自动迁移。模型描述可以使用中文。可选的 thinking 默认值、profile 默认值和限制见[配置参考](docs/REFERENCE.md#configuration)。
53
-
54
- Jev 选择可能产生 TypeSafe 费用。它会接收委派任务文本、模型 ID 与描述、候选工具名称与描述,以及必要约束;不会自动上传仓库文件或对话历史,但任务中主动包含的文本仍可能泄露敏感信息。`action: "plan"` 同样会调用 Jev,之后实际执行时还会重新选择。
55
-
56
- **4. 启动 Pi,委派一个只读任务。**
57
-
58
- 启动 Pi;如果刚切换扩展代码,需要重新加载或重启。加载 `0.10.0` 后,每次新任务都会重新读取配置,修改 `apiKey` 不需要更新 shell 环境变量。
59
-
60
- ```bash
61
- pi
62
- ```
63
-
64
- 让主代理使用 `subagent`,例如传入下面的请求:
65
-
66
- ```json
67
- {
68
- "task": "Read README.md and summarize what this package does.",
69
- "description": "Summarize the README",
70
- "profile": "explore",
71
- "tools": ["read"],
72
- "max_turns": 4,
73
- "timeout_ms": 120000,
74
- "max_retries": 0
75
- }
76
- ```
77
-
78
- 不要传入 `model` 或 `fallback_models`。Jev 从配置的模型列表和允许的工具中进行选择;路由失败会阻止本次新任务启动,不会改用兜底方案。已有任务的管理操作不依赖路由凭据。
79
-
80
- ---
81
-
82
- <a id="delegation"></a>
83
- ### 任务委派
84
-
85
- - **模型与工具路由:**本分支让 Jev 根据任务和模型描述进行匹配,逐个选择工具;本地权限检查和子进程启动核验负责落实选择结果。
86
- - **命名代理与并行工作:**上游引擎支持可复用的代理角色和并发子进程。本分支为每个新子代理执行 Jev 路由,代理文件不能固定其模型或工具选择。
87
- - **后台任务:**上游引擎支持状态查询、可中断等待、取消和中途指导。本分支会显示所选模型,并在展开结果中展示工具详情。
88
- - **隔离修改:**上游工作树机制支持检查、应用或丢弃改动,避免并行代理共用同一个可写工作区。
89
- - **结构化结果与预算:**上游引擎在父进程中校验结构化输出,并保留部分工作成果。本分支始终使用已选定的模型和工具集进行重试,单独统计选择器 token。
90
-
91
- 后台任务设置 `async: true`,之后使用 `subagent_wait` 或 `action: "wait"` 收取结果。中断等待或等待超时不会取消子代理,需要停止任务时使用 `action: "cancel"`。通过 `/subagents` 检查任务,通过 `/subagent-cost` 查看用量。
92
-
93
- [使用参考](docs/REFERENCE.md#quick-usage)涵盖并行任务、结果汇总、恢复与分叉、结构化输出、预算,以及工作树的 diff/apply/discard 操作。[TUI 指南](docs/UX.md)介绍任务查看器和键盘操作。
94
-
95
- ---
96
-
97
- <a id="permissions-and-costs"></a>
98
- ### 权限与费用
99
-
100
- | Profile | 工具选择 | 修改项目文件 |
101
- | --- | --- | --- |
102
- | `explore` | Jev 选择的本地允许的只读工具,加上可用的 Pi 上下文控制工具 | 不允许 |
103
- | `review` | 与 explore 相同的只读策略 | 不允许 |
104
- | `general` | Jev 选择的本地允许的工具,加上可用的 Pi 上下文控制工具 | 选中可写工具时可以修改 |
105
-
106
- 单任务默认使用 `general`,并行任务默认使用 `explore`。显式传入的 `tools` 列表限定候选工具范围。即使传入 `tools: []`,本地仍会补充可用的 Pi 上下文管理工具。工具选择为空绝不表示允许所有工具。
107
-
108
- Profile 是工具选择策略,不是操作系统沙箱。子进程继承主进程环境,也能读取同一用户有权访问的文件,包括私有配置。工作树只隔离代码工作区。委派不可信任务前,请阅读[安全模型](docs/SECURITY.md)。
109
-
110
- 用量账本分别记录主代理、子代理、路由和合计用量。TypeSafe 只报告路由 token,不报告金额,因此选择器费用标记为**未报告**,不代表免费。`max_cost` 限制子代理执行时由提供方报告的费用,不限制 TypeSafe 费用。结果交付、重试和会话分支的统计规则见[费用统计](docs/COST-ACCOUNTING.md)。
111
-
112
- 扩展管理的新任务只支持 Pi 后端,原生 Codex/Claude 后端请求会被拒绝。[底层 SDK](docs/REFERENCE.md#using-the-runner-as-a-library)是另一套显式任务规格 API,不会自动调用 Jev,嵌入方需要自行负责模型和工具选择。
113
-
114
- ---
115
-
116
- <a id="development"></a>
117
- ### 开发
118
-
119
- 源码是使用 peer dependencies 的独立 TypeScript 包,没有构建步骤,也没有随仓库提供的测试运行器或类型检查脚本。本仓库支持的检查方式见[开发与验证](docs/DEVELOPMENT.md)。语法转换不等于语义类型检查;`npm pack --dry-run --ignore-scripts --json` 用于检查打包内容,不会发布包。
120
-
121
- [架构约定](docs/ARCHITECTURE.md)记录模块职责和不变量。[发布维护](docs/RELEASING.md)说明如何选择性更新源码,以及需要单独明确授权的 npm 发布流程。
122
-
123
- ---
124
-
125
- <a id="license"></a>
126
- ### 许可证
127
-
128
- [MIT](LICENSE)。Copyright (c) 2026 Luke Parke。社区分支由 cr1ms0n(awoaCrim)维护。重新分发时请保留原始版权声明和许可证。
129
-
130
- 译自 [README.md](README.md),英文文件 blob:`02294faabd946a50be23551e43e694451628bc39`。中英文内容如有差异,以英文为准。
131
-
132
- 感谢 [Linux.do](https://linux.do/)。
1
+ # Pi Smart Subagents
2
+
3
+ [English](README.md) | [简体中文](README.zh-CN.md)
4
+
5
+ 在 [Pi](https://pi.dev/) 中运行独立子代理,由 Jev 为每项任务选择模型和工具。
6
+
7
+ 本项目是 Luke Parke 的 `@parke.dev/pi-subagent` 的独立社区分支,上游来自 [LukasParke/pi-extensions](https://github.com/LukasParke/pi-extensions/tree/main/packages/pi-subagent)。保留上游的命名代理、并行与后台任务、工作树和用量统计,增加 Jev 路由与子代理能力核验。
8
+
9
+ ---
10
+
11
+ <a id="quick-start"></a>
12
+ ### 安装
13
+
14
+ ```bash
15
+ pi install npm:@cr1ms0n/pi-subagent
16
+ ```
17
+
18
+ ---
19
+
20
+ <a id="delegation"></a>
21
+ ### 使用
22
+
23
+ 首次使用前,在 `~/.pi/subagent.json` 中配置 TypeSafe API key 和候选模型,见[配置示例](docs/REFERENCE.md#jev-routing)。
24
+
25
+ 然后直接对 Pi 说,例如:
26
+
27
+ > 用只读子代理查看这个项目的目录结构,并总结主要模块。
28
+
29
+ Jev 会选择模型和工具。使用 `/subagents` 查看任务,使用 `/subagent-cost` 查看用量。
30
+
31
+ 并行任务、后台执行、工作树和结构化结果见[使用参考](docs/REFERENCE.md#quick-usage),键盘操作见 [TUI 指南](docs/UX.md)。
32
+
33
+ ---
34
+
35
+ <a id="license"></a>
36
+ ### 许可证
37
+
38
+ [MIT](LICENSE)。Copyright (c) 2026 Luke Parke。社区分支由 cr1ms0n(awoaCrim)维护。重新分发时请保留原始版权声明和许可证。
39
+
40
+ 译自 [README.md](README.md),英文文件 blob:`f55b496dc010bd4242e6f6ffc8c987425ee9d7f4`。中英文内容如有差异,以英文为准。
41
+
42
+ 感谢 [Linux.do](https://linux.do/)。
@@ -12,10 +12,7 @@
12
12
  after a second window so retry can take over. Group kills verify process start-time
13
13
  identity (Linux `/proc`, macOS/BSD `ps lstart`) before signalling a possibly-recycled
14
14
  PID; transcript joins happen only on message boundaries, not per-chunk ticks.
15
- - Retry lives in `orchestrator.ts` (`isTransientFailure`): queue timeouts, stalls, spawn
16
- errors, and provider errors re-run the same already-selected spec (model and tool set)
17
- with accumulated usage; there is no fallback-model escalation, and task-quality failures
18
- never retry.
15
+ - Retry lives in [orchestrator.ts](../src/orchestrator.ts). Ranked extension tasks advance through a locally finalized Jev candidate plan only for recognized settled availability failures before any current-invocation tool starts. [model-failover.ts](../src/model-failover.ts) owns conservative evidence classification and bounded attempt helpers. Tools stay fixed, thinking resolves per candidate, and usage accumulates once. Unknown execution evidence blocks restart. The trusted unranked SDK retains its separate `isTransientFailure` and explicit fallback contract.
19
16
  - `context: "fork"` spawns the child with `--fork <parent session file>` so it starts
20
17
  from a real branched copy of the parent conversation. Fail-fast when the parent
21
18
  session is not persisted; single-task only.
@@ -24,7 +21,7 @@
24
21
  - `semaphore.ts`: per-parent-runtime child-process limit.
25
22
  - `process-lock.ts`: machine-wide durable coordination under `~/.pi/subagent-locks/` —
26
23
  exclusive per-child-session resume locks, global concurrency slots, and run process
27
- identity records for orphan reconcile.
24
+ identity records for orphan reconcile. Ranked tasks keep one record running across attempts and final artifact/worktree work; the orchestrator terminalizes it once. A bounded list of attempt sessions protects earlier transcripts from other parents' maintenance while the task is live.
28
25
  - `launch.ts`: resolve the child `pi` invocation via `PI_SUBAGENT_BIN` or
29
26
  `process.execPath` + CLI entry (bare PATH name only as last-resort fallback).
30
27
  - `persistence.ts`: versioned active-branch event folding, the bounded routing-event decoder
@@ -38,14 +35,12 @@
38
35
  shapes and local resource limits; `routing-policy.ts` owns the strict `jevRouting`
39
36
  parser, the candidate intersection with locally available models, and the injected
40
37
  model-facing guidance; `jev-router.ts` owns the injectable TypeSafe transport,
41
- response validation, deadlines and per-request receipts; `dispatch-routing.ts`
42
- resolves every worker before any launch and refuses a partially selected fanout. The
43
- router has no engine imports and makes no parent UI calls.
38
+ response validation, deadlines and per-request receipts, including a validated full probability ranking and model-independent task tool decisions; `dispatch-routing.ts` resolves every worker before any launch and refuses a partially selected fanout. Local policy finalizes a frozen candidate attempt plan with per-model thinking and one shared tool set. The router has no engine imports and makes no parent UI calls.
44
39
  - `config.ts`: defaults ← `~/.pi/subagent.json` ← `PI_SUBAGENT_*` env overrides.
45
40
  - `structured.ts`: structured-output contract (dependency-free JSON-Schema subset
46
41
  validation, fenced json:result extraction, contract/repair prompts) and
47
42
  conservative double-encoded-arg repair. The runner gates the child's settle on
48
- validation and runs one steer-based repair round before accepting failure.
43
+ validation and runs one steer-based repair round after an otherwise successful invalid answer. Ranked provider-error/aborted attempts skip repair and cannot publish structuredOutput from failed text. The latest completed assistant text replaces earlier text even when empty, so a host retry cannot reuse the failed turn's JSON.
49
44
  - `agents.ts`: named agent files (`.pi/agents/`, `.agents/agents/`, global agent dir).
50
45
  Flat-YAML frontmatter + markdown persona body; resolved in policy with explicit
51
46
  params > agent file > profile taskDefaults > parent inheritance. Catalog refreshes
@@ -80,7 +75,7 @@ Invariants:
80
75
  Selector usage is a separate category folded once per selector request ID, with currency
81
76
  reported as unreported rather than inferred.
82
77
  11. Checkpoint persistence events are lightweight (state, usage, process identity, pointers).
83
- Full transcripts and final output are persisted exactly once, in the terminal event.
78
+ Full transcripts and final output are persisted exactly once, in the terminal event. Ranked attempt histories carry bounded metadata/session pointers at checkpoints, with output previews only in terminal projections (1 KiB per preview, 16 KiB total). Active-branch retention includes earlier attempt session references.
84
79
  12. High-frequency registry "changed" events coalesce (trailing window); state transitions,
85
80
  new child sessions, billed-usage advances, and terminal events flush immediately.
86
81
  13. `wait` is interruptible: aborting a wait returns promptly and does NOT cancel the
@@ -108,18 +103,14 @@ Invariants:
108
103
  20. Budget breaches (`max_turns`/`max_cost`) steer a wrap-up message and allow grace
109
104
  turns before SIGTERM; a child that concludes within grace ends `partial` with
110
105
  `wrappedUp: true`. `graceTurns: 0` restores immediate stops.
111
- 21. Transient failures (queued timeout, stall, spawn error, provider error, protocol
112
- truncation) retry up to `maxRetries` extra attempts on the already selected model and
113
- tool set; there is no fallback-model escalation and no reselection. Usage accumulates
114
- across attempts. Task-quality failures (nonzero exit with complete protocol,
115
- cancellation, budget stop, running timeout) never retry.
106
+ 21. Extension-managed ranked tasks permit at most `maxRetries` extra child attempts, locally capped at 255 total launches. A recognized settled availability failure advances to the next candidate only with conclusive no-tool activity; started or unknown activity blocks all new-child restart. Candidate exhaustion never wraps to the primary. Conclusively pre-work infrastructure retry may repeat the same candidate within the same budget. No retry calls Jev or broadens tools. Usage and budget comparisons include prior attempts. Authentication, quota/billing, invalid requests, context limits, task-quality, cancellation, task-deadline and budget stops do not cause model failover. The trusted unranked SDK keeps its legacy transient/explicit-fallback behavior.
116
107
  22. The stall watchdog treats protocol silence as suspect, not fatal: after
117
108
  `stallAfterMs` the task is flagged and probed via `get_state` (a live child's
118
109
  answer clears the flag); only continued silence for `stallKillAfterMs` more kills
119
- the child which is then a transient failure eligible for retry.
110
+ the child. A stall does not authorize restart on the ranked path: silence cannot establish that no work began.
120
111
  23. Only `async: true` runs notify on completion and appear in the ambient widget.
121
112
  Notification delivery respects delivered-once: a `wait` that consumed the run
122
- suppresses the notification.
113
+ suppresses the notification. The actual final model and a bounded attempt-chain tail with its total count use the same display projection as compact results.
123
114
  24. Named agent files supply per-field defaults only; explicit request params always
124
115
  win, and capability profiles fail closed regardless of what an agent file declares.
125
116
  25. Structured-output validation never discards paid work: schema failure after the
@@ -137,11 +128,9 @@ Invariants:
137
128
  local preflights of a real spawn and returns the resolved plan and its selector usage
138
129
  without spawning. It creates no registry entry, and its fee-bearing selection is not
139
130
  cached for a later dispatch.
140
- 29. Every new extension-managed launch (`task`/`tasks[]`, `action:"plan"`, `/btw`,
131
+ 29. Every new extension-managed invocation (`task`/`tasks[]`, `action:"plan"`, `/btw`,
141
132
  resume, fork, nested dispatch and the optional synthesis child) crosses one selector
142
- interface before any child starts. The dedicated candidate list intersected with
143
- locally available models is the only source of execution models; the full locally
144
- permitted tool catalog is the only candidate source. Legacy `model`/`fallback_models`
133
+ interface before any child starts. The dedicated candidate list intersected with locally available models is the only source of execution models. One validated full probability ranking belongs to the invocation, and fallback reuses it without another selection. The original selectedModel/confidence remain immutable; result.model reports the actual attempt. The full locally permitted tool catalog is the only tool candidate source, and one model-independent selection is shared by every attempt. Legacy `model`/`fallback_models`
145
134
  fields are rejected on new work, and an empty selected tool set never becomes
146
135
  inheritance or "all tools".
147
136
  30. The finalized tool subset is passed to the child as Pi's `--tools` allowlist
@@ -154,13 +143,12 @@ Invariants:
154
143
  the nonce-specific bootstrap command exists from the expected package source, then
155
144
  requires the child to acknowledge the exact selected model and finalized tool names
156
145
  (including nested-tool source) before the real task prompt is sent. Missing or
157
- mismatched acknowledgement is a capability/startup diagnostic, never compensated by
158
- broadening tools or choosing another model.
146
+ mismatched acknowledgement is a capability/startup diagnostic, never compensated by broadening tools or choosing another model. Every ranked replacement gets its own exact-model/shared-tools acknowledgement before the task prompt.
159
147
  31. An absolute task deadline is created before preflight/selection, and routing, setup,
160
148
  queue and retries all count against it. Pending selector work is tracked per session
161
149
  runtime, aborted on cancellation, shutdown or session switch, and every post-await
162
150
  transition re-checks captured runtime/session ownership so a late response cannot
163
- launch into a replaced session.
151
+ launch into a replaced session. Replacement attempts await prior child cleanup, retain run/worktree/resume ownership and recheck cancellation, deadline and cumulative task budgets before launch. Durable task records remain running during replacement and finalization, protecting all known attempt sessions and the worktree across parent processes; only child slots are released per attempt. Pi/provider internal retries and global retry settings remain unchanged.
164
152
  32. Before any paid selection, plan and dispatch share a side-effect-free direct-resume
165
153
  availability check (in-memory owner, `resumeBlocked`, durable lock ownership and
166
154
  staleness) that acquires, renews or reaps nothing. Dispatch still takes the
@@ -44,9 +44,7 @@ own record, and all of them count once by full request ID. Plan selections and
44
44
  pre-spawn failures are included, because no child run exists to carry them.
45
45
 
46
46
  Successful route metadata (decision ID, selector model and reported version(s),
47
- selected execution model/tools, locally added control-plane tools, confidence,
48
- success outcome, latency and receipt IDs) travels with the run and both registry
49
- projections. Per-request failure outcomes and safe error codes stay in selector receipts. It carries no descriptions, raw request bodies, headers,
47
+ original selected model, ranked candidate probabilities, shared selected tools, locally added control-plane tools, confidence, success outcome, latency and receipt IDs) travels with the run and both registry projections. Actual attempt models are recorded separately; fallback never rewrites the initial selection as a new decision. Per-request failure outcomes and safe error codes stay in selector receipts. It carries no descriptions, raw request bodies, headers,
50
48
  credentials or invented rationale.
51
49
 
52
50
  Receipts pending append visibility remain in a bounded session-local overlay until the
@@ -79,10 +77,7 @@ Because the native footer counts parent assistant messages plus delivered tool-r
79
77
  4. If an old run is evicted from in-memory UI history, its latest persisted usage still contributes to the session ledger.
80
78
  5. Active and immediately completed runs supplement or replace stale persisted checkpoints until newer session entries become visible; the full run UUID prevents double counting afterward.
81
79
  6. Resumed and forked invocations are distinct billed runs. Their new provider usage is counted once, even though they reuse prior context.
82
- 7. Retry attempts (transient-failure retries on the already selected model and tool set)
83
- accumulate into their run's single usage record: every attempt's billed usage counts once
84
- under one run UUID. There is no fallback-model escalation, so `attemptedModels` repeats the
85
- selected model rather than recording a route change.
80
+ 7. Ranked failover and permitted same-model pre-work retries accumulate into one run usage record. Every attempt's provider-reported usage counts once under the same run UUID; attempted-model metadata is descriptive, not another ledger input. Advancing to a ranked candidate makes no additional selector request and creates no new receipt. The initial selector decision remains distinct from the actual execution model.
86
81
  8. The optional parallel `synthesis` child bills into the same run as an extra result.
87
82
  9. Selector requests are counted once by full selector request ID, including plan
88
83
  requests and pre-spawn rejected decisions. Route references inside task results
@@ -106,6 +101,10 @@ Only `sessionManager.getBranch()` is used. Costs from abandoned sibling branches
106
101
 
107
102
  Any usage reported before a failure, timeout, budget stop, cancellation, or parent crash is retained in a cumulative checkpoint/terminal record. A run with no provider response contributes zero rather than an estimate.
108
103
 
104
+ All ranked attempts share the absolute task deadline and cumulative `max_cost`/`max_turns` budget. Prior usage is an offset for the next child's budget comparisons, not part of that child's returned usage, so aggregation adds each attempt only once. A replacement cannot start after reported cost or turns meets its ceiling. In-attempt completed-turn checks and wrap-up grace remain unchanged. Pi's internal provider retries are not counted as separately launched extension attempts.
105
+
106
+ When every attempt fails, earlier output previews retain their originating model/session and the final task remains failed. Preserving billed work does not convert failure into `partial` or success. The existing native undercount for thrown failures still applies; the extension ledger retains all reported attempt usage.
107
+
109
108
  ## Provider limitations
110
109
 
111
110
  Accounting is only as precise as the provider data normalized by Pi:
package/docs/REFERENCE.md CHANGED
@@ -6,7 +6,7 @@ Return to the [English README](../README.md) or [Chinese README](../README.zh-CN
6
6
 
7
7
  ### Credential setup
8
8
 
9
- Version `0.10.0` reads the TypeSafe key from `jevRouting.apiKey` in your private, user-level `~/.pi/subagent.json`. Set the key locally using an editor, preserve unrelated configuration and replace the placeholder in the [routing example](#jev-routing). Do not paste the key into chat, shell commands, source control or task descriptions.
9
+ Version `0.10.0` and later read the TypeSafe key from `jevRouting.apiKey` in your private, user-level `~/.pi/subagent.json`. Set the key locally using an editor, preserve unrelated configuration and replace the placeholder in the [routing example](#jev-routing). Do not paste the key into chat, shell commands, source control or task descriptions.
10
10
 
11
11
  This file stores the credential in plaintext. Restrict access to your user account and protect editor backups and synchronized copies. Same-user processes, including children with filesystem access, may read it; neither profiles nor worktrees provide an OS sandbox. See [SECURITY](SECURITY.md#routing-disclosure-and-credentials).
12
12
 
@@ -105,7 +105,7 @@ A plan runs local preflights and Jev selection without spawning a child or creat
105
105
 
106
106
  #### Structured output
107
107
 
108
- The child must produce a fenced `json:result` block matching the requested schema. The parent validates it and allows one repair round. An unresolved schema failure preserves raw output as a partial result rather than discarding paid work.
108
+ The child must produce a fenced `json:result` block matching the requested schema. After an otherwise successful answer, the parent validates it and allows one repair round. An unresolved schema failure preserves raw output as a partial result rather than discarding paid work. A terminal provider failure does not trigger a repair prompt or publish a structured result, even if its text contains valid JSON; it follows the availability-failure rules instead.
109
109
 
110
110
  ```json
111
111
  {
@@ -144,7 +144,9 @@ Both operations select again. To guide an existing child instead, steer it; para
144
144
 
145
145
  #### Budgets and retries
146
146
 
147
- A budget breach requests a final answer and allows the configured grace turns. Transient failures retry the already selected model and tool set; they never trigger reselection or fallback models.
147
+ A budget breach requests a final answer and allows the configured grace turns. Before any tool starts, a recognized model-availability failure can advance to the next candidate in Jev probability order. All attempts share the selected tools, task deadline and cumulative execution budgets. Switching does not call Jev again.
148
+
149
+ `max_retries` is the total number of extra child attempts: `0` permits the initial attempt only, `1` permits at most two attempts, and `2` permits at most three. The built-in default is `1`; task, agent, profile and configuration overrides still apply. The list never wraps back to an earlier candidate. Pi's own in-process/provider retries are separate and unchanged, so a child can make multiple provider requests before the extension sees its final failure. See [ranked failover](#probability-ranked-failover) for the failure boundary.
148
150
 
149
151
  ```json
150
152
  { "task": "Audit dependencies.", "profile": "review", "max_turns": 15, "grace_turns": 2, "max_retries": 1 }
@@ -319,6 +321,22 @@ The extension re-reads `jevRouting` on each dispatch and injects non-secret rout
319
321
 
320
322
  The mandatory routing above is the Extension dispatch contract. The stable SDK exports (`runTasks` and `runSubagent`) are trusted low-level library APIs: they execute the explicit `TaskSpec` you pass and perform no implicit routing, config discovery or network call. Library callers own model and tool choice, and must not read these SDK calls as Jev enforcement.
321
323
 
324
+ #### Probability-ranked failover
325
+
326
+ Version `0.11.0` adds this behavior. Published `0.10.0` retries the selected model rather than advancing through the ranked candidates.
327
+
328
+ TypeSafe's Choice response includes a probability for every eligible option. The extension retains that distribution and tries higher-probability candidates first. These values express the selector's preference, not measured model uptime or success rates. The separate `confidence` value belongs to the original answer. A tied maximum keeps Jev's returned choice first; other ties follow configured candidate order. Low or zero probability is not a new exclusion threshold.
329
+
330
+ Jev selects one task-based tool subset, independent of the first execution model, for every attempt. The initial logical selection may use several HTTP batches; failover adds none. Each candidate still gets its own thinking default under the existing precedence and fresh exact-model/tool startup verification. An attestation mismatch stops the task instead of trying a broader capability set.
331
+
332
+ Switching requires a settled provider error and conclusive evidence that no tool execution has begun in this invocation. Recognized cases include an explicitly unavailable model, temporary throttling, service overload and identifiable transport failures. Authentication/configuration errors, quota or billing exhaustion, invalid requests, context limits, refusals, poor answers, schema failures, cancellation and exhausted budgets do not trigger a model switch. Recognition uses only the latest completed assistant error's bounded message and documented primitive `diagnostics.error.code`, never ordinary answer text or arbitrary diagnostic details. Authentication, quota and other excluded evidence take precedence over an availability code. Unfamiliar error formats stop conservatively. A tool-start event blocks restart even when no result arrived; missing or malformed protocol evidence is not permission to retry. Historical tool messages in a resumed or forked session are not new execution.
333
+
334
+ For an eligible failure, the next allowed extension attempt advances immediately to the next candidate; it does not first add a same-model retry. Conclusively pre-work local process failures can retry the same candidate under the same total attempt budget. Attempts also have a local resource ceiling of 255 launches, including infrastructure retries. Expired task deadlines, uncertainty after startup and stalls cannot be used to restart work that may have begun. Pi's internal retries remain enabled or disabled according to your existing Pi settings, which this extension does not change.
335
+
336
+ Plan and status distinguish the original selector choice from the actual execution model. Results retain bounded attempt metadata, failure categories, output previews and child-session pointers; previews are attributed to the attempt that produced them. A later successful structured answer is not concatenated with failed JSON. If Pi retries within the same child, an empty latest answer stays empty; it never reuses text or JSON from the failed turn. If all attempts fail, the final failure/model/session remain authoritative. Earlier output remains available while its session is referenced on the active branch. Usage accumulates under the same run, without duplicating selector receipts; existing native-accounting limitations for thrown failures still apply.
337
+
338
+ A selector timeout or invalid response still stops dispatch. Failover uses only the validated ranking from that invocation, never an emergency model or a new selection. New invocations, including resume/fork and synthesis, select afresh. Trusted SDK specs without a ranked route retain their existing explicit fallback behavior.
339
+
322
340
  #### Named agent files
323
341
 
324
342
  Define reusable subagent personas as markdown files, discovered from the same conventional roots skills use (higher root wins name conflicts):
@@ -364,10 +382,10 @@ Notes on behavior:
364
382
 
365
383
  - `timeout_ms` is the absolute task deadline: local preflight, Jev selection, setup, queue time and runtime all count against it, and selection cannot reset it. Timed-out tasks report `state: "timeout"` with `timeoutPhase: "queued"|"starting"|"running"` so agents can retry capacity issues without confusing them for task failures.
366
384
  - Budget stops (`max_turns`, `max_cost`) trigger a **graceful wrap-up**: the child is steered to produce its final answer NOW and allowed `graceTurns` more turns before SIGTERM. Results end as `partial` with `wrappedUp: true` when the child concluded in time. `graceTurns: 0` restores immediate stops.
367
- - A **stall watchdog** flags children with no protocol activity for `stallAfterMs` (a liveness probe distinguishes quiet-but-thinking from dead), then kills after `stallKillAfterMs` more silence; feeding automatic retry instead of burning the whole timeout.
368
- - **Transient failures retry automatically** (queue timeouts, stalls, spawn errors, provider errors) up to `maxRetries` extra attempts on the already selected model and tool set. There are no emergency or fallback models, and a quality or budget failure never reselects. Usage accumulates across attempts; results record `attempts`. Task-quality failures (nonzero exit with complete protocol, cancellations, budget stops, running timeouts) never retry.
385
+ - A **stall watchdog** flags children with no protocol activity for `stallAfterMs` (a liveness probe distinguishes quiet-but-thinking from dead), then kills after `stallKillAfterMs` more silence. A stall is not proof that no tool ran and does not authorize ranked failover.
386
+ - **Ranked failover** follows the [availability and pre-tool rules](#probability-ranked-failover), bounded by total `maxRetries`, candidate exhaustion, cumulative budgets and the original deadline. A selector failure has no emergency fallback. Task-quality, cancellation and budget failures never trigger model reselection.
369
387
  - `context: "fork"` starts a single child from a real branched copy of the parent conversation (`--fork` on the parent's session file). It requires a persisted parent session, cannot combine with `resume`, and is rejected for parallel fanout (context duplication × N is a cost bug, not a feature).
370
- - **Structured output** (`output_schema`): the contract is appended to the child's system prompt; the final message must end with a fenced `json:result` block. Validation runs parent-side against a dependency-free JSON-Schema subset (type/properties/required/items/enum/const; unknown keywords are ignored, never rejected). Invalid output triggers **one steer-based repair round**; still-invalid results end `partial` with `structuredError` set and the raw text delivered; paid work is never discarded. Validated parallel results feed the `synthesis` child as clean JSON instead of prose.
388
+ - **Structured output** (`output_schema`): the contract is appended to the child's system prompt; the final message must end with a fenced `json:result` block. Validation runs parent-side against a dependency-free JSON-Schema subset (type/properties/required/items/enum/const; unknown keywords are ignored, never rejected). An otherwise successful but invalid answer gets **one steer-based repair round**; still-invalid results end `partial` with `structuredError` and raw text retained. Failed provider attempts neither repair nor publish structured output. Validated successful parallel results feed the `synthesis` child as clean JSON instead of prose.
371
389
  - **Arg repair**: double-encoded task text (literal `\n` / `\"` escapes from LLM re-encoding) is conservatively de-mangled once at validation time. Identifier fields and paths are never touched. Protocol streams truncated after useful assistant output also end as `partial`.
372
390
  - Aborting a `wait` returns immediately without cancelling the background run.
373
391
  - Child processes are launched via the same Node runtime + CLI entry as the parent when possible (`PI_SUBAGENT_BIN` overrides). Bare `pi` on PATH is only a logged last resort.
@@ -427,7 +445,7 @@ The Pi extension entry is unchanged: package `pi.extensions` still points at `./
427
445
 
428
446
  `status`, `/subagent-cost`, and the `/subagents` overlay header show separate **root**, **subagent**, **routing**, and **combined** totals based on provider-reported usage. On Pi builds after v0.80.10, delivered runs also report their total usage natively on the tool result ([pi#6671](https://github.com/earendil-works/pi/pull/6671)), so Pi's own footer, `/session`, and RPC totals include subagent spend exactly once per run. Older Pi hosts ignore the field. Nested usage reported by a child's tool results (e.g. grandchild subagents) folds into the run's totals and budgets. The extension footer stays terse (running/ready counts only). Delivery and replay do not double count runs. See [docs/COST-ACCOUNTING.md](COST-ACCOUNTING.md).
429
447
 
430
- Jev selection is billed separately from execution. TypeSafe reports tokens, not currency, so the ledger shows routing tokens as their own category, counts each selector request once by its request ID (including plan and pre-spawn failures), and marks routing cost as **unreported** rather than free. Numeric dollar totals exclude unreported routing spend, and `max_cost` caps provider-reported execution cost only; it does not cap TypeSafe charges. Route metadata (selected model, selected tools, locally added controls, selector version, confidence, outcome, latency) travels with the run alongside usage.
448
+ Jev selection is billed separately from execution. TypeSafe reports tokens, not currency, so the ledger shows routing tokens as their own category, counts each selector request once by its request ID (including plan and pre-spawn failures), and marks routing cost as **unreported** rather than free. Numeric dollar totals exclude unreported routing spend, and `max_cost` caps provider-reported execution cost only; it does not cap TypeSafe charges. Route metadata (original selected model, ranked probabilities, selected tools, locally added controls, selector version, confidence, outcome, latency) travels with the run alongside usage. Actual attempt models are recorded separately; advancing through the ranking does not create another selector receipt.
431
449
 
432
450
  ---
433
451
 
package/docs/UX.md CHANGED
@@ -41,14 +41,9 @@ The standalone pi-subagent provides rich TUI support for monitoring, inspecting,
41
41
  per-task stats, and a one-line tail (live activity or first output line).
42
42
  - Expanded (Ctrl+O / `app.tools.expand`): full task output capped with a dim
43
43
  `… +N lines` trailer pointing at the artifact/child session.
44
- - Expanded detail adds one bounded route line for Jev-routed runs: selected
45
- execution model, selected tools (plus locally added control-plane tools),
46
- selector version, confidence, outcome and selection latency. Legacy runs
47
- simply have no route line.
44
+ - Expanded detail adds a bounded route summary for Jev-routed runs: original selection, ranked probabilities, shared selected tools (plus locally added control-plane tools), selector version, answer-level confidence, outcome and selection latency. The actual execution model stays separate from the original choice. Large lists show a preview and total count; old runs without new fields remain readable. Compact results and completion notifications show at most the last five attempt models and label a shortened chain with its total attempt count.
48
45
  - Durations freeze at `endedAt`; running durations tick at render time.
49
- - Reliability annotations render inline: `[attempt 2]` during a same-model
50
- retry, `[stalled 2m]` while the stall watchdog is flagging silence, and
51
- `◐ wrapped up` on budget-stopped runs that concluded gracefully.
46
+ - Reliability annotations render inline: `[attempt 2]` during retry/failover, the actual attempt model and bounded attempt chain, `[stalled 2m]` while the stall watchdog is flagging silence, and `◐ wrapped up` on budget-stopped runs that concluded gracefully. Availability failures can switch models only before tools begin; a stalled indicator is not a promise of another attempt.
52
47
 
53
48
  ### Footer status
54
49
  Terse and actionable only: `⚙ 2 running · 1 ready · /subagents`. Cleared when
@@ -80,6 +75,7 @@ text with run ids and a `wait { id }` pointer.
80
75
  failures bypass batching and flush immediately, carrying held successes.
81
76
  - A `wait` that already delivered the run suppresses the redundant
82
77
  notification (delivered-state is re-checked at flush time).
78
+ - Model/attempt annotations use the actual execution history, not the immutable original Jev choice. Fallback creates no extra completion notification or delivery path.
83
79
 
84
80
  ### `/subagents` overlay
85
81
  - Header: title + running/ready counters + full usage ledger + rule.
@@ -129,11 +125,11 @@ usage and a bounded `Optional synthesis blocked: …` diagnostic instead of
129
125
  discarding or re-routing them.
130
126
 
131
127
  ### Plan results (tool output, not TUI)
132
- `action:"plan"` returns the resolved model/tools and the selector usage it
133
- incurred, and states that a later dispatch selects again. It starts no child and
134
- creates no run entry, so plan never adds an overlay row or ambient widget. A
135
- plan whose optional synthesis selection fails still returns the valid worker plan
136
- and labels only that synthetic stage blocked with its diagnostic.
128
+ `action:"plan"` returns the initial model, a bounded probability-ranked candidate preview, common tools, effective total attempt limit and selector usage. Probabilities are selector preferences, not uptime estimates, and `confidence` belongs to the original answer. A plan reports no actual attempts; a later invocation selects again. It starts no child and creates no run entry, so plan never adds an overlay row or ambient widget. A plan whose optional synthesis selection fails still returns the valid worker plan and labels only that stage blocked with its diagnostic.
129
+
130
+ ### Failed-attempt output
131
+
132
+ Earlier attempts retain bounded, attributed output previews and child-session pointers. If all attempts fail, the final state, failure reason, model and session stay authoritative; earlier text does not become that model's answer or a successful structured result. A human-readable earlier preview names its source attempt. Successful final JSON is never concatenated with failed JSON. Full output remains in existing child sessions, which are retained while referenced on the active branch. Compact views remain within their existing output limits.
137
133
 
138
134
  ## States
139
135
  - **Queued/Running**: spinner + live stats + activity tail from live text.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cr1ms0n/pi-subagent",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Community fork of Luke Parke's pi-subagent with Jev model/tool routing and verified Pi child capabilities",
5
5
  "type": "module",
6
6
  "license": "MIT",