pi-crew 0.2.7 → 0.2.8
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/agents/verifier.md
CHANGED
|
@@ -6,10 +6,10 @@ systemPromptMode: replace
|
|
|
6
6
|
inheritProjectContext: true
|
|
7
7
|
inheritSkills: false
|
|
8
8
|
tools: read, grep, find, ls, bash
|
|
9
|
-
maxTurns:
|
|
9
|
+
maxTurns: 15
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
You are a verification specialist. Your job is to run tests ONCE, cache the results, then analyze against findings. You have at most **
|
|
12
|
+
You are a verification specialist. Your job is to run tests ONCE, cache the results, then analyze against findings. You have at most **15 turns**.
|
|
13
13
|
|
|
14
14
|
## Strategy
|
|
15
15
|
|
package/package.json
CHANGED
package/src/config/defaults.ts
CHANGED
|
@@ -14,7 +14,7 @@ export const DEFAULT_CHILD_PI = {
|
|
|
14
14
|
|
|
15
15
|
export const DEFAULT_LIVE_SESSION = {
|
|
16
16
|
/** Maximum wall-clock time for a single live-session task before abort (ms). */
|
|
17
|
-
responseTimeoutMs:
|
|
17
|
+
responseTimeoutMs: 10 * 60_000, // 10 minutes - increased from 5min for complex verification
|
|
18
18
|
/** Maximum yield reminder attempts before accepting no-yield. */
|
|
19
19
|
maxYieldRetries: 3,
|
|
20
20
|
/** Polling interval for session idle check during yield enforcement (ms). */
|
|
@@ -58,6 +58,36 @@ function startInterruptGuard(manifest: { runId: string; stateRoot: string; event
|
|
|
58
58
|
return () => clearInterval(interval);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* CRITICAL: Node.js v24 throws on unhandled rejections by default.
|
|
63
|
+
* Without this handler, any unhandled promise rejection (e.g., from cleanupTempDir,
|
|
64
|
+
* terminateLiveAgentsForRun, or other async cleanup) will crash the background runner
|
|
65
|
+
* BEFORE async.completed is written to the event log.
|
|
66
|
+
* This causes the async notifier to falsely detect a stuck run after quietMs expires.
|
|
67
|
+
*/
|
|
68
|
+
function setupUnhandledRejectionGuard(state: { cwd?: string; runId?: string; eventsPath?: string }): void {
|
|
69
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
70
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
71
|
+
console.error("[background-runner] UNHANDLED REJECTION:", reason);
|
|
72
|
+
try {
|
|
73
|
+
// Try to write async.failed event if we have the necessary state
|
|
74
|
+
if (state.eventsPath && state.runId) {
|
|
75
|
+
appendEvent(state.eventsPath, {
|
|
76
|
+
type: "async.failed",
|
|
77
|
+
runId: state.runId,
|
|
78
|
+
message: `Unhandled rejection: ${message}`,
|
|
79
|
+
data: { reason: String(reason), handled: false },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
} catch (appendErr) {
|
|
83
|
+
console.error("[background-runner] Failed to write async.failed event:", appendErr);
|
|
84
|
+
}
|
|
85
|
+
process.exitCode = 1;
|
|
86
|
+
// Give async operations a moment to flush before exit
|
|
87
|
+
setTimeout(() => process.exit(1), 100);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
61
91
|
async function main(): Promise<void> {
|
|
62
92
|
// Scrub macOS malloc vars BEFORE anything else — must be clean for all child processes
|
|
63
93
|
scrubProcessEnv();
|
|
@@ -73,6 +103,12 @@ async function main(): Promise<void> {
|
|
|
73
103
|
const loaded = loadRunManifestById(cwd, runId);
|
|
74
104
|
if (!loaded) throw new Error(`Run '${runId}' not found.`);
|
|
75
105
|
let { manifest, tasks } = loaded;
|
|
106
|
+
|
|
107
|
+
// Setup unhandled rejection guard EARLY — must be before any async operations
|
|
108
|
+
// that might produce unhandled rejections during cleanup.
|
|
109
|
+
const rejectionGuardState = { cwd, runId, eventsPath: loaded.manifest.eventsPath };
|
|
110
|
+
setupUnhandledRejectionGuard(rejectionGuardState);
|
|
111
|
+
|
|
76
112
|
appendEvent(manifest.eventsPath, { type: "async.started", runId: manifest.runId, data: { pid: process.pid } });
|
|
77
113
|
writeAsyncStartMarker(manifest, { pid: process.pid, startedAt: new Date().toISOString() });
|
|
78
114
|
const stopInterruptGuard = startInterruptGuard(manifest);
|