claude-evolve 1.6.12 → 1.6.14
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 +70 -68
- package/lib/config.sh +3 -2
- package/package.json +1 -1
package/bin/claude-evolve-worker
CHANGED
|
@@ -30,6 +30,7 @@ cleanup_on_exit() {
|
|
|
30
30
|
echo "[WORKER-$$] Determining status before resetting" >&2
|
|
31
31
|
"$PYTHON_CMD" -c "
|
|
32
32
|
import sys
|
|
33
|
+
sys.path.insert(0, '$SCRIPT_DIR/..')
|
|
33
34
|
from lib.evolution_csv import EvolutionCSV
|
|
34
35
|
csv = EvolutionCSV('$FULL_CSV_PATH')
|
|
35
36
|
# Acquire lock and read current status safely
|
|
@@ -115,76 +116,77 @@ call_ai_for_evolution() {
|
|
|
115
116
|
local hash_value=$((gen_num * 1000 + id_num))
|
|
116
117
|
|
|
117
118
|
# Use the centralized AI library for evolution (run command)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
119
|
+
local ai_output
|
|
120
|
+
ai_output=$(call_ai_with_round_robin "$prompt" "run" "$hash_value")
|
|
121
|
+
local ai_exit_code=$?
|
|
122
|
+
|
|
123
|
+
# Handle special exit codes
|
|
124
|
+
if [[ $ai_exit_code -eq 3 ]]; then
|
|
125
|
+
# All models hit usage limits
|
|
126
|
+
if [[ $retry_count -lt $max_retries ]]; then
|
|
127
|
+
((retry_count++))
|
|
128
|
+
echo "[WORKER-$] All models hit usage limits (retry $retry_count/$max_retries)" >&2
|
|
129
|
+
echo "[WORKER-$] Waiting $wait_seconds seconds ($(($wait_seconds / 60)) minutes) before retrying..." >&2
|
|
130
|
+
|
|
131
|
+
# Sleep with countdown
|
|
132
|
+
local remaining=$wait_seconds
|
|
133
|
+
while [[ $remaining -gt 0 ]]; do
|
|
134
|
+
if [[ $((remaining % 60)) -eq 0 ]]; then
|
|
135
|
+
echo "[WORKER-$] Retrying in $((remaining / 60)) minutes..." >&2
|
|
136
|
+
fi
|
|
137
|
+
sleep 60
|
|
138
|
+
remaining=$((remaining - 60))
|
|
139
|
+
done
|
|
140
|
+
|
|
141
|
+
echo "[WORKER-$] Retrying AI call (attempt #$((retry_count + 1)))..." >&2
|
|
142
|
+
|
|
143
|
+
# Exponential backoff: double the wait time, up to max
|
|
144
|
+
wait_seconds=$((wait_seconds * 2))
|
|
145
|
+
if [[ $wait_seconds -gt $max_wait_seconds ]]; then
|
|
146
|
+
wait_seconds=$max_wait_seconds
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Continue to retry
|
|
150
|
+
continue
|
|
151
|
+
else
|
|
152
|
+
# Exhausted retries
|
|
153
|
+
echo "[WORKER-$] All models hit usage limits after $max_retries retries" >&2
|
|
154
|
+
echo "[WORKER-$] Unable to complete evolution due to API limits" >&2
|
|
155
|
+
# Clean up any partial target file before exiting
|
|
156
|
+
rm -f "$target_file"
|
|
157
|
+
exit 3
|
|
158
|
+
fi
|
|
135
159
|
fi
|
|
136
|
-
|
|
137
|
-
remaining=$((remaining - 60))
|
|
138
|
-
done
|
|
139
|
-
|
|
140
|
-
echo "[WORKER-$$] Retrying AI call (attempt #$((retry_count + 1)))..." >&2
|
|
141
|
-
|
|
142
|
-
# Exponential backoff: double the wait time, up to max
|
|
143
|
-
wait_seconds=$((wait_seconds * 2))
|
|
144
|
-
if [[ $wait_seconds -gt $max_wait_seconds ]]; then
|
|
145
|
-
wait_seconds=$max_wait_seconds
|
|
146
|
-
fi
|
|
147
|
-
|
|
148
|
-
# Continue to retry
|
|
149
|
-
continue
|
|
150
|
-
else
|
|
151
|
-
# Exhausted retries
|
|
152
|
-
echo "[WORKER-$$] All models hit usage limits after $max_retries retries" >&2
|
|
153
|
-
echo "[WORKER-$$] Unable to complete evolution due to API limits" >&2
|
|
154
|
-
# Clean up any partial target file before exiting
|
|
155
|
-
rm -f "$target_file"
|
|
156
|
-
exit 3
|
|
157
|
-
fi
|
|
158
|
-
fi
|
|
159
|
-
|
|
160
|
-
# Check if the target file was actually modified
|
|
161
|
-
local file_was_modified=false
|
|
162
|
-
if [[ -f "$target_file" ]]; then
|
|
163
|
-
local file_hash_after
|
|
164
|
-
local file_mtime_after
|
|
165
|
-
file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
|
|
166
|
-
file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
|
|
167
|
-
|
|
168
|
-
if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
|
|
169
|
-
file_was_modified=true
|
|
170
|
-
fi
|
|
171
|
-
fi
|
|
172
|
-
|
|
173
|
-
# Success only if the target file was actually modified.
|
|
174
|
-
# Even if AI exited with code 0, if there were no changes, treat as failure to avoid stale copies.
|
|
175
|
-
if [[ "$file_was_modified" == "true" ]]; then
|
|
176
|
-
echo "[WORKER-$$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
|
|
177
|
-
# Output the result for the worker to use
|
|
178
|
-
echo "$ai_output"
|
|
179
|
-
return 0
|
|
180
|
-
fi
|
|
160
|
+
|
|
181
161
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
162
|
+
|
|
163
|
+
# Check if the target file was actually modified
|
|
164
|
+
local file_was_modified=false
|
|
165
|
+
if [[ -f "$target_file" ]]; then
|
|
166
|
+
local file_hash_after
|
|
167
|
+
local file_mtime_after
|
|
168
|
+
file_hash_after=$(shasum -a 256 "$target_file" 2>/dev/null | cut -d' ' -f1)
|
|
169
|
+
file_mtime_after=$(stat -f %m "$target_file" 2>/dev/null || stat -c %Y "$target_file" 2>/dev/null)
|
|
170
|
+
|
|
171
|
+
if [[ "$file_hash_before" != "$file_hash_after" ]] || [[ "$file_mtime_before" != "$file_mtime_after" ]]; then
|
|
172
|
+
file_was_modified=true
|
|
173
|
+
fi
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
# Success only if the target file was actually modified.
|
|
177
|
+
# Even if AI exited with code 0, if there were no changes, treat as failure to avoid stale copies.
|
|
178
|
+
if [[ "$file_was_modified" == "true" ]]; then
|
|
179
|
+
echo "[WORKER-$] AI successfully modified $target_file (exit code: $ai_exit_code)" >&2
|
|
180
|
+
return 0
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Non-limit failure - no modification detected; clean up the copied file
|
|
184
|
+
echo "[WORKER-$] AI changed nothing or failed; cleaning up temporary file" >&2
|
|
185
|
+
rm -f "$target_file"
|
|
186
|
+
echo "[WORKER-$] AI failed: exit code $ai_exit_code, no file changes detected" >&2
|
|
187
|
+
return 1
|
|
188
|
+
done
|
|
189
|
+
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
# Validate paths
|
package/lib/config.sh
CHANGED
|
@@ -55,9 +55,9 @@ DEFAULT_MEMORY_LIMIT_MB=12288
|
|
|
55
55
|
|
|
56
56
|
# Default LLM CLI configuration - use simple variables instead of arrays
|
|
57
57
|
# Run: 100% local with qwen3 via Codex+Ollama (more reliable than aider)
|
|
58
|
-
DEFAULT_LLM_RUN="codex-qwen3 codex-oss"
|
|
58
|
+
DEFAULT_LLM_RUN="codex-qwen3 codex-oss gemini-flash"
|
|
59
59
|
# Ideate: Commercial models for idea generation + local fallback
|
|
60
|
-
DEFAULT_LLM_IDEATE="gemini sonnet-think gpt5high o3high glm grok-4 codex-qwen3 codex-oss"
|
|
60
|
+
DEFAULT_LLM_IDEATE="gemini sonnet-think gpt5high o3high glm grok-4 codex-qwen3 codex-oss gemini-flash"
|
|
61
61
|
|
|
62
62
|
# Load configuration from config file
|
|
63
63
|
load_config() {
|
|
@@ -116,6 +116,7 @@ load_config() {
|
|
|
116
116
|
LLM_CLI_o3high='codex exec --profile o3high --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
|
|
117
117
|
LLM_CLI_codex='codex exec --dangerously-bypass-approvals-and-sandbox "{{PROMPT}}"'
|
|
118
118
|
LLM_CLI_gemini='gemini -y -p "{{PROMPT}}"'
|
|
119
|
+
LLM_CLI_gemini_flash='gemini -y -p "{{PROMPT}}" --model gemini-2.5-flash'
|
|
119
120
|
LLM_CLI_opus='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "{{PROMPT}}"'
|
|
120
121
|
LLM_CLI_opus_think='claude --dangerously-skip-permissions --mcp-config "" --model opus -p "ultrathink\n\n{{PROMPT}}"'
|
|
121
122
|
LLM_CLI_sonnet='claude --dangerously-skip-permissions --mcp-config "" --model sonnet -p "{{PROMPT}}"'
|