diff --git a/modules/turnero/api/ai_chat.php b/modules/turnero/api/ai_chat.php index 532fa35..a0028cf 100644 --- a/modules/turnero/api/ai_chat.php +++ b/modules/turnero/api/ai_chat.php @@ -14,12 +14,19 @@ $pregunta = trim($body['pregunta'] ?? ''); if ($pregunta === '') jsonError('Pregunta vacía', 400); if (mb_strlen($pregunta) > 800) jsonError('Pregunta demasiado larga', 400); +define('LIA_TOKENS_MAX', 1_000_000); + $pdo = db(); // ── Clave Gemini ────────────────────────────────────────────── -$row = $pdo->query("SELECT valor FROM lab_config WHERE clave = 'gemini_api_key' LIMIT 1")->fetch(); -$apiKey = trim($row['valor'] ?? ''); +$cfg = $pdo->query("SELECT clave, valor FROM lab_config WHERE clave IN ('gemini_api_key','lia_tokens_usados')")->fetchAll(PDO::FETCH_KEY_PAIR); +$apiKey = trim($cfg['gemini_api_key'] ?? ''); +$tokensUsados = (int)($cfg['lia_tokens_usados'] ?? 0); + if (!$apiKey) jsonError('Token de IA no configurado. Ve a Configuración del laboratorio.', 503); +if ($tokensUsados >= LIA_TOKENS_MAX) { + jsonError('⚠️ Se agotaron los tokens de LIA. Solicita tokens a soporte para continuar.', 402); +} // ── Contexto del día ────────────────────────────────────────── $hoy = date('Y-m-d'); @@ -207,5 +214,17 @@ if ($code !== 200 || empty($gemini['candidates'][0]['content']['parts'][0]['text jsonError("Error IA: {$detail}", 502); } -$respuesta = $gemini['candidates'][0]['content']['parts'][0]['text']; -jsonOk(['respuesta' => $respuesta]); +$respuesta = $gemini['candidates'][0]['content']['parts'][0]['text']; +$usage = $gemini['usageMetadata'] ?? []; +$tokensEsta = (int)($usage['totalTokenCount'] ?? (int)((mb_strlen($pregunta) + mb_strlen($respuesta)) / 4)); +$tokensUsados += $tokensEsta; + +$pdo->prepare("INSERT INTO lab_config (clave, valor) VALUES ('lia_tokens_usados', ?) + ON DUPLICATE KEY UPDATE valor = ?")->execute([$tokensUsados, $tokensUsados]); + +jsonOk([ + 'respuesta' => $respuesta, + 'tokens_usados' => $tokensUsados, + 'tokens_restantes' => max(0, LIA_TOKENS_MAX - $tokensUsados), + 'tokens_max' => LIA_TOKENS_MAX, +]); diff --git a/modules/turnero/views/dashboard.php b/modules/turnero/views/dashboard.php index 12bfcf4..0c70025 100644 --- a/modules/turnero/views/dashboard.php +++ b/modules/turnero/views/dashboard.php @@ -140,6 +140,11 @@ Layout::open('Dashboard Turnero', 'fas fa-chart-bar'); .lia-wave span:nth-child(4){height:16px;animation-delay:.3s} .lia-wave span:nth-child(5){height:8px;animation-delay:.4s} @keyframes wave { 0%,100%{transform:scaleY(.5);opacity:.6} 50%{transform:scaleY(1);opacity:1} } + .lia-tokens { padding:6px 14px; background:#f8faff; border-top:1px solid #f1f5f9; flex-shrink:0; } + .lia-tokens-bar { height:5px; border-radius:3px; background:#e2e8f0; overflow:hidden; margin-bottom:3px; } + .lia-tokens-fill { height:100%; border-radius:3px; background:linear-gradient(90deg,#1565c0,#0288d1); transition:width .6s ease; } + .lia-tokens-fill.warn { background:linear-gradient(90deg,#f59e0b,#ef4444); } + .lia-tokens-label { font-size:.68rem; color:#94a3b8; display:flex; justify-content:space-between; } .ai-footer { padding:10px 14px; border-top:1px solid #f1f5f9; display:flex; gap:8px; flex-shrink:0; background:#fafbff; } .ai-footer input { flex:1; border:1.5px solid #e2e8f0; border-radius:10px; padding:9px 14px; font-size:.9rem; outline:none; background:#fff; } .ai-footer input:focus { border-color:#1565c0; } @@ -352,6 +357,13 @@ try {
+