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.
@@ -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 "$parent_id" ]]; then
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: $parent_id"
232
- source_file="$FULL_OUTPUT_DIR/evolution_${parent_id}.py"
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 "$parent_id" ]] && [[ "$candidate_id" =~ ^(baseline|baseline-000|000|0|gen00-000)$ ]]; then
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
- echo "[WORKER-$$] Parent '$parent_id' missing for $candidate_id"
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('$parent_id')
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 '$parent_id' (status: $parent_status)"
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('$parent_id', 'running')
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 "$parent_id" "$parent_of_parent" "$parent_description"
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 '$parent_id'"
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 '$parent_id' (exit code: $parent_exit_code)"
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 '$parent_id' has status '$parent_status' - not processing"
705
+ echo "[WORKER-$$] Parent '$actual_parent_id' has status '$parent_status' - not processing"
673
706
  fi
674
707
  else
675
- echo "[WORKER-$$] Warning: parent '$parent_id' not found in CSV"
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
@@ -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
- candidate_id = row[0].strip()
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
- candidate_id = row[0].strip()
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 '',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.8.1",
3
+ "version": "1.8.3",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",