claude-evolve 1.3.1 → 1.3.3
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/bin/claude-evolve-run +12 -0
- package/bin/claude-evolve-run-parallel +101 -10
- package/package.json +1 -1
package/bin/claude-evolve-run
CHANGED
|
@@ -29,6 +29,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
29
29
|
force_sequential="true"
|
|
30
30
|
shift
|
|
31
31
|
;;
|
|
32
|
+
--keep-awake|--caffeinate)
|
|
33
|
+
use_caffeinate="true"
|
|
34
|
+
shift
|
|
35
|
+
;;
|
|
32
36
|
--help)
|
|
33
37
|
cat <<EOF
|
|
34
38
|
claude-evolve run - Execute evolution candidates
|
|
@@ -40,6 +44,7 @@ OPTIONS:
|
|
|
40
44
|
--timeout <sec> Kill evaluator after specified seconds (default: no timeout)
|
|
41
45
|
--parallel Force parallel execution mode
|
|
42
46
|
--sequential Force sequential execution mode
|
|
47
|
+
--keep-awake Prevent system sleep during execution (macOS only)
|
|
43
48
|
--help Show this help message
|
|
44
49
|
|
|
45
50
|
DESCRIPTION:
|
|
@@ -59,6 +64,13 @@ EOF
|
|
|
59
64
|
esac
|
|
60
65
|
done
|
|
61
66
|
|
|
67
|
+
# Check if caffeinate should be used
|
|
68
|
+
if [[ "$use_caffeinate" == "true" ]] && command -v caffeinate >/dev/null 2>&1; then
|
|
69
|
+
echo "[INFO] Using caffeinate to prevent system sleep"
|
|
70
|
+
# Re-run this script with caffeinate
|
|
71
|
+
exec caffeinate -dims "$0" "$@"
|
|
72
|
+
fi
|
|
73
|
+
|
|
62
74
|
# Determine execution mode
|
|
63
75
|
use_parallel=false
|
|
64
76
|
if [[ "$force_parallel" == "true" ]]; then
|
|
@@ -68,8 +68,16 @@ start_worker() {
|
|
|
68
68
|
echo "[DISPATCHER] Starting worker..."
|
|
69
69
|
$worker_cmd &
|
|
70
70
|
local pid=$!
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
|
|
72
|
+
# Verify worker started successfully
|
|
73
|
+
sleep 0.1
|
|
74
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
75
|
+
worker_pids+=($pid)
|
|
76
|
+
echo "[DISPATCHER] Worker $pid started"
|
|
77
|
+
else
|
|
78
|
+
echo "[ERROR] Worker failed to start" >&2
|
|
79
|
+
((consecutive_failures++))
|
|
80
|
+
fi
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
# Check worker exit status and handle accordingly
|
|
@@ -144,17 +152,78 @@ shutdown_workers() {
|
|
|
144
152
|
exit 0
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
|
|
155
|
+
# Better signal handling with logging
|
|
156
|
+
handle_signal() {
|
|
157
|
+
local signal="$1"
|
|
158
|
+
echo "[DISPATCHER] Received signal: $signal" >&2
|
|
159
|
+
echo "[DISPATCHER] Active workers: ${#worker_pids[@]}" >&2
|
|
160
|
+
|
|
161
|
+
# For expensive workers, give option to continue
|
|
162
|
+
if [[ ${#worker_pids[@]} -gt 0 ]]; then
|
|
163
|
+
echo "[DISPATCHER] Warning: ${#worker_pids[@]} expensive workers are still running!" >&2
|
|
164
|
+
echo "[DISPATCHER] Press Ctrl+C again within 5 seconds to force shutdown, or wait..." >&2
|
|
165
|
+
|
|
166
|
+
# Give 5 seconds to reconsider
|
|
167
|
+
local count=5
|
|
168
|
+
while [[ $count -gt 0 ]]; do
|
|
169
|
+
sleep 1
|
|
170
|
+
((count--))
|
|
171
|
+
# Check if we got another signal
|
|
172
|
+
if [[ -f /tmp/evolve-force-shutdown-$$ ]]; then
|
|
173
|
+
echo "[DISPATCHER] Force shutdown requested" >&2
|
|
174
|
+
rm -f /tmp/evolve-force-shutdown-$$
|
|
175
|
+
shutdown_workers
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
done
|
|
179
|
+
|
|
180
|
+
echo "[DISPATCHER] Continuing with active workers..." >&2
|
|
181
|
+
return
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
shutdown_workers
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Set up signal handlers
|
|
188
|
+
trap 'handle_signal INT' INT
|
|
189
|
+
trap 'handle_signal TERM' TERM
|
|
190
|
+
trap 'echo "[DISPATCHER] Exiting with code $?" >&2' EXIT
|
|
191
|
+
|
|
192
|
+
# Check for stuck "running" candidates from previous runs
|
|
193
|
+
check_stuck_candidates() {
|
|
194
|
+
if read_csv_with_lock csv_content; then
|
|
195
|
+
local stuck_count=$(echo "$csv_content" | awk -F',' 'NR>1 && $5 == "running" { count++ } END { print count+0 }')
|
|
196
|
+
if [[ $stuck_count -gt 0 ]]; then
|
|
197
|
+
echo "[DISPATCHER] Found $stuck_count candidates stuck in 'running' status"
|
|
198
|
+
echo "[DISPATCHER] Resetting them to 'pending' for retry..."
|
|
199
|
+
|
|
200
|
+
# Reset stuck candidates
|
|
201
|
+
if acquire_csv_lock; then
|
|
202
|
+
awk -F',' -v OFS=',' '
|
|
203
|
+
NR==1 { print }
|
|
204
|
+
NR>1 {
|
|
205
|
+
if ($5 == "running") $5 = "pending"
|
|
206
|
+
print
|
|
207
|
+
}
|
|
208
|
+
' "$FULL_CSV_PATH" > "${FULL_CSV_PATH}.tmp" && mv -f "${FULL_CSV_PATH}.tmp" "$FULL_CSV_PATH"
|
|
209
|
+
release_csv_lock
|
|
210
|
+
fi
|
|
211
|
+
fi
|
|
212
|
+
fi
|
|
213
|
+
}
|
|
148
214
|
|
|
149
215
|
# Main dispatcher loop
|
|
150
216
|
echo "[DISPATCHER] Starting main dispatch loop"
|
|
151
217
|
|
|
218
|
+
# Check for stuck candidates from previous runs
|
|
219
|
+
check_stuck_candidates
|
|
220
|
+
|
|
221
|
+
# Set error handling
|
|
222
|
+
set +e # Don't exit on error in the main loop
|
|
223
|
+
|
|
152
224
|
while true; do
|
|
153
|
-
#
|
|
154
|
-
|
|
155
|
-
echo "[ERROR] Too many consecutive failures ($consecutive_failures). Stopping." >&2
|
|
156
|
-
break
|
|
157
|
-
fi
|
|
225
|
+
# In parallel mode, let individual algorithm failures happen
|
|
226
|
+
# The generation is finite, so worst case it just completes with many failures
|
|
158
227
|
|
|
159
228
|
# Check if rate limit was hit
|
|
160
229
|
if [[ $rate_limit_hit == true ]]; then
|
|
@@ -164,7 +233,7 @@ while true; do
|
|
|
164
233
|
fi
|
|
165
234
|
|
|
166
235
|
# Count pending work
|
|
167
|
-
pending_count=$(count_pending)
|
|
236
|
+
pending_count=$(count_pending || echo "0")
|
|
168
237
|
active_workers=${#worker_pids[@]}
|
|
169
238
|
|
|
170
239
|
echo "[DISPATCHER] Status: $pending_count pending, $active_workers active workers"
|
|
@@ -180,6 +249,7 @@ while true; do
|
|
|
180
249
|
if [[ $pending_count -eq 0 && $active_workers -eq 0 ]]; then
|
|
181
250
|
echo "[DISPATCHER] No pending candidates found. Evolution complete."
|
|
182
251
|
echo "[DISPATCHER] Run 'claude-evolve ideate' to generate more candidates."
|
|
252
|
+
echo "[DISPATCHER] Exiting main loop: no work remaining" >&2
|
|
183
253
|
break
|
|
184
254
|
fi
|
|
185
255
|
|
|
@@ -210,10 +280,31 @@ while true; do
|
|
|
210
280
|
handle_worker_exit "$pid" "$exit_code"
|
|
211
281
|
fi
|
|
212
282
|
done
|
|
283
|
+
|
|
284
|
+
# Safety check - if we have workers but the array is corrupted
|
|
285
|
+
if [[ ${#worker_pids[@]} -eq 0 ]] && jobs -r | grep -q .; then
|
|
286
|
+
echo "[DISPATCHER] Warning: Lost track of workers but jobs still running!" >&2
|
|
287
|
+
echo "[DISPATCHER] Attempting to recover..." >&2
|
|
288
|
+
|
|
289
|
+
# Try to recover PIDs from jobs
|
|
290
|
+
while read -r job_info; do
|
|
291
|
+
if [[ $job_info =~ \[([0-9]+)\][[:space:]]+([0-9]+) ]]; then
|
|
292
|
+
local recovered_pid="${BASH_REMATCH[2]}"
|
|
293
|
+
echo "[DISPATCHER] Recovered worker PID: $recovered_pid" >&2
|
|
294
|
+
worker_pids+=($recovered_pid)
|
|
295
|
+
fi
|
|
296
|
+
done < <(jobs -l)
|
|
297
|
+
fi
|
|
213
298
|
else
|
|
214
299
|
# No active workers but we might be waiting for ideation or have pending work
|
|
215
300
|
sleep 1
|
|
216
301
|
fi
|
|
217
302
|
done
|
|
218
303
|
|
|
219
|
-
echo "[DISPATCHER] Evolution run complete"
|
|
304
|
+
echo "[DISPATCHER] Evolution run complete"
|
|
305
|
+
|
|
306
|
+
# Final cleanup check
|
|
307
|
+
if [[ ${#worker_pids[@]} -gt 0 ]]; then
|
|
308
|
+
echo "[DISPATCHER] Warning: ${#worker_pids[@]} workers still active at exit"
|
|
309
|
+
shutdown_workers
|
|
310
|
+
fi
|