| #!/bin/bash |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| set -e |
|
|
| |
|
|
| 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() { |
| 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 |
| } |
|
|
| |
|
|
| AGENT="" |
| MODEL="" |
| PROVIDER="" |
| EXTRA_ARGS=() |
|
|
| case "${1:-}" in |
| -h|--help) usage ;; |
| --) shift; EXTRA_ARGS=("$@") ;; |
| "") ;; |
| -*) ;; |
| *) 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 |
|
|
| |
|
|
| 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 |
|
|
| |
|
|
| 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 |
|
|
| |
|
|
| if [[ "$PROVIDER" == "auto" || -z "$PROVIDER" ]]; then |
| MODEL_STRING="$MODEL" |
| else |
| MODEL_STRING="${MODEL}:${PROVIDER}" |
| fi |
|
|
| echo "→ $AGENT @ $MODEL_STRING" >&2 |
|
|
| |
|
|
| 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 |
|
|