import React, { useEffect, useState } from "react"; import { http } from "../lib/api"; import { ExternalLink, KeyRound, RefreshCw } from "lucide-react"; const KEY_LINKS = [ { id: "openrouter", label: "OpenRouter", url: "https://openrouter.ai/keys", hint: "Modèles free (Llama, Gemma, Qwen)" }, { id: "deepseek", label: "DeepSeek", url: "https://platform.deepseek.com/api_keys", hint: "Chat + R1 Reasoner" }, { id: "groq", label: "Groq", url: "https://console.groq.com/keys", hint: "Llama / Gemma gratuit" }, { id: "huggingface", label: "Hugging Face", url: "https://huggingface.co/settings/tokens", hint: "HF_TOKEN (Read)" }, { id: "gemini", label: "Gemini", url: "https://aistudio.google.com/apikey", hint: "Google AI Studio" }, { id: "openai", label: "OpenAI", url: "https://platform.openai.com/api-keys", hint: "GPT-4o mini" }, { id: "anthropic", label: "Anthropic", url: "https://console.anthropic.com/settings/keys", hint: "Claude" }, ]; export default function LLMKeysPanel() { const [status, setStatus] = useState(null); const [loading, setLoading] = useState(true); const refresh = async () => { setLoading(true); try { const r = await http.get("/llm/status"); setStatus(r.data); } catch (_) { setStatus(null); } finally { setLoading(false); } }; useEffect(() => { refresh(); }, []); const live = status?.live || {}; return (

Clés IA (prod)

Configure localement avec{" "} scripts\setup-llm-keys.ps1 {" "}puis{" "} scripts\sync-hf-secrets.bat

{KEY_LINKS.map((k) => { const configured = status?.[k.id]; const row = live[k.id]; const ok = configured && row?.ok === true; const bad = configured && row?.ok === false; const dot = !configured ? "emo-status-dot-offline" : ok ? "emo-status-dot-online" : bad ? "bg-red-500" : "bg-amber-500"; return (

{k.label}

{!configured ? "Clé absente sur HF" : bad ? (row.detail || "Erreur").slice(0, 60) : ok ? "Opérationnel" : "Clé présente"}

); })}
Ouvrir secrets HF Space →
); }