File size: 5,138 Bytes
156aa6c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/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