#!/usr/bin/env bash # description: Spawn N subagents with a shared prompt, wait for all to complete, return concatenated results (fork-join). # Args: [-n N] [-agent A] [-backend B] [-model M] [-cwd DIR] [-keep] # Output: concatenated results from all subagents, in submission order. With -n > 1, results are separated by === {id} === headers. set -euo pipefail OLLIE="${OLLIE:-$HOME/mnt/ollie}" die() { printf 'subagent_spawn: %s\n' "$*" >&2; exit 1; } n=1; agent=; backend=; model=; cwd=; keep=0 while [ $# -gt 0 ]; do case $1 in -n) n=$2; shift ;; -agent) agent=$2; shift ;; -backend) backend=$2; shift ;; -model) model=$2; shift ;; -cwd) cwd=$2; shift ;; -keep) keep=1 ;; --) shift; break ;; -*) die "unknown flag: $1" ;; *) break ;; esac shift done [ $# -eq 0 ] && die "prompt required" prompt="$*" cwd="${cwd:-$(pwd)}" base="spawn-$(date +%s%N)-$$" # Submit all jobs as one parallel spec. { printf 'name=%s\n' "$base" printf 'cwd=%s\n' "$cwd" [ -n "$agent" ] && printf 'agent=%s\n' "$agent" [ -n "$backend" ] && printf 'backend=%s\n' "$backend" [ -n "$model" ] && printf 'model=%s\n' "$model" printf 'parallel=%s\n' "$n" printf -- '---\n' printf '%s\n' "$prompt" } > "$OLLIE/b/new" || die "failed to submit jobs" # Fork: poll each job's status in a background subshell, write result to tmpdir. tmpdir=$(mktemp -d) trap 'rm -rf "$tmpdir"' EXIT declare -a pids for i in $(seq 0 $((n - 1))); do id="${base}-${i}" ( while true; do status=$(tr -d '[:space:]' < "$OLLIE/b/$id/status" 2>/dev/null) || { sleep 0.05; continue; } case "$status" in done*) cat "$OLLIE/b/$id/result" 2>/dev/null > "$tmpdir/$i"; break ;; failed*) printf 'error: subagent %s failed: %s\n' "$id" "$status" > "$tmpdir/$i"; break ;; *) sleep 0.05 ;; esac done ) & pids[$i]=$! done # Join: wait for all pollers. for i in $(seq 0 $((n - 1))); do wait "${pids[$i]}" done # Collect results in submission order. for i in $(seq 0 $((n - 1))); do id="${base}-${i}" [ "$n" -gt 1 ] && printf '=== %s ===\n' "$id" cat "$tmpdir/$i" 2>/dev/null || true [ "$keep" -eq 0 ] && rm -r "$OLLIE/b/$id" 2>/dev/null || true done