bf4f55aed1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
60 lines
2.9 KiB
Bash
Executable File
60 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Run one pi agent per task file in a wave directory, each in its own git worktree.
|
|
# usage: scripts/pi-wave.sh scripts/waves/wave1 [parallel=4]
|
|
set -euo pipefail
|
|
root=$(git rev-parse --show-toplevel)
|
|
dir=$(cd "$1" && pwd)
|
|
par=${2:-4}
|
|
mkdir -p "$root/.worktrees"
|
|
|
|
run() {
|
|
task=$(basename "$1" .md)
|
|
wt="$root/.worktrees/$task"
|
|
[ -d "$wt" ] || git -C "$root" worktree add -q "$wt" -b "feat/$task"
|
|
if [ "${AGENT_CLI:-pi}" = codex ]; then
|
|
# Codex CLI: model and effort from CODEX_MODEL / CODEX_EFFORT (defaults: gpt-6.1-sol, high).
|
|
# The sandbox may write the worktree, this task's target dir and the cargo/rustup homes.
|
|
mkdir -p "$root/target/agent-$task"
|
|
(
|
|
cd "$wt"
|
|
PATH="$HOME/.cargo/bin:$PATH" CARGO_NET_GIT_FETCH_WITH_CLI=true CARGO_TARGET_DIR="$root/target/agent-$task" \
|
|
timeout 3000 codex exec --skip-git-repo-check --ignore-user-config --ignore-rules --ephemeral --json \
|
|
-m "${CODEX_MODEL:-gpt-6.1-sol}" -c "model_reasoning_effort=\"${CODEX_EFFORT:-high}\"" \
|
|
--sandbox workspace-write -c sandbox_workspace_write.network_access=true \
|
|
--add-dir "$root/target/agent-$task" --add-dir "$HOME/.cargo" --add-dir "$HOME/.rustup" \
|
|
-o "$root/.worktrees/$task.log" -C "$wt" "$(cat "$root/scripts/waves/_common.md" "$1")" >"$root/.worktrees/$task.jsonl" 2>&1
|
|
)
|
|
rc=$?
|
|
else
|
|
(
|
|
cd "$wt"
|
|
# message_update events repeat the whole partial message (quadratic log size): drop them
|
|
PATH="$HOME/.cargo/bin:$PATH" CARGO_NET_GIT_FETCH_WITH_CLI=true CARGO_TARGET_DIR="${PI_SHARED_TARGET:-$root/target/agent-$task}" \
|
|
timeout 3000 pi -p --mode json --no-session --no-extensions --no-skills --no-themes -np --thinking low ${PI_EXTRA:-} \
|
|
"$(cat "$root/scripts/waves/_common.md" "$1")" 2>&1 | grep --line-buffered -v '"type":"message_update"' >"$root/.worktrees/$task.jsonl"
|
|
)
|
|
rc=$?
|
|
# final assistant text -> <task>.log
|
|
python3 - "$root/.worktrees/$task.jsonl" >"$root/.worktrees/$task.log" <<'PY'
|
|
import json,sys
|
|
last=""
|
|
for l in open(sys.argv[1],errors="replace"):
|
|
try: e=json.loads(l)
|
|
except ValueError: continue
|
|
if e.get("type")=="message_end" and e["message"].get("role")=="assistant":
|
|
t="".join(c.get("text","") for c in e["message"]["content"] if c.get("type")=="text")
|
|
if t.strip(): last=t
|
|
print(last)
|
|
PY
|
|
fi
|
|
# an empty final message means the agent never answered
|
|
[ -s "$root/.worktrees/$task.log" ] && [ "$(wc -c <"$root/.worktrees/$task.log")" -gt 2 ] || rc="$rc-EMPTY-LOG"
|
|
echo "$task exit $rc" >>"$root/.worktrees/summary.log"
|
|
}
|
|
export -f run
|
|
export root
|
|
export AGENT_CLI CODEX_MODEL CODEX_EFFORT PI_EXTRA PI_SHARED_TARGET
|
|
|
|
# an optional order.txt (one task file name per line) sets the queue order; else alphabetical
|
|
if [ -f "$dir/order.txt" ]; then sed "s|^|$dir/|" "$dir/order.txt"; else ls "$dir"/*.md; fi | xargs -P "$par" -I{} bash -c 'run {}'
|