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
|
#!/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
|