scripts: b/job parallel improvements — streaming results, input/output headers, -failfast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Levi Neely 2026-04-18 13:52:22 +02:00
parent c3d8879702
commit e3eb782be5
1 changed files with 68 additions and 22 deletions

View File

@ -11,9 +11,10 @@
# -backend backend override # -backend backend override
# -model model override # -model model override
# -json shorthand for -output json; emit JSONL output # -json shorthand for -output json; emit JSONL output
# -parallel run the same prompt N times in parallel (default: 1) # -parallel run the same prompt N times in parallel (default: 1)
# -keep do not remove job(s) after printing result # -keep do not remove job(s) after printing result
# -bg submit job and exit immediately; prints session id(s); implies -keep # -bg submit job and exit immediately; prints session id(s); implies -keep
# -failfast on first failure, cancel remaining running jobs and exit
set -euo pipefail set -euo pipefail
@ -38,26 +39,28 @@ Flags:
-parallel N run the same prompt N times in parallel (default: 1) -parallel N run the same prompt N times in parallel (default: 1)
-keep do not remove job(s) after printing result -keep do not remove job(s) after printing result
-bg submit and exit immediately; prints job id(s); implies -keep -bg submit and exit immediately; prints job id(s); implies -keep
-failfast on first failure, cancel remaining running jobs and exit
-help show this help -help show this help
EOF EOF
exit 0 exit 0
} }
name=; cwd=; agent=; backend=; model=; output=; parallel=1; keep=0; bg=0 name=; cwd=; agent=; backend=; model=; output=; parallel=1; keep=0; bg=0; failfast=0
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case $1 in case $1 in
-name) name=$2; shift ;; -name) name=$2; shift ;;
-cwd) cwd=$2; shift ;; -cwd) cwd=$2; shift ;;
-agent) agent=$2; shift ;; -agent) agent=$2; shift ;;
-backend) backend=$2; shift ;; -backend) backend=$2; shift ;;
-model) model=$2; shift ;; -model) model=$2; shift ;;
-json) output=json ;; -json) output=json ;;
-parallel) parallel=$2; shift ;; -parallel) parallel=$2; shift ;;
-keep) keep=1 ;; -keep) keep=1 ;;
-bg) bg=1; keep=1 ;; -bg) bg=1; keep=1 ;;
-help) usage ;; -failfast) failfast=1 ;;
--) shift; break ;; -help) usage ;;
--) shift; break ;;
-*) die "unknown flag: $1" ;; -*) die "unknown flag: $1" ;;
*) break ;; *) break ;;
esac esac
@ -99,16 +102,60 @@ if [ "$bg" -eq 1 ]; then
fi fi
rc=0 rc=0
for i in $(seq 0 $((parallel - 1))); do
id="${name}-${i}" if [ "$parallel" -gt 1 ]; then
abort=$(mktemp)
trap 'rm -f "$abort"' EXIT
pids=()
for i in $(seq 0 $((parallel - 1))); do
id="${name}-${i}"
B="$MOUNT/b/$id"
(
while true; do
[ -s "$abort" ] && exit 1
status=$(tr -d '[:space:]' < "$B/status" 2>/dev/null) || { sleep 0.05; continue; }
case "$status" in
done*) break ;;
failed*) printf 'subagent %s failed: %s\n' "$id" "$status" >&2
if [ "$failfast" -eq 1 ]; then
echo 1 > "$abort"
for j in $(seq 0 $((parallel - 1))); do
jid="${name}-${j}"
[ "$jid" != "$id" ] && rm -r "$MOUNT/b/$jid" 2>/dev/null || true
done
fi
[ "$keep" -eq 0 ] && rm -r "$B" 2>/dev/null || true
exit 1 ;;
*) sleep 0.05 ;;
esac
done
if [ -s "$abort" ]; then
[ "$keep" -eq 0 ] && rm -r "$B" 2>/dev/null || true
exit 1
fi
if [ -n "$output" ]; then
printf '{"session":"%s","result":%s}\n' "$id" \
"$(cat "$B/result" 2>/dev/null | jq -Rs .)"
else
printf '=== %s ===\nInput: "%s"\nOutput: ' "$id" "$prompt"
cat "$B/result" 2>/dev/null
printf '\n'
fi
[ "$keep" -eq 0 ] && rm -r "$B" 2>/dev/null || true
) &
pids+=($!)
done
for pid in "${pids[@]}"; do wait "$pid" || rc=1; done
else
id="${name}-0"
B="$MOUNT/b/$id" B="$MOUNT/b/$id"
while true; do while true; do
status=$(tr -d '[:space:]' < "$B/status" 2>/dev/null) || { sleep 0.05; continue; } status=$(tr -d '[:space:]' < "$B/status" 2>/dev/null) || { sleep 0.05; continue; }
case "$status" in case "$status" in
done*) break ;; done*) break ;;
failed*) rc=1; break ;; failed*) rc=1; break ;;
*) sleep 0.05 ;; *) sleep 0.05 ;;
esac esac
done done
@ -116,12 +163,11 @@ for i in $(seq 0 $((parallel - 1))); do
printf '{"session":"%s","result":%s}\n' "$id" \ printf '{"session":"%s","result":%s}\n' "$id" \
"$(cat "$B/result" 2>/dev/null | jq -Rs .)" "$(cat "$B/result" 2>/dev/null | jq -Rs .)"
else else
[ "$parallel" -gt 1 ] && printf '=== %s ===\n' "$id"
cat "$B/result" 2>/dev/null cat "$B/result" 2>/dev/null
printf '\n' printf '\n'
fi fi
[ "$keep" -eq 0 ] && rm -r "$B" 2>/dev/null || true [ "$keep" -eq 0 ] && rm -r "$B" 2>/dev/null || true
done fi
exit $rc exit $rc