claude-evolve 1.5.0 → 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 +396 -337
- package/bin/claude-evolve-run +15 -3
- package/bin/claude-evolve-worker +20 -104
- 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,197 +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
|
-
ai_output=$(echo "$prompt" | codex exec -m o3 --full-auto 2>&1)
|
|
87
|
-
local ai_exit_code=$?
|
|
88
|
-
|
|
89
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
90
|
-
# Clean o3 output - it may be JSON with the response in a field
|
|
91
|
-
local cleaned_output
|
|
92
|
-
# Try to extract content from JSON response if present
|
|
93
|
-
if echo "$ai_output" | grep -q '"content"'; then
|
|
94
|
-
# Attempt to extract content field from JSON
|
|
95
|
-
cleaned_output=$(echo "$ai_output" | python3 -c "
|
|
96
|
-
import sys
|
|
97
|
-
import json
|
|
98
|
-
try:
|
|
99
|
-
data = json.load(sys.stdin)
|
|
100
|
-
if 'content' in data:
|
|
101
|
-
print(data['content'])
|
|
102
|
-
elif 'response' in data:
|
|
103
|
-
print(data['response'])
|
|
104
|
-
elif 'text' in data:
|
|
105
|
-
print(data['text'])
|
|
106
|
-
else:
|
|
107
|
-
# If no known field, print the whole thing
|
|
108
|
-
print(json.dumps(data))
|
|
109
|
-
except:
|
|
110
|
-
# If not valid JSON, print as-is
|
|
111
|
-
print(sys.stdin.read())
|
|
112
|
-
" 2>/dev/null || echo "$ai_output")
|
|
113
|
-
else
|
|
114
|
-
cleaned_output="$ai_output"
|
|
115
|
-
fi
|
|
116
|
-
|
|
117
|
-
# Validate the output is not empty and doesn't contain error messages
|
|
118
|
-
if [[ -n "$cleaned_output" ]] && ! echo "$cleaned_output" | grep -q "error\|failed\|exception"; then
|
|
119
|
-
echo "$cleaned_output"
|
|
120
|
-
return 0
|
|
121
|
-
else
|
|
122
|
-
echo "[WARN] Codex o3 returned invalid output, falling back to Claude Opus" >&2
|
|
123
|
-
preferred_model="opus"
|
|
124
|
-
fi
|
|
125
|
-
else
|
|
126
|
-
echo "[WARN] Codex o3 failed with exit code $ai_exit_code, falling back to Claude Opus" >&2
|
|
127
|
-
preferred_model="opus"
|
|
128
|
-
fi
|
|
129
|
-
elif [[ "$preferred_model" == "gemini" ]] && command -v gemini >/dev/null 2>&1; then
|
|
130
|
-
echo "[INFO] Using gemini 2.5 pro for ideation" >&2
|
|
131
|
-
|
|
132
|
-
# Call gemini with -y and -p flags
|
|
133
|
-
local ai_output
|
|
134
|
-
ai_output=$(gemini -y -p "$prompt" 2>&1)
|
|
135
|
-
local ai_exit_code=$?
|
|
136
|
-
|
|
137
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
138
|
-
# Check for authentication messages or other non-response content
|
|
139
|
-
if echo "$ai_output" | grep -q "Attempting to authenticate\|Authenticating\|Loading\|Initializing"; then
|
|
140
|
-
echo "[WARN] Gemini is still authenticating, falling back to Claude Opus" >&2
|
|
141
|
-
preferred_model="opus"
|
|
142
|
-
elif [[ -z "$ai_output" ]] || [[ $(echo "$ai_output" | wc -l) -lt 2 ]]; then
|
|
143
|
-
echo "[WARN] Gemini returned insufficient output, falling back to Claude Opus" >&2
|
|
144
|
-
preferred_model="opus"
|
|
145
|
-
else
|
|
146
|
-
echo "$ai_output"
|
|
147
|
-
return 0
|
|
148
|
-
fi
|
|
149
|
-
else
|
|
150
|
-
echo "[WARN] Gemini failed with exit code $ai_exit_code, falling back to Claude Opus" >&2
|
|
151
|
-
preferred_model="opus"
|
|
152
|
-
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
|
|
153
32
|
fi
|
|
154
33
|
|
|
155
|
-
# Use
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
local claude_output
|
|
160
|
-
claude_output=$(echo "$prompt" | claude --dangerously-skip-permissions --model "$preferred_model" -p 2>&1)
|
|
161
|
-
local claude_exit_code=$?
|
|
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=$?
|
|
162
38
|
|
|
163
|
-
#
|
|
164
|
-
if
|
|
165
|
-
#
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
# Print red error message
|
|
169
|
-
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
|
|
170
43
|
echo -e "\033[31m[ERROR] Ideation halted due to API rate limits.\033[0m" >&2
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
# Convert timestamp to human-readable format
|
|
174
|
-
local limit_date=$(date -r "$limit_timestamp" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "Unknown time")
|
|
175
|
-
echo -e "\033[31m[ERROR] Limit will be released at: $limit_date\033[0m" >&2
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
echo -e "\033[33m[INFO] Please wait for the rate limit to reset before continuing.\033[0m" >&2
|
|
179
|
-
echo -e "\033[33m[INFO] No ideas were generated. Run ideate again when the limit resets.\033[0m" >&2
|
|
180
|
-
|
|
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
|
|
181
46
|
exit 1
|
|
182
47
|
fi
|
|
183
48
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
echo "[
|
|
187
|
-
|
|
188
|
-
|
|
49
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
50
|
+
# For ideation, AI modifies files directly - just return success
|
|
51
|
+
echo "[INFO] AI succeeded" >&2
|
|
52
|
+
return 0
|
|
53
|
+
else
|
|
54
|
+
return $ai_exit_code
|
|
189
55
|
fi
|
|
190
|
-
|
|
191
|
-
# Output Claude's response
|
|
192
|
-
echo "$claude_output"
|
|
193
|
-
|
|
194
|
-
return $claude_exit_code
|
|
195
56
|
}
|
|
196
57
|
|
|
58
|
+
|
|
197
59
|
# Backward compatibility alias
|
|
198
60
|
call_claude_with_limit_check() {
|
|
199
61
|
call_ai_with_limit_check "$@"
|
|
200
62
|
}
|
|
201
63
|
|
|
202
64
|
# Robust AI calling with fallbacks across all available models
|
|
203
|
-
|
|
65
|
+
call_ai_for_ideation() {
|
|
204
66
|
local prompt="$1"
|
|
205
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
|
|
206
70
|
|
|
207
|
-
#
|
|
71
|
+
# Calculate hash value for round-robin based on generation
|
|
208
72
|
local gen_num
|
|
209
73
|
if [[ $generation =~ ^0*([0-9]+)$ ]]; then
|
|
210
74
|
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
@@ -212,100 +76,47 @@ call_ai_with_fallbacks() {
|
|
|
212
76
|
gen_num=1
|
|
213
77
|
fi
|
|
214
78
|
|
|
215
|
-
#
|
|
216
|
-
local
|
|
217
|
-
if
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
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
|
|
222
85
|
fi
|
|
223
|
-
available_models+=("opus") # Claude Opus always available
|
|
224
86
|
|
|
225
|
-
#
|
|
226
|
-
local
|
|
227
|
-
|
|
228
|
-
local
|
|
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=$?
|
|
229
91
|
|
|
230
|
-
#
|
|
231
|
-
for
|
|
232
|
-
local idx=$(((start_index + i) % num_models))
|
|
233
|
-
models+=("${available_models[$idx]}")
|
|
234
|
-
done
|
|
235
|
-
|
|
236
|
-
echo "[INFO] Model order for generation $generation (round-robin): ${models[*]}" >&2
|
|
92
|
+
# Handle special exit codes
|
|
93
|
+
# No special handling for exit codes anymore
|
|
237
94
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
local ai_exit_code
|
|
244
|
-
|
|
245
|
-
if [[ "$model" == "o3" ]] && command -v codex >/dev/null 2>&1; then
|
|
246
|
-
ai_output=$(echo "$prompt" | codex exec -m o3 --full-auto 2>&1)
|
|
247
|
-
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)
|
|
248
100
|
|
|
249
|
-
if [[ $
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if 'content' in data:
|
|
258
|
-
print(data['content'])
|
|
259
|
-
elif 'response' in data:
|
|
260
|
-
print(data['response'])
|
|
261
|
-
elif 'text' in data:
|
|
262
|
-
print(data['text'])
|
|
263
|
-
else:
|
|
264
|
-
print(json.dumps(data))
|
|
265
|
-
except:
|
|
266
|
-
print(sys.stdin.read())
|
|
267
|
-
" 2>/dev/null || echo "$ai_output")
|
|
268
|
-
fi
|
|
269
|
-
|
|
270
|
-
if [[ -n "$ai_output" ]] && ! echo "$ai_output" | grep -q "error\|failed\|exception"; then
|
|
271
|
-
echo "$ai_output"
|
|
272
|
-
return 0
|
|
273
|
-
fi
|
|
274
|
-
fi
|
|
275
|
-
|
|
276
|
-
elif [[ "$model" == "gemini" ]] && command -v gemini >/dev/null 2>&1; then
|
|
277
|
-
ai_output=$(gemini -y -p "$prompt" 2>&1)
|
|
278
|
-
ai_exit_code=$?
|
|
279
|
-
|
|
280
|
-
if [[ $ai_exit_code -eq 0 ]]; then
|
|
281
|
-
if ! echo "$ai_output" | grep -q "Attempting to authenticate\|Authenticating\|Loading\|Initializing"; then
|
|
282
|
-
if [[ -n "$ai_output" ]] && [[ $(echo "$ai_output" | wc -l) -ge 2 ]]; then
|
|
283
|
-
echo "$ai_output"
|
|
284
|
-
return 0
|
|
285
|
-
fi
|
|
286
|
-
fi
|
|
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
|
|
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
|
|
287
109
|
fi
|
|
288
|
-
|
|
289
110
|
else
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
# Check for usage limits
|
|
296
|
-
if ! echo "$ai_output" | grep -q "Claude AI usage limit reached"; then
|
|
297
|
-
if ! echo "$ai_output" | grep -E "EOF.*<.*null|<<.*EOF|<.*dev.*null" >/dev/null 2>&1; then
|
|
298
|
-
echo "$ai_output"
|
|
299
|
-
return 0
|
|
300
|
-
fi
|
|
301
|
-
fi
|
|
302
|
-
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
|
|
303
116
|
fi
|
|
304
|
-
|
|
305
|
-
echo "[WARN] $model failed or returned unusable output, trying next model..." >&2
|
|
306
|
-
done
|
|
117
|
+
fi
|
|
307
118
|
|
|
308
|
-
echo "[
|
|
119
|
+
echo "[INFO] No AI model successfully modified the CSV file" >&2
|
|
309
120
|
return 1
|
|
310
121
|
}
|
|
311
122
|
|
|
@@ -375,16 +186,15 @@ if [[ $use_strategies == true ]]; then
|
|
|
375
186
|
fi
|
|
376
187
|
fi
|
|
377
188
|
|
|
378
|
-
# Get next generation number
|
|
189
|
+
# Get next generation number that doesn't have existing Python files
|
|
379
190
|
get_next_generation() {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
return
|
|
383
|
-
fi
|
|
191
|
+
# Start with generation 1 if no CSV exists
|
|
192
|
+
local start_gen=1
|
|
384
193
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
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 "
|
|
388
198
|
import csv
|
|
389
199
|
max_gen = 0
|
|
390
200
|
with open('$FULL_CSV_PATH', 'r') as f:
|
|
@@ -402,9 +212,36 @@ with open('$FULL_CSV_PATH', 'r') as f:
|
|
|
402
212
|
pass
|
|
403
213
|
print(max_gen)
|
|
404
214
|
")
|
|
215
|
+
# Start checking from the next generation after max
|
|
216
|
+
start_gen=$((max_gen + 1))
|
|
217
|
+
fi
|
|
405
218
|
|
|
406
|
-
#
|
|
407
|
-
|
|
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
|
|
408
245
|
}
|
|
409
246
|
|
|
410
247
|
# This function is no longer used with direct CSV modification approach
|
|
@@ -439,31 +276,64 @@ validate_direct_csv_modification() {
|
|
|
439
276
|
return 1
|
|
440
277
|
fi
|
|
441
278
|
|
|
442
|
-
#
|
|
443
|
-
#
|
|
444
|
-
|
|
445
|
-
|
|
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
|
|
446
286
|
local new_count
|
|
447
287
|
new_count=$(grep -v '^[[:space:]]*$' "$temp_csv" | tail -n +2 | wc -l)
|
|
448
288
|
|
|
449
|
-
echo "[DEBUG]
|
|
450
|
-
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
|
|
451
291
|
echo "[DEBUG] Expected to add: $expected_count ideas" >&2
|
|
452
292
|
|
|
453
|
-
if
|
|
454
|
-
|
|
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
|
|
455
296
|
echo "[DEBUG] First 10 lines of CSV after AI attempt:" >&2
|
|
456
297
|
head -10 "$temp_csv" >&2
|
|
457
298
|
return 1
|
|
458
299
|
fi
|
|
459
300
|
|
|
460
|
-
|
|
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))
|
|
461
310
|
if [[ $added_count -ne $expected_count ]]; then
|
|
462
311
|
echo "[WARN] Expected to add $expected_count ideas but added $added_count" >&2
|
|
463
312
|
fi
|
|
464
313
|
|
|
465
|
-
#
|
|
466
|
-
|
|
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
|
|
467
337
|
|
|
468
338
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
469
339
|
return 0
|
|
@@ -534,8 +404,29 @@ validate_and_apply_csv_modification_old() {
|
|
|
534
404
|
echo "[WARN] Expected to add $expected_count ideas but added $added_count" >&2
|
|
535
405
|
fi
|
|
536
406
|
|
|
537
|
-
#
|
|
538
|
-
|
|
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
|
|
539
430
|
|
|
540
431
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
541
432
|
return 0
|
|
@@ -580,8 +471,8 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
580
471
|
|
|
581
472
|
# Get AI to modify the CSV with fallbacks
|
|
582
473
|
local modified_csv
|
|
583
|
-
local stderr_file="/
|
|
584
|
-
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
|
|
585
476
|
echo "[ERROR] All AI models failed to modify CSV" >&2
|
|
586
477
|
cat "$stderr_file" >&2
|
|
587
478
|
rm -f "$temp_csv" "$stderr_file"
|
|
@@ -659,14 +550,72 @@ IMPORTANT: Output the complete modified CSV file. Do not add any explanation or
|
|
|
659
550
|
echo "[WARN] Expected to add $count ideas but added $added_count" >&2
|
|
660
551
|
fi
|
|
661
552
|
|
|
662
|
-
#
|
|
663
|
-
|
|
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
|
|
664
576
|
|
|
665
577
|
echo "[INFO] Successfully added $added_count $idea_type ideas to CSV"
|
|
666
578
|
|
|
667
579
|
return 0
|
|
668
580
|
}
|
|
669
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
|
+
|
|
670
619
|
# Get next available ID for current generation
|
|
671
620
|
get_next_id() {
|
|
672
621
|
local generation="$1"
|
|
@@ -796,10 +745,55 @@ ideate_ai_strategies() {
|
|
|
796
745
|
echo " Crossover hybrid: $CROSSOVER_HYBRID"
|
|
797
746
|
|
|
798
747
|
# Generate each type of idea by having Claude directly edit the CSV
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
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
|
|
803
797
|
}
|
|
804
798
|
|
|
805
799
|
# Generate novel exploration ideas using direct CSV modification
|
|
@@ -817,34 +811,71 @@ generate_novel_ideas_direct() {
|
|
|
817
811
|
# Use relative paths and change to evolution directory so AI can access files
|
|
818
812
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
819
813
|
|
|
820
|
-
|
|
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
|
|
821
818
|
|
|
822
819
|
Current evolution context:
|
|
823
820
|
- Generation: $CURRENT_GENERATION
|
|
824
821
|
- Algorithm: algorithm.py (base algorithm)
|
|
825
|
-
- Brief: $(head -
|
|
822
|
+
- Brief: $(head -5 "$FULL_BRIEF_PATH" 2>/dev/null | head -c 500 || echo "No brief file found")
|
|
826
823
|
|
|
827
|
-
|
|
824
|
+
CRITICAL INSTRUCTIONS:
|
|
828
825
|
1. Use the Read tool to examine the current CSV file
|
|
829
|
-
2.
|
|
830
|
-
3.
|
|
831
|
-
4.
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
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
|
|
837
860
|
|
|
838
861
|
# Change to evolution directory so AI can access files
|
|
839
862
|
local original_pwd=$(pwd)
|
|
840
863
|
cd "$FULL_EVOLUTION_DIR"
|
|
841
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
|
+
|
|
842
869
|
# Get AI to directly edit the CSV file
|
|
843
870
|
local ai_response
|
|
844
871
|
local stderr_file="stderr-$$.txt"
|
|
845
|
-
|
|
872
|
+
# Temporarily show stderr for debugging
|
|
873
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
846
874
|
echo "[ERROR] All AI models failed to generate novel ideas" >&2
|
|
875
|
+
echo "[DEBUG] Stderr output from AI calls:" >&2
|
|
847
876
|
cat "$stderr_file" >&2
|
|
877
|
+
echo "[DEBUG] Temp CSV location: $temp_csv" >&2
|
|
878
|
+
echo "[DEBUG] Working directory: $(pwd)" >&2
|
|
848
879
|
cd "$original_pwd"
|
|
849
880
|
rm -f "$temp_csv" "$stderr_file"
|
|
850
881
|
return 1
|
|
@@ -879,6 +910,9 @@ generate_hill_climbing_direct() {
|
|
|
879
910
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
880
911
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
881
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
|
+
|
|
882
916
|
# Extract just the IDs from top performers for clarity
|
|
883
917
|
local valid_parent_ids
|
|
884
918
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -886,7 +920,7 @@ generate_hill_climbing_direct() {
|
|
|
886
920
|
# Use relative paths and change to evolution directory so AI can access files
|
|
887
921
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
888
922
|
|
|
889
|
-
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
|
|
890
924
|
|
|
891
925
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
892
926
|
|
|
@@ -897,16 +931,20 @@ CRITICAL INSTRUCTION: Before generating parameter tuning ideas, you MUST read th
|
|
|
897
931
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
898
932
|
For example: evolution_gen01-251.py
|
|
899
933
|
|
|
900
|
-
|
|
934
|
+
CRITICAL INSTRUCTIONS:
|
|
901
935
|
1. Use the Read tool to examine the current CSV file
|
|
902
|
-
2.
|
|
903
|
-
3.
|
|
904
|
-
4.
|
|
905
|
-
5.
|
|
906
|
-
6.
|
|
907
|
-
7.
|
|
908
|
-
|
|
909
|
-
|
|
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."
|
|
910
948
|
|
|
911
949
|
# Change to evolution directory so AI can access files
|
|
912
950
|
local original_pwd=$(pwd)
|
|
@@ -915,7 +953,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
915
953
|
# Get AI to directly edit the CSV file
|
|
916
954
|
local ai_response
|
|
917
955
|
local stderr_file="stderr-$$.txt"
|
|
918
|
-
|
|
956
|
+
# Temporarily show stderr for debugging
|
|
957
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
919
958
|
echo "[ERROR] All AI models failed to generate hill climbing ideas" >&2
|
|
920
959
|
cat "$stderr_file" >&2
|
|
921
960
|
cd "$original_pwd"
|
|
@@ -952,6 +991,9 @@ generate_structural_mutation_direct() {
|
|
|
952
991
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
953
992
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
954
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
|
+
|
|
955
997
|
# Extract just the IDs from top performers for clarity
|
|
956
998
|
local valid_parent_ids
|
|
957
999
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -959,7 +1001,7 @@ generate_structural_mutation_direct() {
|
|
|
959
1001
|
# Use relative paths and change to evolution directory so AI can access files
|
|
960
1002
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
961
1003
|
|
|
962
|
-
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
|
|
963
1005
|
|
|
964
1006
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
965
1007
|
|
|
@@ -970,16 +1012,20 @@ CRITICAL INSTRUCTION: Before generating structural modification ideas, you MUST
|
|
|
970
1012
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
971
1013
|
For example: evolution_gen01-251.py
|
|
972
1014
|
|
|
973
|
-
|
|
1015
|
+
CRITICAL INSTRUCTIONS:
|
|
974
1016
|
1. Use the Read tool to examine the current CSV file
|
|
975
|
-
2.
|
|
976
|
-
3.
|
|
977
|
-
4.
|
|
978
|
-
5.
|
|
979
|
-
6.
|
|
980
|
-
7.
|
|
981
|
-
|
|
982
|
-
|
|
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."
|
|
983
1029
|
|
|
984
1030
|
# Change to evolution directory so AI can access files
|
|
985
1031
|
local original_pwd=$(pwd)
|
|
@@ -988,7 +1034,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
988
1034
|
# Get AI to directly edit the CSV file
|
|
989
1035
|
local ai_response
|
|
990
1036
|
local stderr_file="stderr-$$.txt"
|
|
991
|
-
|
|
1037
|
+
# Temporarily show stderr for debugging
|
|
1038
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
992
1039
|
echo "[ERROR] All AI models failed to generate structural mutation ideas" >&2
|
|
993
1040
|
cat "$stderr_file" >&2
|
|
994
1041
|
cd "$original_pwd"
|
|
@@ -1025,6 +1072,9 @@ generate_crossover_direct() {
|
|
|
1025
1072
|
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
1026
1073
|
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
1027
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
|
+
|
|
1028
1078
|
# Extract just the IDs from top performers for clarity
|
|
1029
1079
|
local valid_parent_ids
|
|
1030
1080
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
@@ -1032,7 +1082,7 @@ generate_crossover_direct() {
|
|
|
1032
1082
|
# Use relative paths and change to evolution directory so AI can access files
|
|
1033
1083
|
local temp_csv_basename=$(basename "$temp_csv")
|
|
1034
1084
|
|
|
1035
|
-
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
|
|
1036
1086
|
|
|
1037
1087
|
IMPORTANT: You MUST use ONLY these exact parent IDs: $valid_parent_ids
|
|
1038
1088
|
|
|
@@ -1043,16 +1093,20 @@ CRITICAL INSTRUCTION: Before generating hybrid combination ideas, you MUST read
|
|
|
1043
1093
|
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
1044
1094
|
For example: evolution_gen01-251.py
|
|
1045
1095
|
|
|
1046
|
-
|
|
1096
|
+
CRITICAL INSTRUCTIONS:
|
|
1047
1097
|
1. Use the Read tool to examine the current CSV file
|
|
1048
|
-
2.
|
|
1049
|
-
3.
|
|
1050
|
-
4.
|
|
1051
|
-
5.
|
|
1052
|
-
6.
|
|
1053
|
-
7.
|
|
1054
|
-
|
|
1055
|
-
|
|
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."
|
|
1056
1110
|
|
|
1057
1111
|
# Change to evolution directory so AI can access files
|
|
1058
1112
|
local original_pwd=$(pwd)
|
|
@@ -1061,7 +1115,8 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
1061
1115
|
# Get AI to directly edit the CSV file
|
|
1062
1116
|
local ai_response
|
|
1063
1117
|
local stderr_file="stderr-$$.txt"
|
|
1064
|
-
|
|
1118
|
+
# Temporarily show stderr for debugging
|
|
1119
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$count" "$temp_csv_basename"); then
|
|
1065
1120
|
echo "[ERROR] All AI models failed to generate crossover hybrid ideas" >&2
|
|
1066
1121
|
cat "$stderr_file" >&2
|
|
1067
1122
|
cd "$original_pwd"
|
|
@@ -1133,13 +1188,15 @@ $top_performers"
|
|
|
1133
1188
|
|
|
1134
1189
|
prompt+="
|
|
1135
1190
|
|
|
1136
|
-
|
|
1191
|
+
CRITICAL INSTRUCTIONS:
|
|
1137
1192
|
1. Use the Read tool to examine the current CSV file
|
|
1138
|
-
2.
|
|
1139
|
-
3.
|
|
1140
|
-
4.
|
|
1141
|
-
5.
|
|
1142
|
-
6.
|
|
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
|
|
1143
1200
|
|
|
1144
1201
|
⚠️ AVOID ONLY: Kelly floor/cap adjustments that assume leverage > 1.0 (these get clamped and have no effect)
|
|
1145
1202
|
|
|
@@ -1153,7 +1210,9 @@ Instructions:
|
|
|
1153
1210
|
- Time-Based Patterns: Intraday effects, calendar anomalies, volatility timing
|
|
1154
1211
|
- Parameter Optimization: Entry thresholds, indicator periods, strategy weights
|
|
1155
1212
|
|
|
1156
|
-
|
|
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."
|
|
1157
1216
|
|
|
1158
1217
|
# Change to evolution directory so AI can access files
|
|
1159
1218
|
local original_pwd=$(pwd)
|
|
@@ -1162,7 +1221,7 @@ CRITICAL: You must use your file editing tools (Edit/MultiEdit) to modify the CS
|
|
|
1162
1221
|
# Get AI to directly edit the CSV file
|
|
1163
1222
|
local ai_response
|
|
1164
1223
|
local stderr_file="stderr-$$.txt"
|
|
1165
|
-
if ! ai_response=$(
|
|
1224
|
+
if ! ai_response=$(call_ai_for_ideation "$prompt" "$CURRENT_GENERATION" "$TOTAL_IDEAS" "$temp_csv_basename" 2>"$stderr_file"); then
|
|
1166
1225
|
echo "[ERROR] All AI models failed to generate ideas" >&2
|
|
1167
1226
|
cat "$stderr_file" >&2
|
|
1168
1227
|
cd "$original_pwd"
|