@ferris1225/pi-subagents 2.0.1 → 2.0.2

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/README.md CHANGED
@@ -88,9 +88,10 @@ index.
88
88
  - **Direct fallback with real thinking capabilities** — each agent has at most
89
89
  one selected model. An unavailable selection, rate limit, invalid key, quota,
90
90
  missing model, or provider failure hands directly to the current main model.
91
- A child-only provider adapter forces request retries to zero, and the RPC
92
- parent cancels Pi's outer turn retry before another call, without changing user
93
- settings. Auto thinking clamps the agent preference to the
91
+ A child-only provider adapter forces inner request retries to zero; transient
92
+ stream drops still use Pi's outer turn retry, and only a settled model-level
93
+ failure hands off, without changing user settings. Auto thinking clamps the
94
+ agent preference to the
94
95
  effective model's real `thinkingLevelMap`; manual setup shows only levels that
95
96
  model supports.
96
97
  - **Resumes, retargets, and forks preserve context** — every run is session-backed.
@@ -331,12 +332,13 @@ available catalog is skipped. Any model-level runtime failure — rate limit,
331
332
  quota, invalid key/auth, missing model, provider error, or idle model stream —
332
333
  hands directly to current main, including stream errors that retain partial text.
333
334
  A child-only Pi extension wraps the selected provider's registered API stream
334
- with `maxRetries: 0`; if Pi schedules its separate outer turn retry, the RPC parent
335
- immediately sends `abort_retry` before another provider call. This uses supported
336
- extension/RPC surfaces in Node and standalone/Bun builds, never rewrites global or
337
- project settings, and does not alter descendant tool environments. Tool/test
338
- failures stay on the same model because they are task failures, not model
339
- availability failures. Only a truly
335
+ with `maxRetries: 0` so a deterministic auth/quota miss fails fast. Transient
336
+ stream drops such as xAI `terminated` still use Pi's outer turn retry — the
337
+ parent does not `abort_retry` them — and only a settled model-level failure
338
+ hands off to current main. This uses supported extension/RPC surfaces in Node
339
+ and standalone/Bun builds, never rewrites global or project settings, and does
340
+ not alter descendant tool environments. Tool/test failures stay on the same
341
+ model because they are task failures, not model availability failures. Only a truly
340
342
  zero-activity process startup race can retry; an accepted prompt or any
341
343
  agent/turn/stream/tool activity forbids replay.
342
344
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ferris1225/pi-subagents",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Controllable background sub-agent threads for pi: specialized roles, capability-aware thinking, direct main-model fallback, auto-fix chains, and Git worktree isolation.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/dispatch.ts CHANGED
@@ -1483,7 +1483,8 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
1483
1483
  triggerTurn: completionTriggersTurn(result, runConfig.notifyOnReviewPass),
1484
1484
  };
1485
1485
  if (modelLevel) {
1486
- runCtx.ui.notify(`✗ ${result.agent} dispatch failed: model unavailable or broken — task handed to the main window`, "error");
1486
+ const detail = result.errorMessage?.trim() || "model unavailable or broken";
1487
+ runCtx.ui.notify(`✗ ${result.agent} dispatch failed: ${detail} — task handed to the main window`, "error");
1487
1488
  } else if (dispatchFailed) {
1488
1489
  runCtx.ui.notify(`✗ ${result.agent} dispatch failed: ${result.errorMessage ?? "dispatch crashed"}`, "error");
1489
1490
  }
package/src/format.ts CHANGED
@@ -155,11 +155,15 @@ export function formatCompletionBlock(
155
155
  * fresh (which would re-scan everything). */
156
156
  export function modelLevelTakeoverNote(result: SingleResult, opts?: { runId?: number }): string {
157
157
  const retry = result.modelFallbackFrom ? ", and the current main model also failed" : "";
158
+ const detail = result.errorMessage?.trim();
159
+ const cause = detail
160
+ ? `its model/provider call failed (${detail})`
161
+ : "its model was unavailable or failed (or the run stalled)";
158
162
  const sessionPreserved = Boolean(result.sessionDir && result.sessionId) && opts?.runId !== undefined;
159
163
  const recovery = sessionPreserved
160
164
  ? ` The sub-agent's earlier work in this run is preserved. Once a model is available again, call subagent_control with { action: "resume", id: ${opts!.runId} } to CONTINUE it in-context (it keeps the same run id and does not re-scan), or execute the task in the main window with your own tools.`
161
165
  : ` Please execute this task in the main window with your own tools; do not re-dispatch it as a sub-agent.`;
162
- return `The sub-agent could not complete this task: its model was unavailable or failed (or the run stalled)${retry}.${recovery}`;
166
+ return `The sub-agent could not complete this task: ${cause}${retry}.${recovery}`;
163
167
  }
164
168
 
165
169
  /** Resolve a run-id request to actual ids: an exact numeric match always wins
package/src/rpc-run.ts CHANGED
@@ -813,12 +813,11 @@ export async function runRpcAgentAttempt(options: RunRpcAttemptOptions): Promise
813
813
  result.rpcActivity = true;
814
814
  }
815
815
 
816
- // The child provider adapter disables request-level retries. Cancel Pi's
817
- // separate outer turn retry the instant it is scheduled, before another
818
- // same-model provider call can begin.
819
- if (event.type === "auto_retry_start") {
820
- void send({ type: "abort_retry" }).catch(() => undefined);
821
- }
816
+ // Let Pi's outer turn retry run. Grok/xAI long streams commonly drop with
817
+ // a retryable `terminated` mid-turn; aborting that retry was misread as
818
+ // "model unavailable" and handed a still-working model back to the parent.
819
+ // After retries exhaust, dispatch still classifies a settled model-level
820
+ // failure and hands off.
822
821
 
823
822
  // Child RPC mode exposes extension dialogs. Sub-agents are non-interactive:
824
823
  // cancel blocking dialogs so an unrelated child extension cannot deadlock.