qgallouedec's picture
download
raw
3.07 kB
#!/usr/bin/env bash
# TRL ecosystem intelligence bot — entrypoint of the Hugging Face scheduled Job.
# Scans the projects/sources listed in /eco/sources.json and posts the few developments that
# actually matter to TRL maintainers to Slack.
#
# The bucket hf://buckets/qgallouedec/ecosystem-watch is mounted read-write at /eco and holds
# everything that must outlive a run: this script, prompt.txt, sources.json, state/ and logs/.
# Edit those in the bucket (`hf sync <dir> hf://buckets/qgallouedec/ecosystem-watch`) — the
# scheduled Job itself never needs to change.
#
# Secrets come from the scheduled Job: SLACK_BOT_TOKEN, GH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, HF_TOKEN.
set -euo pipefail
STAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
mkdir -p /eco/state /eco/logs
exec > >(tee /tmp/run.log) 2>&1
trap 'python3 /eco/scrub.py < /tmp/run.log > "/eco/logs/$STAMP.log"' EXIT
echo "===== $STAMP ecosystem-watch start ====="
# claude, gh, jq and hf are absent from the base image. The claude installer hangs when run
# from / as root, hence the cd.
mkdir -p /work && cd /work
curl -fsSL https://claude.ai/install.sh | bash
export PATH="$HOME/.local/bin:$PATH"
curl -fsSL https://github.com/cli/cli/releases/download/v2.97.0/gh_2.97.0_linux_amd64.tar.gz \
| tar -xz -C /usr/local/bin --strip-components=2 gh_2.97.0_linux_amd64/bin/gh
curl -fsSLo /usr/local/bin/jq https://github.com/jqlang/jq/releases/download/jq-1.8.2/jq-linux-amd64
chmod +x /usr/local/bin/jq
pip install --quiet --root-user-action=ignore huggingface_hub
# The bot reads TRL and must never write to it; a fresh clone per run is that guarantee.
git clone --quiet --filter=blob:none https://github.com/huggingface/trl /trl
# Preflight: the bot posts to its own channel. Bail out cheaply rather than spending a full
# scan and then failing at the post. See _slack_setup in sources.json.
CHANNEL=$(jq -r '.slack_channel' /eco/sources.json)
if [ "$CHANNEL" = "REPLACE_ME" ] || [ -z "$CHANNEL" ] || [ "$CHANNEL" = "null" ]; then
echo "FATAL: slack_channel not set in /eco/sources.json — see _slack_setup there."
exit 1
fi
# stream-json puts every tool call and result in the trace file; the run log keeps the readable
# summary, rendered from the final `result` event once the pass is over. The trace goes through
# scrub.py on the way to the bucket so no unredacted line ever reaches durable storage.
claude \
--print \
--verbose \
--output-format stream-json \
--effort xhigh \
--allowedTools "Bash Read Grep Glob WebFetch WebSearch Edit Write" \
< /eco/prompt.txt \
| python3 /eco/scrub.py > "/eco/logs/$STAMP.jsonl"
python3 - "/eco/logs/$STAMP.jsonl" <<'PY'
import json, sys
for line in open(sys.argv[1]):
event = json.loads(line)
if event.get("type") == "result":
print(event.get("result", ""))
print(
f"\n[{event.get('num_turns')} turns · {event.get('duration_ms', 0) / 1000:.0f}s"
f" · ${event.get('total_cost_usd', 0):.2f}]"
)
PY
echo "===== $(date -u '+%Y-%m-%dT%H:%M:%SZ') ecosystem-watch done ====="

Xet Storage Details

Size:
3.07 kB
·
Xet hash:
bd67c406932d0ed962decad1e3bd35e4aef171f59f1980db5f13a69971c37324

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.