claude-evolve 1.5.28 → 1.5.30

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.
@@ -72,68 +72,106 @@ fi
72
72
  call_ai_for_evolution() {
73
73
  local prompt="$1"
74
74
  local candidate_id="$2"
75
-
75
+
76
76
  # Get target file path from worker context
77
77
  local target_file="$FULL_OUTPUT_DIR/evolution_${candidate_id}.py"
78
-
79
- # Capture file state before AI call
80
- local file_hash_before=""
81
- local file_mtime_before=""
82
- if [[ -f "$target_file" ]]; then
83
- file_hash_before=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
84
- file_mtime_before=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
85
- fi
86
-
87
- # Extract generation and ID numbers for round-robin calculation
88
- local gen_num=0
89
- local id_num=0
90
- if [[ $candidate_id =~ ^gen([0-9]+)-([0-9]+)$ ]]; then
91
- gen_num=$((10#${BASH_REMATCH[1]}))
92
- id_num=$((10#${BASH_REMATCH[2]}))
93
- fi
94
-
95
- # Calculate hash for round-robin (combine generation and ID)
96
- local hash_value=$((gen_num * 1000 + id_num))
97
-
98
- # Use the centralized AI library for evolution (run command)
99
- local ai_output
100
- ai_output=$(call_ai_with_round_robin "$prompt" "run" "$hash_value")
101
- local ai_exit_code=$?
102
-
103
- # Handle special exit codes
104
- if [[ $ai_exit_code -eq 3 ]]; then
105
- echo "[WORKER-$$] All models hit usage limits" >&2
106
- echo "[WORKER-$$] Unable to complete evolution due to API limits" >&2
107
- exit 3
108
- fi
109
-
110
- # Check if the target file was actually modified
111
- local file_was_modified=false
112
- if [[ -f "$target_file" ]]; then
113
- local file_hash_after
114
- local file_mtime_after
115
- file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
116
- file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
117
-
118
- if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
119
- file_was_modified=true
78
+
79
+ # Retry configuration for API limits
80
+ local retry_count=0
81
+ local max_retries=3
82
+ local wait_seconds=300 # Start with 5 minutes
83
+ local max_wait_seconds=1800 # Cap at 30 minutes
84
+
85
+ while true; do
86
+ # Capture file state before AI call
87
+ local file_hash_before=""
88
+ local file_mtime_before=""
89
+ if [[ -f "$target_file" ]]; then
90
+ file_hash_before=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
91
+ file_mtime_before=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
120
92
  fi
121
- fi
122
-
123
- # Success if file was modified OR exit code is 0 (for cases where file validation isn't applicable)
124
- if [[ "$file_was_modified" == "true" ]] || [[ $ai_exit_code -eq 0 ]]; then
125
- if [[ "$file_was_modified" == "true" ]]; then
126
- echo "[WORKER-$$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
127
- else
128
- echo "[WORKER-$$] AI succeeded with exit code 0" >&2
93
+
94
+ # Extract generation and ID numbers for round-robin calculation
95
+ local gen_num=0
96
+ local id_num=0
97
+ if [[ $candidate_id =~ ^gen([0-9]+)-([0-9]+)$ ]]; then
98
+ gen_num=$((10#${BASH_REMATCH[1]}))
99
+ id_num=$((10#${BASH_REMATCH[2]}))
129
100
  fi
130
- # Output the result for the worker to use
131
- echo "$ai_output"
132
- return 0
133
- fi
134
-
135
- echo "[WORKER-$$] AI failed: exit code $ai_exit_code, no file changes detected" >&2
136
- return 1
101
+
102
+ # Calculate hash for round-robin (combine generation and ID)
103
+ local hash_value=$((gen_num * 1000 + id_num))
104
+
105
+ # Use the centralized AI library for evolution (run command)
106
+ local ai_output
107
+ ai_output=$(call_ai_with_round_robin "$prompt" "run" "$hash_value")
108
+ local ai_exit_code=$?
109
+
110
+ # Handle special exit codes
111
+ if [[ $ai_exit_code -eq 3 ]]; then
112
+ # All models hit usage limits
113
+ if [[ $retry_count -lt $max_retries ]]; then
114
+ ((retry_count++))
115
+ echo "[WORKER-$$] All models hit usage limits (retry $retry_count/$max_retries)" >&2
116
+ echo "[WORKER-$$] Waiting $wait_seconds seconds ($(($wait_seconds / 60)) minutes) before retrying..." >&2
117
+
118
+ # Sleep with countdown
119
+ local remaining=$wait_seconds
120
+ while [[ $remaining -gt 0 ]]; do
121
+ if [[ $((remaining % 60)) -eq 0 ]]; then
122
+ echo "[WORKER-$$] Retrying in $((remaining / 60)) minutes..." >&2
123
+ fi
124
+ sleep 60
125
+ remaining=$((remaining - 60))
126
+ done
127
+
128
+ echo "[WORKER-$$] Retrying AI call (attempt #$((retry_count + 1)))..." >&2
129
+
130
+ # Exponential backoff: double the wait time, up to max
131
+ wait_seconds=$((wait_seconds * 2))
132
+ if [[ $wait_seconds -gt $max_wait_seconds ]]; then
133
+ wait_seconds=$max_wait_seconds
134
+ fi
135
+
136
+ # Continue to retry
137
+ continue
138
+ else
139
+ # Exhausted retries
140
+ echo "[WORKER-$$] All models hit usage limits after $max_retries retries" >&2
141
+ echo "[WORKER-$$] Unable to complete evolution due to API limits" >&2
142
+ exit 3
143
+ fi
144
+ fi
145
+
146
+ # Check if the target file was actually modified
147
+ local file_was_modified=false
148
+ if [[ -f "$target_file" ]]; then
149
+ local file_hash_after
150
+ local file_mtime_after
151
+ file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
152
+ file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
153
+
154
+ if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
155
+ file_was_modified=true
156
+ fi
157
+ fi
158
+
159
+ # Success if file was modified OR exit code is 0 (for cases where file validation isn't applicable)
160
+ if [[ "$file_was_modified" == "true" ]] || [[ $ai_exit_code -eq 0 ]]; then
161
+ if [[ "$file_was_modified" == "true" ]]; then
162
+ echo "[WORKER-$$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
163
+ else
164
+ echo "[WORKER-$$] AI succeeded with exit code 0" >&2
165
+ fi
166
+ # Output the result for the worker to use
167
+ echo "$ai_output"
168
+ return 0
169
+ fi
170
+
171
+ # Non-limit failure - don't retry
172
+ echo "[WORKER-$$] AI failed: exit code $ai_exit_code, no file changes detected" >&2
173
+ return 1
174
+ done
137
175
  }
138
176
 
139
177
  # Validate paths
@@ -222,11 +260,13 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
222
260
  # Use relative path for AI prompt
223
261
  local target_basename=$(basename "$target_file")
224
262
  local evolution_prompt="Modify the algorithm in $target_basename based on this description: $description
225
-
263
+
226
264
  The modification should be substantial and follow the description exactly. Make sure the algorithm still follows all interface requirements and can run properly.
227
265
 
228
266
  Important: Make meaningful changes that match the description. Don't just add comments or make trivial adjustments.
229
267
 
268
+ CRITICAL: If you do not know how to implement what was asked for, or if the requested change is unclear or not feasible, you MUST refuse to make any changes. DO NOT modify the code if you are uncertain about the implementation. Simply respond that you cannot implement the requested change and explain why. It is better to refuse than to make incorrect or random changes.
269
+
230
270
  CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
231
271
 
232
272
  if [[ "$is_baseline" != "true" ]]; then
package/lib/ai-cli.sh CHANGED
@@ -19,7 +19,7 @@ call_ai_model_configured() {
19
19
  case "$model_name" in
20
20
  opus|sonnet)
21
21
  local ai_output
22
- ai_output=$(timeout 300 claude --dangerously-skip-permissions --model "$model_name" -p "$prompt" 2>&1)
22
+ ai_output=$(timeout 300 claude --dangerously-skip-permissions --mcp-config '' --model "$model_name" -p "$prompt" 2>&1)
23
23
  local ai_exit_code=$?
24
24
  ;;
25
25
  sonnet-think)
@@ -28,7 +28,7 @@ call_ai_model_configured() {
28
28
  local think_prompt="ultrathink
29
29
 
30
30
  $prompt"
31
- ai_output=$(timeout 600 claude --dangerously-skip-permissions --model sonnet -p "$think_prompt" 2>&1)
31
+ ai_output=$(timeout 600 claude --dangerously-skip-permissions --mcp-config '' --model sonnet -p "$think_prompt" 2>&1)
32
32
  local ai_exit_code=$?
33
33
  ;;
34
34
  opus-think)
@@ -37,7 +37,7 @@ $prompt"
37
37
  local think_prompt="ultrathink
38
38
 
39
39
  $prompt"
40
- ai_output=$(timeout 600 claude --dangerously-skip-permissions --model opus -p "$think_prompt" 2>&1)
40
+ ai_output=$(timeout 600 claude --dangerously-skip-permissions --mcp-config '' --model opus -p "$think_prompt" 2>&1)
41
41
  local ai_exit_code=$?
42
42
  ;;
43
43
  gpt5high)
@@ -81,6 +81,11 @@ $prompt"
81
81
  ai_output=$(timeout 300 opencode -m openrouter/z-ai/glm-4.6 run "$prompt" 2>&1)
82
82
  local ai_exit_code=$?
83
83
  ;;
84
+ deepseek)
85
+ local ai_output
86
+ ai_output=$(timeout 300 opencode -m openrouter/deepseek/deepseek-v3.1-terminus run "$prompt" 2>&1)
87
+ local ai_exit_code=$?
88
+ ;;
84
89
  *)
85
90
  echo "[ERROR] Unknown model: $model_name" >&2
86
91
  return 1
package/lib/config.sh CHANGED
@@ -54,8 +54,8 @@ DEFAULT_MAX_RETRIES=3
54
54
  DEFAULT_MEMORY_LIMIT_MB=12288
55
55
 
56
56
  # Default LLM CLI configuration - use simple variables instead of arrays
57
- DEFAULT_LLM_RUN="sonnet gpt5 cursor-sonnet glm"
58
- DEFAULT_LLM_IDEATE="gemini sonnet-think sonnet-think gpt5high sonnet-think o3high"
57
+ DEFAULT_LLM_RUN="sonnet gpt5 cursor-sonnet glm deepseek"
58
+ DEFAULT_LLM_IDEATE="gemini sonnet-think sonnet-think gpt5high sonnet-think o3high glm"
59
59
 
60
60
  # Load configuration from config file
61
61
  load_config() {
@@ -102,13 +102,14 @@ load_config() {
102
102
  LLM_CLI_o3high='codex exec --profile o3high --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
103
103
  LLM_CLI_codex='codex exec --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
104
104
  LLM_CLI_gemini='gemini -y -p "{{PROMPT}}"'
105
- LLM_CLI_opus='claude --dangerously-skip-permissions --model opus -p "{{PROMPT}}"'
106
- LLM_CLI_opus_think='claude --dangerously-skip-permissions --model opus -p "ultrathink\n\n{{PROMPT}}"'
107
- LLM_CLI_sonnet='claude --dangerously-skip-permissions --model sonnet -p "{{PROMPT}}"'
108
- LLM_CLI_sonnet_think='claude --dangerously-skip-permissions --model sonnet -p "ultrathink\n\n{{PROMPT}}"'
105
+ LLM_CLI_opus='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "{{PROMPT}}"'
106
+ LLM_CLI_opus_think='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "ultrathink\n\n{{PROMPT}}"'
107
+ LLM_CLI_sonnet='claude --dangerously-skip-permissions --mcp-config "" --model sonnet -p "{{PROMPT}}"'
108
+ LLM_CLI_sonnet_think='claude --dangerously-skip-permissions --mcp-config "" --model sonnet -p "ultrathink\n\n{{PROMPT}}"'
109
109
  LLM_CLI_cursor_sonnet='cursor-agent sonnet -p "{{PROMPT}}"'
110
110
  LLM_CLI_cursor_opus='cursor-agent opus -p "{{PROMPT}}"'
111
111
  LLM_CLI_glm='opencode -m openrouter/z-ai/glm-4.6 run "{{PROMPT}}"'
112
+ LLM_CLI_deepseek='opencode -m openrouter/deepseek/deepseek-v3.1-terminus run "{{PROMPT}}"'
112
113
  LLM_RUN="$DEFAULT_LLM_RUN"
113
114
  LLM_IDEATE="$DEFAULT_LLM_IDEATE"
114
115
 
@@ -328,7 +329,7 @@ show_config() {
328
329
  echo " Memory limit: ${MEMORY_LIMIT_MB}MB"
329
330
  echo " LLM configuration:"
330
331
  # Show LLM configurations using dynamic variable names
331
- for model in gpt5high o3high codex gemini opus opus_think sonnet sonnet_think cursor_sonnet cursor_opus glm; do
332
+ for model in gpt5high o3high codex gemini opus opus_think sonnet sonnet_think cursor_sonnet cursor_opus glm deepseek; do
332
333
  var_name="LLM_CLI_${model}"
333
334
  var_value=$(eval echo "\$$var_name")
334
335
  if [[ -n "$var_value" ]]; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-evolve",
3
- "version": "1.5.28",
3
+ "version": "1.5.30",
4
4
  "bin": {
5
5
  "claude-evolve": "./bin/claude-evolve",
6
6
  "claude-evolve-main": "./bin/claude-evolve-main",