fix: feat: evolve.sh auto-incrementing per-run results directory (#752)

- --output now accepts a base dir (default: evolved/) instead of requiring
  an explicit path each run
- On each invocation, scan base dir for existing run_NNN/ subdirectories,
  find the highest N, and create run_(N+1)/ for this run's outputs
- All generation JSONL files, best.push3, diff.txt, and evolution.log are
  written to the new run dir — previous runs are never overwritten
- Log header now shows both Base dir and Output (run dir) for clarity

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-14 11:08:04 +00:00
parent 6ff8282a7e
commit b5bf53b010

View file

@ -11,7 +11,7 @@
# --generations 5 \
# --mutation-rate 2 \
# --elites 2 \
# --output evolved/ \
# [--output evolved/] \
# [--diverse-seeds] \
# [--run-id <N>]
#
@ -40,7 +40,7 @@
# 4. Show diff: original vs evolved (which constants changed, by how much).
#
# Output:
# <output>/
# <output>/run_NNN/ NNN auto-increments from the highest existing run dir
# generation_0.jsonl {candidate_id, fitness, mutations_applied}
# generation_1.jsonl
# ...
@ -80,7 +80,7 @@ POPULATION=10
GENERATIONS=5
MUTATION_RATE=2
ELITES=2
OUTPUT_DIR=""
OUTPUT_DIR="evolved"
DIVERSE_SEEDS=false
RUN_ID=""
@ -98,9 +98,8 @@ while [[ $# -gt 0 ]]; do
esac
done
if [ -z "$SEED" ]; then echo "Error: --seed required" >&2; exit 2; fi
if [ -z "$OUTPUT_DIR" ]; then echo "Error: --output required" >&2; exit 2; fi
if [ ! -f "$SEED" ]; then echo "Error: seed file not found: $SEED" >&2; exit 2; fi
if [ -z "$SEED" ]; then echo "Error: --seed required" >&2; exit 2; fi
if [ ! -f "$SEED" ]; then echo "Error: seed file not found: $SEED" >&2; exit 2; fi
# Validate numeric args
for _name_val in "population:$POPULATION" "generations:$GENERATIONS" "mutation-rate:$MUTATION_RATE"; do
@ -119,8 +118,27 @@ fi
# Canonicalize paths
SEED="$(cd "$(dirname "$SEED")" && pwd)/$(basename "$SEED")"
# Resolve base output dir and create run_NNN subdirectory
mkdir -p "$OUTPUT_DIR"
BASE_DIR="$(cd "$OUTPUT_DIR" && pwd)"
# Auto-increment: find the highest run_NNN directory under BASE_DIR and add 1
RUN_NUM=$(python3 - "$BASE_DIR" <<'PYEOF'
import sys, os, re
base = sys.argv[1]
max_n = 0
if os.path.isdir(base):
for name in os.listdir(base):
m = re.fullmatch(r'run(\d+)', name)
if m and os.path.isdir(os.path.join(base, name)):
max_n = max(max_n, int(m.group(1)))
print(f"{max_n + 1:03d}")
PYEOF
)
OUTPUT_DIR="$BASE_DIR/run_${RUN_NUM}"
mkdir -p "$OUTPUT_DIR"
OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
LOG="$OUTPUT_DIR/evolution.log"
# Seeds pool — persistent candidate pool across all runs
@ -294,6 +312,7 @@ log " Mutation rate: $MUTATION_RATE"
log " Elites: $ELITES"
log " Diverse seeds: $DIVERSE_SEEDS"
log " Run ID: $RUN_ID"
log " Base dir: $BASE_DIR"
log " Output: $OUTPUT_DIR"
log " TSX: $TSX_CMD"
log " Eval mode: $EVAL_MODE"