Skill: chapati23/llm-speedtest (version 1.0.0)

--- name: llm-speedtest version: 1.0.0 description: "Ping major LLM providers in parallel and compare real API latency. Run with /ping" metadata: category: utility capabilities: - api dependencies: [] interface: shell openclaw: emoji: "⚡" requires: env: - ANTHROPIC_API_KEY (optional) - OPENAI_API_KEY (optional) - GEMINI_API_KEY (optional) - MINIMAX_API_KEY (optional) - XAI_API_KEY (optional) author: name: chapati23 --- # LLM Speedtest Ping major LLM providers in parallel and compare real API latency (TTFT). ## When to Use - User types `/ping` or asks about model latency/speed - Comparing provider response times - Checking if a specific provider is slow or down ## How It Works Runs `scripts/ping.sh` which: 1. Retrieves API keys from `pass shared/` (users may need to adapt key sourcing for their setup) 2. Fires parallel `curl` requests to each provider with a minimal prompt ("hi", `max_tokens=1`) 3. Measures total round-trip time per provider 4. Sorts results by latency and displays with color badges ## Output Format Results are sorted fastest-to-slowest with color badges: - 🟢 **< 2s** — Fast - 🟡 **2–5s** — Normal - 🔴 **5–30s** — Slow - ⚫ **30s** — Timeout Example: ``` ⚡ Model Latency — 14:32 🟢 `Gemini 412ms` 🟢 `GPT-4o 623ms` 🟢 `Sonnet 891ms` 🟡 `Grok 2104ms` 🟡 `MiniMax 3210ms` 🟡 `Opus 4102ms` _real API latency (TTFT)_ ``` ## Models Tested | Provider | Model | |----------|-------| | Anthropic | Claude Sonnet 4 | | Anthropic | Claude Opus 4 | | OpenAI | GPT-4o-mini | | Google | Gemini 2.5 Flash | | MiniMax | MiniMax-M1 | | xAI | Grok 3 Mini Fast | ## Cost ~$0.0001 per run (1 token per model, cheapest tiers). ## Note This skill uses `pass shared/` for API key retrieval. If you don't use `pass`, you'll need to adapt `scripts/ping.sh` to source keys from environment variables or another secret manager.

path: scripts/ping.sh
content: #!/bin/bash
# Model latency checker - real API TTFT (parallel)

ANTHROPIC_KEY=$(pass shared/anthropic/api-key 2>/dev/null)
GEMINI_KEY=$(pass shared/gemini/api-key 2>/dev/null)
MINIMAX_KEY=$(pass shared/minimax/api-key 2>/dev/null)
XAI_KEY=$(pass shared/xai/api-key 2>/dev/null)
OPENAI_KEY=$(pass shared/openai/api-key 2>/dev/null)

TMPDIR=$(mktemp -d)

if [[ -n "$ANTHROPIC_KEY" ]]; then
  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://api.anthropic.com/v1/messages" \
    -H "x-[REDACTED_SECRET]" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
    -d '{"model":"claude-sonnet-4-20250514","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|Sonnet" > "$TMPDIR/sonnet") &

  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://api.anthropic.com/v1/messages" \
    -H "x-[REDACTED_SECRET]" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
    -d '{"model":"claude-opus-4-20250514","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|Opus" > "$TMPDIR/opus") &
fi

if [[ -n "$GEMINI_KEY" ]]; then
  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$GEMINI_KEY" \
    -H "Content-Type: application/json" \
    -d '{"contents":[{"parts":[{"text":"hi"}]}],"generationConfig":{"maxOutputTokens":1}}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|Gemini" > "$TMPDIR/gemini") &
fi

if [[ -n "$MINIMAX_KEY" ]]; then
  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://api.minimax.chat/v1/text/chatcompletion_v2" \
    -H "Authorization: Bearer $MINIMAX_KEY" -H "Content-Type: application/json" \
    -d '{"model":"MiniMax-M1","messages":[{"role":"user","content":"hi"}],"max_tokens":1}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|MiniMax" > "$TMPDIR/minimax") &
fi

if [[ -n "$XAI_KEY" ]]; then
  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://api.x.ai/v1/chat/completions" \
    -H "Authorization: Bearer $XAI_KEY" -H "Content-Type: application/json" \
    -d '{"model":"grok-3-mini-fast","messages":[{"role":"user","content":"hi"}],"max_tokens":1}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|Grok" > "$TMPDIR/grok") &
fi

if [[ -n "$OPENAI_KEY" ]]; then
  (ms=$(curl -s -o /dev/null -w "%{time_total}" --max-time 30 \
    -X POST "https://api.openai.com/v1/chat/completions" \
    -H "Authorization: Bearer $OPENAI_KEY" -H "Content-Type: application/json" \
    -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}],"max_tokens":1}')
  echo "$(echo "$ms * 1000" | bc -l | cut -d. -f1)|GPT-4o" > "$TMPDIR/gpt4o") &
fi

wait

results=()
for f in "$TMPDIR"/*; do
  [[ -f "$f" ]] && results+=("$(cat "$f")")
done
rm -rf "$TMPDIR"

output="⚡ Model Latency — $(date +%H:%M)\n\n"

while IFS='|' read -r ms name; do
  if [[ $ms -lt 2000 ]]; then badge="🟢"; elif [[ $ms -lt 5000 ]]; then badge="🟡"; elif [[ $ms -lt 30000 ]]; then badge="🔴"; else badge="⚫"; fi
  padded=$(printf "%-10s %6sms" "$name" "$ms")
  output+="${badge} \`${padded}\`\n"
done < <(printf '%s\n' "${results[@]}" | sort -t'|' -n)

output+="\n_real API latency (TTFT)_"
printf "$output"


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)