Files
wevads-arsenal/public/consensus-engine-raw.php

168 lines
6.2 KiB
PHP

<?php
/**
* WEVIA CONSENSUS v4.0 "INTERNET ENABLED"
* 5 providers Groq + Recherche Web via Compound
* 100% GRATUIT - 100% ILLIMITÉ - ACCÈS INTERNET
*/
header("Content-Type: application/json");
class ConsensusV4 {
private $groq = "https://api.groq.com/openai/v1/chat/completions";
private $key = "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";
private $models = [
"compound" => "groq/compound",
"kimi" => "moonshotai/kimi-k2-instruct",
"qwen" => "qwen/qwen3-32b",
"llama4" => "meta-llama/llama-4-maverick-17b-128e-instruct",
"gpt-oss" => "openai/gpt-oss-120b"
];
public function ask($query, $sys = "", $webSearch = true) {
$start = microtime(true);
$responses = [];
$webResults = null;
// 1. Si recherche web demandée, utiliser Compound d'abord
if ($webSearch && $this->needsWebSearch($query)) {
$webResults = $this->searchWeb($query);
}
// 2. Enrichir le prompt avec les résultats web
$enrichedQuery = $query;
if ($webResults) {
$enrichedQuery = "Contexte web récent:\n" . $webResults . "\n\nQuestion: " . $query;
}
// 3. Query tous les modèles en parallèle
$mh = curl_multi_init();
$handles = [];
foreach ($this->models as $name => $model) {
if ($name === "compound" && $webResults) continue;
$ch = curl_init($this->groq);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer " . $this->key
],
CURLOPT_POSTFIELDS => json_encode([
"model" => $model,
"messages" => [
["role" => "system", "content" => $sys ?: "Tu es WEVIA, assistant WEVAL Consulting Casablanca. Expert SAP, Cloud, Data, IA. Réponds en français, 2-3 phrases, direct et précis. Utilise les infos web fournies si disponibles."],
["role" => "user", "content" => $enrichedQuery]
],
"max_tokens" => 800,
"temperature" => 0.7
])
]);
curl_multi_add_handle($mh, $ch);
$handles[$name] = $ch;
}
do {
$status = curl_multi_exec($mh, $active);
curl_multi_select($mh);
} while ($active && $status == CURLM_OK);
foreach ($handles as $name => $ch) {
$result = curl_multi_getcontent($ch);
$data = json_decode($result, true);
if (isset($data["choices"][0]["message"]["content"])) {
$content = $data["choices"][0]["message"]["content"];
$content = preg_replace("/<think>.*<\/think>/s", "", $content);
$responses[$name] = trim($content);
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
if (empty($responses)) {
return ["error" => "No responses", "models" => 0];
}
$best = $this->selectBest($responses);
$ms = round((microtime(true) - $start) * 1000);
return [
"response" => $best,
"models" => count($responses),
"providers" => array_keys($responses),
"web_search" => $webResults ? true : false,
"ms" => $ms,
"version" => "v4.0-internet",
"cost" => "0€"
];
}
private function needsWebSearch($query) {
$keywords = ["actualité", "news", "aujourd'hui", "récent", "2024", "2025", "2026",
"prix", "météo", "bourse", "cours", "dernier", "nouveau", "latest",
"current", "now", "today", "recherche", "find", "search", "internet"];
$q = strtolower($query);
foreach ($keywords as $kw) {
if (strpos($q, $kw) !== false) return true;
}
if (preg_match("/qui est|what is|where is|how much|combien|où est/i", $query)) return true;
return false;
}
private function searchWeb($query) {
$ch = curl_init($this->groq);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Authorization: Bearer " . $this->key
],
CURLOPT_POSTFIELDS => json_encode([
"model" => "groq/compound",
"messages" => [
["role" => "system", "content" => "Tu es un assistant de recherche. Trouve les informations les plus récentes et pertinentes sur Internet. Réponds avec les faits clés uniquement."],
["role" => "user", "content" => $query]
],
"max_tokens" => 500
])
]);
$result = curl_exec($ch);
curl_close($ch);
$data = json_decode($result, true);
return $data["choices"][0]["message"]["content"] ?? null;
}
private function selectBest($responses) {
$best = "";
$bestScore = 0;
foreach ($responses as $name => $text) {
$score = strlen($text);
if (preg_match("/[.!?]$/", trim($text))) $score += 50;
if ($name === "compound") $score += 150;
if ($name === "kimi") $score += 100;
if (preg_match("/(\b\w+\b).*\1.*\1/i", $text)) $score -= 30;
if ($score > $bestScore) {
$bestScore = $score;
$best = $text;
}
}
return $best;
}
}
$input = json_decode(file_get_contents("php://input"), true);
$q = $input["message"] ?? $_GET["q"] ?? "";
$web = isset($input["web_search"]) ? $input["web_search"] : true;
if (!$q) {
echo json_encode(["error" => "Message requis", "version" => "v4.0-internet"]);
exit;
}
echo json_encode((new ConsensusV4())->ask($q, $input["system"] ?? "", $web));