@ferris1225/pi-subagents 2.0.2 → 2.1.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/README.md +11 -6
- package/package.json +1 -1
- package/src/announcements.ts +70 -70
- package/src/dispatch.ts +24 -996
- package/src/format.ts +177 -177
- package/src/index.ts +3 -2
- package/src/rpc-run.ts +1125 -1059
- package/src/spawn.ts +13 -1
- package/src/thread-lifecycle.ts +1061 -0
- package/src/widget.ts +144 -144
- package/src/worktree.ts +687 -687
package/src/spawn.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
emptyUsage,
|
|
23
23
|
extractToolErrorText,
|
|
24
24
|
getPiInvocation,
|
|
25
|
+
isRpcCommandTimeoutError,
|
|
25
26
|
RpcRunControl,
|
|
26
27
|
runRpcAgentAttempt,
|
|
27
28
|
sessionExists,
|
|
@@ -37,6 +38,7 @@ export {
|
|
|
37
38
|
DEPTH_ENV_VAR,
|
|
38
39
|
extractToolErrorText,
|
|
39
40
|
getPiInvocation,
|
|
41
|
+
isRpcCommandTimeoutError,
|
|
40
42
|
RpcRunControl,
|
|
41
43
|
sessionExists,
|
|
42
44
|
SUBAGENT_KILL_GRACE_MS,
|
|
@@ -201,6 +203,8 @@ export function isModelLevelFailure(result: SingleResult): boolean {
|
|
|
201
203
|
if (!isFailedResult(result)) return false;
|
|
202
204
|
if (result.stopReason === "aborted") return false;
|
|
203
205
|
if (result.dispatchFailed) return false;
|
|
206
|
+
if (result.rpcStartupFailed) return false;
|
|
207
|
+
if (isRpcCommandTimeoutError(result.errorMessage)) return false;
|
|
204
208
|
if (result.integrationStatus === "retained") return false;
|
|
205
209
|
if (result.errorMessage?.includes("idle timeout")) return true;
|
|
206
210
|
if (result.rpcPromptRejected) return true;
|
|
@@ -217,6 +221,9 @@ export function isModelLevelFailure(result: SingleResult): boolean {
|
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
if ((result.failedTools?.length ?? 0) > 0) return false;
|
|
224
|
+
// No accepted prompt, no activity, and no assistant turn means the provider
|
|
225
|
+
// was never reached. Stderr or an exit error here is a startup/transport miss.
|
|
226
|
+
if (!result.rpcPromptAccepted && !result.rpcActivity) return false;
|
|
220
227
|
return Boolean(
|
|
221
228
|
result.rpcPromptAccepted ||
|
|
222
229
|
result.rpcActivity ||
|
|
@@ -235,6 +242,7 @@ export function isRetryableStartupFailure(result: SingleResult, durationMs: numb
|
|
|
235
242
|
if (result.messages.length > 0) return false;
|
|
236
243
|
const usage = result.usage;
|
|
237
244
|
if (usage.turns || usage.input || usage.output || usage.cacheRead || usage.cacheWrite || usage.cost) return false;
|
|
245
|
+
if (result.rpcStartupFailed) return true;
|
|
238
246
|
if (durationMs > MAX_SUBAGENT_STARTUP_FAILURE_DURATION_MS) return false;
|
|
239
247
|
if (result.stderr.trim().length > 0) return false;
|
|
240
248
|
if (result.errorMessage && result.errorMessage.trim().length > 0) return false;
|
|
@@ -242,7 +250,7 @@ export function isRetryableStartupFailure(result: SingleResult, durationMs: numb
|
|
|
242
250
|
}
|
|
243
251
|
|
|
244
252
|
export function formatStartupRetryExhaustedError(model: string, attempts: number): string {
|
|
245
|
-
return `Subagent failed to start after ${attempts} attempt${attempts === 1 ? "" : "s"} on ${model}: the child
|
|
253
|
+
return `Subagent failed to start after ${attempts} attempt${attempts === 1 ? "" : "s"} on ${model}: the child never accepted its initial RPC prompt or produced any model, tool, output, or usage activity. This is typically a concurrent pi startup race (several sub-agents starting at once). Retry the dispatch, or temporarily lower maxConcurrency in /subagents-setup.`;
|
|
246
254
|
}
|
|
247
255
|
|
|
248
256
|
export async function waitForStartupRetry(delayMs: number, signal?: AbortSignal): Promise<boolean> {
|
|
@@ -326,6 +334,8 @@ export interface RunSingleOptions {
|
|
|
326
334
|
env?: NodeJS.ProcessEnv;
|
|
327
335
|
/** Stable logical-generation controller shared across retry attempts. */
|
|
328
336
|
control?: RpcRunControl;
|
|
337
|
+
rpcReadyTimeoutMs?: number;
|
|
338
|
+
rpcCommandTimeoutMs?: number;
|
|
329
339
|
}
|
|
330
340
|
|
|
331
341
|
function controlledDisposition(options: RunSingleOptions, base?: SingleResult): SingleResult | undefined {
|
|
@@ -391,6 +401,8 @@ export async function runSingleAgent(options: RunSingleOptions): Promise<SingleR
|
|
|
391
401
|
onLive: options.onLive,
|
|
392
402
|
env: options.env,
|
|
393
403
|
control,
|
|
404
|
+
rpcReadyTimeoutMs: options.rpcReadyTimeoutMs,
|
|
405
|
+
rpcCommandTimeoutMs: options.rpcCommandTimeoutMs,
|
|
394
406
|
});
|
|
395
407
|
result.task = control?.getObjective() ?? result.task;
|
|
396
408
|
return result;
|