claude-evolve 1.8.33 → 1.8.35

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.
@@ -54,36 +54,16 @@ safe_popd() {
54
54
  fi
55
55
  }
56
56
 
57
- # Helper function to call AI with limit check
57
+ # Helper function to call AI (legacy wrapper)
58
58
  call_ai_with_limit_check() {
59
59
  local prompt="$1"
60
- local generation="${2:-01}" # Default to generation 01 if not provided
61
-
62
- # Calculate hash value for round-robin based on generation
63
- local gen_num
64
- if [[ $generation =~ ^0*([0-9]+)$ ]]; then
65
- gen_num=$((10#${BASH_REMATCH[1]}))
66
- else
67
- gen_num=1
68
- fi
69
-
70
- # Use centralized AI library for ideation
60
+
61
+ # Use centralized AI library for ideation (random model selection)
71
62
  local ai_output
72
- ai_output=$(call_ai_with_round_robin "$prompt" "ideate" "$gen_num")
63
+ ai_output=$(call_ai_random "$prompt" "ideate")
73
64
  local ai_exit_code=$?
74
-
75
- # Handle special exit codes
76
- if [[ $ai_exit_code -eq 3 ]]; then
77
- # All models hit usage limits
78
- echo -e "\033[31m[ERROR] ALL AI MODELS HIT USAGE LIMITS!\033[0m" >&2
79
- echo -e "\033[31m[ERROR] Ideation halted due to API rate limits.\033[0m" >&2
80
- echo -e "\033[33m[INFO] Please wait for the rate limits to reset before continuing.\033[0m" >&2
81
- echo -e "\033[33m[INFO] No ideas were generated. Run ideate again when the limits reset.\033[0m" >&2
82
- exit 1
83
- fi
84
-
65
+
85
66
  if [[ $ai_exit_code -eq 0 ]]; then
86
- # For ideation, AI modifies files directly - just return success
87
67
  echo "[INFO] AI succeeded" >&2
88
68
  return 0
89
69
  else
@@ -97,28 +77,16 @@ call_claude_with_limit_check() {
97
77
  call_ai_with_limit_check "$@"
98
78
  }
99
79
 
100
- # Robust AI calling with fallbacks across all available models
80
+ # Robust AI calling with random model selection (no fallback)
101
81
  # Returns 0 on success and echoes the successful model name to stdout
102
82
  call_ai_for_ideation() {
103
83
  local prompt="$1"
104
84
  local generation="${2:-01}"
105
85
  local expected_count="${3:-1}" # Number of ideas expected to be added
106
86
  local temp_csv_file="${4:-temp-csv-$$.csv}" # Optional temp CSV filename
107
-
108
- # Calculate hash value for round-robin based on generation
109
- local gen_num
110
- if [[ $generation =~ ^0*([0-9]+)$ ]]; then
111
- gen_num=$((10#${BASH_REMATCH[1]}))
112
- else
113
- gen_num=1
114
- fi
115
-
116
- # Make a backup of the pre-populated temp CSV (which includes stub rows from caller)
117
- # This preserves the stub rows that the caller added
118
- local temp_csv_backup="${temp_csv_file}.backup"
119
- if [[ -f "$temp_csv_file" ]]; then
120
- cp "$temp_csv_file" "$temp_csv_backup"
121
- else
87
+
88
+ # Verify temp CSV exists
89
+ if [[ ! -f "$temp_csv_file" ]]; then
122
90
  echo "[ERROR] Temp CSV file not found at start: $temp_csv_file" >&2
123
91
  return 1
124
92
  fi
@@ -137,103 +105,68 @@ call_ai_for_ideation() {
137
105
 
138
106
  if [[ ${#models[@]} -eq 0 ]]; then
139
107
  echo "[ERROR] No models configured for ideation" >&2
140
- rm -f "$temp_csv_backup"
141
108
  return 1
142
109
  fi
143
110
 
144
- # Calculate starting index for round-robin
111
+ # Pick one random model (no fallback)
145
112
  local num_models=${#models[@]}
146
- local start_index=$((gen_num % num_models))
113
+ local random_index=$((RANDOM % num_models))
114
+ local model="${models[$random_index]}"
147
115
 
148
- # Create ordered list based on round-robin
149
- local ordered_models=()
150
- for ((i=0; i<num_models; i++)); do
151
- local idx=$(((start_index + i) % num_models))
152
- ordered_models+=("${models[$idx]}")
153
- done
116
+ echo "[AI] Selected $model for ideate (random from $num_models models)" >&2
154
117
 
155
- echo "[AI] Model order for ideate (round-robin): ${ordered_models[*]}" >&2
156
-
157
- # Try each model until CSV changes
158
- for model in "${ordered_models[@]}"; do
159
- echo "[AI] Attempting ideate with $model" >&2
160
-
161
- # Restore temp CSV from backup before each attempt (in case previous model corrupted it)
162
- # This preserves the stub rows that the caller pre-populated
163
- cp "$temp_csv_backup" "$temp_csv_file"
164
-
165
- # Call the model directly
166
- local ai_output
167
- ai_output=$(call_ai_model_configured "$model" "$prompt")
168
- local ai_exit_code=$?
169
-
170
- # Check if the file was modified correctly
171
- if [[ -f "$temp_csv_file" ]]; then
172
- local new_csv_count
173
- new_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l | tr -d '[:space:]')
174
- local added_count=$((new_csv_count - original_csv_count))
175
-
176
- echo "[DEBUG] After $model: original=$original_csv_count, new=$new_csv_count, added=$added_count" >&2
177
-
178
- # Check if row count is correct (should be same since we're editing stubs, not adding)
179
- if [[ $new_csv_count -eq $original_csv_count ]]; then
180
- # Count remaining placeholders - there should be none if AI did its job
181
- local placeholder_count
182
- placeholder_count=$(grep -c "PLACEHOLDER" "$temp_csv_file" 2>/dev/null || echo "0")
183
- # Strip whitespace and ensure we have a clean integer
184
- placeholder_count=$(echo "$placeholder_count" | tr -d '[:space:]')
185
- placeholder_count=${placeholder_count:-0}
186
-
187
- if [[ $placeholder_count -eq 0 ]]; then
188
- echo "[INFO] CSV modified by $model: filled $expected_count placeholder rows ✓" >&2
189
-
190
- # Post-process to ensure all description fields are quoted
191
- local fixed_csv_file="${temp_csv_file}.fixed"
192
-
193
- # Use the CSV fixer script
194
- if "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_fixer.py" "$temp_csv_file" "$fixed_csv_file"; then
195
- mv "$fixed_csv_file" "$temp_csv_file"
196
- echo "[INFO] CSV format validated and fixed if needed" >&2
197
- else
198
- echo "[WARN] CSV format validation failed, using original" >&2
199
- fi
200
-
201
- # Clean up backup file
202
- rm -f "$temp_csv_backup"
203
-
204
- # Echo the successful model name for caller to capture
205
- echo "$model"
206
- return 0
207
- else
208
- echo "[WARN] $model left $placeholder_count placeholders unfilled - trying next model" >&2
209
- # Continue to next model
210
- fi
211
- elif [[ $added_count -lt 0 ]]; then
212
- echo "[WARN] $model deleted rows ($added_count) - trying next model" >&2
213
- # Continue to next model
214
- elif [[ $added_count -gt 0 ]]; then
215
- echo "[WARN] $model added extra rows ($added_count) instead of editing stubs - trying next model" >&2
216
- # Continue to next model
217
- else
218
- echo "[INFO] CSV unchanged after $model (exit code: $ai_exit_code)" >&2
219
- # Log last few lines of AI output to help debug why it succeeded but didn't change the file
220
- if [[ -n "$ai_output" ]]; then
221
- echo "[AI] Last 10 lines of $model output:" >&2
222
- echo "$ai_output" | tail -n 10 >&2
223
- echo "[AI] ---" >&2
224
- fi
225
- # Continue to next model
226
- fi
118
+ # Call the model directly
119
+ local ai_output
120
+ ai_output=$(call_ai_model_configured "$model" "$prompt")
121
+ local ai_exit_code=$?
122
+
123
+ # Check if the file was modified correctly
124
+ if [[ ! -f "$temp_csv_file" ]]; then
125
+ echo "[ERROR] Temp CSV file not found after $model: $temp_csv_file" >&2
126
+ return 1
127
+ fi
128
+
129
+ local new_csv_count
130
+ new_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l | tr -d '[:space:]')
131
+ local added_count=$((new_csv_count - original_csv_count))
132
+
133
+ echo "[DEBUG] After $model: original=$original_csv_count, new=$new_csv_count, added=$added_count" >&2
134
+
135
+ # Check if row count is correct (should be same since we're editing stubs, not adding)
136
+ if [[ $new_csv_count -ne $original_csv_count ]]; then
137
+ if [[ $added_count -lt 0 ]]; then
138
+ echo "[ERROR] $model deleted rows ($added_count)" >&2
227
139
  else
228
- echo "[INFO] Temp CSV file not found after $model: $temp_csv_file" >&2
229
- # Continue to next model
140
+ echo "[ERROR] $model added extra rows ($added_count) instead of editing stubs" >&2
230
141
  fi
231
- done
232
-
233
- # All models tried, none changed the file
234
- rm -f "$temp_csv_backup"
235
- echo "[ERROR] All AI models failed to generate ideas" >&2
236
- return 1
142
+ return 1
143
+ fi
144
+
145
+ # Count remaining placeholders - there should be none if AI did its job
146
+ local placeholder_count
147
+ placeholder_count=$(grep -c "PLACEHOLDER" "$temp_csv_file" 2>/dev/null || echo "0")
148
+ placeholder_count=$(echo "$placeholder_count" | tr -d '[:space:]')
149
+ placeholder_count=${placeholder_count:-0}
150
+
151
+ if [[ $placeholder_count -ne 0 ]]; then
152
+ echo "[ERROR] $model left $placeholder_count placeholders unfilled" >&2
153
+ return 1
154
+ fi
155
+
156
+ echo "[INFO] CSV modified by $model: filled $expected_count placeholder rows ✓" >&2
157
+
158
+ # Post-process to ensure all description fields are quoted
159
+ local fixed_csv_file="${temp_csv_file}.fixed"
160
+ if "$PYTHON_CMD" "$SCRIPT_DIR/../lib/csv_fixer.py" "$temp_csv_file" "$fixed_csv_file"; then
161
+ mv "$fixed_csv_file" "$temp_csv_file"
162
+ echo "[INFO] CSV format validated and fixed if needed" >&2
163
+ else
164
+ echo "[WARN] CSV format validation failed, using original" >&2
165
+ fi
166
+
167
+ # Echo the successful model name for caller to capture
168
+ echo "$model"
169
+ return 0
237
170
  }
238
171
 
239
172
  # Parse arguments
@@ -654,7 +587,7 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
654
587
  local modified_csv
655
588
  local stderr_file="$FULL_EVOLUTION_DIR/stderr-$$.txt"
656
589
  if ! modified_csv=$(call_ai_for_ideation "$csv_prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
657
- echo "[ERROR] All AI models failed to modify CSV" >&2
590
+ echo "[ERROR] AI model failed to modify CSV" >&2
658
591
  cat "$stderr_file" >&2
659
592
  rm -f "$temp_csv" "$stderr_file"
660
593
  return 1
@@ -1138,7 +1071,7 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
1138
1071
  local stderr_file="stderr-$$.txt"
1139
1072
  # Temporarily show stderr for debugging
1140
1073
  if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
1141
- echo "[ERROR] All AI models failed to generate novel ideas" >&2
1074
+ echo "[ERROR] AI model failed to generate novel ideas" >&2
1142
1075
  cat "$stderr_file" >&2
1143
1076
  safe_popd
1144
1077
  rm -f "$temp_csv" "$stderr_file"
@@ -1291,7 +1224,7 @@ CRITICAL INSTRUCTIONS:
1291
1224
  local stderr_file="stderr-$$.txt"
1292
1225
  # Temporarily show stderr for debugging
1293
1226
  if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
1294
- echo "[ERROR] All AI models failed to generate hill climbing ideas" >&2
1227
+ echo "[ERROR] AI model failed to generate hill climbing ideas" >&2
1295
1228
  cat "$stderr_file" >&2
1296
1229
  safe_popd
1297
1230
  rm -f "$temp_csv" "$stderr_file"
@@ -1434,7 +1367,7 @@ CRITICAL INSTRUCTIONS:
1434
1367
  local stderr_file="stderr-$$.txt"
1435
1368
  # Temporarily show stderr for debugging
1436
1369
  if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
1437
- echo "[ERROR] All AI models failed to generate structural mutation ideas" >&2
1370
+ echo "[ERROR] AI model failed to generate structural mutation ideas" >&2
1438
1371
  cat "$stderr_file" >&2
1439
1372
  safe_popd
1440
1373
  rm -f "$temp_csv" "$stderr_file"
@@ -1577,7 +1510,7 @@ CRITICAL INSTRUCTIONS:
1577
1510
  local stderr_file="stderr-$$.txt"
1578
1511
  # Temporarily show stderr for debugging
1579
1512
  if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
1580
- echo "[ERROR] All AI models failed to generate crossover hybrid ideas" >&2
1513
+ echo "[ERROR] AI model failed to generate crossover hybrid ideas" >&2
1581
1514
  cat "$stderr_file" >&2
1582
1515
  safe_popd
1583
1516
  rm -f "$temp_csv" "$stderr_file"
@@ -1697,7 +1630,7 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
1697
1630
  local ai_response
1698
1631
  local stderr_file="stderr-$$.txt"
1699
1632
  if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$TOTAL_IDEAS" "$temp_csv_basename" 2>"$stderr_file"); then
1700
- echo "[ERROR] All AI models failed to generate ideas" >&2
1633
+ echo "[ERROR] AI model failed to generate ideas" >&2
1701
1634
  cat "$stderr_file" >&2
1702
1635
  safe_popd
1703
1636
  rm -f "$temp_csv" "$stderr_file"
@@ -110,7 +110,7 @@ else
110
110
  load_config
111
111
  fi
112
112
 
113
- # AI round-robin with fallback function for code evolution
113
+ # AI random selection function for code evolution
114
114
  call_ai_for_evolution() {
115
115
  local prompt="$1"
116
116
  local candidate_id="$2"
@@ -118,104 +118,44 @@ call_ai_for_evolution() {
118
118
  # Get target file path from worker context
119
119
  local target_file="$FULL_OUTPUT_DIR/evolution_${candidate_id}.py"
120
120
 
121
- # Retry configuration for API limits
122
- local retry_count=0
123
- local max_retries=3
124
- local wait_seconds=300 # Start with 5 minutes
125
- local max_wait_seconds=300 # Cap at 5 minutes
126
-
127
- while true; do
128
- # Capture file state before AI call
129
- local file_hash_before=""
130
- local file_mtime_before=""
131
- if [[ -f "$target_file" ]]; then
132
- file_hash_before=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
133
- file_mtime_before=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
134
- fi
121
+ # Capture file state before AI call
122
+ local file_hash_before=""
123
+ local file_mtime_before=""
124
+ if [[ -f "$target_file" ]]; then
125
+ file_hash_before=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
126
+ file_mtime_before=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
127
+ fi
135
128
 
136
- # Extract generation and ID numbers for round-robin calculation
137
- local gen_num=0
138
- local id_num=0
139
- if [[ $candidate_id =~ ^gen([0-9]+)-([0-9]+)$ ]]; then
140
- gen_num=$((10#${BASH_REMATCH[1]}))
141
- id_num=$((10#${BASH_REMATCH[2]}))
129
+ # Use the centralized AI library for evolution (random model selection)
130
+ local ai_output
131
+ ai_output=$(call_ai_random "$prompt" "run")
132
+ local ai_exit_code=$?
133
+
134
+ # Check if the target file was actually modified
135
+ local file_was_modified=false
136
+ if [[ -f "$target_file" ]]; then
137
+ local file_hash_after
138
+ local file_mtime_after
139
+ file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
140
+ file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
141
+
142
+ if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
143
+ file_was_modified=true
142
144
  fi
145
+ fi
143
146
 
144
- # Calculate hash for round-robin (combine generation and ID)
145
- local hash_value=$((gen_num * 1000 + id_num))
146
-
147
- # Use the centralized AI library for evolution (run command)
148
- local ai_output
149
- ai_output=$(call_ai_with_round_robin "$prompt" "run" "$hash_value")
150
- local ai_exit_code=$?
151
-
152
- # Handle special exit codes
153
- if [[ $ai_exit_code -eq 3 ]]; then
154
- # All models hit usage limits
155
- if [[ $retry_count -lt $max_retries ]]; then
156
- ((retry_count++))
157
- echo "[WORKER-$] All models hit usage limits (retry $retry_count/$max_retries)" >&2
158
- echo "[WORKER-$] Waiting $wait_seconds seconds ($(($wait_seconds / 60)) minutes) before retrying..." >&2
159
-
160
- # Sleep with countdown
161
- local remaining=$wait_seconds
162
- while [[ $remaining -gt 0 ]]; do
163
- if [[ $((remaining % 60)) -eq 0 ]]; then
164
- echo "[WORKER-$] Retrying in $((remaining / 60)) minutes..." >&2
165
- fi
166
- sleep 60
167
- remaining=$((remaining - 60))
168
- done
169
-
170
- echo "[WORKER-$] Retrying AI call (attempt #$((retry_count + 1)))..." >&2
171
-
172
- # Exponential backoff: double the wait time, up to max
173
- wait_seconds=$((wait_seconds * 2))
174
- if [[ $wait_seconds -gt $max_wait_seconds ]]; then
175
- wait_seconds=$max_wait_seconds
176
- fi
177
-
178
- # Continue to retry
179
- continue
180
- else
181
- # Exhausted retries
182
- echo "[WORKER-$] All models hit usage limits after $max_retries retries" >&2
183
- echo "[WORKER-$] Unable to complete evolution due to API limits" >&2
184
- # Clean up any partial target file before exiting
185
- rm -f "$target_file"
186
- exit 3
187
- fi
188
- fi
189
-
147
+ # Success only if the target file was actually modified.
148
+ # Even if AI exited with code 0, if there were no changes, treat as failure to avoid stale copies.
149
+ if [[ "$file_was_modified" == "true" ]]; then
150
+ echo "[WORKER-$$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
151
+ return 0
152
+ fi
190
153
 
191
-
192
- # Check if the target file was actually modified
193
- local file_was_modified=false
194
- if [[ -f "$target_file" ]]; then
195
- local file_hash_after
196
- local file_mtime_after
197
- file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
198
- file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
199
-
200
- if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
201
- file_was_modified=true
202
- fi
203
- fi
204
-
205
- # Success only if the target file was actually modified.
206
- # Even if AI exited with code 0, if there were no changes, treat as failure to avoid stale copies.
207
- if [[ "$file_was_modified" == "true" ]]; then
208
- echo "[WORKER-$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
209
- return 0
210
- fi
211
-
212
- # Non-limit failure - no modification detected; clean up the copied file
213
- echo "[WORKER-$] AI changed nothing or failed; cleaning up temporary file" >&2
214
- rm -f "$target_file"
215
- echo "[WORKER-$] AI failed: exit code $ai_exit_code, no file changes detected" >&2
216
- return 1
217
- done
218
-
154
+ # No modification detected; clean up the copied file
155
+ echo "[WORKER-$$] AI changed nothing or failed; cleaning up temporary file" >&2
156
+ rm -f "$target_file"
157
+ echo "[WORKER-$$] AI failed: exit code $ai_exit_code, no file changes detected" >&2
158
+ return 1
219
159
  }
220
160
 
221
161
  # Validate paths
@@ -370,9 +310,9 @@ CRITICAL: If you do not know how to implement what was asked for, or if the requ
370
310
  return 1
371
311
  }
372
312
 
373
- # Try AI models with round-robin based on candidate ID
313
+ # Call AI with random model selection
374
314
  if ! call_ai_for_evolution "$evolution_prompt" "$candidate_id"; then
375
- echo "[WORKER-$$] ERROR: All AI models failed to generate code - leaving as pending for retry" >&2
315
+ echo "[WORKER-$$] ERROR: AI model failed to generate code - leaving as pending for retry" >&2
376
316
  safe_popd
377
317
  rm -f "$target_file" # Clean up on failure
378
318
  # Return with special code to indicate AI failure (should remain pending)
package/lib/ai-cli.sh CHANGED
@@ -298,14 +298,13 @@ get_models_for_command() {
298
298
  echo "$model_list"
299
299
  }
300
300
 
301
- # Call AI with random selection and fallback support
302
- # Usage: call_ai_with_round_robin <prompt> <command> <hash_value>
301
+ # Call AI with random model selection (no fallback)
302
+ # Usage: call_ai_random <prompt> <command>
303
303
  # command: "run" or "ideate"
304
- # hash_value: unused (kept for backward compatibility)
305
- call_ai_with_round_robin() {
304
+ # Picks one random model from the list and uses it
305
+ call_ai_random() {
306
306
  local prompt="$1"
307
307
  local command="$2"
308
- local hash_value="${3:-0}"
309
308
 
310
309
  # Get model list for this command
311
310
  local model_list
@@ -324,69 +323,43 @@ call_ai_with_round_robin() {
324
323
  return 1
325
324
  fi
326
325
 
327
- # Shuffle the models using Fisher-Yates algorithm for random selection
326
+ # Pick one random model
328
327
  local num_models=${#models[@]}
329
- for ((i=num_models-1; i>0; i--)); do
330
- local j=$((RANDOM % (i+1)))
331
- # Swap models[i] and models[j]
332
- local temp="${models[i]}"
333
- models[i]="${models[j]}"
334
- models[j]="$temp"
335
- done
328
+ local random_index=$((RANDOM % num_models))
329
+ local model="${models[$random_index]}"
336
330
 
337
- # Use the shuffled array directly
338
- local ordered_models=("${models[@]}")
331
+ echo "[AI] Selected $model for $command (random from $num_models models)" >&2
339
332
 
340
- # Debug output (commented out - no need to show shuffled order every time)
341
- # echo "[AI] Model order for $command (random): ${ordered_models[*]}" >&2
333
+ # Call the AI model
334
+ local ai_output
335
+ ai_output=$(call_ai_model_configured "$model" "$prompt")
336
+ local ai_exit_code=$?
342
337
 
343
- # Track models that hit usage limits
344
- local limited_models=()
345
- local tried_models=()
346
-
347
- # Try each model in order
348
- for model in "${ordered_models[@]}"; do
349
- echo "[AI] Attempting $command with $model" >&2
350
- tried_models+=("$model")
351
-
352
- # Call the AI model
353
- local ai_output
354
- ai_output=$(call_ai_model_configured "$model" "$prompt")
355
- local ai_exit_code=$?
356
-
357
- # Clean output if needed
358
- ai_output=$(clean_ai_output "$ai_output" "$model")
359
-
360
- # Success if exit code is 0, or if it's just a timeout (124)
361
- # Timeout doesn't mean the AI failed - it may have completed the task
362
- if [[ $ai_exit_code -eq 0 ]] || [[ $ai_exit_code -eq 124 ]]; then
363
- if [[ $ai_exit_code -eq 124 ]]; then
364
- echo "[AI] $model timed out but continuing (exit code: 124)" >&2
365
- else
366
- echo "[AI] $model returned exit code 0" >&2
367
- fi
368
- # Export the successful model for tracking (used by worker)
369
- export SUCCESSFUL_RUN_MODEL="$model"
370
- # Debug: log what AI returned on success
371
- if [[ "${DEBUG_AI_SUCCESS:-}" == "true" ]]; then
372
- echo "[AI] $model success output preview:" >&2
373
- echo "$ai_output" | head -10 >&2
374
- echo "[AI] (truncated to first 10 lines)" >&2
375
- fi
376
- # Output the cleaned result
377
- echo "$ai_output"
378
- return 0
379
- fi
380
-
381
- echo "[AI] $model returned exit code $ai_exit_code, trying next model..." >&2
382
- done
383
-
384
- # All models have been tried
385
- echo "[AI] All models have been tried without success" >&2
386
- return 1
338
+ # Clean output if needed
339
+ ai_output=$(clean_ai_output "$ai_output" "$model")
340
+
341
+ # Export the model used for tracking (used by worker)
342
+ export SUCCESSFUL_RUN_MODEL="$model"
343
+
344
+ # Log result
345
+ if [[ $ai_exit_code -eq 0 ]]; then
346
+ echo "[AI] $model returned exit code 0" >&2
347
+ elif [[ $ai_exit_code -eq 124 ]]; then
348
+ echo "[AI] $model timed out (exit code: 124)" >&2
349
+ else
350
+ echo "[AI] $model returned exit code $ai_exit_code" >&2
351
+ fi
352
+
353
+ # Output the result
354
+ echo "$ai_output"
355
+ return $ai_exit_code
356
+ }
357
+
358
+ # Legacy function names for compatibility
359
+ call_ai_with_round_robin() {
360
+ call_ai_random "$@"
387
361
  }
388
362
 
389
- # Legacy function name for compatibility
390
363
  call_ai_with_fallbacks() {
391
- call_ai_with_round_robin "$@"
364
+ call_ai_random "$@"
392
365
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.8.33",
3
+ "version": "1.8.35",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",