hf-tools / agent
celinah's picture
celinah HF Staff
Rename hf-launch to agent
38631c9 verified
#!/bin/bash
# hf-launch — Launch coding agents with HF Inference Providers
#
# Dependencies: curl, jq, fzf, HF_TOKEN
#
# Usage:
# hf tool run launch # interactive picker
# hf tool run launch claude # interactive model picker
# hf tool run launch claude --model Qwen/Qwen3-235B-A22B # explicit model
set -e
# ── Token ────────────────────────────────────────────────────────────────────
HF_TOKEN="${HF_TOKEN:-}"
if [[ -z "$HF_TOKEN" ]]; then
HF_TOKEN=$(python3 -c "from huggingface_hub.utils import get_token; print(get_token() or '', end='')" 2>/dev/null)
fi
if [[ -z "$HF_TOKEN" ]]; then
echo "Error: Not logged in. Run 'hf auth login' or export HF_TOKEN." >&2
exit 1
fi
# ── Usage ────────────────────────────────────────────────────────────────────
usage() {
cat >&2 << 'EOF'
Usage: hf tool run launch [agent] [options] [-- extra-args...]
Agents: claude, opencode
Options:
--model <id> Model ID (e.g. Qwen/Qwen3-235B-A22B)
--provider <name> Inference provider (e.g. fireworks-ai). Default: auto
-h, --help Show this help
Examples:
hf tool run launch
hf tool run launch claude
hf tool run launch claude --model Qwen/Qwen3-235B-A22B
hf tool run launch claude --model Qwen/Qwen3-235B-A22B --provider fireworks-ai
hf tool run launch opencode
EOF
exit 1
}
# ── Parse args ───────────────────────────────────────────────────────────────
AGENT=""
MODEL=""
PROVIDER=""
EXTRA_ARGS=()
case "${1:-}" in
-h|--help) usage ;;
--) shift; EXTRA_ARGS=("$@") ;;
"") ;;
-*) ;; # flags handled below
*) AGENT="$1"; shift ;;
esac
while [[ $# -gt 0 ]]; do
case "$1" in
--model) MODEL="$2"; shift 2 ;;
--provider) PROVIDER="$2"; shift 2 ;;
-h|--help) usage ;;
--) shift; EXTRA_ARGS=("$@"); break ;;
*) EXTRA_ARGS+=("$1"); shift ;;
esac
done
# ── Fetch models & pick ─────────────────────────────────────────────────────
if [[ -z "$MODEL" ]]; then
MODEL_DATA=$(curl -s "https://router.huggingface.co/v1/models" \
-H "Authorization: Bearer $HF_TOKEN" 2>/dev/null)
MODEL=$(echo "$MODEL_DATA" | jq -r '.data[].id' | fzf --prompt="HF Model: " \
--height=50% \
--reverse \
--header="HuggingFace Router - Select Model" \
--preview='echo {}' \
--preview-window=up:1)
if [[ -z "$MODEL" ]]; then
echo "No model selected" >&2
exit 1
fi
PROVIDER=$( (echo "auto"; echo "$MODEL_DATA" | jq -r --arg model "$MODEL" \
'.data[] | select(.id == $model) | .providers[].provider') \
| fzf --prompt="Provider: " \
--height=20% \
--reverse \
--header="Select Provider for $MODEL (auto = no suffix)")
if [[ -z "$PROVIDER" ]]; then
echo "No provider selected" >&2
exit 1
fi
fi
# ── Select agent (if not provided) ───────────────────────────────────────────
if [[ -z "$AGENT" ]]; then
AGENT=$(printf "claude\nopencode" | fzf --prompt="CLI: " \
--height=10% \
--reverse \
--header="Select CLI")
if [[ -z "$AGENT" ]]; then
echo "No CLI selected" >&2
exit 1
fi
fi
case "$AGENT" in
claude|opencode) ;;
*) echo "Error: Unknown agent '$AGENT'. Choose: claude, opencode" >&2; exit 1 ;;
esac
# ── Build model string ───────────────────────────────────────────────────────
if [[ "$PROVIDER" == "auto" || -z "$PROVIDER" ]]; then
MODEL_STRING="$MODEL"
else
MODEL_STRING="${MODEL}:${PROVIDER}"
fi
echo "→ $AGENT @ $MODEL_STRING" >&2
# ── Launch ───────────────────────────────────────────────────────────────────
case "$AGENT" in
claude)
export ANTHROPIC_API_KEY="$HF_TOKEN"
export ANTHROPIC_AUTH_TOKEN="$HF_TOKEN"
export ANTHROPIC_BASE_URL="https://router.huggingface.co"
export ANTHROPIC_DEFAULT_SONNET_MODEL="$MODEL_STRING"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$MODEL_STRING"
export ANTHROPIC_DEFAULT_OPUS_MODEL="$MODEL_STRING"
exec claude --model "$MODEL_STRING" "${EXTRA_ARGS[@]}"
;;
opencode)
exec opencode -m "huggingface/$MODEL_STRING" "${EXTRA_ARGS[@]}"
;;
esac