claude-evolve 1.4.13 → 1.5.0
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 +146 -68
- package/bin/claude-evolve-worker +143 -19
- package/package.json +1 -1
package/bin/claude-evolve-ideate
CHANGED
|
@@ -81,9 +81,9 @@ call_ai_with_limit_check() {
|
|
|
81
81
|
if [[ "$preferred_model" == "o3" ]] && command -v codex >/dev/null 2>&1; then
|
|
82
82
|
echo "[INFO] Using codex o3 for ideation" >&2
|
|
83
83
|
|
|
84
|
-
# Call codex with o3 model using
|
|
84
|
+
# Call codex with o3 model using exec subcommand
|
|
85
85
|
local ai_output
|
|
86
|
-
ai_output=$(codex -m o3 --full-auto
|
|
86
|
+
ai_output=$(echo "$prompt" | codex exec -m o3 --full-auto 2>&1)
|
|
87
87
|
local ai_exit_code=$?
|
|
88
88
|
|
|
89
89
|
if [[ $ai_exit_code -eq 0 ]]; then
|
|
@@ -204,28 +204,46 @@ call_ai_with_fallbacks() {
|
|
|
204
204
|
local prompt="$1"
|
|
205
205
|
local generation="${2:-01}"
|
|
206
206
|
|
|
207
|
-
#
|
|
208
|
-
local
|
|
207
|
+
# Determine which model to use based on generation (round-robin)
|
|
208
|
+
local gen_num
|
|
209
|
+
if [[ $generation =~ ^0*([0-9]+)$ ]]; then
|
|
210
|
+
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
211
|
+
else
|
|
212
|
+
gen_num=1
|
|
213
|
+
fi
|
|
209
214
|
|
|
210
215
|
# Check which AI tools are available
|
|
216
|
+
local available_models=()
|
|
211
217
|
if command -v codex >/dev/null 2>&1; then
|
|
212
|
-
|
|
218
|
+
available_models+=("o3")
|
|
213
219
|
fi
|
|
214
220
|
if command -v gemini >/dev/null 2>&1; then
|
|
215
|
-
|
|
221
|
+
available_models+=("gemini")
|
|
216
222
|
fi
|
|
217
|
-
# Claude
|
|
218
|
-
|
|
223
|
+
available_models+=("opus") # Claude Opus always available
|
|
224
|
+
|
|
225
|
+
# Create ordered list based on round-robin for this generation
|
|
226
|
+
local num_models=${#available_models[@]}
|
|
227
|
+
local start_index=$((gen_num % num_models))
|
|
228
|
+
local models=()
|
|
229
|
+
|
|
230
|
+
# Add models in round-robin order starting from the calculated index
|
|
231
|
+
for ((i=0; i<num_models; i++)); do
|
|
232
|
+
local idx=$(((start_index + i) % num_models))
|
|
233
|
+
models+=("${available_models[$idx]}")
|
|
234
|
+
done
|
|
219
235
|
|
|
220
|
-
|
|
236
|
+
echo "[INFO] Model order for generation $generation (round-robin): ${models[*]}" >&2
|
|
237
|
+
|
|
238
|
+
# Try each model in the ordered sequence
|
|
221
239
|
for model in "${models[@]}"; do
|
|
222
|
-
echo "[INFO] Trying $model for ideation
|
|
240
|
+
echo "[INFO] Trying $model for ideation" >&2
|
|
223
241
|
|
|
224
242
|
local ai_output
|
|
225
243
|
local ai_exit_code
|
|
226
244
|
|
|
227
245
|
if [[ "$model" == "o3" ]] && command -v codex >/dev/null 2>&1; then
|
|
228
|
-
ai_output=$(codex -m o3 --full-auto
|
|
246
|
+
ai_output=$(echo "$prompt" | codex exec -m o3 --full-auto 2>&1)
|
|
229
247
|
ai_exit_code=$?
|
|
230
248
|
|
|
231
249
|
if [[ $ai_exit_code -eq 0 ]]; then
|
|
@@ -422,17 +440,18 @@ validate_direct_csv_modification() {
|
|
|
422
440
|
fi
|
|
423
441
|
|
|
424
442
|
# Validate the modified CSV has more entries than original
|
|
443
|
+
# Count actual data rows (excluding header and empty lines)
|
|
425
444
|
local original_count
|
|
426
|
-
original_count=$(
|
|
445
|
+
original_count=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
427
446
|
local new_count
|
|
428
|
-
new_count=$(
|
|
447
|
+
new_count=$(grep -v '^[[:space:]]*$' "$temp_csv" | tail -n +2 | wc -l)
|
|
429
448
|
|
|
430
|
-
echo "[DEBUG] Original CSV
|
|
431
|
-
echo "[DEBUG] Modified CSV
|
|
449
|
+
echo "[DEBUG] Original CSV data rows: $original_count" >&2
|
|
450
|
+
echo "[DEBUG] Modified CSV data rows: $new_count" >&2
|
|
432
451
|
echo "[DEBUG] Expected to add: $expected_count ideas" >&2
|
|
433
452
|
|
|
434
453
|
if [[ $new_count -le $original_count ]]; then
|
|
435
|
-
echo "[ERROR] CSV file wasn't modified - same number of
|
|
454
|
+
echo "[ERROR] CSV file wasn't modified - same number of data rows ($new_count <= $original_count)" >&2
|
|
436
455
|
echo "[DEBUG] First 10 lines of CSV after AI attempt:" >&2
|
|
437
456
|
head -10 "$temp_csv" >&2
|
|
438
457
|
return 1
|
|
@@ -529,8 +548,8 @@ process_ai_ideas_direct_old() {
|
|
|
529
548
|
local top_performers="${3:-}" # Optional, for non-novel ideas
|
|
530
549
|
local ai_output="$4" # The AI's response with ideas
|
|
531
550
|
|
|
532
|
-
# Create temporary CSV copy
|
|
533
|
-
local temp_csv="/
|
|
551
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
552
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
534
553
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
535
554
|
|
|
536
555
|
echo "[DEBUG] Starting CSV modification for $count $idea_type ideas" >&2
|
|
@@ -787,42 +806,54 @@ ideate_ai_strategies() {
|
|
|
787
806
|
generate_novel_ideas_direct() {
|
|
788
807
|
local count="$1"
|
|
789
808
|
|
|
790
|
-
# Create temporary CSV copy
|
|
791
|
-
local temp_csv="/
|
|
809
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
810
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
792
811
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
793
812
|
|
|
794
813
|
echo "[INFO] Generating $count novel exploration ideas..."
|
|
795
|
-
|
|
814
|
+
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
815
|
+
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
816
|
+
|
|
817
|
+
# Use relative paths and change to evolution directory so AI can access files
|
|
818
|
+
local temp_csv_basename=$(basename "$temp_csv")
|
|
796
819
|
|
|
797
|
-
local prompt="
|
|
820
|
+
local prompt="I need you to use your file editing capabilities to add exactly $count novel algorithmic ideas to the CSV file: $temp_csv_basename
|
|
798
821
|
|
|
799
822
|
Current evolution context:
|
|
800
823
|
- Generation: $CURRENT_GENERATION
|
|
801
|
-
- Algorithm:
|
|
824
|
+
- Algorithm: algorithm.py (base algorithm)
|
|
802
825
|
- Brief: $(head -20 "$FULL_BRIEF_PATH")
|
|
803
826
|
|
|
804
827
|
Instructions:
|
|
805
|
-
1. Read the current CSV file
|
|
806
|
-
2.
|
|
828
|
+
1. Use the Read tool to examine the current CSV file
|
|
829
|
+
2. Use the Edit or MultiEdit tool to add exactly $count new rows to the CSV file
|
|
807
830
|
3. Use the next available generation numbers (gen$CURRENT_GENERATION-XXX format)
|
|
808
831
|
4. For each idea, create a row with: id,,description,,pending (empty parent_id for novel ideas)
|
|
809
832
|
5. Each description should be one clear sentence describing a novel algorithmic approach
|
|
810
833
|
6. Focus on creative, ambitious ideas that haven't been tried yet
|
|
811
834
|
7. Consider machine learning, new indicators, regime detection, risk management, etc.
|
|
812
835
|
|
|
813
|
-
|
|
836
|
+
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."
|
|
814
837
|
|
|
838
|
+
# Change to evolution directory so AI can access files
|
|
839
|
+
local original_pwd=$(pwd)
|
|
840
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
841
|
+
|
|
815
842
|
# Get AI to directly edit the CSV file
|
|
816
843
|
local ai_response
|
|
817
|
-
local stderr_file="
|
|
844
|
+
local stderr_file="stderr-$$.txt"
|
|
818
845
|
if ! ai_response=$(call_ai_with_fallbacks "$prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
819
846
|
echo "[ERROR] All AI models failed to generate novel ideas" >&2
|
|
820
847
|
cat "$stderr_file" >&2
|
|
848
|
+
cd "$original_pwd"
|
|
821
849
|
rm -f "$temp_csv" "$stderr_file"
|
|
822
850
|
return 1
|
|
823
851
|
fi
|
|
824
852
|
rm -f "$stderr_file"
|
|
825
853
|
|
|
854
|
+
# Restore working directory
|
|
855
|
+
cd "$original_pwd"
|
|
856
|
+
|
|
826
857
|
echo "[DEBUG] AI response: $ai_response" >&2
|
|
827
858
|
|
|
828
859
|
# Validate that the CSV file was actually modified
|
|
@@ -840,18 +871,22 @@ generate_hill_climbing_direct() {
|
|
|
840
871
|
local count="$1"
|
|
841
872
|
local top_performers="$2"
|
|
842
873
|
|
|
843
|
-
# Create temporary CSV copy
|
|
844
|
-
local temp_csv="/
|
|
874
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
875
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
845
876
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
846
877
|
|
|
847
878
|
echo "[INFO] Generating $count hill climbing ideas..."
|
|
848
|
-
|
|
879
|
+
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
880
|
+
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
849
881
|
|
|
850
882
|
# Extract just the IDs from top performers for clarity
|
|
851
883
|
local valid_parent_ids
|
|
852
884
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
853
885
|
|
|
854
|
-
|
|
886
|
+
# Use relative paths and change to evolution directory so AI can access files
|
|
887
|
+
local temp_csv_basename=$(basename "$temp_csv")
|
|
888
|
+
|
|
889
|
+
local prompt="I need you to use your file editing capabilities to add exactly $count parameter tuning ideas to the CSV file: $temp_csv_basename
|
|
855
890
|
|
|
856
891
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
857
892
|
|
|
@@ -859,31 +894,39 @@ Successful algorithms to tune:
|
|
|
859
894
|
$top_performers
|
|
860
895
|
|
|
861
896
|
CRITICAL INSTRUCTION: Before generating parameter tuning ideas, you MUST read the source code of the parent algorithms.
|
|
862
|
-
Algorithm source files are located at:
|
|
863
|
-
For example:
|
|
897
|
+
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
898
|
+
For example: evolution_gen01-251.py
|
|
864
899
|
|
|
865
900
|
Instructions:
|
|
866
|
-
1. Read the current CSV file
|
|
867
|
-
2.
|
|
901
|
+
1. Use the Read tool to examine the current CSV file
|
|
902
|
+
2. Use the Edit or MultiEdit tool to add exactly $count new rows to the CSV file
|
|
868
903
|
3. Use the next available generation numbers (gen$CURRENT_GENERATION-XXX format)
|
|
869
904
|
4. For each idea, create a row with: id,parent_id,description,,pending
|
|
870
905
|
5. Each parent_id MUST be one of: $valid_parent_ids
|
|
871
906
|
6. Each description should focus on adjusting specific parameters that exist in the parent's source code
|
|
872
907
|
7. Include current and new parameter values (e.g., \"Lower rsi_entry from 21 to 18\")
|
|
873
908
|
|
|
874
|
-
|
|
909
|
+
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."
|
|
875
910
|
|
|
911
|
+
# Change to evolution directory so AI can access files
|
|
912
|
+
local original_pwd=$(pwd)
|
|
913
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
914
|
+
|
|
876
915
|
# Get AI to directly edit the CSV file
|
|
877
916
|
local ai_response
|
|
878
|
-
local stderr_file="
|
|
917
|
+
local stderr_file="stderr-$$.txt"
|
|
879
918
|
if ! ai_response=$(call_ai_with_fallbacks "$prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
880
919
|
echo "[ERROR] All AI models failed to generate hill climbing ideas" >&2
|
|
881
920
|
cat "$stderr_file" >&2
|
|
921
|
+
cd "$original_pwd"
|
|
882
922
|
rm -f "$temp_csv" "$stderr_file"
|
|
883
923
|
return 1
|
|
884
924
|
fi
|
|
885
925
|
rm -f "$stderr_file"
|
|
886
926
|
|
|
927
|
+
# Restore working directory
|
|
928
|
+
cd "$original_pwd"
|
|
929
|
+
|
|
887
930
|
echo "[DEBUG] AI response: $ai_response" >&2
|
|
888
931
|
|
|
889
932
|
# Validate that the CSV file was actually modified
|
|
@@ -901,18 +944,22 @@ generate_structural_mutation_direct() {
|
|
|
901
944
|
local count="$1"
|
|
902
945
|
local top_performers="$2"
|
|
903
946
|
|
|
904
|
-
# Create temporary CSV copy
|
|
905
|
-
local temp_csv="/
|
|
947
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
948
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
906
949
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
907
950
|
|
|
908
951
|
echo "[INFO] Generating $count structural mutation ideas..."
|
|
909
|
-
|
|
952
|
+
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
953
|
+
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
910
954
|
|
|
911
955
|
# Extract just the IDs from top performers for clarity
|
|
912
956
|
local valid_parent_ids
|
|
913
957
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
914
958
|
|
|
915
|
-
|
|
959
|
+
# Use relative paths and change to evolution directory so AI can access files
|
|
960
|
+
local temp_csv_basename=$(basename "$temp_csv")
|
|
961
|
+
|
|
962
|
+
local prompt="I need you to use your file editing capabilities to add exactly $count structural modification ideas to the CSV file: $temp_csv_basename
|
|
916
963
|
|
|
917
964
|
IMPORTANT: You MUST use one of these exact parent IDs: $valid_parent_ids
|
|
918
965
|
|
|
@@ -920,31 +967,39 @@ Successful algorithms to modify structurally:
|
|
|
920
967
|
$top_performers
|
|
921
968
|
|
|
922
969
|
CRITICAL INSTRUCTION: Before generating structural modification ideas, you MUST read the source code of the parent algorithms.
|
|
923
|
-
Algorithm source files are located at:
|
|
924
|
-
For example:
|
|
970
|
+
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
971
|
+
For example: evolution_gen01-251.py
|
|
925
972
|
|
|
926
973
|
Instructions:
|
|
927
|
-
1. Read the current CSV file
|
|
928
|
-
2.
|
|
974
|
+
1. Use the Read tool to examine the current CSV file
|
|
975
|
+
2. Use the Edit or MultiEdit tool to add exactly $count new rows to the CSV file
|
|
929
976
|
3. Use the next available generation numbers (gen$CURRENT_GENERATION-XXX format)
|
|
930
977
|
4. For each idea, create a row with: id,parent_id,description,,pending
|
|
931
978
|
5. Each parent_id MUST be one of: $valid_parent_ids
|
|
932
979
|
6. Each description should focus on architectural/structural changes based on the parent's actual code
|
|
933
980
|
7. Reference actual components/methods found in the source code
|
|
934
981
|
|
|
935
|
-
|
|
982
|
+
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."
|
|
936
983
|
|
|
984
|
+
# Change to evolution directory so AI can access files
|
|
985
|
+
local original_pwd=$(pwd)
|
|
986
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
987
|
+
|
|
937
988
|
# Get AI to directly edit the CSV file
|
|
938
989
|
local ai_response
|
|
939
|
-
local stderr_file="
|
|
990
|
+
local stderr_file="stderr-$$.txt"
|
|
940
991
|
if ! ai_response=$(call_ai_with_fallbacks "$prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
941
992
|
echo "[ERROR] All AI models failed to generate structural mutation ideas" >&2
|
|
942
993
|
cat "$stderr_file" >&2
|
|
994
|
+
cd "$original_pwd"
|
|
943
995
|
rm -f "$temp_csv" "$stderr_file"
|
|
944
996
|
return 1
|
|
945
997
|
fi
|
|
946
998
|
rm -f "$stderr_file"
|
|
947
999
|
|
|
1000
|
+
# Restore working directory
|
|
1001
|
+
cd "$original_pwd"
|
|
1002
|
+
|
|
948
1003
|
echo "[DEBUG] AI response: $ai_response" >&2
|
|
949
1004
|
|
|
950
1005
|
# Validate that the CSV file was actually modified
|
|
@@ -962,18 +1017,22 @@ generate_crossover_direct() {
|
|
|
962
1017
|
local count="$1"
|
|
963
1018
|
local top_performers="$2"
|
|
964
1019
|
|
|
965
|
-
# Create temporary CSV copy
|
|
966
|
-
local temp_csv="/
|
|
1020
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
1021
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
967
1022
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
968
1023
|
|
|
969
1024
|
echo "[INFO] Generating $count crossover hybrid ideas..."
|
|
970
|
-
|
|
1025
|
+
local data_rows=$(grep -v '^[[:space:]]*$' "$FULL_CSV_PATH" | tail -n +2 | wc -l)
|
|
1026
|
+
echo "[DEBUG] Original CSV has $data_rows data rows" >&2
|
|
971
1027
|
|
|
972
1028
|
# Extract just the IDs from top performers for clarity
|
|
973
1029
|
local valid_parent_ids
|
|
974
1030
|
valid_parent_ids=$(echo "$top_performers" | cut -d',' -f1 | paste -sd ',' -)
|
|
975
1031
|
|
|
976
|
-
|
|
1032
|
+
# Use relative paths and change to evolution directory so AI can access files
|
|
1033
|
+
local temp_csv_basename=$(basename "$temp_csv")
|
|
1034
|
+
|
|
1035
|
+
local prompt="I need you to use your file editing capabilities to add exactly $count hybrid combination ideas to the CSV file: $temp_csv_basename
|
|
977
1036
|
|
|
978
1037
|
IMPORTANT: You MUST use ONLY these exact parent IDs: $valid_parent_ids
|
|
979
1038
|
|
|
@@ -981,31 +1040,39 @@ Top performers to combine (reference at least 2 in each idea):
|
|
|
981
1040
|
$top_performers
|
|
982
1041
|
|
|
983
1042
|
CRITICAL INSTRUCTION: Before generating hybrid combination ideas, you MUST read the source code of the parent algorithms.
|
|
984
|
-
Algorithm source files are located at:
|
|
985
|
-
For example:
|
|
1043
|
+
Algorithm source files are located at: evolution_<PARENT_ID>.py
|
|
1044
|
+
For example: evolution_gen01-251.py
|
|
986
1045
|
|
|
987
1046
|
Instructions:
|
|
988
|
-
1. Read the current CSV file
|
|
989
|
-
2.
|
|
1047
|
+
1. Use the Read tool to examine the current CSV file
|
|
1048
|
+
2. Use the Edit or MultiEdit tool to add exactly $count new rows to the CSV file
|
|
990
1049
|
3. Use the next available generation numbers (gen$CURRENT_GENERATION-XXX format)
|
|
991
1050
|
4. For each idea, create a row with: id,parent_id,description,,pending
|
|
992
1051
|
5. Each parent_id MUST be one of: $valid_parent_ids (choose the primary parent)
|
|
993
1052
|
6. Each description should combine actual elements from 2+ algorithms based on their source code
|
|
994
1053
|
7. Reference specific components/features found in the actual source code
|
|
995
1054
|
|
|
996
|
-
|
|
1055
|
+
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."
|
|
997
1056
|
|
|
1057
|
+
# Change to evolution directory so AI can access files
|
|
1058
|
+
local original_pwd=$(pwd)
|
|
1059
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
1060
|
+
|
|
998
1061
|
# Get AI to directly edit the CSV file
|
|
999
1062
|
local ai_response
|
|
1000
|
-
local stderr_file="
|
|
1063
|
+
local stderr_file="stderr-$$.txt"
|
|
1001
1064
|
if ! ai_response=$(call_ai_with_fallbacks "$prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
1002
1065
|
echo "[ERROR] All AI models failed to generate crossover hybrid ideas" >&2
|
|
1003
1066
|
cat "$stderr_file" >&2
|
|
1067
|
+
cd "$original_pwd"
|
|
1004
1068
|
rm -f "$temp_csv" "$stderr_file"
|
|
1005
1069
|
return 1
|
|
1006
1070
|
fi
|
|
1007
1071
|
rm -f "$stderr_file"
|
|
1008
1072
|
|
|
1073
|
+
# Restore working directory
|
|
1074
|
+
cd "$original_pwd"
|
|
1075
|
+
|
|
1009
1076
|
echo "[DEBUG] AI response: $ai_response" >&2
|
|
1010
1077
|
|
|
1011
1078
|
# Validate that the CSV file was actually modified
|
|
@@ -1025,8 +1092,8 @@ ideate_ai_legacy() {
|
|
|
1025
1092
|
exit 1
|
|
1026
1093
|
fi
|
|
1027
1094
|
|
|
1028
|
-
# Create temporary CSV copy
|
|
1029
|
-
local temp_csv="/
|
|
1095
|
+
# Create temporary CSV copy in evolution directory (so AI can access it)
|
|
1096
|
+
local temp_csv="$FULL_EVOLUTION_DIR/temp-csv-$$.csv"
|
|
1030
1097
|
cp "$FULL_CSV_PATH" "$temp_csv"
|
|
1031
1098
|
|
|
1032
1099
|
echo "[INFO] Generating $TOTAL_IDEAS ideas (legacy mode)..."
|
|
@@ -1040,15 +1107,18 @@ ideate_ai_legacy() {
|
|
|
1040
1107
|
fi
|
|
1041
1108
|
|
|
1042
1109
|
# Build prompt for direct CSV modification
|
|
1043
|
-
|
|
1110
|
+
# Use relative paths and change to evolution directory so AI can access files
|
|
1111
|
+
local temp_csv_basename=$(basename "$temp_csv")
|
|
1112
|
+
|
|
1113
|
+
local prompt="I need you to use your file editing capabilities to add exactly $TOTAL_IDEAS algorithmic ideas to the CSV file: $temp_csv_basename
|
|
1044
1114
|
|
|
1045
1115
|
Algorithm files for context:
|
|
1046
|
-
- Base algorithm:
|
|
1047
|
-
- Evolved algorithms:
|
|
1116
|
+
- Base algorithm: algorithm.py
|
|
1117
|
+
- Evolved algorithms: evolution_*.py
|
|
1048
1118
|
|
|
1049
1119
|
IMPORTANT: Before generating ideas, you should:
|
|
1050
|
-
1. Read the base algorithm to understand the codebase structure and possibilities
|
|
1051
|
-
2. Read ALL existing evolution_*.py files to see what modifications have been attempted
|
|
1120
|
+
1. Use the Read tool to examine the base algorithm to understand the codebase structure and possibilities
|
|
1121
|
+
2. Use the Read tool to examine ALL existing evolution_*.py files to see what modifications have been attempted
|
|
1052
1122
|
3. Consider which approaches might work well
|
|
1053
1123
|
|
|
1054
1124
|
Project Brief:
|
|
@@ -1064,8 +1134,8 @@ $top_performers"
|
|
|
1064
1134
|
prompt+="
|
|
1065
1135
|
|
|
1066
1136
|
Instructions:
|
|
1067
|
-
1. Read the current CSV file
|
|
1068
|
-
2.
|
|
1137
|
+
1. Use the Read tool to examine the current CSV file
|
|
1138
|
+
2. Use the Edit or MultiEdit tool to add exactly $TOTAL_IDEAS new rows to the CSV file
|
|
1069
1139
|
3. Use the next available generation numbers (gen$CURRENT_GENERATION-XXX format)
|
|
1070
1140
|
4. For each idea, create a row with: id,parent_id,description,,pending
|
|
1071
1141
|
5. Mix both parameter tuning and structural changes
|
|
@@ -1083,19 +1153,27 @@ Instructions:
|
|
|
1083
1153
|
- Time-Based Patterns: Intraday effects, calendar anomalies, volatility timing
|
|
1084
1154
|
- Parameter Optimization: Entry thresholds, indicator periods, strategy weights
|
|
1085
1155
|
|
|
1086
|
-
|
|
1156
|
+
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."
|
|
1087
1157
|
|
|
1158
|
+
# Change to evolution directory so AI can access files
|
|
1159
|
+
local original_pwd=$(pwd)
|
|
1160
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
1161
|
+
|
|
1088
1162
|
# Get AI to directly edit the CSV file
|
|
1089
1163
|
local ai_response
|
|
1090
|
-
local stderr_file="
|
|
1164
|
+
local stderr_file="stderr-$$.txt"
|
|
1091
1165
|
if ! ai_response=$(call_ai_with_fallbacks "$prompt" "$CURRENT_GENERATION" 2>"$stderr_file"); then
|
|
1092
1166
|
echo "[ERROR] All AI models failed to generate ideas" >&2
|
|
1093
1167
|
cat "$stderr_file" >&2
|
|
1168
|
+
cd "$original_pwd"
|
|
1094
1169
|
rm -f "$temp_csv" "$stderr_file"
|
|
1095
1170
|
return 1
|
|
1096
1171
|
fi
|
|
1097
1172
|
rm -f "$stderr_file"
|
|
1098
1173
|
|
|
1174
|
+
# Restore working directory
|
|
1175
|
+
cd "$original_pwd"
|
|
1176
|
+
|
|
1099
1177
|
echo "[DEBUG] AI response: $ai_response" >&2
|
|
1100
1178
|
|
|
1101
1179
|
# Validate that the CSV file was actually modified
|
package/bin/claude-evolve-worker
CHANGED
|
@@ -79,6 +79,132 @@ else
|
|
|
79
79
|
load_config
|
|
80
80
|
fi
|
|
81
81
|
|
|
82
|
+
# AI round-robin with fallback function for code evolution
|
|
83
|
+
call_ai_for_evolution() {
|
|
84
|
+
local prompt="$1"
|
|
85
|
+
local candidate_id="$2"
|
|
86
|
+
|
|
87
|
+
# Extract generation and ID numbers for round-robin calculation
|
|
88
|
+
local gen_num=0
|
|
89
|
+
local id_num=0
|
|
90
|
+
if [[ $candidate_id =~ ^gen([0-9]+)-([0-9]+)$ ]]; then
|
|
91
|
+
gen_num=$((10#${BASH_REMATCH[1]}))
|
|
92
|
+
id_num=$((10#${BASH_REMATCH[2]}))
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Calculate hash for round-robin (combine generation and ID)
|
|
96
|
+
local hash_value=$((gen_num * 1000 + id_num))
|
|
97
|
+
|
|
98
|
+
# Check which AI tools are available
|
|
99
|
+
local available_models=()
|
|
100
|
+
available_models+=("claude") # Claude Sonnet always available
|
|
101
|
+
if command -v gemini >/dev/null 2>&1; then
|
|
102
|
+
available_models+=("gemini")
|
|
103
|
+
fi
|
|
104
|
+
if command -v codex >/dev/null 2>&1; then
|
|
105
|
+
available_models+=("codex")
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# Create ordered list based on round-robin for this candidate
|
|
109
|
+
local num_models=${#available_models[@]}
|
|
110
|
+
local start_index=$((hash_value % num_models))
|
|
111
|
+
local models=()
|
|
112
|
+
|
|
113
|
+
# Add models in round-robin order starting from the calculated index
|
|
114
|
+
for ((i=0; i<num_models; i++)); do
|
|
115
|
+
local idx=$(((start_index + i) % num_models))
|
|
116
|
+
models+=("${available_models[$idx]}")
|
|
117
|
+
done
|
|
118
|
+
|
|
119
|
+
echo "[WORKER-$$] Model order for $candidate_id (round-robin): ${models[*]}" >&2
|
|
120
|
+
|
|
121
|
+
# Try each model in the ordered sequence
|
|
122
|
+
for model in "${models[@]}"; do
|
|
123
|
+
echo "[WORKER-$$] Attempting code evolution with $model" >&2
|
|
124
|
+
local ai_output
|
|
125
|
+
local ai_exit_code
|
|
126
|
+
|
|
127
|
+
case "$model" in
|
|
128
|
+
"claude")
|
|
129
|
+
ai_output=$(echo "$prompt" | claude --dangerously-skip-permissions -p 2>&1)
|
|
130
|
+
ai_exit_code=$?
|
|
131
|
+
|
|
132
|
+
# Check for usage limits
|
|
133
|
+
if echo "$ai_output" | grep -q "Claude AI usage limit reached"; then
|
|
134
|
+
echo "[WORKER-$$] Claude AI usage limit reached - trying next model" >&2
|
|
135
|
+
continue
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
139
|
+
echo "[WORKER-$$] Claude Sonnet succeeded" >&2
|
|
140
|
+
return 0
|
|
141
|
+
fi
|
|
142
|
+
;;
|
|
143
|
+
|
|
144
|
+
"gemini")
|
|
145
|
+
ai_output=$(gemini -y -p "$prompt" 2>&1)
|
|
146
|
+
ai_exit_code=$?
|
|
147
|
+
|
|
148
|
+
# Check for authentication messages or valid response
|
|
149
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
150
|
+
if ! echo "$ai_output" | grep -q "Attempting to authenticate\|Authenticating\|Loading\|Initializing"; then
|
|
151
|
+
if [[ -n "$ai_output" ]] && [[ $(echo "$ai_output" | wc -l) -ge 2 ]]; then
|
|
152
|
+
echo "[WORKER-$$] Gemini succeeded" >&2
|
|
153
|
+
return 0
|
|
154
|
+
fi
|
|
155
|
+
fi
|
|
156
|
+
fi
|
|
157
|
+
;;
|
|
158
|
+
|
|
159
|
+
"codex")
|
|
160
|
+
ai_output=$(echo "$prompt" | codex exec --full-auto 2>&1)
|
|
161
|
+
ai_exit_code=$?
|
|
162
|
+
|
|
163
|
+
if [[ $ai_exit_code -eq 0 ]]; then
|
|
164
|
+
# Clean codex output if it's JSON
|
|
165
|
+
if echo "$ai_output" | grep -q '"content"'; then
|
|
166
|
+
ai_output=$(echo "$ai_output" | python3 -c "
|
|
167
|
+
import sys
|
|
168
|
+
import json
|
|
169
|
+
try:
|
|
170
|
+
data = json.load(sys.stdin)
|
|
171
|
+
if 'content' in data:
|
|
172
|
+
print(data['content'])
|
|
173
|
+
elif 'response' in data:
|
|
174
|
+
print(data['response'])
|
|
175
|
+
elif 'text' in data:
|
|
176
|
+
print(data['text'])
|
|
177
|
+
else:
|
|
178
|
+
print(json.dumps(data))
|
|
179
|
+
except:
|
|
180
|
+
print(sys.stdin.read())
|
|
181
|
+
" 2>/dev/null || echo "$ai_output")
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
if [[ -n "$ai_output" ]] && ! echo "$ai_output" | grep -q "error\|failed\|exception"; then
|
|
185
|
+
echo "[WORKER-$$] Codex succeeded" >&2
|
|
186
|
+
return 0
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
189
|
+
;;
|
|
190
|
+
esac
|
|
191
|
+
|
|
192
|
+
echo "[WORKER-$$] $model failed (exit code $ai_exit_code), trying next model..." >&2
|
|
193
|
+
if [[ -n "$ai_output" ]]; then
|
|
194
|
+
echo "[WORKER-$$] $model error: $(echo "$ai_output" | head -5)" >&2
|
|
195
|
+
fi
|
|
196
|
+
done
|
|
197
|
+
|
|
198
|
+
# All models in round-robin failed, check for API limit exit
|
|
199
|
+
if echo "${ai_output:-}" | grep -q "Claude AI usage limit reached"; then
|
|
200
|
+
echo "[WORKER-$$] ERROR: All AI models unavailable - Claude hit usage limit" >&2
|
|
201
|
+
exit 3
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
echo "[WORKER-$$] All AI models failed for code evolution" >&2
|
|
205
|
+
return 1
|
|
206
|
+
}
|
|
207
|
+
|
|
82
208
|
# Validate paths
|
|
83
209
|
if [[ ! -f "$FULL_CSV_PATH" ]]; then
|
|
84
210
|
echo "[WORKER-$$] CSV file not found: $FULL_CSV_PATH" >&2
|
|
@@ -153,42 +279,40 @@ with EvolutionCSV('$FULL_CSV_PATH') as csv:
|
|
|
153
279
|
echo "[WORKER-$$] Copying $source_file to $target_file"
|
|
154
280
|
cp "$source_file" "$target_file"
|
|
155
281
|
|
|
156
|
-
# Apply evolution using
|
|
157
|
-
echo "[WORKER-$$] Applying evolution
|
|
158
|
-
|
|
282
|
+
# Apply evolution using AI
|
|
283
|
+
echo "[WORKER-$$] Applying evolution..."
|
|
284
|
+
|
|
285
|
+
# Use relative path for AI prompt
|
|
286
|
+
local target_basename=$(basename "$target_file")
|
|
287
|
+
local evolution_prompt="Modify the algorithm in $target_basename based on this description: $description
|
|
159
288
|
|
|
160
289
|
The modification should be substantial and follow the description exactly. Make sure the algorithm still follows all interface requirements and can run properly.
|
|
161
290
|
|
|
162
291
|
Important: Make meaningful changes that match the description. Don't just add comments or make trivial adjustments."
|
|
163
292
|
|
|
164
293
|
if [[ "$is_baseline" != "true" ]]; then
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
294
|
+
# Change to evolution directory so AI can access files
|
|
295
|
+
local original_pwd=$(pwd)
|
|
296
|
+
cd "$FULL_EVOLUTION_DIR"
|
|
168
297
|
|
|
169
|
-
#
|
|
170
|
-
if
|
|
171
|
-
echo "[WORKER-$$] ERROR:
|
|
172
|
-
|
|
173
|
-
rm -f "$target_file" # Clean up on failure
|
|
174
|
-
# Exit with special code 3 to indicate API limit
|
|
175
|
-
exit 3
|
|
176
|
-
fi
|
|
177
|
-
|
|
178
|
-
if [[ $claude_exit_code -ne 0 ]]; then
|
|
179
|
-
echo "[WORKER-$$] ERROR: Claude evolution failed with exit code $claude_exit_code" >&2
|
|
180
|
-
echo "[WORKER-$$] ERROR: Claude output: $claude_output" >&2
|
|
298
|
+
# Try AI models with round-robin based on candidate ID
|
|
299
|
+
if ! call_ai_for_evolution "$evolution_prompt" "$candidate_id"; then
|
|
300
|
+
echo "[WORKER-$$] ERROR: All AI models failed to generate code" >&2
|
|
301
|
+
cd "$original_pwd"
|
|
181
302
|
rm -f "$target_file" # Clean up on failure
|
|
182
303
|
return 1
|
|
183
304
|
fi
|
|
184
305
|
|
|
306
|
+
# Restore working directory
|
|
307
|
+
cd "$original_pwd"
|
|
308
|
+
|
|
185
309
|
echo "[WORKER-$$] Evolution applied successfully"
|
|
186
310
|
fi
|
|
187
311
|
fi
|
|
188
312
|
|
|
189
313
|
# Run evaluation
|
|
190
314
|
echo "[WORKER-$$] Evaluating algorithm..."
|
|
191
|
-
local eval_output_file="/
|
|
315
|
+
local eval_output_file="$FULL_EVOLUTION_DIR/temp-eval-$$-$candidate_id.out"
|
|
192
316
|
local eval_start=$(date +%s)
|
|
193
317
|
|
|
194
318
|
# Prepare evaluation command
|