- Update ultimate guide and cheatsheet - Update llms.txt and reference YAML - Add velocity-governor hook and cc-sessions script Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
3.3 KiB
Bash
Executable file
76 lines
3.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# velocity-governor.sh — Claude Code PreToolUse hook
|
|
# Limite le débit de tokens pour éviter les rate limits API
|
|
#
|
|
# Variables d'environnement officielles Claude Code :
|
|
# CLAUDE_PROJECT_DIR — chemin absolu du projet
|
|
# CLAUDE_VELOCITY_MAX_TPM — override du seuil (défaut : 50000 tokens/min)
|
|
#
|
|
# Headers API Anthropic pour le rate limiting :
|
|
# anthropic-ratelimit-tokens-remaining
|
|
# anthropic-ratelimit-tokens-reset
|
|
# retry-after (sur 429)
|
|
#
|
|
# Installation : ajouter dans .claude/settings.json sous hooks.PreToolUse
|
|
# {
|
|
# "hooks": {
|
|
# "PreToolUse": [{ "matcher": ".*", "hooks": [{ "type": "command", "command": "bash examples/hooks/bash/velocity-governor.sh" }] }]
|
|
# }
|
|
# }
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Configuration ──────────────────────────────────────────────────────────────
|
|
MAX_TOKENS_PER_MINUTE="${CLAUDE_VELOCITY_MAX_TPM:-50000}"
|
|
PROJECT_SLUG="${CLAUDE_PROJECT_DIR//\//-}"
|
|
STATE_FILE="/tmp/claude-velocity-${PROJECT_SLUG}.json"
|
|
|
|
# ── Lecture stdin (JSON fourni par Claude Code) ────────────────────────────────
|
|
input=$(cat)
|
|
# Contient : session_id, cwd, tool_name, tool_input (selon event PreToolUse)
|
|
|
|
# ── Récupération ou initialisation de l'état ──────────────────────────────────
|
|
now=$(date +%s)
|
|
|
|
if [[ -f "$STATE_FILE" ]]; then
|
|
window_start=$(jq -r '.window_start // 0' "$STATE_FILE" 2>/dev/null || echo "$now")
|
|
tokens_used=$(jq -r '.tokens_used // 0' "$STATE_FILE" 2>/dev/null || echo 0)
|
|
else
|
|
window_start=$now
|
|
tokens_used=0
|
|
fi
|
|
|
|
# ── Réinitialisation de la fenêtre glissante (60 secondes) ────────────────────
|
|
window_age=$(( now - window_start ))
|
|
if (( window_age >= 60 )); then
|
|
window_start=$now
|
|
tokens_used=0
|
|
fi
|
|
|
|
# ── Estimation conservative du coût de l'outil ────────────────────────────────
|
|
# 1 appel outil ≈ 500 tokens (lecture + écriture courte)
|
|
# Ajuster CLAUDE_VELOCITY_MAX_TPM selon votre tier API
|
|
estimated_tokens=500
|
|
new_total=$(( tokens_used + estimated_tokens ))
|
|
|
|
# ── Throttle si seuil dépassé ─────────────────────────────────────────────────
|
|
if (( new_total > MAX_TOKENS_PER_MINUTE )); then
|
|
remaining=$(( 60 - window_age ))
|
|
if (( remaining > 0 )); then
|
|
# Attendre la fin de la fenêtre courante
|
|
sleep "$remaining"
|
|
window_start=$(date +%s)
|
|
new_total=$estimated_tokens
|
|
fi
|
|
fi
|
|
|
|
# ── Persistance de l'état ─────────────────────────────────────────────────────
|
|
jq -n \
|
|
--argjson ws "$window_start" \
|
|
--argjson tu "$new_total" \
|
|
'{window_start: $ws, tokens_used: $tu}' > "$STATE_FILE"
|
|
|
|
# ── Laisser passer l'outil ─────────────────────────────────────────────────────
|
|
# exit 0 = continuer normalement
|
|
# exit 1 = bloquer l'outil (non utilisé ici, préférer le throttle)
|
|
exit 0
|