File size: 5,587 Bytes
21665fa | 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 | #!/bin/bash
# codex with the `viggle-remake` MCP (examples/codex_config.toml: pool image mode by default). Extra args go to codex, e.g.
# scripts/codex_exec.sh interactive
# scripts/codex_exec.sh exec "swap the singer in /videos/x.mp4 ..." non-interactive, resumed after "at capacity"
# Settings (environment):
# REMAKE_HOME sessions, queue, workers (default ~/.viggle-remake); must match the workers'
# REMAKE_CODEX_DIR codex's home and workspace (default $REMAKE_HOME/codex). Put it on a local disk: codex's sqlite
# logs break on network filesystems
# REMAKE_CODEX_AUTH a codex login to copy in (default ~/.codex/auth.json; skipped if missing - then log in once
# with CODEX_HOME=$REMAKE_CODEX_DIR/codex_home codex login); pool helpers read the same login
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
REMAKE_HOME=$(realpath -m "${REMAKE_HOME:-$HOME/.viggle-remake}")
DIR=${REMAKE_CODEX_DIR:-$REMAKE_HOME/codex}
AUTH=${REMAKE_CODEX_AUTH:-$HOME/.codex/auth.json}
MCP=$(command -v viggle-remake-mcp) || { echo "codex_exec.sh: viggle-remake-mcp is not on PATH (pip install -e .)" >&2; exit 1; }
export CODEX_HOME=$DIR/codex_home
WS=$DIR/ws
mkdir -p "$CODEX_HOME" "$WS" "$REMAKE_HOME/sessions"
[ -f "$AUTH" ] && cp -u "$AUTH" "$CODEX_HOME/auth.json" # -u: pick up a refreshed login
sed -e "s#@WS@#$WS#g" -e "s#@CODEX_HOME@#$CODEX_HOME#g" -e "s#@REMAKE_HOME@#$REMAKE_HOME#g" -e "s#@MCP@#$MCP#g" "$ROOT/examples/codex_config.toml" \
> "$CODEX_HOME/config.toml"
# AGENTS.md + the short prompt-writing guide (data/short_guide.md) and the two format examples: codex re-reads AGENTS.md after every
# context compaction, a tool result does not survive one (the config sets REMAKE_GUIDE_IN_AGENTS, so write_prompts and
# cut_windows leave them out, and project_doc_max_bytes, since the whole file is ~60 KB)
G=$ROOT/viggle_remake_mcp/data/short_guide.md
{ cat "$ROOT/viggle_remake_mcp/data/AGENTS.md"
printf '\n\n# Prompt-writing guide (write_prompts and cut_windows do not repeat it)\n\n=== GUIDE ===\n'
cat "$G"
printf '\n\n=== FORMAT EXAMPLE, swap sessions (a different edit of a different clip - copy its structure, tags and level of detail, not its content) ===\n'
cat "$ROOT/viggle_remake_mcp/data/example_prompt.txt"
printf '\n\n=== FORMAT EXAMPLE, edit sessions (same) ===\n'
cat "$ROOT/viggle_remake_mcp/data/example_edit_prompt.txt"; } > "$WS/AGENTS.md"
if [ "$1" = exec ]; then # the workspace is no git repo; an open stdin makes exec wait for more prompt
shift
# "model at capacity" ends the turn: resume the same session, at most 10 times. stdout/stderr still stream through.
# Assumes the prompt is the last argument and, for `exec resume ...`, the session id is the one before it.
CONT='Your previous turn was cut off by a transient "model at capacity" error; this is not new user feedback.
Continue the same task from where it stopped: call `status` first and do not redo finished steps. If your last tool
call returned a CODEX IMAGE STEP, call that tool again with the same arguments: it imports the picture if it is in
place, otherwise it gives you a fresh brief.'
set -o pipefail
log=$(mktemp -d -p "$DIR")
: > "$CODEX_HOME/run_sids" # the MCP adds every session this run touches (REMAKE_RUN_SIDS in the config)
run() { { codex exec --skip-git-repo-check -C "$WS" "$@" </dev/null 2>&1 1>&3 3>&- | tee "$log/err" >&2; } 3>&1 | tee "$log/out"; }
run "$@"; rc=$?
args=("$@"); n=$#
if [ "$1" = resume ]; then id=${args[n-2]}; opts=("${args[@]:1:n-3}"); else id=; opts=("${args[@]:0:n-1}"); fi
sid() { [ -n "$id" ] || id=$(grep -ohE '"thread_id":"[0-9a-f-]{36}"|session id: [0-9a-f-]{36}' "$log/out" "$log/err" | grep -oE '[0-9a-f-]{36}' | head -1); }
for i in $(seq 10); do
tail -n 5 "$log/out" "$log/err" | grep -q "at capacity" || break
sid
echo "codex_exec.sh: model at capacity, resuming $id ($i/10)" >&2
sleep 30
run resume "${opts[@]}" "$id" "$CONT"; rc=$?
done
# codex sometimes ends its turn with the job half done and nothing saved (3 of ~8 runs on a 2-minute film, each after a `!!` warning or a long to-do list). A session it touched without writing a
# result.json during this run gets the turn back, at most twice; `save_result` with status failed is the way out.
for i in 1 2; do
open=$(for s in $(cat "$CODEX_HOME/run_sids"); do [ "$REMAKE_HOME/sessions/$s/result.json" -nt "$log" ] || printf '%s ' $s; done)
[ $rc = 0 ] && [ -n "$open" ] && [ ! -f "${REMAKE_STOP:-$REMAKE_HOME/STOP}" ] || break
sid
echo "codex_exec.sh: ended without a result for ${open% }, resuming $id ($i/2)" >&2
run resume "${opts[@]}" "$id" "Your turn ended, but session(s) ${open% } have no result: save_result was not called. This is not new user
feedback. The job is not done and nothing has gone wrong: there is no time or token limit and nobody is waiting - a
film of a minute or more takes an hour or more. Call status first and do not redo finished steps, then continue the
task: paint every remaining keyframe, render every window, review every strip, do the fix round, finish and
save_result. A \`!!\` line from \`windows\` is advice, not a blocker: follow it or accept the weak window, note it and go
on. Only if the job truly cannot go on (painting STOPPED, no live workers) call save_result with status failed and
say why."; rc=$?
done
rm -r "$log"
exit $rc
fi
exec codex -C "$WS" "$@"
|