59 lines
2.6 KiB
PHP
59 lines
2.6 KiB
PHP
<?php
|
|
/**
|
|
* wv_llm() — Sovereign LLM cascade for WEVIA Master intents
|
|
* Cascade: Groq → Cerebras → Mistral → Ollama local (0€)
|
|
*/
|
|
function wv_llm($prompt, $system = "Tu es WEVIA, IA souveraine de WEVAL Consulting.") {
|
|
static $keys = null;
|
|
if (!$keys) {
|
|
$env = @file_get_contents("/etc/weval/secrets.env");
|
|
$keys = [];
|
|
if (preg_match("/GROQ_KEY=(.+)/", $env, $m)) $keys["groq"] = trim($m[1]);
|
|
if (preg_match("/CEREBRAS_API_KEY=(.+)/", $env, $m)) $keys["cerebras"] = trim($m[1]);
|
|
if (preg_match("/MISTRAL_KEY=(.+)/", $env, $m)) $keys["mistral"] = trim($m[1]);
|
|
}
|
|
$msgs = [["role" => "system", "content" => $system], ["role" => "user", "content" => $prompt]];
|
|
|
|
// CASCADE: try each provider
|
|
$providers = [
|
|
["url" => "https://api.groq.com/openai/v1/chat/completions", "key" => $keys["groq"] ?? "", "model" => "llama-3.3-70b-versatile", "name" => "groq"],
|
|
["url" => "https://api.cerebras.ai/v1/chat/completions", "key" => $keys["cerebras"] ?? "", "model" => "llama3.1-8b", "name" => "cerebras"],
|
|
["url" => "https://api.mistral.ai/v1/chat/completions", "key" => $keys["mistral"] ?? "", "model" => "open-mistral-7b", "name" => "mistral"],
|
|
["url" => "http://127.0.0.1:11435/api/chat", "key" => "", "model" => "qwen3:4b", "name" => "ollama"]
|
|
];
|
|
|
|
foreach ($providers as $p) {
|
|
if (!$p["key"] && $p["name"] !== "ollama") continue;
|
|
|
|
if ($p["name"] === "ollama") {
|
|
// Ollama uses different format
|
|
$data = json_encode(["model" => $p["model"], "messages" => $msgs, "stream" => false]);
|
|
$headers = ["Content-Type: application/json"];
|
|
} else {
|
|
$data = json_encode(["model" => $p["model"], "messages" => $msgs, "max_tokens" => 1500]);
|
|
$headers = ["Content-Type: application/json", "Authorization: Bearer " . $p["key"]];
|
|
}
|
|
|
|
$ch = curl_init($p["url"]);
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => $data,
|
|
CURLOPT_HTTPHEADER => $headers,
|
|
CURLOPT_TIMEOUT => 20,
|
|
CURLOPT_SSL_VERIFYPEER => false
|
|
]);
|
|
$r = curl_exec($ch);
|
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
|
|
if ($code === 200) {
|
|
$d = @json_decode($r, true);
|
|
$content = $d["choices"][0]["message"]["content"] ?? ($d["message"]["content"] ?? null);
|
|
if ($content) return $content;
|
|
}
|
|
// 429 or error → try next provider
|
|
}
|
|
return "LLM cascade: tous les providers occupes";
|
|
}
|