true, CURLOPT_HTTPHEADER => $h, CURLOPT_TIMEOUT => 8, CURLOPT_SSL_VERIFYPEER => false]; if ($data) { $opts[CURLOPT_POST] = true; $opts[CURLOPT_POSTFIELDS] = $data; } curl_setopt_array($ch, $opts); $r = curl_exec($ch); return curl_getinfo($ch, CURLINFO_HTTP_CODE); } $checks = [ "GITHUB_TOKEN" => ["GET", "https://api.github.com/repos/Yacineutt/weval-consulting", null, ["User-Agent: WEVIA"]], "GROQ_KEY" => ["POST", "https://api.groq.com/openai/v1/chat/completions", '{"model":"llama-3.3-70b-versatile","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'], "CEREBRAS_API_KEY" => ["POST", "https://api.cerebras.ai/v1/chat/completions", '{"model":"llama3.1-8b","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'], "GEMINI_KEY" => ["POST", "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", '{"model":"gemini-2.5-flash","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'], "SAMBANOVA_KEY" => ["POST", "https://api.sambanova.ai/v1/chat/completions", '{"model":"DeepSeek-V3.2","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'], "MISTRAL_KEY" => ["POST", "https://api.mistral.ai/v1/chat/completions", '{"model":"open-mistral-nemo","messages":[{"role":"user","content":"hi"}],"max_tokens":5}'], ]; foreach ($checks as $name => $test) { $key = ""; if (preg_match("/{$name}=(.+)/", $env, $m)) $key = trim($m[1]); if (!$key) { $expired[] = ["name" => $name, "reason" => "NO_KEY"]; continue; } $code = testKey($test[1], $key, $test[2] ?? null, $test[3] ?? []); if ($code !== 200 && $code !== 429) { $expired[] = ["name" => $name, "code" => $code, "reason" => $code == 401 ? "EXPIRED" : ($code == 402 ? "NO_BALANCE" : "FAIL")]; } $results[$name] = $code; } // AUTO-ACTIONS for expired keys foreach ($expired as $e) { $name = $e["name"]; // 1. Queue to Blade for browser renewal $task = [ "type" => "key_renewal", "provider" => $name, "reason" => $e["reason"], "urls" => [ "GITHUB_TOKEN" => "https://github.com/settings/tokens/new?scopes=repo,workflow&description=WEVIA-Auto", "GROQ_KEY" => "https://console.groq.com/keys", "CEREBRAS_API_KEY" => "https://cloud.cerebras.ai/platform", "GEMINI_KEY" => "https://aistudio.google.com/apikey", "SAMBANOVA_KEY" => "https://cloud.sambanova.ai/apis", "MISTRAL_KEY" => "https://console.mistral.ai/api-keys", ], "ts" => date("c"), "priority" => $name === "GITHUB_TOKEN" ? "P0" : "P1" ]; // Save task for Blade $task_id = "key_" . strtolower($name) . "_" . date("Ymd"); @file_put_contents("/var/www/html/api/blade-tasks/{$task_id}.json", json_encode($task, JSON_PRETTY_PRINT)); // 2. Try auto-renewal via API where possible if ($name === "GEMINI_KEY") { // Gemini: can create new key via API $existing = trim(shell_exec("grep GEMINI_KEY /etc/weval/secrets.env | cut -d= -f2")); if ($existing && strlen($existing) > 10) { // Key exists but might need refresh - Gemini keys don't expire $renewed[] = $name . " (key valid, test transient)"; } } } // 3. Alert via Mattermost webhook if any expired if ($expired) { $webhook = ""; if (preg_match("/MATTERMOST_WEBHOOK=(.+)/", $env, $m)) $webhook = trim($m[1]); $alert = "āš ļø **WEVIA Key Alert**\n"; foreach ($expired as $e) { $alert .= "āŒ {$e['name']}: {$e['reason']} (HTTP {$e['code']})\n"; } $alert .= "\nšŸ”§ Tasks queued to Blade for auto-renewal."; if ($webhook) { $ch = curl_init($webhook); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["text" => $alert]), CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_TIMEOUT => 5]); curl_exec($ch); } } // Save status $status = [ "ts" => date("c"), "results" => $results, "expired" => $expired, "renewed" => $renewed, "ok" => count($results) - count($expired), "total" => count($results), "blade_tasks" => count($expired) ]; file_put_contents("/var/www/html/api/key-health.json", json_encode($status, JSON_PRETTY_PRINT)); // Output if (php_sapi_name() === 'cli') { echo "KEY HEALTH: " . $status["ok"] . "/" . $status["total"] . " OK\n"; foreach ($expired as $e) echo " āŒ {$e['name']}: {$e['reason']}\n"; foreach ($renewed as $r) echo " šŸ”„ $r\n"; echo "Blade tasks: " . count($expired) . "\n"; } else { header("Content-Type: application/json"); echo json_encode($status); }