claude-evolve 1.8.1 → 1.8.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-worker +52 -19
- package/lib/evolution_csv.py +5 -3
- package/package.json +1 -1
package/bin/claude-evolve-worker
CHANGED
|
@@ -221,24 +221,50 @@ process_candidate() {
|
|
|
221
221
|
parent_id=""
|
|
222
222
|
echo "[WORKER-$$] Parent ID 'baseline-000' treated as baseline (empty parent)"
|
|
223
223
|
fi
|
|
224
|
-
|
|
224
|
+
|
|
225
|
+
# Handle multi-parent IDs - extract first valid parent
|
|
226
|
+
# Use global variable so caller can access resolved parent for recursive processing
|
|
227
|
+
RESOLVED_PARENT_ID=""
|
|
228
|
+
if [[ -n "$parent_id" ]]; then
|
|
229
|
+
# Split by comma or space and try each parent in order
|
|
230
|
+
IFS=$',; ' read -ra parent_candidates <<< "$parent_id"
|
|
231
|
+
for candidate_parent in "${parent_candidates[@]}"; do
|
|
232
|
+
# Trim whitespace
|
|
233
|
+
candidate_parent="${candidate_parent// /}"
|
|
234
|
+
if [[ -z "$candidate_parent" ]]; then
|
|
235
|
+
continue
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# Check if this parent file exists
|
|
239
|
+
local test_file="$FULL_OUTPUT_DIR/evolution_${candidate_parent}.py"
|
|
240
|
+
if [[ -f "$test_file" ]]; then
|
|
241
|
+
RESOLVED_PARENT_ID="$candidate_parent"
|
|
242
|
+
echo "[WORKER-$$] Resolved multi-parent '$parent_id' -> '$RESOLVED_PARENT_ID'"
|
|
243
|
+
break
|
|
244
|
+
fi
|
|
245
|
+
done
|
|
246
|
+
|
|
247
|
+
# If no valid parent found, fail
|
|
248
|
+
if [[ -z "$RESOLVED_PARENT_ID" ]]; then
|
|
249
|
+
echo "[WORKER-$$] ERROR: None of the parent algorithms found for: $parent_id" >&2
|
|
250
|
+
echo "[WORKER-$$] Attempted parents: ${parent_candidates[*]}" >&2
|
|
251
|
+
return 78 # Exit code for missing parent
|
|
252
|
+
fi
|
|
253
|
+
fi
|
|
254
|
+
|
|
225
255
|
# Determine source algorithm
|
|
226
256
|
local source_file
|
|
227
|
-
if [[ -z "$
|
|
257
|
+
if [[ -z "$RESOLVED_PARENT_ID" ]]; then
|
|
228
258
|
echo "[WORKER-$$] Using base algorithm"
|
|
229
259
|
source_file="$FULL_ALGORITHM_PATH"
|
|
230
260
|
else
|
|
231
|
-
echo "[WORKER-$$] Using parent algorithm: $
|
|
232
|
-
source_file="$FULL_OUTPUT_DIR/evolution_${
|
|
233
|
-
if [[ ! -f "$source_file" ]]; then
|
|
234
|
-
echo "[WORKER-$$] ERROR: Parent algorithm not found: $source_file" >&2
|
|
235
|
-
return 78 # New exit code for missing parent
|
|
236
|
-
fi
|
|
261
|
+
echo "[WORKER-$$] Using parent algorithm: $RESOLVED_PARENT_ID"
|
|
262
|
+
source_file="$FULL_OUTPUT_DIR/evolution_${RESOLVED_PARENT_ID}.py"
|
|
237
263
|
fi
|
|
238
|
-
|
|
264
|
+
|
|
239
265
|
# Check if this is a baseline candidate (no parent and specific ID pattern)
|
|
240
266
|
local is_baseline=false
|
|
241
|
-
if [[ -z "$
|
|
267
|
+
if [[ -z "$RESOLVED_PARENT_ID" ]] && [[ "$candidate_id" =~ ^(baseline|baseline-000|000|0|gen00-000)$ ]]; then
|
|
242
268
|
is_baseline=true
|
|
243
269
|
echo "[WORKER-$$] Detected baseline candidate - will run algorithm.py directly"
|
|
244
270
|
fi
|
|
@@ -278,6 +304,8 @@ from lib.evolution_csv import EvolutionCSV
|
|
|
278
304
|
with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
279
305
|
csv.update_candidate_status('$candidate_id', 'complete')
|
|
280
306
|
" 2>/dev/null || true
|
|
307
|
+
# Clear CURRENT_CANDIDATE_ID before returning to prevent cleanup from interfering
|
|
308
|
+
CURRENT_CANDIDATE_ID=""
|
|
281
309
|
return 0
|
|
282
310
|
fi
|
|
283
311
|
|
|
@@ -348,6 +376,8 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
|
348
376
|
echo "[WORKER-$$] Deleted corrupted algorithm file: $target_file" >&2
|
|
349
377
|
# Set status to pending for retry
|
|
350
378
|
update_candidate_status "$candidate_id" "pending"
|
|
379
|
+
# Clear CURRENT_CANDIDATE_ID before returning
|
|
380
|
+
CURRENT_CANDIDATE_ID=""
|
|
351
381
|
# Return 0 to indicate that this specific processing step is handled,
|
|
352
382
|
# and the candidate is now pending for a future retry.
|
|
353
383
|
return 0
|
|
@@ -612,7 +642,10 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
|
612
642
|
" 2>/dev/null || true
|
|
613
643
|
elif [[ $process_exit_code -eq 78 ]]; then
|
|
614
644
|
# Missing parent; mark child as failed and immediately process parent
|
|
615
|
-
|
|
645
|
+
# Use RESOLVED_PARENT_ID which was set by process_candidate
|
|
646
|
+
local actual_parent_id="${RESOLVED_PARENT_ID:-$parent_id}"
|
|
647
|
+
|
|
648
|
+
echo "[WORKER-$$] Parent '$actual_parent_id' missing for $candidate_id"
|
|
616
649
|
echo "[WORKER-$$] Marking $candidate_id as failed-parent-missing"
|
|
617
650
|
|
|
618
651
|
"$PYTHON_CMD" -c "
|
|
@@ -630,7 +663,7 @@ import sys
|
|
|
630
663
|
sys.path.insert(0, '$SCRIPT_DIR/..')
|
|
631
664
|
from lib.evolution_csv import EvolutionCSV
|
|
632
665
|
with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
633
|
-
parent = csv.get_candidate_info('$
|
|
666
|
+
parent = csv.get_candidate_info('$actual_parent_id')
|
|
634
667
|
if parent:
|
|
635
668
|
status = parent.get('status', '').lower()
|
|
636
669
|
parent_of_parent = parent.get('basedOnId', '')
|
|
@@ -644,7 +677,7 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
|
644
677
|
|
|
645
678
|
# Only process if parent needs processing
|
|
646
679
|
if [[ "$parent_status" == "" || "$parent_status" == "pending" || "$parent_status" == "skipped" || "$parent_status" == "failed-parent-missing" ]]; then
|
|
647
|
-
echo "[WORKER-$$] Immediately processing parent '$
|
|
680
|
+
echo "[WORKER-$$] Immediately processing parent '$actual_parent_id' (status: $parent_status)"
|
|
648
681
|
|
|
649
682
|
# Mark parent as running
|
|
650
683
|
"$PYTHON_CMD" -c "
|
|
@@ -652,27 +685,27 @@ import sys
|
|
|
652
685
|
sys.path.insert(0, '$SCRIPT_DIR/..')
|
|
653
686
|
from lib.evolution_csv import EvolutionCSV
|
|
654
687
|
with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
655
|
-
csv.update_candidate_status('$
|
|
688
|
+
csv.update_candidate_status('$actual_parent_id', 'running')
|
|
656
689
|
" 2>/dev/null || true
|
|
657
690
|
|
|
658
691
|
# Clear current candidate (parent processing will set its own)
|
|
659
692
|
CURRENT_CANDIDATE_ID=""
|
|
660
693
|
|
|
661
694
|
# Process parent recursively
|
|
662
|
-
process_candidate "$
|
|
695
|
+
process_candidate "$actual_parent_id" "$parent_of_parent" "$parent_description"
|
|
663
696
|
parent_exit_code=$?
|
|
664
697
|
|
|
665
698
|
if [[ $parent_exit_code -eq 0 ]]; then
|
|
666
|
-
echo "[WORKER-$$] Successfully processed parent '$
|
|
699
|
+
echo "[WORKER-$$] Successfully processed parent '$actual_parent_id'"
|
|
667
700
|
# Now the child can potentially be retried (user can reset failed-parent-missing later)
|
|
668
701
|
else
|
|
669
|
-
echo "[WORKER-$$] Failed to process parent '$
|
|
702
|
+
echo "[WORKER-$$] Failed to process parent '$actual_parent_id' (exit code: $parent_exit_code)"
|
|
670
703
|
fi
|
|
671
704
|
else
|
|
672
|
-
echo "[WORKER-$$] Parent '$
|
|
705
|
+
echo "[WORKER-$$] Parent '$actual_parent_id' has status '$parent_status' - not processing"
|
|
673
706
|
fi
|
|
674
707
|
else
|
|
675
|
-
echo "[WORKER-$$] Warning: parent '$
|
|
708
|
+
echo "[WORKER-$$] Warning: parent '$actual_parent_id' not found in CSV"
|
|
676
709
|
fi
|
|
677
710
|
|
|
678
711
|
# Clear current candidate and continue to next
|
package/lib/evolution_csv.py
CHANGED
|
@@ -153,7 +153,8 @@ class EvolutionCSV:
|
|
|
153
153
|
for i in range(len(rows) - 1, start_idx - 1, -1):
|
|
154
154
|
row = rows[i]
|
|
155
155
|
if self.is_pending_candidate(row):
|
|
156
|
-
|
|
156
|
+
# Strip both whitespace and quotes to handle CSV corruption
|
|
157
|
+
candidate_id = row[0].strip().strip('"')
|
|
157
158
|
current_status = row[4].strip() if len(row) > 4 else ''
|
|
158
159
|
pending.append((candidate_id, current_status))
|
|
159
160
|
|
|
@@ -181,7 +182,8 @@ class EvolutionCSV:
|
|
|
181
182
|
row = rows[i]
|
|
182
183
|
|
|
183
184
|
if self.is_pending_candidate(row):
|
|
184
|
-
|
|
185
|
+
# Strip both whitespace and quotes to handle CSV corruption
|
|
186
|
+
candidate_id = row[0].strip().strip('"')
|
|
185
187
|
original_status = row[4].strip() if len(row) > 4 else ''
|
|
186
188
|
|
|
187
189
|
# Ensure row has at least 5 columns
|
|
@@ -335,7 +337,7 @@ class EvolutionCSV:
|
|
|
335
337
|
for row in rows[start_idx:]:
|
|
336
338
|
if self.is_valid_candidate_row(row) and row[0].strip().strip('"') == candidate_id.strip().strip('"'):
|
|
337
339
|
return {
|
|
338
|
-
'id': row[0].strip() if len(row) > 0 else '',
|
|
340
|
+
'id': row[0].strip().strip('"') if len(row) > 0 else '',
|
|
339
341
|
'basedOnId': row[1].strip() if len(row) > 1 else '',
|
|
340
342
|
'description': row[2].strip() if len(row) > 2 else '',
|
|
341
343
|
'performance': row[3].strip() if len(row) > 3 else '',
|