claude-evolve 1.5.1 → 1.5.2
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-ideate +389 -276
- package/bin/claude-evolve-run +15 -3
- package/bin/claude-evolve-worker +19 -215
- package/lib/ai-cli.sh +221 -0
- package/lib/config.sh +71 -1
- package/package.json +1 -1
- package/templates/config.yaml +17 -1
package/bin/claude-evolve-ideate
CHANGED
|
@@ -6,6 +6,10 @@ set -e
|
|
|
6
6
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
7
|
# shellcheck source=../lib/config.sh
|
|
8
8
|
source "$SCRIPT_DIR/../lib/config.sh"
|
|
9
|
+
# shellcheck source=../lib/csv-lock.sh
|
|
10
|
+
source "$SCRIPT_DIR/../lib/csv-lock.sh"
|
|
11
|
+
# shellcheck source=../lib/ai-cli.sh
|
|
12
|
+
source "$SCRIPT_DIR/../lib/ai-cli.sh"
|
|
9
13
|
|
|
10
14
|
# Use CLAUDE_EVOLVE_CONFIG if set, otherwise default
|
|
11
15
|
if [[ -n ${CLAUDE_EVOLVE_CONFIG:-} ]]; then
|
|
@@ -14,154 +18,57 @@ else
|
|
|
14
18
|
load_config
|
|
15
19
|
fi
|
|
16
20
|
|
|
17
|
-
#
|
|
18
|
-
get_model_for_generation() {
|
|
19
|
-
local generation="$1"
|
|
20
|
-
local gen_num
|
|
21
|
-
|
|
22
|
-
# Extract numeric part of generation (e.g., "05" from gen05)
|
|
23
|
-
if [[ $generation =~ ^0*([0-9]+)$ ]]; then
|
|
24
|
-
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
25
|
-
else
|
|
26
|
-
gen_num=1 # Default for malformed input
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
# Check which AI tools are available
|
|
30
|
-
local has_o3=false
|
|
31
|
-
local has_gemini=false
|
|
32
|
-
|
|
33
|
-
if command -v codex >/dev/null 2>&1; then
|
|
34
|
-
has_o3=true
|
|
35
|
-
fi
|
|
36
|
-
|
|
37
|
-
if command -v gemini >/dev/null 2>&1; then
|
|
38
|
-
has_gemini=true
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# Determine rotation based on what's available
|
|
42
|
-
if [[ "$has_o3" == "true" && "$has_gemini" == "true" ]]; then
|
|
43
|
-
# All three available: opus -> o3 -> gemini rotation
|
|
44
|
-
case $((gen_num % 3)) in
|
|
45
|
-
1) echo "opus" ;; # 1, 4, 7, 10...
|
|
46
|
-
2) echo "o3" ;; # 2, 5, 8, 11...
|
|
47
|
-
0) echo "gemini" ;; # 3, 6, 9, 12...
|
|
48
|
-
esac
|
|
49
|
-
elif [[ "$has_o3" == "true" ]]; then
|
|
50
|
-
# Only opus and o3: alternate between them
|
|
51
|
-
if (( gen_num % 2 == 1 )); then
|
|
52
|
-
echo "opus" # Odd generations
|
|
53
|
-
else
|
|
54
|
-
echo "o3" # Even generations
|
|
55
|
-
fi
|
|
56
|
-
elif [[ "$has_gemini" == "true" ]]; then
|
|
57
|
-
# Only opus and gemini: alternate between them
|
|
58
|
-
if (( gen_num % 2 == 1 )); then
|
|
59
|
-
echo "opus" # Odd generations
|
|
60
|
-
else
|
|
61
|
-
echo "gemini" # Even generations
|
|
62
|
-
fi
|
|
63
|
-
else
|
|
64
|
-
# Only opus available
|
|
65
|
-
echo "opus"
|
|
66
|
-
fi
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
# Helper function to call AI model (alternating based on generation)
|
|
21
|
+
# Helper function to call AI with limit check
|
|
70
22
|
call_ai_with_limit_check() {
|
|
71
23
|
local prompt="$1"
|
|
72
24
|
local generation="${2:-01}" # Default to generation 01 if not provided
|
|
73
25
|
|
|
74
|
-
#
|
|
75
|
-
local
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Try preferred model first
|
|
81
|
-
if [[ "$preferred_model" == "o3" ]] && command -v codex >/dev/null 2>&1; then
|
|
82
|
-
echo "[INFO] Using codex o3 for ideation" >&2
|
|
83
|
-
|
|
84
|
-
# Call codex with o3 model using exec subcommand
|
|
85
|
-
local ai_output
|
|
86
|
-
# Pass prompt as argument, not via stdin
|
|
87
|
-
ai_output=$(timeout 300 codex exec -m o3 --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
88
|
-
local ai_exit_code=$?
|
|
89
|
-
|
|
90
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
91
|
-
# For ideation, AI modifies files directly - just return success
|
|
92
|
-
echo "[INFO] Codex o3 succeeded" >&2
|
|
93
|
-
return 0
|
|
94
|
-
else
|
|
95
|
-
echo "[WARN] Codex o3 failed with exit code $ai_exit_code, falling back to Claude Opus" >&2
|
|
96
|
-
preferred_model="opus"
|
|
97
|
-
fi
|
|
98
|
-
elif [[ "$preferred_model" == "gemini" ]] && command -v gemini >/dev/null 2>&1; then
|
|
99
|
-
echo "[INFO] Using gemini 2.5 pro for ideation" >&2
|
|
100
|
-
|
|
101
|
-
# Call gemini with -y and -p flags
|
|
102
|
-
local ai_output
|
|
103
|
-
ai_output=$(echo "$prompt" | timeout 300 gemini -y -p 2>&1)
|
|
104
|
-
local ai_exit_code=$?
|
|
105
|
-
|
|
106
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
107
|
-
# For ideation, AI modifies files directly - just return success
|
|
108
|
-
echo "[INFO] Gemini succeeded" >&2
|
|
109
|
-
return 0
|
|
110
|
-
else
|
|
111
|
-
echo "[WARN] Gemini failed with exit code $ai_exit_code, falling back to Claude Opus" >&2
|
|
112
|
-
preferred_model="opus"
|
|
113
|
-
fi
|
|
26
|
+
# Calculate hash value for round-robin based on generation
|
|
27
|
+
local gen_num
|
|
28
|
+
if [[ $generation =~ ^0*([0-9]+)$ ]]; then
|
|
29
|
+
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
30
|
+
else
|
|
31
|
+
gen_num=1
|
|
114
32
|
fi
|
|
115
33
|
|
|
116
|
-
# Use
|
|
117
|
-
|
|
34
|
+
# Use centralized AI library for ideation
|
|
35
|
+
local ai_output
|
|
36
|
+
ai_output=$(call_ai_with_round_robin "$prompt" "ideate" "$gen_num")
|
|
37
|
+
local ai_exit_code=$?
|
|
118
38
|
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# Check for usage limit
|
|
125
|
-
if echo "$claude_output" | grep -q "Claude AI usage limit reached"; then
|
|
126
|
-
# Extract timestamp if available
|
|
127
|
-
local limit_timestamp=$(echo "$claude_output" | grep -o "Claude AI usage limit reached|[0-9]*" | cut -d'|' -f2)
|
|
128
|
-
|
|
129
|
-
# Print red error message
|
|
130
|
-
echo -e "\033[31m[ERROR] CLAUDE AI USAGE LIMIT REACHED!\033[0m" >&2
|
|
39
|
+
# Handle special exit codes
|
|
40
|
+
if [[ $ai_exit_code -eq 3 ]]; then
|
|
41
|
+
# All models hit usage limits
|
|
42
|
+
echo -e "\033[31m[ERROR] ALL AI MODELS HIT USAGE LIMITS!\033[0m" >&2
|
|
131
43
|
echo -e "\033[31m[ERROR] Ideation halted due to API rate limits.\033[0m" >&2
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# Convert timestamp to human-readable format
|
|
135
|
-
local limit_date=$(date -r "$limit_timestamp" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "Unknown time")
|
|
136
|
-
echo -e "\033[31m[ERROR] Limit will be released at: $limit_date\033[0m" >&2
|
|
137
|
-
fi
|
|
138
|
-
|
|
139
|
-
echo -e "\033[33m[INFO] Please wait for the rate limit to reset before continuing.\033[0m" >&2
|
|
140
|
-
echo -e "\033[33m[INFO] No ideas were generated. Run ideate again when the limit resets.\033[0m" >&2
|
|
141
|
-
|
|
44
|
+
echo -e "\033[33m[INFO] Please wait for the rate limits to reset before continuing.\033[0m" >&2
|
|
45
|
+
echo -e "\033[33m[INFO] No ideas were generated. Run ideate again when the limits reset.\033[0m" >&2
|
|
142
46
|
exit 1
|
|
143
47
|
fi
|
|
144
48
|
|
|
145
|
-
if [[ $
|
|
49
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
146
50
|
# For ideation, AI modifies files directly - just return success
|
|
147
|
-
echo "[INFO]
|
|
51
|
+
echo "[INFO] AI succeeded" >&2
|
|
148
52
|
return 0
|
|
149
53
|
else
|
|
150
|
-
return $
|
|
54
|
+
return $ai_exit_code
|
|
151
55
|
fi
|
|
152
56
|
}
|
|
153
57
|
|
|
58
|
+
|
|
154
59
|
# Backward compatibility alias
|
|
155
60
|
call_claude_with_limit_check() {
|
|
156
61
|
call_ai_with_limit_check "$@"
|
|
157
62
|
}
|
|
158
63
|
|
|
159
64
|
# Robust AI calling with fallbacks across all available models
|
|
160
|
-
|
|
65
|
+
call_ai_for_ideation() {
|
|
161
66
|
local prompt="$1"
|
|
162
67
|
local generation="${2:-01}"
|
|
68
|
+
local expected_count="${3:-1}" # Number of ideas expected to be added
|
|
69
|
+
local temp_csv_file="${4:-temp-csv-$$.csv}" # Optional temp CSV filename
|
|
163
70
|
|
|
164
|
-
#
|
|
71
|
+
# Calculate hash value for round-robin based on generation
|
|
165
72
|
local gen_num
|
|
166
73
|
if [[ $generation =~ ^0*([0-9]+)$ ]]; then
|
|
167
74
|
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
@@ -169,81 +76,47 @@ call_ai_with_fallbacks() {
|
|
|
169
76
|
gen_num=1
|
|
170
77
|
fi
|
|
171
78
|
|
|
172
|
-
#
|
|
173
|
-
local
|
|
174
|
-
if
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
available_models+=("gemini")
|
|
79
|
+
# Get the current row count before any modifications
|
|
80
|
+
local original_csv_count
|
|
81
|
+
if [[ -f "$temp_csv_file" ]]; then
|
|
82
|
+
original_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l)
|
|
83
|
+
else
|
|
84
|
+
original_csv_count=0
|
|
179
85
|
fi
|
|
180
|
-
available_models+=("opus") # Claude Opus always available
|
|
181
|
-
|
|
182
|
-
# Create ordered list based on round-robin for this generation
|
|
183
|
-
local num_models=${#available_models[@]}
|
|
184
|
-
local start_index=$((gen_num % num_models))
|
|
185
|
-
local models=()
|
|
186
86
|
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
done
|
|
87
|
+
# Use centralized AI library
|
|
88
|
+
local ai_output
|
|
89
|
+
ai_output=$(call_ai_with_round_robin "$prompt" "ideate" "$gen_num")
|
|
90
|
+
local ai_exit_code=$?
|
|
192
91
|
|
|
193
|
-
|
|
92
|
+
# Handle special exit codes
|
|
93
|
+
# No special handling for exit codes anymore
|
|
194
94
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
local ai_exit_code
|
|
201
|
-
|
|
202
|
-
if [[ "$model" == "o3" ]] && command -v codex >/dev/null 2>&1; then
|
|
203
|
-
# Pass prompt as argument, not via stdin
|
|
204
|
-
ai_output=$(timeout 300 codex exec -m o3 --dangerously-bypass-approvals-and-sandbox "$prompt" 2>&1)
|
|
205
|
-
ai_exit_code=$?
|
|
95
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
96
|
+
# For ideation, we need to verify the CSV file was actually modified
|
|
97
|
+
if [[ -f "$temp_csv_file" ]]; then
|
|
98
|
+
local new_csv_count
|
|
99
|
+
new_csv_count=$(grep -v '^[[:space:]]*$' "$temp_csv_file" | tail -n +2 | wc -l)
|
|
206
100
|
|
|
207
|
-
if [[ $
|
|
208
|
-
|
|
209
|
-
echo "[INFO] o3 completed successfully (exit code 0)" >&2
|
|
101
|
+
if [[ $new_csv_count -gt $original_csv_count ]]; then
|
|
102
|
+
echo "[INFO] AI completed successfully and modified CSV ($new_csv_count vs $original_csv_count rows)" >&2
|
|
210
103
|
return 0
|
|
104
|
+
else
|
|
105
|
+
echo "[INFO] $model returned exit code 0 but didn't modify CSV file" >&2
|
|
106
|
+
echo "[DEBUG] Expected file: $temp_csv_file" >&2
|
|
107
|
+
echo "[DEBUG] Original count: $original_csv_count, New count: $new_csv_count" >&2
|
|
108
|
+
return 1
|
|
211
109
|
fi
|
|
212
|
-
|
|
213
|
-
elif [[ "$model" == "gemini" ]] && command -v gemini >/dev/null 2>&1; then
|
|
214
|
-
ai_output=$(echo "$prompt" | timeout 300 gemini -y -p 2>&1)
|
|
215
|
-
ai_exit_code=$?
|
|
216
|
-
|
|
217
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
218
|
-
# For ideation, we don't care about output content - AI modifies files directly
|
|
219
|
-
echo "[INFO] gemini completed successfully (exit code 0)" >&2
|
|
220
|
-
return 0
|
|
221
|
-
fi
|
|
222
|
-
|
|
223
110
|
else
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
# Check for usage limits
|
|
230
|
-
if echo "$ai_output" | grep -q "Claude AI usage limit reached"; then
|
|
231
|
-
echo "[INFO] Claude hit usage limit" >&2
|
|
232
|
-
else
|
|
233
|
-
# For ideation, we don't care about output content - AI modifies files directly
|
|
234
|
-
echo "[INFO] $model completed successfully (exit code 0)" >&2
|
|
235
|
-
return 0
|
|
236
|
-
fi
|
|
237
|
-
fi
|
|
111
|
+
echo "[INFO] Exit code 0 but temp CSV file not found: $temp_csv_file" >&2
|
|
112
|
+
echo "[DEBUG] Current directory: $(pwd)" >&2
|
|
113
|
+
echo "[DEBUG] Files matching temp-csv-*.csv:" >&2
|
|
114
|
+
ls -la temp-csv-*.csv 2>&1 >&2
|
|
115
|
+
return 1
|
|
238
116
|
fi
|
|
239
|
-
|
|
240
|
-
echo "[WARN] $model failed or returned unusable output, trying next model..." >&2
|
|
241
|
-
echo "[DEBUG] $model exit code: ${ai_exit_code:-unknown}" >&2
|
|
242
|
-
echo "[DEBUG] $model output length: ${#ai_output} chars" >&2
|
|
243
|
-
echo "[DEBUG] $model output preview: $(echo "$ai_output" | head -3 | tr '\n' ' ')" >&2
|
|
244
|
-
done
|
|
117
|
+
fi
|
|
245
118
|
|
|
246
|
-
echo "[
|
|
119
|
+
echo "[INFO] No AI model successfully modified the CSV file" >&2
|
|
247
120
|
return 1
|
|
248
121
|
}
|
|
249
122
|
|
|
@@ -313,16 +186,15 @@ if [[ $use_strategies == true ]]; then
|
|
|
313
186
|
fi
|
|
314
187
|
fi
|
|
315
188
|
|
|
316
|
-
# Get next generation number
|
|
189
|
+
# Get next generation number that doesn't have existing Python files
|
|
317
190
|
get_next_generation() {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
return
|
|
321
|
-
fi
|
|
191
|
+
# Start with generation 1 if no CSV exists
|
|
192
|
+
local start_gen=1
|
|
322
193
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
194
|
+
if [[ -f "$FULL_CSV_PATH" ]]; then
|
|
195
|
+
# Use Python for proper CSV parsing to find max generation
|
|
196
|
+
local max_gen
|
|
197
|
+
max_gen=$("$PYTHON_CMD" -c "
|
|
326
198
|
import csv
|
|
327
199
|
max_gen = 0
|
|
328
200
|
with open('$FULL_CSV_PATH', 'r') as f:
|
|
@@ -340,9 +212,36 @@ with open('$FULL_CSV_PATH', 'r') as f:
|
|
|
340
212
|
pass
|
|
341
213
|
print(max_gen)
|
|
342
214
|
")
|
|
215
|
+
# Start checking from the next generation after max
|
|
216
|
+
start_gen=$((max_gen + 1))
|
|
217
|
+
fi
|
|
343
218
|
|
|
344
|
-
#
|
|
345
|
-
|
|
219
|
+
# Keep incrementing until we find a generation with no Python files
|
|
220
|
+
local candidate_gen=$start_gen
|
|
221
|
+
while true; do
|
|
222
|
+
local gen_formatted=$(printf "%02d" $candidate_gen)
|
|
223
|
+
|
|
224
|
+
# Check if any Python files exist for this generation
|
|
225
|
+
local py_files_exist=false
|
|
226
|
+
if ls "$FULL_OUTPUT_DIR"/evolution_gen${gen_formatted}-*.py >/dev/null 2>&1; then
|
|
227
|
+
py_files_exist=true
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
if [[ "$py_files_exist" == "false" ]]; then
|
|
231
|
+
# This generation is safe to use
|
|
232
|
+
echo "$gen_formatted"
|
|
233
|
+
return
|
|
234
|
+
else
|
|
235
|
+
echo "[WARN] Generation $gen_formatted already has Python files, skipping to next generation" >&2
|
|
236
|
+
candidate_gen=$((candidate_gen + 1))
|
|
237
|
+
|
|
238
|
+
# Safety check to prevent infinite loop
|
|
239
|
+
if [[ $candidate_gen -gt 999 ]]; then
|
|
240
|
+
echo "[ERROR] Could not find a safe generation number (checked up to 999)" >&2
|
|
241
|
+
exit 1
|
|
242
|
+
fi
|
|
243
|
+
fi
|
|
244
|
+
done
|
|
346
245
|
}
|
|
347
246
|
|
|
348
247
|
# This function is no longer used with direct CSV modification approach
|
|
@@ -377,31 +276,64 @@ validate_direct_csv_modification() {
|
|
|
377
276
|
return 1
|
|
378
277
|
fi
|
|
379
278
|
|
|
380
|
-
#
|
|
381
|
-
#
|
|
382
|
-
|
|
383
|
-
|
|
279
|
+
# Get the count before modification from the temp CSV (which was copied from original before AI ran)
|
|
280
|
+
# We need to track this before the AI runs by reading from the beginning state
|
|
281
|
+
# First, get a fresh count from the current main CSV (which reflects any previous operations in this session)
|
|
282
|
+
local current_original_count
|
|
283
|
+
current_original_count=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
284
|
+
|
|
285
|
+
# Count data rows in the modified temp CSV
|
|
384
286
|
local new_count
|
|
385
287
|
new_count=$(grep -v '^[[:space:]]*$' "$temp_csv" | tail -n +2 | wc -l)
|
|
386
288
|
|
|
387
|
-
echo "[DEBUG]
|
|
388
|
-
echo "[DEBUG] Modified CSV data rows: $new_count" >&2
|
|
289
|
+
echo "[DEBUG] Current main CSV data rows: $current_original_count" >&2
|
|
290
|
+
echo "[DEBUG] Modified temp CSV data rows: $new_count" >&2
|
|
389
291
|
echo "[DEBUG] Expected to add: $expected_count ideas" >&2
|
|
390
292
|
|
|
391
|
-
if
|
|
392
|
-
|
|
293
|
+
# Check if AI overwrote the file instead of appending
|
|
294
|
+
if [[ $new_count -lt $current_original_count ]]; then
|
|
295
|
+
echo "[ERROR] AI overwrote the CSV file instead of appending ($new_count < $current_original_count)" >&2
|
|
393
296
|
echo "[DEBUG] First 10 lines of CSV after AI attempt:" >&2
|
|
394
297
|
head -10 "$temp_csv" >&2
|
|
395
298
|
return 1
|
|
396
299
|
fi
|
|
397
300
|
|
|
398
|
-
|
|
301
|
+
# Check if no changes were made
|
|
302
|
+
if [[ $new_count -eq $current_original_count ]]; then
|
|
303
|
+
echo "[ERROR] CSV file wasn't modified - same number of data rows ($new_count = $current_original_count)" >&2
|
|
304
|
+
echo "[DEBUG] First 10 lines of CSV after AI attempt:" >&2
|
|
305
|
+
head -10 "$temp_csv" >&2
|
|
306
|
+
return 1
|
|
307
|
+
fi
|
|
308
|
+
|
|
309
|
+
local added_count=$((new_count - current_original_count))
|
|
399
310
|
if [[ $added_count -ne $expected_count ]]; then
|
|
400
311
|
echo "[WARN] Expected to add $expected_count ideas but added $added_count" >&2
|
|
401
312
|
fi
|
|
402
313
|
|
|
403
|
-
#
|
|
404
|
-
|
|
314
|
+
# Use proper locking to safely update the CSV
|
|
315
|
+
echo "[INFO] Acquiring CSV lock to apply changes..."
|
|
316
|
+
|
|
317
|
+
# Set the lockfile path
|
|
318
|
+
CSV_LOCKFILE="$FULL_EVOLUTION_DIR/.evolution.csv.lock"
|
|
319
|
+
|
|
320
|
+
if ! acquire_csv_lock; then
|
|
321
|
+
echo "[ERROR] Failed to acquire CSV lock for update" >&2
|
|
322
|
+
rm -f "$temp_csv"
|
|
323
|
+
return 1
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
# Get just the new entries (skip header and existing entries)
|
|
327
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
328
|
+
|
|
329
|
+
# Append only the new lines from temp CSV to the main CSV
|
|
330
|
+
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
331
|
+
|
|
332
|
+
# Clean up temp file
|
|
333
|
+
rm -f "$temp_csv"
|
|
334
|
+
|
|
335
|
+
# Release the lock
|
|
336
|
+
release_csv_lock
|
|
405
337
|
|
|
406
338
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
407
339
|
return 0
|
|
@@ -472,8 +404,29 @@ validate_and_apply_csv_modification_old() {
|
|
|
472
404
|
echo "[WARN] Expected to add $expected_count ideas but added $added_count" >&2
|
|
473
405
|
fi
|
|
474
406
|
|
|
475
|
-
#
|
|
476
|
-
|
|
407
|
+
# Use proper locking to safely update the CSV
|
|
408
|
+
echo "[INFO] Acquiring CSV lock to apply changes..."
|
|
409
|
+
|
|
410
|
+
# Set the lockfile path
|
|
411
|
+
CSV_LOCKFILE="$FULL_EVOLUTION_DIR/.evolution.csv.lock"
|
|
412
|
+
|
|
413
|
+
if ! acquire_csv_lock; then
|
|
414
|
+
echo "[ERROR] Failed to acquire CSV lock for update" >&2
|
|
415
|
+
rm -f "$temp_csv"
|
|
416
|
+
return 1
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
# Get just the new entries (skip header and existing entries)
|
|
420
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
421
|
+
|
|
422
|
+
# Append only the new lines from temp CSV to the main CSV
|
|
423
|
+
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
424
|
+
|
|
425
|
+
# Clean up temp file
|
|
426
|
+
rm -f "$temp_csv"
|
|
427
|
+
|
|
428
|
+
# Release the lock
|
|
429
|
+
release_csv_lock
|
|
477
430
|
|
|
478
431
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
479
432
|
return 0
|
|
@@ -518,8 +471,8 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
518
471
|
|
|
519
472
|
# Get AI to modify the CSV with fallbacks
|
|
520
473
|
local modified_csv
|
|
521
|
-
local stderr_file="/
|
|
522
|
-
if ! modified_csv=$(
|
|
474
|
+
local stderr_file="$FULL_EVOLUTION_DIR/stderr-$$.txt"
|
|
475
|
+
if ! modified_csv=$(call_ai_for_ideation "$csv_prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
523
476
|
echo "[ERROR] All AI models failed to modify CSV" >&2
|
|
524
477
|
cat "$stderr_file" >&2
|
|
525
478
|
rm -f "$temp_csv" "$stderr_file"
|
|
@@ -597,14 +550,72 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
597
550
|
echo "[WARN] Expected to add $count ideas but added $added_count" >&2
|
|
598
551
|
fi
|
|
599
552
|
|
|
600
|
-
#
|
|
601
|
-
|
|
553
|
+
# Use proper locking to safely update the CSV
|
|
554
|
+
echo "[INFO] Acquiring CSV lock to apply changes..."
|
|
555
|
+
|
|
556
|
+
# Set the lockfile path
|
|
557
|
+
CSV_LOCKFILE="$FULL_EVOLUTION_DIR/.evolution.csv.lock"
|
|
558
|
+
|
|
559
|
+
if ! acquire_csv_lock; then
|
|
560
|
+
echo "[ERROR] Failed to acquire CSV lock for update" >&2
|
|
561
|
+
rm -f "$temp_csv"
|
|
562
|
+
return 1
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
# Get just the new entries (skip header and existing entries)
|
|
566
|
+
local original_line_count=$(wc -l < "$FULL_CSV_PATH")
|
|
567
|
+
|
|
568
|
+
# Append only the new lines from temp CSV to the main CSV
|
|
569
|
+
tail -n +$((original_line_count + 1)) "$temp_csv" >> "$FULL_CSV_PATH"
|
|
570
|
+
|
|
571
|
+
# Clean up temp file
|
|
572
|
+
rm -f "$temp_csv"
|
|
573
|
+
|
|
574
|
+
# Release the lock
|
|
575
|
+
release_csv_lock
|
|
602
576
|
|
|
603
577
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
604
578
|
|
|
605
579
|
return 0
|
|
606
580
|
}
|
|
607
581
|
|
|
582
|
+
# Get list of existing Python files for a generation
|
|
583
|
+
get_existing_py_files_for_generation() {
|
|
584
|
+
local generation="$1"
|
|
585
|
+
local py_files=""
|
|
586
|
+
|
|
587
|
+
# List all Python files for this generation
|
|
588
|
+
for py_file in "$FULL_OUTPUT_DIR"/evolution_gen${generation}-*.py; do
|
|
589
|
+
if [[ -f "$py_file" ]]; then
|
|
590
|
+
local basename=$(basename "$py_file" .py)
|
|
591
|
+
local id="${basename#evolution_}"
|
|
592
|
+
if [[ -n "$py_files" ]]; then
|
|
593
|
+
py_files="$py_files, $id"
|
|
594
|
+
else
|
|
595
|
+
py_files="$id"
|
|
596
|
+
fi
|
|
597
|
+
fi
|
|
598
|
+
done
|
|
599
|
+
|
|
600
|
+
echo "$py_files"
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
# Add existing Python files warning to prompt
|
|
604
|
+
add_existing_files_warning() {
|
|
605
|
+
local prompt="$1"
|
|
606
|
+
local generation="$2"
|
|
607
|
+
local existing_py_files=$(get_existing_py_files_for_generation "$generation")
|
|
608
|
+
|
|
609
|
+
if [[ -n "$existing_py_files" ]]; then
|
|
610
|
+
prompt+="
|
|
611
|
+
|
|
612
|
+
WARNING: The following IDs already have Python files and MUST NOT be reused: $existing_py_files
|
|
613
|
+
Skip these IDs when assigning new IDs (e.g., if gen$generation-001 and gen$generation-002 exist as Python files, start with gen$generation-003)"
|
|
614
|
+
fi
|
|
615
|
+
|
|
616
|
+
echo "$prompt"
|
|
617
|
+
}
|
|
618
|
+
|
|
608
619
|
# Get next available ID for current generation
|
|
609
620
|
get_next_id() {
|
|
610
621
|
local generation="$1"
|
|
@@ -734,10 +745,55 @@ ideate_ai_strategies() {
|
|
|
734
745
|
echo " Crossover hybrid: $CROSSOVER_HYBRID"
|
|
735
746
|
|
|
736
747
|
# Generate each type of idea by having Claude directly edit the CSV
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
748
|
+
# Track successes - continue even if some strategies fail
|
|
749
|
+
local strategies_attempted=0
|
|
750
|
+
local strategies_succeeded=0
|
|
751
|
+
|
|
752
|
+
if [[ $NOVEL_EXPLORATION -gt 0 ]]; then
|
|
753
|
+
((strategies_attempted++))
|
|
754
|
+
if generate_novel_ideas_direct "$NOVEL_EXPLORATION"; then
|
|
755
|
+
((strategies_succeeded++))
|
|
756
|
+
else
|
|
757
|
+
echo "[WARN] Novel exploration strategy failed, continuing with other strategies" >&2
|
|
758
|
+
fi
|
|
759
|
+
fi
|
|
760
|
+
|
|
761
|
+
if [[ $HILL_CLIMBING -gt 0 ]]; then
|
|
762
|
+
((strategies_attempted++))
|
|
763
|
+
if generate_hill_climbing_direct "$HILL_CLIMBING" "$top_performers"; then
|
|
764
|
+
((strategies_succeeded++))
|
|
765
|
+
else
|
|
766
|
+
echo "[WARN] Hill climbing strategy failed, continuing with other strategies" >&2
|
|
767
|
+
fi
|
|
768
|
+
fi
|
|
769
|
+
|
|
770
|
+
if [[ $STRUCTURAL_MUTATION -gt 0 ]]; then
|
|
771
|
+
((strategies_attempted++))
|
|
772
|
+
if generate_structural_mutation_direct "$STRUCTURAL_MUTATION" "$top_performers"; then
|
|
773
|
+
((strategies_succeeded++))
|
|
774
|
+
else
|
|
775
|
+
echo "[WARN] Structural mutation strategy failed, continuing with other strategies" >&2
|
|
776
|
+
fi
|
|
777
|
+
fi
|
|
778
|
+
|
|
779
|
+
if [[ $CROSSOVER_HYBRID -gt 0 ]]; then
|
|
780
|
+
((strategies_attempted++))
|
|
781
|
+
if generate_crossover_direct "$CROSSOVER_HYBRID" "$top_performers"; then
|
|
782
|
+
((strategies_succeeded++))
|
|
783
|
+
else
|
|
784
|
+
echo "[WARN] Crossover strategy failed, continuing with other strategies" >&2
|
|
785
|
+
fi
|
|
786
|
+
fi
|
|
787
|
+
|
|
788
|
+
echo "[INFO] Strategy results: $strategies_succeeded/$strategies_attempted succeeded" >&2
|
|
789
|
+
|
|
790
|
+
# Success if at least one strategy worked
|
|
791
|
+
if [[ $strategies_succeeded -gt 0 ]]; then
|
|
792
|
+
return 0
|
|
793
|
+
else
|
|
794
|
+
echo "[ERROR] All ideation strategies failed" >&2
|
|
795
|
+
return 1
|
|
796
|
+
fi
|
|
741
797
|
}
|
|
742
798
|
|
|
743
799
|
# Generate novel exploration ideas using direct CSV modification
|
|
@@ -755,33 +811,66 @@ generate_novel_ideas_direct() {
|
|
|
755
811
|
# Use relative paths and change to evolution directory so AI can access files
|
|
756
812
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
757
813
|
|
|
758
|
-
|
|
814
|
+
# Get existing Python files for this generation to avoid ID collisions
|
|
815
|
+
local existing_py_files=$(get_existing_py_files_for_generation "$CURRENT_GENERATION")
|
|
816
|
+
|
|
817
|
+
local prompt="I need you to use your file editing capabilities to APPEND exactly $count novel algorithmic ideas to the CSV file: $temp_csv_basename
|
|
759
818
|
|
|
760
819
|
Current evolution context:
|
|
761
820
|
- Generation: $CURRENT_GENERATION
|
|
762
821
|
- Algorithm: algorithm.py (base algorithm)
|
|
763
|
-
- Brief: $(head -
|
|
822
|
+
- Brief: $(head -5 "$FULL_BRIEF_PATH" 2>/dev/null | head -c 500 || echo "No brief file found")
|
|
764
823
|
|
|
765
|
-
|
|
824
|
+
CRITICAL INSTRUCTIONS:
|
|
766
825
|
1. Use the Read tool to examine the current CSV file
|
|
767
|
-
2.
|
|
768
|
-
3.
|
|
769
|
-
4.
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
826
|
+
2. DO NOT DELETE OR REPLACE ANY EXISTING ROWS - YOU MUST PRESERVE ALL EXISTING DATA
|
|
827
|
+
3. Find the highest ID number for generation $CURRENT_GENERATION (e.g., if gen$CURRENT_GENERATION-003 exists, next should be gen$CURRENT_GENERATION-004)
|
|
828
|
+
4. If no gen$CURRENT_GENERATION entries exist yet, start with gen$CURRENT_GENERATION-001"
|
|
829
|
+
|
|
830
|
+
if [[ -n "$existing_py_files" ]]; then
|
|
831
|
+
prompt+="
|
|
832
|
+
5. IMPORTANT: The following IDs already have Python files and MUST NOT be reused: $existing_py_files
|
|
833
|
+
6. Skip these IDs when assigning new IDs (e.g., if gen$CURRENT_GENERATION-001 and gen$CURRENT_GENERATION-002 exist as Python files, start with gen$CURRENT_GENERATION-003)"
|
|
834
|
+
else
|
|
835
|
+
prompt+="
|
|
836
|
+
5. No existing Python files found for generation $CURRENT_GENERATION"
|
|
837
|
+
fi
|
|
838
|
+
|
|
839
|
+
prompt+="
|
|
840
|
+
6. Use the Edit or MultiEdit tool to APPEND exactly $count new rows AT THE END of the CSV file
|
|
841
|
+
7. For each idea, create a row with: id,,description,,pending (empty parent_id for novel ideas)
|
|
842
|
+
8. Each description should be one clear sentence describing a novel algorithmic approach
|
|
843
|
+
9. Focus on creative, ambitious ideas that haven't been tried yet
|
|
844
|
+
10. Consider machine learning, new indicators, regime detection, risk management, etc.
|
|
845
|
+
|
|
846
|
+
IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the file contents. All existing rows must remain unchanged.
|
|
847
|
+
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
848
|
+
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
849
|
+
|
|
850
|
+
# Debug prompt size and context
|
|
851
|
+
echo "[DEBUG] Novel ideas prompt length: ${#prompt} characters" >&2
|
|
852
|
+
echo "[DEBUG] Working dir: $(pwd)" >&2
|
|
853
|
+
echo "[DEBUG] Evolution dir: $FULL_EVOLUTION_DIR" >&2
|
|
854
|
+
echo "[DEBUG] Temp CSV: $temp_csv" >&2
|
|
855
|
+
if [[ -f "$temp_csv" ]]; then
|
|
856
|
+
echo "[DEBUG] Temp CSV exists, size: $(wc -l < "$temp_csv") lines" >&2
|
|
857
|
+
else
|
|
858
|
+
echo "[DEBUG] Temp CSV does not exist yet" >&2
|
|
859
|
+
fi
|
|
776
860
|
|
|
777
861
|
# Change to evolution directory so AI can access files
|
|
778
862
|
local original_pwd=$(pwd)
|
|
779
863
|
cd "$FULL_EVOLUTION_DIR"
|
|
780
864
|
|
|
865
|
+
# Debug: Show files in evolution directory
|
|
866
|
+
echo "[DEBUG] Current directory: $(pwd)" >&2
|
|
867
|
+
echo "[DEBUG] Temp CSV exists: $(ls -la "$temp_csv_basename" 2>&1)" >&2
|
|
868
|
+
|
|
781
869
|
# Get AI to directly edit the CSV file
|
|
782
870
|
local ai_response
|
|
783
871
|
local stderr_file="stderr-$$.txt"
|
|
784
|
-
|
|
872
|
+
# Temporarily show stderr for debugging
|
|
873
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
785
874
|
echo "[ERROR] All AI models failed to generate novel ideas" >&2
|
|
786
875
|
echo "[DEBUG] Stderr output from AI calls:" >&2
|
|
787
876
|
cat "$stderr_file" >&2
|
|
@@ -821,6 +910,9 @@ generate_hill_climbing_direct() {
|
|
|
821
910
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
822
911
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
823
912
|
|
|
913
|
+
# Get existing Python files for this generation to avoid ID collisions
|
|
914
|
+
local existing_py_files=$(get_existing_py_files_for_generation "$CURRENT_GENERATION")
|
|
915
|
+
|
|
824
916
|
# Extract just the IDs from top performers for clarity
|
|
825
917
|
local valid_parent_ids
|
|
826
918
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -828,7 +920,7 @@ generate_hill_climbing_direct() {
|
|
|
828
920
|
# Use relative paths and change to evolution directory so AI can access files
|
|
829
921
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
830
922
|
|
|
831
|
-
local prompt="I need you to use your file editing capabilities to
|
|
923
|
+
local prompt="I need you to use your file editing capabilities to APPEND exactly $count parameter tuning ideas to the CSV file: $temp_csv_basename
|
|
832
924
|
|
|
833
925
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
834
926
|
|
|
@@ -839,17 +931,20 @@ CRITICAL INSTRUCTION: Before generating parameter tuning ideas, you MUST read th
|
|
|
839
931
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
840
932
|
For example: evolution_gen01-251.py
|
|
841
933
|
|
|
842
|
-
|
|
934
|
+
CRITICAL INSTRUCTIONS:
|
|
843
935
|
1. Use the Read tool to examine the current CSV file
|
|
844
|
-
2.
|
|
845
|
-
3.
|
|
846
|
-
4.
|
|
847
|
-
5.
|
|
848
|
-
6.
|
|
849
|
-
7. Each
|
|
850
|
-
8.
|
|
851
|
-
|
|
852
|
-
|
|
936
|
+
2. DO NOT DELETE OR REPLACE ANY EXISTING ROWS - YOU MUST PRESERVE ALL EXISTING DATA
|
|
937
|
+
3. Find the highest ID number for generation $CURRENT_GENERATION (e.g., if gen$CURRENT_GENERATION-003 exists, next should be gen$CURRENT_GENERATION-004)
|
|
938
|
+
4. If no gen$CURRENT_GENERATION entries exist yet, start with gen$CURRENT_GENERATION-001
|
|
939
|
+
5. Use the Edit or MultiEdit tool to APPEND exactly $count new rows AT THE END of the CSV file
|
|
940
|
+
6. For each idea, create a row with: id,parent_id,description,,pending
|
|
941
|
+
7. Each parent_id MUST be one of: $valid_parent_ids
|
|
942
|
+
8. Each description should focus on adjusting specific parameters that exist in the parent's source code
|
|
943
|
+
9. Include current and new parameter values (e.g., \"Lower rsi_entry from 21 to 18\")
|
|
944
|
+
|
|
945
|
+
IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the file contents. All existing rows must remain unchanged.
|
|
946
|
+
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
947
|
+
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
853
948
|
|
|
854
949
|
# Change to evolution directory so AI can access files
|
|
855
950
|
local original_pwd=$(pwd)
|
|
@@ -858,7 +953,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
858
953
|
# Get AI to directly edit the CSV file
|
|
859
954
|
local ai_response
|
|
860
955
|
local stderr_file="stderr-$$.txt"
|
|
861
|
-
|
|
956
|
+
# Temporarily show stderr for debugging
|
|
957
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
862
958
|
echo "[ERROR] All AI models failed to generate hill climbing ideas" >&2
|
|
863
959
|
cat "$stderr_file" >&2
|
|
864
960
|
cd "$original_pwd"
|
|
@@ -895,6 +991,9 @@ generate_structural_mutation_direct() {
|
|
|
895
991
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
896
992
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
897
993
|
|
|
994
|
+
# Get existing Python files for this generation to avoid ID collisions
|
|
995
|
+
local existing_py_files=$(get_existing_py_files_for_generation "$CURRENT_GENERATION")
|
|
996
|
+
|
|
898
997
|
# Extract just the IDs from top performers for clarity
|
|
899
998
|
local valid_parent_ids
|
|
900
999
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -902,7 +1001,7 @@ generate_structural_mutation_direct() {
|
|
|
902
1001
|
# Use relative paths and change to evolution directory so AI can access files
|
|
903
1002
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
904
1003
|
|
|
905
|
-
local prompt="I need you to use your file editing capabilities to
|
|
1004
|
+
local prompt="I need you to use your file editing capabilities to APPEND exactly $count structural modification ideas to the CSV file: $temp_csv_basename
|
|
906
1005
|
|
|
907
1006
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
908
1007
|
|
|
@@ -913,17 +1012,20 @@ CRITICAL INSTRUCTION: Before generating structural modification ideas, you MUST
|
|
|
913
1012
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
914
1013
|
For example: evolution_gen01-251.py
|
|
915
1014
|
|
|
916
|
-
|
|
1015
|
+
CRITICAL INSTRUCTIONS:
|
|
917
1016
|
1. Use the Read tool to examine the current CSV file
|
|
918
|
-
2.
|
|
919
|
-
3.
|
|
920
|
-
4.
|
|
921
|
-
5.
|
|
922
|
-
6.
|
|
923
|
-
7. Each
|
|
924
|
-
8.
|
|
925
|
-
|
|
926
|
-
|
|
1017
|
+
2. DO NOT DELETE OR REPLACE ANY EXISTING ROWS - YOU MUST PRESERVE ALL EXISTING DATA
|
|
1018
|
+
3. Find the highest ID number for generation $CURRENT_GENERATION (e.g., if gen$CURRENT_GENERATION-003 exists, next should be gen$CURRENT_GENERATION-004)
|
|
1019
|
+
4. If no gen$CURRENT_GENERATION entries exist yet, start with gen$CURRENT_GENERATION-001
|
|
1020
|
+
5. Use the Edit or MultiEdit tool to APPEND exactly $count new rows AT THE END of the CSV file
|
|
1021
|
+
6. For each idea, create a row with: id,parent_id,description,,pending
|
|
1022
|
+
7. Each parent_id MUST be one of: $valid_parent_ids
|
|
1023
|
+
8. Each description should focus on architectural/structural changes based on the parent's actual code
|
|
1024
|
+
9. Reference actual components/methods found in the source code
|
|
1025
|
+
|
|
1026
|
+
IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the file contents. All existing rows must remain unchanged.
|
|
1027
|
+
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
1028
|
+
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
927
1029
|
|
|
928
1030
|
# Change to evolution directory so AI can access files
|
|
929
1031
|
local original_pwd=$(pwd)
|
|
@@ -932,7 +1034,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
932
1034
|
# Get AI to directly edit the CSV file
|
|
933
1035
|
local ai_response
|
|
934
1036
|
local stderr_file="stderr-$$.txt"
|
|
935
|
-
|
|
1037
|
+
# Temporarily show stderr for debugging
|
|
1038
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
936
1039
|
echo "[ERROR] All AI models failed to generate structural mutation ideas" >&2
|
|
937
1040
|
cat "$stderr_file" >&2
|
|
938
1041
|
cd "$original_pwd"
|
|
@@ -969,6 +1072,9 @@ generate_crossover_direct() {
|
|
|
969
1072
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
970
1073
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
971
1074
|
|
|
1075
|
+
# Get existing Python files for this generation to avoid ID collisions
|
|
1076
|
+
local existing_py_files=$(get_existing_py_files_for_generation "$CURRENT_GENERATION")
|
|
1077
|
+
|
|
972
1078
|
# Extract just the IDs from top performers for clarity
|
|
973
1079
|
local valid_parent_ids
|
|
974
1080
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -976,7 +1082,7 @@ generate_crossover_direct() {
|
|
|
976
1082
|
# Use relative paths and change to evolution directory so AI can access files
|
|
977
1083
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
978
1084
|
|
|
979
|
-
local prompt="I need you to use your file editing capabilities to
|
|
1085
|
+
local prompt="I need you to use your file editing capabilities to APPEND exactly $count hybrid combination ideas to the CSV file: $temp_csv_basename
|
|
980
1086
|
|
|
981
1087
|
IMPORTANT: You MUST use ONLY these exact parent IDs: $valid_parent_ids
|
|
982
1088
|
|
|
@@ -987,17 +1093,20 @@ CRITICAL INSTRUCTION: Before generating hybrid combination ideas, you MUST read
|
|
|
987
1093
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
988
1094
|
For example: evolution_gen01-251.py
|
|
989
1095
|
|
|
990
|
-
|
|
1096
|
+
CRITICAL INSTRUCTIONS:
|
|
991
1097
|
1. Use the Read tool to examine the current CSV file
|
|
992
|
-
2.
|
|
993
|
-
3.
|
|
994
|
-
4.
|
|
995
|
-
5.
|
|
996
|
-
6.
|
|
997
|
-
7. Each
|
|
998
|
-
8.
|
|
999
|
-
|
|
1000
|
-
|
|
1098
|
+
2. DO NOT DELETE OR REPLACE ANY EXISTING ROWS - YOU MUST PRESERVE ALL EXISTING DATA
|
|
1099
|
+
3. Find the highest ID number for generation $CURRENT_GENERATION (e.g., if gen$CURRENT_GENERATION-003 exists, next should be gen$CURRENT_GENERATION-004)
|
|
1100
|
+
4. If no gen$CURRENT_GENERATION entries exist yet, start with gen$CURRENT_GENERATION-001
|
|
1101
|
+
5. Use the Edit or MultiEdit tool to APPEND exactly $count new rows AT THE END of the CSV file
|
|
1102
|
+
6. For each idea, create a row with: id,parent_id,description,,pending
|
|
1103
|
+
7. Each parent_id MUST be one of: $valid_parent_ids (choose the primary parent)
|
|
1104
|
+
8. Each description should combine actual elements from 2+ algorithms based on their source code
|
|
1105
|
+
9. Reference specific components/features found in the actual source code
|
|
1106
|
+
|
|
1107
|
+
IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the file contents. All existing rows must remain unchanged.
|
|
1108
|
+
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
1109
|
+
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1001
1110
|
|
|
1002
1111
|
# Change to evolution directory so AI can access files
|
|
1003
1112
|
local original_pwd=$(pwd)
|
|
@@ -1006,7 +1115,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
1006
1115
|
# Get AI to directly edit the CSV file
|
|
1007
1116
|
local ai_response
|
|
1008
1117
|
local stderr_file="stderr-$$.txt"
|
|
1009
|
-
|
|
1118
|
+
# Temporarily show stderr for debugging
|
|
1119
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1010
1120
|
echo "[ERROR] All AI models failed to generate crossover hybrid ideas" >&2
|
|
1011
1121
|
cat "$stderr_file" >&2
|
|
1012
1122
|
cd "$original_pwd"
|
|
@@ -1078,14 +1188,15 @@ $top_performers"
|
|
|
1078
1188
|
|
|
1079
1189
|
prompt+="
|
|
1080
1190
|
|
|
1081
|
-
|
|
1191
|
+
CRITICAL INSTRUCTIONS:
|
|
1082
1192
|
1. Use the Read tool to examine the current CSV file
|
|
1083
|
-
2.
|
|
1084
|
-
3.
|
|
1085
|
-
4.
|
|
1086
|
-
5.
|
|
1087
|
-
6.
|
|
1088
|
-
7.
|
|
1193
|
+
2. DO NOT DELETE OR REPLACE ANY EXISTING ROWS - YOU MUST PRESERVE ALL EXISTING DATA
|
|
1194
|
+
3. Find the highest ID number for generation $CURRENT_GENERATION (e.g., if gen$CURRENT_GENERATION-003 exists, next should be gen$CURRENT_GENERATION-004)
|
|
1195
|
+
4. If no gen$CURRENT_GENERATION entries exist yet, start with gen$CURRENT_GENERATION-001
|
|
1196
|
+
5. Use the Edit or MultiEdit tool to APPEND exactly $TOTAL_IDEAS new rows AT THE END of the CSV file
|
|
1197
|
+
6. For each idea, create a row with: id,parent_id,description,,pending
|
|
1198
|
+
7. Mix both parameter tuning and structural changes
|
|
1199
|
+
8. If building on existing algorithms, use their ID as parent_id, otherwise leave parent_id empty
|
|
1089
1200
|
|
|
1090
1201
|
⚠️ AVOID ONLY: Kelly floor/cap adjustments that assume leverage > 1.0 (these get clamped and have no effect)
|
|
1091
1202
|
|
|
@@ -1099,7 +1210,9 @@ Instructions:
|
|
|
1099
1210
|
- Time-Based Patterns: Intraday effects, calendar anomalies, volatility timing
|
|
1100
1211
|
- Parameter Optimization: Entry thresholds, indicator periods, strategy weights
|
|
1101
1212
|
|
|
1102
|
-
|
|
1213
|
+
IMPORTANT: You must APPEND new rows to the existing CSV file. DO NOT replace the file contents. All existing rows must remain unchanged.
|
|
1214
|
+
CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CSV file. DO NOT return CSV text - use your tools to edit the file directly.
|
|
1215
|
+
CRITICAL: Do NOT use any git commands (git add, git commit, git reset, etc.). Only modify the file directly."
|
|
1103
1216
|
|
|
1104
1217
|
# Change to evolution directory so AI can access files
|
|
1105
1218
|
local original_pwd=$(pwd)
|
|
@@ -1108,7 +1221,7 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
1108
1221
|
# Get AI to directly edit the CSV file
|
|
1109
1222
|
local ai_response
|
|
1110
1223
|
local stderr_file="stderr-$$.txt"
|
|
1111
|
-
if ! ai_response=$(
|
|
1224
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$TOTAL_IDEAS" "$temp_csv_basename" 2>"$stderr_file"); then
|
|
1112
1225
|
echo "[ERROR] All AI models failed to generate ideas" >&2
|
|
1113
1226
|
cat "$stderr_file" >&2
|
|
1114
1227
|
cd "$original_pwd"
|