dam, erase experimental file from before that snuck through in my purge

This commit is contained in:
Andrej Karpathy 2026-03-06 22:03:27 +00:00
parent 2a70301b10
commit 1e207aaf21

248
spawn.sh
View File

@ -1,248 +0,0 @@
#!/bin/bash
# spawn.sh — launch and manage autonomous research groups
#
# Usage:
# bash spawn.sh launch <tag> <agent:gpu> [agent:gpu ...]
# bash spawn.sh stop <tag>
# bash spawn.sh status
#
# Examples:
# bash spawn.sh launch mar5 claude:0 claude:1 claude:2 claude:3
# bash spawn.sh launch mar5 opus:0 sonnet:1 codex:2 codex:3
# bash spawn.sh stop mar5
# bash spawn.sh status
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")" && pwd)"
WORKTREE_DIR="${REPO_ROOT}/worktrees"
INITIAL_PROMPT="Read program.md and follow the instructions."
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
usage() {
echo "Usage:"
echo " $0 launch <tag> <agent:gpu> [agent:gpu ...]"
echo " $0 stop <tag>"
echo " $0 status"
echo ""
echo "Examples:"
echo " $0 launch mar5 claude:0 claude:1 claude:2 claude:3"
echo " $0 launch mar5 opus:0 sonnet:1 codex:2 codex:3"
echo " $0 stop mar5"
exit 1
}
setup_worker() {
local tag="$1" gpu="$2" agent="$3"
local branch="autoresearch/${tag}-gpu${gpu}"
local worktree="${WORKTREE_DIR}/gpu${gpu}"
local claude_model="${CLAUDE_MODEL:-sonnet}"
# Create branch (must be fresh)
cd "$REPO_ROOT"
if git show-ref --verify --quiet "refs/heads/${branch}"; then
echo "ERROR: Branch '${branch}' already exists. Use a different tag or clean up first." >&2
exit 1
fi
git checkout -q master
git checkout -q -b "$branch"
git checkout -q master
# Set up worktree
if [ -d "$worktree" ]; then
git worktree remove "$worktree" --force 2>/dev/null || rm -rf "$worktree"
fi
mkdir -p "$(dirname "$worktree")"
git worktree add "$worktree" "$branch"
# Symlink .venv so uv/python work
ln -sf "${REPO_ROOT}/.venv" "${worktree}/.venv"
# Build agent command
case "$agent" in
claude|sonnet|opus|haiku)
case "$agent" in
sonnet|opus|haiku) claude_model="$agent" ;;
esac
echo "cd ${worktree} && CUDA_VISIBLE_DEVICES=${gpu} claude --dangerously-skip-permissions --model ${claude_model} \"${INITIAL_PROMPT}\""
;;
codex)
echo "cd ${worktree} && CUDA_VISIBLE_DEVICES=${gpu} codex --dangerously-bypass-approvals-and-sandbox --model gpt-5.3-codex-spark \"${INITIAL_PROMPT}\""
;;
*)
echo "ERROR: Unknown agent '${agent}'. Supported: claude, sonnet, opus, haiku, codex" >&2
git worktree remove "$worktree" --force 2>/dev/null || true
git branch -D "$branch" 2>/dev/null || true
exit 1
;;
esac
}
# ---------------------------------------------------------------------------
# Commands
# ---------------------------------------------------------------------------
cmd_launch() {
if [ $# -lt 2 ]; then
usage
fi
local tag="$1"
shift
local specs=("$@")
local tmux_session="autoresearch-${tag}"
local num_workers=${#specs[@]}
# Kill existing session
tmux kill-session -t "$tmux_session" 2>/dev/null || true
echo ""
echo "============================================"
echo " RESEARCH GROUP: ${tag}"
echo "============================================"
echo " Workers: ${num_workers}"
local pane_cmds=()
local labels=()
local agents=()
for spec in "${specs[@]}"; do
local agent="${spec%%:*}"
local gpu="${spec#*:}"
echo " - GPU ${gpu}: ${agent}"
local cmd
cmd=$(setup_worker "$tag" "$gpu" "$agent")
pane_cmds+=("$cmd")
labels+=("$spec")
case "$agent" in
sonnet|opus|haiku|claude) agents+=("claude") ;;
*) agents+=("$agent") ;;
esac
done
echo " tmux: ${tmux_session}"
echo "============================================"
echo ""
# Create tmux session with tiled grid
tmux new-session -d -s "$tmux_session" -n workers \
"${pane_cmds[0]}; echo ''; echo 'Session ended. Press any key to exit.'; read"
for ((i=1; i<num_workers; i++)); do
tmux split-window -t "$tmux_session:workers" \
"${pane_cmds[$i]}; echo ''; echo 'Session ended. Press any key to exit.'; read"
tmux select-layout -t "$tmux_session:workers" tiled
done
tmux select-layout -t "$tmux_session:workers" tiled
echo " Attach: tmux attach -t ${tmux_session}"
echo " Detach: Ctrl-b d"
echo " Zoom: Ctrl-b z (toggle pane fullscreen)"
echo " Navigate: Ctrl-b arrow keys"
echo ""
# Background watcher — nudge idle agents
local nudge_interval=120
echo "Watcher running (nudge interval: ${nudge_interval}s). Ctrl-C to stop watcher only."
echo ""
declare -A prev_hash
while tmux has-session -t "$tmux_session" 2>/dev/null; do
sleep "$nudge_interval"
for ((i=0; i<num_workers; i++)); do
tmux has-session -t "$tmux_session" 2>/dev/null || break
local pane="${tmux_session}:workers.${i}"
local content curr_hash
content=$(tmux capture-pane -t "$pane" -p 2>/dev/null) || continue
curr_hash=$(echo "$content" | md5sum | cut -d' ' -f1)
if [ "${prev_hash[$i]:-}" != "$curr_hash" ]; then
prev_hash[$i]="$curr_hash"
continue
fi
local is_idle=false
if echo "$content" | grep -qP '^\s*$'; then
is_idle=true
elif echo "$content" | grep -qP '^\s*$'; then
is_idle=true
fi
if [ "$is_idle" = true ]; then
local nudge_msg="Keep going. Do not stop — continue your research loop."
if [ "${agents[$i]}" = "codex" ]; then
tmux send-keys -t "$pane" "$nudge_msg" Enter
else
tmux send-keys -t "$pane" "$nudge_msg" C-m
fi
echo "[$(date +%H:%M:%S)] Nudged pane ${i} (${labels[$i]})"
prev_hash[$i]=""
fi
done
done
echo "tmux session ended. Watcher exiting."
}
cmd_stop() {
if [ $# -lt 1 ]; then
usage
fi
local tag="$1"
local tmux_session="autoresearch-${tag}"
# Kill tmux session
if tmux kill-session -t "$tmux_session" 2>/dev/null; then
echo "Killed tmux session '${tmux_session}'"
else
echo "No tmux session '${tmux_session}' found"
fi
# Remove worktrees
local removed=0
for wt in "${WORKTREE_DIR}"/gpu*; do
[ -d "$wt" ] || continue
git -C "$REPO_ROOT" worktree remove "$wt" --force 2>/dev/null && removed=$((removed + 1))
done
echo "Removed ${removed} worktree(s)"
echo "Branches kept for review (git branch -l 'autoresearch/${tag}-*')"
}
cmd_status() {
echo "Active tmux sessions:"
tmux list-sessions 2>/dev/null | grep "^autoresearch-" || echo " (none)"
echo ""
echo "Active worktrees:"
git -C "$REPO_ROOT" worktree list 2>/dev/null | grep "worktrees/" || echo " (none)"
echo ""
echo "Research branches:"
git -C "$REPO_ROOT" branch -l 'autoresearch/*' 2>/dev/null || echo " (none)"
}
# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------
if [ $# -lt 1 ]; then
usage
fi
COMMAND="$1"
shift
case "$COMMAND" in
launch) cmd_launch "$@" ;;
stop) cmd_stop "$@" ;;
status) cmd_status "$@" ;;
*) usage ;;
esac