Files
wevads-platform/scripts/hamid-router-dashboard.php
2026-02-26 04:53:11 +01:00

182 lines
9.5 KiB
PHP
Executable File

<?php
/**
* WEVAL MIND INTELLIGENT ROUTER - DASHBOARD
*/
try {
$pdo = new PDO('pgsql:host=localhost;dbname=adx_system', 'admin', 'admin123');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (Exception $e) {
die("DB Error: " . $e->getMessage());
}
// Get API keys from database
$apiKeys = [];
try {
$stmt = $pdo->query("SELECT config_key, config_value FROM admin.commonia_config WHERE config_key LIKE '%_api_key' AND config_value != ''");
while ($row = $stmt->fetch()) {
$provider = str_replace('_api_key', '', $row['config_key']);
$apiKeys[$provider] = $row['config_value'];
}
} catch (Exception $e) {}
$providers = [
'claude' => ['name' => 'Claude', 'icon' => '🧠', 'tier' => 'premium', 'key' => 'anthropic'],
'groq' => ['name' => 'Groq', 'icon' => '⚡', 'tier' => 'free', 'key' => 'groq'],
'deepseek' => ['name' => 'DeepSeek', 'icon' => '🔮', 'tier' => 'budget', 'key' => 'deepseek'],
'cerebras' => ['name' => 'Cerebras', 'icon' => '🧠', 'tier' => 'free', 'key' => 'cerebras'],
'gemini' => ['name' => 'Gemini', 'icon' => '💎', 'tier' => 'free', 'key' => 'gemini'],
'mistral' => ['name' => 'Mistral', 'icon' => '🇫🇷', 'tier' => 'standard', 'key' => 'mistral'],
'hyperbolic' => ['name' => 'Hyperbolic', 'icon' => '🌀', 'tier' => 'free', 'key' => 'hyperbolic'],
'cohere' => ['name' => 'Cohere', 'icon' => '🔶', 'tier' => 'standard', 'key' => 'cohere'],
'sambanova' => ['name' => 'SambaNova', 'icon' => '🚀', 'tier' => 'free', 'key' => 'sambanova'],
];
function analyzeQuery($q) {
$score = 0; $type = 'simple'; $reasons = [];
foreach (['debug','architecture','optimize','analyze','complex','erreur 500'] as $p) {
if (stripos($q,$p)!==false) { $score+=30; $reasons[]=['p'=>$p,'s'=>'+30']; }
}
foreach (['code','script','php','python','sql','function','créer'] as $p) {
if (stripos($q,$p)!==false) { $score+=20; $type='code'; $reasons[]=['p'=>$p,'s'=>'+20']; }
}
foreach (['bonjour','merci','hello','comment'] as $p) {
if (stripos($q,$p)!==false) { $score-=15; $reasons[]=['p'=>$p,'s'=>'-15']; }
}
if ($score>=40) $prov='claude'; elseif ($type=='code'&&$score>=20) $prov='deepseek'; else $prov='groq';
return ['score'=>max(0,$score),'provider'=>$prov,'reasons'=>$reasons];
}
if (isset($_GET['action']) && $_GET['action']=='analyze') {
header('Content-Type: application/json');
echo json_encode(analyzeQuery($_GET['query']??''));
exit;
}
$testResult = isset($_POST['q']) ? analyzeQuery($_POST['q']) : null;
$configured = count(array_filter($apiKeys));
?>
<!DOCTYPE html>
<html data-theme="dark"><head>
<meta charset="UTF-8"><title>🧠 WEVAL MIND Router</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:system-ui;background:linear-gradient(135deg,#0f172a,#1e293b);color:#e2e8f0;min-height:100vh}
.header{background:linear-gradient(135deg,#0d9488,#0891b2);padding:20px 30px;display:flex;justify-content:space-between;align-items:center}
.header h1{font-size:1.5rem;display:flex;align-items:center;gap:10px}
.kpis{display:flex;gap:20px}
.kpi{text-align:center;background:rgba(255,255,255,0.1);padding:10px 20px;border-radius:10px}
.kpi .v{font-size:1.8rem;font-weight:bold;color:#5eead4}
.kpi .l{font-size:0.75rem;opacity:0.8}
.container{max-width:1400px;margin:0 auto;padding:20px}
.card{background:rgba(30,41,59,0.9);border-radius:16px;padding:20px;margin-bottom:20px;border:1px solid rgba(255,255,255,0.1)}
.card-title{font-size:1.1rem;font-weight:600;margin-bottom:15px;display:flex;align-items:center;gap:10px;color:#5eead4}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:15px}
.prov{background:rgba(15,23,42,0.7);border-radius:12px;padding:15px;border:2px solid transparent;cursor:pointer;transition:all 0.3s}
.prov:hover{transform:translateY(-3px)}
.prov.ok{border-color:rgba(16,185,129,0.5)}
.prov.no{opacity:0.5;border-color:rgba(239,68,68,0.3)}
.prov-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.prov-icon{font-size:1.8rem}
.prov-name{font-weight:600}
.tier{position:absolute;top:8px;right:8px;padding:2px 8px;border-radius:6px;font-size:0.65rem;text-transform:uppercase}
.tier-free{background:#10b981}.tier-budget{background:#3b82f6}.tier-premium{background:#8b5cf6}.tier-standard{background:#f59e0b}
.prov{position:relative}
.status{margin-top:10px;font-size:0.8rem}
.status.ok{color:#10b981}.status.no{color:#ef4444}
.flow{display:flex;align-items:center;justify-content:center;gap:15px;padding:20px;background:rgba(15,23,42,0.6);border-radius:12px;flex-wrap:wrap}
.step{text-align:center;padding:15px;background:rgba(255,255,255,0.05);border-radius:10px;min-width:100px}
.step i{font-size:1.5rem;margin-bottom:8px;display:block}
.arrow{color:#5eead4;font-size:1.3rem}
.test-form{display:flex;gap:10px;margin-bottom:15px}
.test-input{flex:1;padding:12px;border:1px solid rgba(255,255,255,0.2);border-radius:10px;background:rgba(15,23,42,0.8);color:white;font-size:1rem}
.test-btn{padding:12px 25px;background:linear-gradient(135deg,#0d9488,#14b8a6);border:none;border-radius:10px;color:white;font-weight:600;cursor:pointer}
.result{background:rgba(15,23,42,0.8);border-radius:12px;padding:20px;border:2px solid #5eead4}
.result-head{display:flex;justify-content:space-between;align-items:center}
.result-prov{display:flex;align-items:center;gap:15px}
.result-icon{font-size:2.5rem}
.result-name{font-size:1.3rem;font-weight:bold}
.result-score{font-size:2rem;font-weight:bold;padding:10px 20px;border-radius:10px}
.score-high{background:#8b5cf6}.score-med{background:#3b82f6}.score-low{background:#10b981}
.reasons{margin-top:15px}
.reason{display:flex;justify-content:space-between;padding:8px 12px;background:rgba(255,255,255,0.05);border-radius:6px;margin-bottom:5px}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media(max-width:768px){.g2{grid-template-columns:1fr}}
</style>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700
</head>family=JetBrains+Mono:wght@400;500;700</head>display=swap" rel="stylesheet">
</head><body>
<div class="header">
<h1><span style="font-size:2rem">🧠</span> WEVAL MIND Intelligent Router</h1>
<div class="kpis">
<div class="kpi"><div class="v"><?=$configured?>/<?=count($providers)?></div><div class="l">Providers</div></div>
<div class="kpi"><div class="v">~80%</div><div class="l">Économies</div></div>
</div>
</div>
<div class="container">
<div class="card">
<div class="card-title">📊 Process de Routing</div>
<div class="flow">
<div class="step"><i style="color:#5eead4">💬</i>Question</div>
<span class="arrow">→</span>
<div class="step"><i style="color:#f59e0b">🧠</i>Analyse</div>
<span class="arrow">→</span>
<div class="step"><i style="color:#8b5cf6">🔢</i>Score</div>
<span class="arrow">→</span>
<div class="step"><i style="color:#3b82f6">🔀</i>Routing</div>
<span class="arrow">→</span>
<div class="step" style="border:2px solid #5eead4"><i style="color:#10b981">🤖</i>Provider</div>
</div>
</div>
<div class="g2">
<div class="card">
<div class="card-title">🧪 Tester le Routing</div>
<form method="POST" class="test-form">
<input type="text" name="q" class="test-input" placeholder="Tapez une question..." value="<?=htmlspecialchars($_POST['q']??'')?>">
<button class="test-btn">Analyser</button>
</form>
<?php if($testResult):$p=$providers[$testResult['provider']]??['name'=>$testResult['provider'],'icon'=>'🤖'];?>
<div class="result">
<div class="result-head">
<div class="result-prov">
<span class="result-icon"><?=$p['icon']?></span>
<span class="result-name"><?=$p['name']?></span>
</div>
<div class="result-score <?=$testResult['score']>=40?'score-high':($testResult['score']>=20?'score-med':'score-low')?>"><?=$testResult['score']?></div>
</div>
<?php if($testResult['reasons']):?><div class="reasons">
<?php foreach($testResult['reasons'] as $r):?><div class="reason"><span style="font-family:monospace;color:#5eead4"><?=$r['p']?></span><span style="color:<?=strpos($r['s'],'+')!==false?'#10b981':'#ef4444'?>"><?=$r['s']?></span></div><?php endforeach;?>
</div><?php endif;?>
</div>
<?php else:?><p style="text-align:center;opacity:0.6;padding:20px">Exemples: "Bonjour" → Groq | "Créer fonction PHP" → DeepSeek | "Debug erreur 500" → Claude</p><?php endif;?>
</div>
<div class="card">
<div class="card-title">📋 Règles de Routing</div>
<div style="background:rgba(139,92,246,0.2);border-left:4px solid #8b5cf6;padding:12px;border-radius:8px;margin-bottom:10px">
<strong>🧠 Premium (Score ≥40)</strong> → Claude<br><small>debug, architecture, optimize, complex, security</small>
</div>
<div style="background:rgba(59,130,246,0.2);border-left:4px solid #3b82f6;padding:12px;border-radius:8px;margin-bottom:10px">
<strong>💻 Code (Score ≥20)</strong> → DeepSeek<br><small>code, script, php, python, sql, function</small>
</div>
<div style="background:rgba(16,185,129,0.2);border-left:4px solid #10b981;padding:12px;border-radius:8px">
<strong>⚡ Simple (Score &lt;20)</strong> → Groq<br><small>bonjour, merci, comment, hello</small>
</div>
</div>
</div>
<div class="card">
<div class="card-title">🔌 Providers Configurés</div>
<div class="grid">
<?php foreach($providers as $k=>$p):$ok=!empty($apiKeys[$p['key']]);?>
<div class="prov <?=$ok?'ok':'no'?>">
<span class="tier tier-<?=$p['tier']?>"><?=$p['tier']?></span>
<div class="prov-head"><span class="prov-icon"><?=$p['icon']?></span><span class="prov-name"><?=$p['name']?></span></div>
<div class="status <?=$ok?'ok':'no'?>"><?=$ok?'✅ Configuré':'❌ Non configuré'?></div>
</div>
<?php endforeach;?>
</div>
</div>
</div>
</body></html>