Jeton Hugging Face réglable dans l'interface

Le jeton ne vivait que dans la variable d'environnement HF_TOKEN : découvrir
depuis l'interface qu'un dépôt est verrouillé, c'était devoir éditer un
docker-compose et recréer le conteneur pour y répondre.

- Éditeur de preset → Modèle → « Jeton Hugging Face » : ligne repliée comme
  « Dossiers de modèles », qui affiche l'état (aucun / masqué / fourni par
  l'environnement). Le bandeau d'un dépôt verrouillé y mène d'un clic.
- Le jeton est VÉRIFIÉ auprès de /api/whoami-v2 avant d'être enregistré (le
  compte s'affiche) : un jeton mal collé accepté en silence rendrait le 401
  qu'on cherchait à expliquer. Il est rangé avec les secrets en base d'état, pas
  dans config.env que le changement de preset réécrit en bloc, et n'est jamais
  renvoyé en clair — seulement masqué.
- Priorité : jeton enregistré, puis HF_TOKEN. Rien d'enregistré = comportement
  d'avant à l'identique. L'enregistrement vide le cache des réponses obtenues
  sans jeton.
- Le jeton n'est envoyé qu'aux adresses Hugging Face : un lien collé vers un
  autre hébergeur n'a aucune raison de recevoir un secret.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hz1QWmvZqW3t53YC5SJBKC
This commit is contained in:
Claude committed 2026-08-20 10:32:44 +00:00
1 parent b339cced0a
commit 7f5765160d
10 files changed
+498 -16

No files matched your search

+9 -5
View File
@@ -489,8 +489,12 @@ func dlRequest(ctx context.Context, dlURL, rng string) (*http.Request, error) {
if err != nil {
return nil, err
}
// HF gated/private repos may need a token; reuse the same key store if set.
if k := os.Getenv("HF_TOKEN"); k != "" {
// Dépôt gated/privé : le jeton (réglage de l'interface, sinon HF_TOKEN) est
// ce qui débloque le transfert. Il n'accompagne QUE les liens Hugging Face :
// un lien collé vers un autre hébergeur n'a aucune raison de recevoir un
// secret, et le CDN vers lequel HF redirige est signé, donc n'en a pas besoin
// non plus (Go retire l'en-tête au changement de domaine).
if k := hfToken(); k != "" && isHFHost(req.URL.Host) {
req.Header.Set("Authorization", "Bearer "+k)
}
req.Header.Set("User-Agent", "loki/"+Version)
@@ -577,10 +581,10 @@ func dlAccessReason(code, repo string) string {
// se cachent derrière le même 401 : pas de jeton du tout, ou un jeton qui n'a
// pas accès à CE dépôt — et le geste à faire n'est pas le même.
func dlTokenHint() string {
if strings.TrimSpace(os.Getenv("HF_TOKEN")) == "" {
return " — puis renseigne la variable d'environnement HF_TOKEN (jeton Hugging Face)"
if !hfTokenSet() {
return " — puis renseigne le jeton Hugging Face (réglage « Jeton Hugging Face », ou variable d'environnement HF_TOKEN)"
}
return " — le jeton HF_TOKEN utilisé n'y donne pas accès (expiré, ou conditions non acceptées avec ce compte)"
return " — le jeton Hugging Face enregistré n'y donne pas accès (expiré, ou conditions non acceptées avec ce compte)"
}
// dlProbe asks the server for the first byte to learn the total size and