diff options
Diffstat (limited to 'skills/pi-subagent/status.sh')
| -rwxr-xr-x | skills/pi-subagent/status.sh | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/skills/pi-subagent/status.sh b/skills/pi-subagent/status.sh new file mode 100755 index 0000000..15a75de --- /dev/null +++ b/skills/pi-subagent/status.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Report on the subagents of one workdir: what is still running, and the +# cost table of everything that finished, failed attempts included. +# +# status.sh <workdir> report once +# status.sh --wait [secs] <workdir> report every <secs> (default 60) until +# nothing is running, then the table +# +# Exit status: 0 when nothing is running, 3 while something still is. +# +# "Running" means <workdir>/out/<name>.running exists and its PID is alive. A +# marker whose process is gone (run-agent.sh was killed) is reported as stale +# and removed. + +set -u + +wait=""; interval=60 +if [[ "${1:-}" == "--wait" ]] +then + wait=y; shift + if [[ "${1:-}" =~ ^[0-9]+$ ]]; then interval="$1"; shift; fi +fi +P="${1:?workdir}" +out="$P/out" + +running() { + local marker pid alive=() + for marker in "$out"/*.running + do + [[ -e "$marker" ]] || continue + pid="$(cat "$marker" 2>/dev/null)" + if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null + then + alive+=("$(basename "$marker" .running)") + else + echo "stale: $(basename "$marker" .running) (process gone)" >&2 + rm -f "$marker" + fi + done + echo "${alive[*]:-}" +} + +free_gb() { + df -k "$P" | awk 'NR==2 {printf "%.1f", $4/1048576}' +} + +if [[ -n "$wait" ]] +then + while : + do + names="$(running)" + [[ -z "$names" ]] && break + echo "$(date +%H:%M:%S) running=$(wc -w <<< "$names" | tr -d ' ') freeGB=$(free_gb): $names" + sleep "$interval" + done +fi + +names="$(running)" +if [[ -n "$names" ]] +then + echo "running: $names" +fi + +shopt -s nullglob +costs=("$out"/*.cost.json) +if [[ ${#costs[@]} -gt 0 ]] +then + { + echo -e "name\tprovider\tmodel\texit\tstop\tsecs\tturns\tin\tout\tanswer_bytes\tcost" + for f in "${costs[@]}" + do + n="$(basename "$f" .cost.json)" + bytes=0 + [[ -e "$out/$n.md" ]] && bytes="$(wc -c < "$out/$n.md" | tr -d '[:space:]')" + jq -r --arg b "$bytes" '[.name,.provider,.model,(.exit|tostring),(.stopReason // "-"),(.seconds|tostring), + (.turns|tostring),(.input|tostring),(.output|tostring),$b, + (.cost*10000|round/10000|tostring)] | @tsv' "$f" 2>/dev/null \ + || echo -e "$n\t?\t?\t?\t?\t?\t?\t?\t?\t$bytes\t(unreadable cost file)" + done | sort -t$'\t' -k11 -rn + } | column -t -s$'\t' + jq -s -r '"runs: \(length) failed: \(map(select(.exit != 0)) | length) total cost: $\(map(.cost) | add | .*10000 | round/10000)"' \ + "${costs[@]}" 2>/dev/null +fi + +[[ -z "$names" ]] || exit 3 |
