-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmeta_loop.sh
More file actions
executable file
·149 lines (121 loc) · 3.65 KB
/
Copy pathmeta_loop.sh
File metadata and controls
executable file
·149 lines (121 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/bash
set -euo pipefail
SDK_DIR="$(cd "$(dirname "$0")" && pwd)"
SCRIPT_DIR="${THREADMILL_TASK_DIR:-$SDK_DIR}"
if [[ "$SCRIPT_DIR" != /* ]]; then
SCRIPT_DIR="$(cd "$SCRIPT_DIR" && pwd)"
fi
find_harness_dir() {
local base candidate
for base in "$SCRIPT_DIR" "$SDK_DIR"; do
while [[ -n "$base" && "$base" != "/" ]]; do
candidate="$base/harnesses"
if [[ -d "$candidate" ]]; then
echo "$candidate"
return 0
fi
base="$(dirname "$base")"
done
done
return 1
}
find_latest_generation() {
local max_num=-1
local latest=""
shopt -s nullglob
for path in "$SCRIPT_DIR"/generation_*; do
[[ -d "$path" ]] || continue
local base num
base="$(basename "$path")"
num="${base#generation_}"
[[ "$num" =~ ^[0-9]+$ ]] || continue
if (( num > max_num )); then
max_num="$num"
latest="$path"
fi
done
shopt -u nullglob
echo "$latest"
}
next_generation_number() {
local max_num=0
shopt -s nullglob
for path in "$SCRIPT_DIR"/generation_*; do
[[ -d "$path" ]] || continue
local base num
base="$(basename "$path")"
num="${base#generation_}"
[[ "$num" =~ ^[0-9]+$ ]] || continue
if (( num > max_num )); then
max_num="$num"
fi
done
shopt -u nullglob
echo "$((max_num + 1))"
}
create_new_generation() {
local next_num
next_num="$(next_generation_number)"
local new_dir="$SCRIPT_DIR/generation_$next_num"
local prev_dir
prev_dir="$(find_latest_generation)"
echo "=== Creating generation_$next_num ===" >&2
mkdir -p "$new_dir"
# Copy core files from the previous generation if available, otherwise
# from the root template.
for file in AGENTS.md loop.sh run.sh threadmill.env threadmill.env.example; do
if [[ -n "$prev_dir" && -f "$prev_dir/$file" ]]; then
cp "$prev_dir/$file" "$new_dir/$file"
elif [[ -f "$SCRIPT_DIR/$file" ]]; then
cp "$SCRIPT_DIR/$file" "$new_dir/$file"
elif [[ "$file" == "loop.sh" || "$file" == "run.sh" ]] && [[ -f "$SDK_DIR/$file" ]]; then
cp "$SDK_DIR/$file" "$new_dir/$file"
fi
done
# MAIN_GOAL.md always comes from the root template.
if [[ -f "$SCRIPT_DIR/MAIN_GOAL.md" ]]; then
cp "$SCRIPT_DIR/MAIN_GOAL.md" "$new_dir/MAIN_GOAL.md"
fi
# Harnesses are runtime templates; prefer the task copy, then walk upward so
# copied experiments can still find the SDK-level harnesses.
local harness_dir
harness_dir="$(find_harness_dir || true)"
if [[ -n "$harness_dir" ]]; then
cp -R "$harness_dir" "$new_dir/harnesses"
elif [[ -n "$prev_dir" && -d "$prev_dir/harnesses" ]]; then
cp -R "$prev_dir/harnesses" "$new_dir/harnesses"
fi
chmod +x "$new_dir/loop.sh" "$new_dir/run.sh" "$new_dir"/harnesses/*.sh 2>/dev/null || true
: > "$new_dir/INBOX.md"
echo "$new_dir"
}
run_generation() {
local dir="$1"
echo "=== Running generation: $(basename "$dir") ==="
(
cd "$dir"
THREADMILL_TASK_DIR="$dir" THREADMILL_META_LOOP=1 bash "./loop.sh"
)
echo "=== Generation finished: $(basename "$dir") ==="
}
# --- Main loop ---
while true; do
latest="$(find_latest_generation)"
if [[ -z "$latest" ]]; then
echo "=== No generation_* found yet, creating the first one ==="
latest="$(create_new_generation)"
fi
if [[ -f "$latest/STOP" ]]; then
echo "=== $(basename "$latest") stopped (STOP), creating the next one ==="
latest="$(create_new_generation)"
fi
if [[ ! -f "$latest/loop.sh" ]]; then
echo "$(basename "$latest") has no loop.sh, cannot run it" >&2
exit 1
fi
run_generation "$latest"
if [[ ! -f "$latest/STOP" ]]; then
echo "=== loop.sh exited without STOP -- treating this as a crash ===" >&2
exit 1
fi
done