478 lines
25 KiB
PHP
478 lines
25 KiB
PHP
<?php
|
|
$_RAW=file_get_contents("php://input");$_JIN=json_decode($_RAW,true);$_mam=$_JIN["message"]??"";
|
|
|
|
// OPUS WIRE: Content-generation guard — bypass multiagent for content requests
|
|
$_is_content_req = preg_match('/(?:r[eé]dige|[eé]cris|pr[eé]pare|g[eé]n[eè]re|compose|cr[eé]e|fais)[\s\-].*(?:post|linkedin|article|contenu|texte|email|marketing|communic|blog|newsletter|carousel|pitch)/iu', $_mam)
|
|
|| preg_match('/(?:post|article|contenu|texte)[\s\-].*(?:linkedin|marketing|r[eé]seau|social)/iu', $_mam)
|
|
|| preg_match('/(?:plan|calendrier|strat[eé]gie)[\s\-]+(?:de\s+)?(?:contenu|[eé]ditorial|publication|linkedin|marketing)/iu', $_mam);
|
|
if (!$_is_content_req) { // Only multiagent SSE if NOT a content request
|
|
if(preg_match("/multi[\s\-]?agents?|plusieurs[\s\-]?agents?|\d+\s*agents?[\s\-]+(en[\s\-]+)?parall[eè]le|agents?[\s\-]+en[\s\-]+parall[eè]le|agir[\s\-]+en[\s\-]+(multi[\s\-]?)?agents?/iu",$_mam)){$_GET["msg"]=$_mam;header("X-Accel-Buffering: no");include __DIR__."/wevia-sse-orchestrator.php";exit;}}
|
|
|
|
// OPUS WIRE: Content enrichment — inject real platform data for content-generation requests
|
|
if ($_is_content_req ?? false) {
|
|
$_platform_data = "DONNÉES PLATEFORME RÉELLES WEVAL (à utiliser dans le contenu):\n"
|
|
. "- 153/153 tests NonReg (zéro régression)\n"
|
|
. "- 930 agents en production\n"
|
|
. "- 382 outils dans le resolver dynamique\n"
|
|
. "- 131 639 HCPs Ethica (109K email, 131K tel)\n"
|
|
. "- 12/13 providers IA souverains, 0€\n"
|
|
. "- 19 containers Docker\n"
|
|
. "- -40% délais de pilotage\n"
|
|
. "- 1,2M€ de gaspillage identifié\n"
|
|
. "- ROI en 4 mois\n"
|
|
. "- POC gratuit 2 semaines\n"
|
|
. "- 15 dépôts enterprise\n";
|
|
$_mam = $_platform_data . "\n\nDEMANDE UTILISATEUR: " . $_mam;
|
|
// CONTENT_ENRICHMENT_WIRE marker
|
|
// OPUS_CONTENT_DIRECT_LLM_FIX — bypass opus-intents + fast-path for content requests
|
|
// Direct to sovereign LLM with enriched $_mam
|
|
$__ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($__ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
|
CURLOPT_POSTFIELDS => json_encode([
|
|
"messages" => [
|
|
["role" => "system", "content" => "Tu es WEVIA Master, IA souveraine de WEVAL Consulting Casablanca. Tu es un expert en rédaction de contenu professionnel, marketing digital et LinkedIn. Tu rédiges du contenu premium en français impeccable : orthographe parfaite, accents corrects, ton de dirigeant. Tu utilises les données réelles de la plateforme WEVAL fournies ci-dessous pour enrichir tes textes. Sois concret, percutant, orienté storytelling terrain. Maximum 1200 caractères par post sauf indication contraire."],
|
|
["role" => "user", "content" => $_mam]
|
|
],
|
|
"max_tokens" => 2000,
|
|
"stream" => false
|
|
]),
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 25
|
|
]);
|
|
$__cr = curl_exec($__ch); curl_close($__ch);
|
|
$__cd = @json_decode($__cr, true);
|
|
$__ct = $__cd["choices"][0]["message"]["content"] ?? null;
|
|
if ($__ct) {
|
|
header("Content-Type: application/json");
|
|
echo json_encode([
|
|
"response" => $__ct,
|
|
"provider" => "wevia-master-enhanced",
|
|
"executed" => true,
|
|
"wire" => "content-direct-llm"
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
// If LLM fails, fall through to normal pipeline
|
|
|
|
}
|
|
// OPUS LEARNING LOOP v2 — capture TOUTES requêtes avant tout fast-path/include
|
|
if ($_mam) {
|
|
@mkdir('/var/log/wevia', 0755, true);
|
|
register_shutdown_function(function() {
|
|
$m = $GLOBALS['_mam'] ?? '';
|
|
if (!$m) return;
|
|
$http = http_response_code();
|
|
$prov = $GLOBALS['_OPUS_PROVIDER'] ?? '';
|
|
$entry = json_encode([
|
|
'ts' => date('c'),
|
|
'msg' => substr($m, 0, 500),
|
|
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
|
|
'origin' => $_SERVER['HTTP_ORIGIN'] ?? '',
|
|
'http' => $http,
|
|
], JSON_UNESCAPED_UNICODE);
|
|
@file_put_contents('/var/log/wevia/requests-all.jsonl', $entry . "\n", FILE_APPEND | LOCK_EX);
|
|
});
|
|
}
|
|
// OPUS_CONTENT_BYPASS_FP
|
|
if (!($_is_content_req ?? false)) {
|
|
// OPUS WIRED INTENTS — fired BEFORE fast-path-v3 (priority for: audit_6sigma, brains_status, debug_fix, send_test, new_pages)
|
|
// OPUS46 ADVANCED EXECUTION INTENTS (16AVR)
|
|
@require_once __DIR__ . "/wevia-opus46-intents.php";
|
|
if (function_exists("wevia_opus46_exec")) {
|
|
$_o46 = wevia_opus46_exec(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "");
|
|
if ($_o46) { header("Content-Type:application/json"); echo json_encode($_o46); exit; }
|
|
}
|
|
@require_once __DIR__ . "/wevia-opus-intents.php";
|
|
if (function_exists("wevia_opus_intents")) {
|
|
$_oi = wevia_opus_intents(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "");
|
|
if ($_oi) { header("Content-Type:application/json"); echo json_encode($_oi); exit; }
|
|
}
|
|
@require_once __DIR__ . "/wevia-fast-path-v3.php";
|
|
$_fp = function_exists("wevia_fast_path") ? wevia_fast_path(json_decode(file_get_contents("php://input"),true)["message"] ?? $_POST["message"] ?? $_GET["message"] ?? "") : null;
|
|
if ($_fp) { header("Content-Type:application/json"); echo json_encode($_fp); exit; }
|
|
|
|
} // end OPUS_CONTENT_BYPASS_FP
|
|
|
|
// OPUS AUTONOMY LAYER (BEFORE conv-guard): execution + paperclip bridge + archi-aware + self-wire
|
|
@require_once __DIR__ . '/wevia-opus-autonomy.php';
|
|
if (function_exists('opus_autonomy_check') && isset($_JIN['message'])) {
|
|
$_oa = opus_autonomy_check($_JIN['message']);
|
|
if ($_oa) { header('Content-Type:application/json'); echo json_encode($_oa, JSON_UNESCAPED_UNICODE); exit; }
|
|
}
|
|
// === CONV_GUARD ===
|
|
$_cg=$_JIN["message"]??"";
|
|
if(preg_match("/(aide|r[eé]dig|[eé]cri|explique|propose|compare|analyse|tradui|r[eé]sum|am[eé]lior|pr[eé]par|d[eé]cri|donne|raconte|conseille|argumente|convainc|formule|g[eé]n[eé]r|imagine|sugg[eé]r|[eé]labor|d[eé]taill|comment\s+(faire|amelior|organis|structur|convaincr))\/iu",$_cg) && !preg_match("/\b(status|git|docker|cron|disk|nonreg|sovereign|deploy|restart|backup|push|system|infra|l99|scan|diagnostic|nginx|domain|paperclip|deerflow|qdrant|ssl|wiki|vault|arena|cortex|mirofish|provider|cascade|agent|tool|registry|playwright|selenium|qa|visual.*test|chrome.*test|nonreg|l99|reconcil|tableau|dashboard|screenshot|sous-domain|vid[eé]o|ollama|doctrine)\b/i",$_cg)){
|
|
// SOVEREIGN DIRECT (bypass mr_route qui timeout)
|
|
$__ch=curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
|
curl_setopt_array($__ch,[CURLOPT_POST=>true,CURLOPT_HTTPHEADER=>["Content-Type: application/json"],CURLOPT_POSTFIELDS=>json_encode(["messages"=>[["role"=>"system","content"=>"Tu es WEVIA, IA souveraine de WEVAL Consulting Casablanca. Tu aides Yacine avec des réponses directes, concrètes et en français. Tu connais: WEVADS (email marketing), Ethica (141K HCPs pharma), 13 providers IA gratuits, 412 tools, 179 pages."],["role"=>"user","content"=>$_cg]],"max_tokens"=>600,"stream"=>false]),CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>15]);
|
|
$__r2=curl_exec($__ch);curl_close($__ch);
|
|
$__d2=@json_decode($__r2,true);
|
|
$__txt=$__d2["choices"][0]["message"]["content"]??null;
|
|
if($__txt){header("Content-Type:application/json");echo json_encode(["provider"=>"conv-guard-sovereign","content"=>$__txt,"tool"=>"conv-guard","model"=>$__d2["model"]??"auto"],JSON_UNESCAPED_UNICODE);exit;}
|
|
}
|
|
|
|
// OPUS-PERSISTENT PRE-ROUTER HOOK
|
|
$_jin=json_decode(file_get_contents('php://input'),true);
|
|
if($_jin && isset($_jin['message'])) $_POST['message']=$_jin['message'];
|
|
if(isset($_POST['message'])||isset($_GET['message'])||isset($_jin['message'])){
|
|
$_msg=$_jin['message']??$_POST['message']??$_GET['message']??'';
|
|
@require_once '/opt/wevia-brain/arena-pre-intents.php';
|
|
$_arena=function_exists('arena_pre_check')?arena_pre_check($_msg):null;
|
|
if($_arena){header('Content-Type:application/json');echo json_encode($_arena);exit;}
|
|
// Dynamic Tool Resolver — 67 tools from JSON registry
|
|
@require_once '/opt/wevia-brain/wevia-dynamic-resolver.php';
|
|
$_dyn = function_exists('wevia_dynamic_resolve') ? wevia_dynamic_resolve($_msg) : null;
|
|
if ($_dyn) { $_dyn['provider']=$_dyn['provider']??'fs-verify'; header('Content-Type:application/json'); echo json_encode($_dyn); exit; }
|
|
require_once '/opt/wevia-brain/wevia-wave200.php';
|
|
$_w200=wevia_wave200($_msg,['provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'wave200-pre']);
|
|
if($_w200){header('Content-Type:application/json');echo json_encode($_w200);exit;}
|
|
require_once '/opt/wevia-brain/wevia-gap-intents.php';
|
|
$_base=['provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'opus-persistent'];
|
|
$_r=function_exists('opus_persistent_intents')?opus_persistent_intents($_msg,$_base):null;
|
|
if(!$_r && function_exists('opus_ux_audit')) $_r=opus_ux_audit($_msg,$_base);
|
|
if(!$_r && function_exists('opus_mega_intents')) $_r=opus_mega_intents($_msg,$_base);
|
|
if(!$_r && function_exists('opus_tout_va_bien')) $_r=opus_tout_va_bien($_msg,$_base);
|
|
if(!$_r && function_exists('opus_extra_intents')) $_r=opus_extra_intents($_msg,$_base);
|
|
if($_r){header('Content-Type:application/json');echo json_encode($_r);exit;}
|
|
}
|
|
|
|
/**
|
|
* WEVIA MASTER API v1.0 — Standalone endpoint
|
|
* URL: /api/wevia-master-api.php
|
|
*
|
|
* ENDPOINTS:
|
|
* POST /api/wevia-master-api.php → Route a message
|
|
* GET /api/wevia-master-api.php?health → Health check
|
|
* GET /api/wevia-master-api.php?stats → Routing statistics
|
|
* GET /api/wevia-master-api.php?test → Quick test
|
|
* GET /api/wevia-master-api.php?dashboard → Visual dashboard
|
|
*/
|
|
|
|
header("Content-Type: application/json; charset=utf-8");
|
|
header("Access-Control-Allow-Origin: *");
|
|
header("Access-Control-Allow-Headers: Content-Type");
|
|
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
|
|
if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") { http_response_code(200); exit; }
|
|
clearstatcache(true, "/opt/wevia-brain/wevia-master-router.php"); if (function_exists('opcache_invalidate')) opcache_invalidate("/opt/wevia-brain/wevia-master-router.php", true);
|
|
|
|
require_once "/opt/wevia-brain/wevia-master-router.php";
|
|
|
|
// ═══ ROUTING ═══
|
|
$action = null;
|
|
if (isset($_GET['health'])) $action = 'health';
|
|
elseif (isset($_GET['stats'])) $action = 'stats';
|
|
elseif (isset($_GET['test'])) $action = 'test';
|
|
elseif (isset($_GET['score'])) $action = 'score';
|
|
elseif (isset($_GET['dashboard'])) $action = 'dashboard';
|
|
elseif (isset($_GET['rag'])) $action = 'rag';
|
|
elseif (isset($_GET['capabilities'])) $action = 'capabilities';
|
|
|
|
switch ($action) {
|
|
case 'health':
|
|
echo json_encode(mr_healthCheck(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'stats':
|
|
echo json_encode(mr_getStats(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'test':
|
|
$msg = $_GET['q'] ?? 'Bonjour, comment vas-tu?';
|
|
// Dynamic Resolver FIRST (258 exec tools)
|
|
@require_once '/opt/wevia-brain/wevia-dynamic-resolver.php';
|
|
$_dr = function_exists('wevia_dynamic_resolve') ? wevia_dynamic_resolve($msg) : null;
|
|
if ($_dr) { echo json_encode(['provider'=>$_dr['source']??'dynamic-resolver','response'=>$_dr['content']??''], JSON_UNESCAPED_UNICODE); exit; }
|
|
|
|
// OPUS INTERCEPT GET
|
|
$__base2 = ['provider' => 'opus-intercept', 'tier' => 0];
|
|
$__r2 = opus_persistent_intents($msg, $__base2);
|
|
if (!$__r2) $__r2 = opus_ux_audit($msg, $__base2);
|
|
if (!$__r2) $__r2 = opus_mega_intents($msg, $__base2);
|
|
if ($__r2) { echo json_encode($__r2); exit; }
|
|
$result = mr_route($msg, @file_get_contents('/etc/wevia/system-prompt.txt') ?: 'Tu es WEVIA, IA souveraine de WEVAL Consulting.');
|
|
echo json_encode([
|
|
'input' => $msg,
|
|
'response' => mb_substr($result['content'], 0, 500),
|
|
'model' => $result['model'],
|
|
'provider' => $result['provider'],
|
|
'tier' => $result['tier'],
|
|
'latency_ms' => $result['latency_ms'],
|
|
'source' => $result['source'],
|
|
'routing' => $result['routing'] ?? null,
|
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'score':
|
|
$msg = $_GET['q'] ?? '';
|
|
if (empty($msg)) {
|
|
echo json_encode(['error' => 'Pass ?score&q=your+message']);
|
|
exit;
|
|
}
|
|
echo json_encode(mr_scoreComplexity($msg), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'capabilities':
|
|
$caps = wevia_listCapabilities();
|
|
// Wire dormant capabilities from registry
|
|
$dormFile = '/opt/wevia-brain/wevia-master-capabilities.json';
|
|
if (file_exists($dormFile)) {
|
|
$dorm = json_decode(file_get_contents($dormFile), true);
|
|
$caps['dormant_capabilities'] = $dorm['summary'] ?? [];
|
|
$caps['total_capabilities'] = ($dorm['total'] ?? 0) + count($caps);
|
|
$caps['dormant_categories'] = array_keys($dorm['categories'] ?? []);
|
|
}
|
|
echo json_encode($caps, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'rag':
|
|
$msg = $_GET['q'] ?? 'Comment fonctionne WEVADS?';
|
|
$rag = rag_search($msg);
|
|
echo json_encode($rag, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
|
|
case 'dashboard':
|
|
header("Content-Type: text/html; charset=utf-8");
|
|
$stats = mr_getStats();
|
|
$health = mr_healthCheck();
|
|
?><!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>WEVIA Master Router — Dashboard</title>
|
|
<style>
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
body{background:#0a0a0f;color:#e8e6f0;font-family:-apple-system,sans-serif;padding:2rem}
|
|
h1{font-size:1.8rem;margin-bottom:1rem;color:#00ff88}
|
|
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:1rem;margin:1.5rem 0}
|
|
.card{background:#12121a;border:1px solid #2a2a3d;border-radius:12px;padding:1.2rem;text-align:center}
|
|
.card .num{font-size:2.2rem;font-weight:700;color:#00ff88;font-family:monospace}
|
|
.card .label{font-size:.75rem;color:#8888a8;margin-top:.3rem}
|
|
.status{display:inline-block;padding:.2em .6em;border-radius:100px;font-size:.7rem;font-family:monospace}
|
|
.up{background:#00ff8822;color:#00ff88;border:1px solid #00ff88}
|
|
.down{background:#ff446622;color:#ff4466;border:1px solid #ff4466}
|
|
table{width:100%;border-collapse:collapse;margin:1rem 0;font-size:.85rem}
|
|
th{background:#1a1a28;padding:.6rem;text-align:left;font-size:.7rem;text-transform:uppercase;letter-spacing:.1em;color:#8888a8}
|
|
td{padding:.5rem .6rem;border-bottom:1px solid #2a2a3d}
|
|
.t0{color:#00ff88}.t1{color:#4488ff}.t2{color:#aa66ff}.t3{color:#ff4466}
|
|
pre{background:#12121a;border:1px solid #2a2a3d;border-radius:8px;padding:1rem;overflow-x:auto;font-size:.75rem;margin:1rem 0}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>⚡ WEVIA Master Router v<?=MR_VERSION?></h1>
|
|
|
|
<div class="grid">
|
|
<div class="card">
|
|
<div class="num"><?=$health['ollama']==='UP'?'<span class="status up">UP</span>':'<span class="status down">DOWN</span>'?></div>
|
|
<div class="label">Ollama (port 11434)</div>
|
|
</div>
|
|
<div class="card"><div class="num"><?=$health['ollama_models']??0?></div><div class="label">Modèles locaux</div></div>
|
|
<div class="card"><div class="num"><?=$health['tier1_providers']?></div><div class="label">Tier 1 (free fast)</div></div>
|
|
<div class="card"><div class="num"><?=$health['tier2_providers']?></div><div class="label">Tier 2 (free quality)</div></div>
|
|
<div class="card"><div class="num"><?=$health['secrets_count']?></div><div class="label">Secrets chargés</div></div>
|
|
</div>
|
|
|
|
<h2 style="margin-top:2rem">📊 Stats par jour</h2>
|
|
<table>
|
|
<thead><tr><th>Date</th><th>Total</th><th class="t0">Tier 0 (local)</th><th class="t1">Tier 1 (fast)</th><th class="t2">Tier 2 (quality)</th><th>Latence moy.</th><th>Coût</th></tr></thead>
|
|
<tbody>
|
|
<?php
|
|
if (is_array($stats)) {
|
|
krsort($stats);
|
|
foreach ($stats as $date => $d) {
|
|
if (!is_array($d)) continue;
|
|
$t0 = $d['by_tier'][0] ?? 0;
|
|
$t1 = $d['by_tier'][1] ?? 0;
|
|
$t2 = $d['by_tier'][2] ?? 0;
|
|
$total = $d['total'] ?? 0;
|
|
$pct0 = $total > 0 ? round($t0/$total*100) : 0;
|
|
echo "<tr><td>$date</td><td>{$total}</td>";
|
|
echo "<td class='t0'>{$t0} ({$pct0}%)</td>";
|
|
echo "<td class='t1'>{$t1}</td><td class='t2'>{$t2}</td>";
|
|
echo "<td>{$d['avg_latency']}ms</td><td>{$d['cost']}€</td></tr>";
|
|
}
|
|
}
|
|
?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>🔍 Test rapide</h2>
|
|
<p style="color:#8888a8;margin:.5rem 0">Exemples:</p>
|
|
<pre>
|
|
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?test&q=Bonjour"
|
|
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?score&q=Explique+comment+optimiser+nginx"
|
|
curl "<?=$_SERVER['HTTP_HOST']?>/api/wevia-master-api.php?health"
|
|
</pre>
|
|
|
|
<h2>🏗️ Architecture</h2>
|
|
<pre>
|
|
TIER 0 (Souverain, 0€) → Ollama:11434 [weval-brain-v2, qwen2.5:7b, qwen3:4b, mistral, medllama2]
|
|
TIER 1 (Free ultra-fast) → Cerebras, Groq, SambaNova
|
|
TIER 2 (Free quality) → Mistral Cloud, Cohere, Gemini
|
|
TIER 3 (Frontier, payant) → Claude API, GPT API (non implémenté — dernier recours)
|
|
</pre>
|
|
|
|
<h2>📡 Providers actifs</h2>
|
|
<pre><?php
|
|
$t1 = mr_getTier1Providers();
|
|
foreach ($t1 as $n => $c) echo "TIER1 $n: {$c['model']} ({$c['speed']})\n";
|
|
$t2 = mr_getTier2Providers();
|
|
foreach ($t2 as $n => $c) echo "TIER2 $n: {$c['model']} ({$c['speed']})\n";
|
|
?></pre>
|
|
|
|
<p style="margin-top:2rem;font-size:.7rem;color:#555">WEVIA Master Router — WEVAL Consulting — Avril 2026</p>
|
|
</body></html>
|
|
<?php
|
|
exit;
|
|
}
|
|
|
|
// ═══ POST: Route a message ═══
|
|
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
|
|
echo json_encode(['error' => 'POST required. Try ?health, ?stats, ?test, ?dashboard']);
|
|
exit;
|
|
}
|
|
|
|
// Debug: log raw input
|
|
$rawInput = file_get_contents("php://input");
|
|
@file_put_contents("/tmp/master-debug.log", date("H:i:s")." RAW=".substr($rawInput,0,200)."\n", FILE_APPEND);
|
|
$input = json_decode($rawInput, true);
|
|
$message = $input['message'] ?? $input['msg'] ?? $input['content'] ?? '';
|
|
$system = $input['system'] ?? (@file_get_contents('/etc/wevia/system-prompt.txt') ?: 'Tu es WEVIA, IA souveraine de WEVAL Consulting.');
|
|
// OPUS-FIX RC#7: Inject architecture context for LLM awareness
|
|
$system .= "\nARCHI INTERNE: Sovereign=port4000(13 providers IA). Paperclip=890agents/2484skills. DeerFlow=14skills. Registry=375tools. Wiki=1229. Vault=550. Pages=174. APIs=437. Ethica=141K HCPs. MonDsh=test NonReg Monitoring Dashboard. Monitor=test FUNC NonReg. WEVCODE=IDE souverain. Arsenal=backoffice port5890.";
|
|
$history = $input['history'] ?? [];
|
|
|
|
// W115b-PRE: Snapshot Hetzner (12-AVR) — intercept BEFORE wave114
|
|
if (preg_match('/(snapshot.*hetzner|hetzner.*snap|snap.*archiv|archiv.*snap|snap.*status|snap.*progress)/iu', $message)) {
|
|
$log = @file_get_contents('/tmp/wevia-snapshot-archiver.log');
|
|
$ps = trim(@shell_exec('ps aux 2>/dev/null | grep "wevia-snap-archiver" | grep -v grep'));
|
|
// W115b-LAUNCH/KILL (wired by Opus)
|
|
if (preg_match("/(lance|start|relance|demarre)/iu", $message) && empty($ps)) {
|
|
@shell_exec("rm -f /tmp/snap-archiver.lock; echo /tmp/snap-final.sh | at now 2>&1");
|
|
sleep(3);
|
|
$r = "ARCHIVER LANCE! Verifier dans 30s avec snap archiver status";
|
|
echo json_encode(["content"=>$r,"provider"=>"fs-verify","source"=>"w115b-launch"], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
if (preg_match("/(kill|stop|arret)/iu", $message)) {
|
|
@shell_exec("pkill -f wevia-snap-archiver 2>/dev/null; rm -f /tmp/snap-archiver.lock");
|
|
$r = "ARCHIVER STOPPE";
|
|
echo json_encode(["content"=>$r,"provider"=>"fs-verify","source"=>"w115b-kill"], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
$hz = trim(@shell_exec('python3 /opt/weval-l99/wevia-snap-archiver.py list 2>&1'));
|
|
$r = "ARCHIVER: " . ($ps ? "RUNNING
|
|
" . $ps : "STOPPED") . "
|
|
Snapshots:
|
|
" . $hz . "
|
|
Log (last 10):
|
|
" . ($log ? implode("
|
|
", array_slice(explode("
|
|
", trim($log)), -10)) : "NO_LOG");
|
|
echo json_encode(['content'=>$r,'provider'=>'fs-verify','tier'=>0,'latency_ms'=>0,'cost'=>0,'source'=>'w115b'],JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
// STRATEGIC GUARD: skip wave114 for business/strategy questions → go direct mr_route
|
|
require_once '/opt/wevia-brain/wevia-strategic-guard.php';
|
|
if (!is_strategic_question($message)) {
|
|
// === WAVE 114: Intent-first routing ===
|
|
$_exec_url = "https://127.0.0.1/api/wevia-full-exec.php?" . http_build_query(['m' => $message]);
|
|
$_exec_ctx = stream_context_create(["http" => ["timeout" => 25, "header" => "Host: weval-consulting.com
|
|
"], "ssl" => ["verify_peer" => false, "verify_peer_name" => false]]);
|
|
$_exec_raw = @file_get_contents($_exec_url, false, $_exec_ctx);
|
|
if ($_exec_raw) {
|
|
$_exec_d = @json_decode($_exec_raw, true);
|
|
$_exec_r = $_exec_d['response'] ?? '';
|
|
if ($_exec_r && strlen($_exec_r) > 20 && strpos($_exec_r, 'Dispo:') !== 0) {
|
|
echo json_encode(['content' => $_exec_r, 'provider' => 'fs-verify', 'tier' => 0, 'latency_ms' => 0, 'cost' => 0, 'source' => 'intent-execution'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
}
|
|
} // end strategic guard wave114
|
|
|
|
$options = $input['options'] ?? [];
|
|
|
|
// === WAVE 135: Handle file attachments ===
|
|
$attachments = $input['attachments'] ?? [];
|
|
if (!empty($attachments)) {
|
|
@mkdir('/tmp/wevia-uploads', 0777, true);
|
|
$fileContext = "\n\nFICHIERS JOINTS:\n";
|
|
foreach (array_slice($attachments, 0, 5) as $att) {
|
|
$name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $att['name'] ?? 'file');
|
|
$data = base64_decode($att['data'] ?? '');
|
|
$path = "/tmp/wevia-uploads/" . time() . "_" . $name;
|
|
file_put_contents($path, $data);
|
|
$size = strlen($data);
|
|
$type = $att['type'] ?? 'unknown';
|
|
|
|
if (strpos($type, 'image') !== false) {
|
|
// Image: save and describe
|
|
$fileContext .= "- Image: $name ({$size}B) sauvee: $path\n";
|
|
$fileContext .= " Type: $type. Analyse visuelle demandee.\n";
|
|
// Copy to public screenshots for reference
|
|
@copy($path, "/var/www/html/screenshots/upload_" . basename($path));
|
|
$fileContext .= " URL: https://weval-consulting.com/screenshots/upload_" . basename($path) . "\n";
|
|
} elseif (strpos($type, 'text') !== false || strpos($type, 'javascript') !== false || strpos($type, 'php') !== false || strpos($type, 'json') !== false || strpos($type, 'xml') !== false || strpos($type, 'csv') !== false) {
|
|
// Text/code: read content
|
|
$content = substr($data, 0, 5000);
|
|
$fileContext .= "- Fichier texte: $name ({$size}B)\n";
|
|
$fileContext .= " Contenu:\n```\n$content\n```\n";
|
|
} elseif (strpos($type, 'pdf') !== false) {
|
|
$fileContext .= "- PDF: $name ({$size}B) sauve: $path\n";
|
|
// Try pdftotext
|
|
$txt = @shell_exec("pdftotext $path - 2>/dev/null | head -100");
|
|
if ($txt) $fileContext .= " Extrait:\n$txt\n";
|
|
} else {
|
|
$fileContext .= "- Fichier: $name ($type, {$size}B) sauve: $path\n";
|
|
}
|
|
}
|
|
$message .= $fileContext;
|
|
}
|
|
|
|
|
|
if (empty(trim($message))) {
|
|
echo json_encode(['error' => 'message required']);
|
|
exit;
|
|
}
|
|
|
|
ob_start();
|
|
try {
|
|
// OPUS INTERCEPT: check persistent intents BEFORE LLM
|
|
$__base = ['provider' => 'opus-intercept', 'tier' => 0, 'latency_ms' => 0, 'cost' => 0, 'source' => 'opus-persistent'];
|
|
$__r = opus_persistent_intents($message, $__base);
|
|
if (!$__r) $__r = opus_ux_audit($message, $__base);
|
|
if (!$__r) $__r = opus_mega_intents($message, $__base);
|
|
if ($__r) {
|
|
echo json_encode($__r);
|
|
exit;
|
|
}
|
|
// VAULT CONTEXT: inject relevant notes to reduce tokens
|
|
@include_once '/opt/wevia-brain/wevia-vault-context.php';
|
|
if (function_exists('wevia_vault_context')) {
|
|
$vaultCtx = wevia_vault_context($message, 3);
|
|
if ($vaultCtx) $system .= $vaultCtx;
|
|
}
|
|
$result = mr_route($message, $system, $history, $options);
|
|
$stray = ob_get_clean();
|
|
if (!$result || empty($result)) {
|
|
echo json_encode(['error'=>'empty_result','stray_output'=>substr($stray,0,500),'provider'=>'unknown','response'=>'']);
|
|
} else {
|
|
// Ensure response key exists for admin compatibility
|
|
if (!isset($result['response']) && isset($result['content'])) {
|
|
$result['response'] = $result['content'];
|
|
}
|
|
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
if ($json === false) {
|
|
// JSON encode failed - likely UTF8 issue
|
|
array_walk_recursive($result, function(&$v){if(is_string($v))$v=mb_convert_encoding($v,'UTF-8','UTF-8');});
|
|
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
|
|
}
|
|
echo $json;
|
|
}
|
|
} catch (\Throwable $e) {
|
|
$stray = ob_get_clean();
|
|
echo json_encode(['error'=>$e->getMessage(),'file'=>basename($e->getFile()),'line'=>$e->getLine(),'stray'=>substr($stray,0,200)]);
|
|
}
|