Files
wevads-platform/scripts/weval-brain-providers.php
2026-02-26 04:53:11 +01:00

219 lines
9.6 KiB
PHP
Executable File

<?php
/**
* WEVAL BRAIN - AI Provider Discovery & Management
* 26+ providers avec rotation intelligente
*/
$WEVAL_AI_PROVIDERS = [
// 🟢 GRATUITS ILLIMITÉS (Priorité 1-5)
'cerebras' => [
'name' => 'Cerebras', 'url' => 'https://api.cerebras.ai/v1/chat/completions',
'model' => 'llama3.1-8b', 'type' => 'FREE_UNLIMITED', 'priority' => 1,
'speed_ms' => 500, 'quality' => 8, 'context' => 8192, 'active' => true
],
'groq' => [
'name' => 'Groq', 'url' => 'https://api.groq.com/openai/v1/chat/completions',
'model' => 'llama-3.1-70b-versatile', 'type' => 'FREE_QUOTA', 'priority' => 2,
'speed_ms' => 800, 'quality' => 9, 'context' => 131072, 'limit' => '100k/day', 'active' => true
],
'deepseek' => [
'name' => 'DeepSeek', 'url' => 'https://api.deepseek.com/v1/chat/completions',
'model' => 'deepseek-chat', 'type' => 'FREE_QUOTA', 'priority' => 3,
'speed_ms' => 2000, 'quality' => 9, 'context' => 64000, 'active' => true
],
'sambanova' => [
'name' => 'SambaNova', 'url' => 'https://api.sambanova.ai/v1/chat/completions',
'model' => 'Meta-Llama-3.1-8B-Instruct', 'type' => 'FREE_UNLIMITED', 'priority' => 4,
'speed_ms' => 2000, 'quality' => 7, 'context' => 8192, 'active' => true
],
'gemini' => [
'name' => 'Google Gemini', 'url' => 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent',
'model' => 'gemini-1.5-flash', 'type' => 'FREE_QUOTA', 'priority' => 5,
'speed_ms' => 1500, 'quality' => 9, 'context' => 1000000, 'limit' => '60/min', 'active' => true
],
// 🟡 GRATUITS LIMITÉS (Priorité 6-15)
'cloudflare' => [
'name' => 'Cloudflare AI', 'url' => 'https://api.cloudflare.com/client/v4/accounts/{account_id}/ai/run/@cf/meta/llama-3.1-8b-instruct',
'model' => 'llama-3.1-8b', 'type' => 'FREE_QUOTA', 'priority' => 6,
'speed_ms' => 700, 'quality' => 7, 'limit' => '10k/day', 'active' => true
],
'mistral' => [
'name' => 'Mistral', 'url' => 'https://api.mistral.ai/v1/chat/completions',
'model' => 'mistral-small-latest', 'type' => 'FREE_TRIAL', 'priority' => 7,
'speed_ms' => 2000, 'quality' => 8, 'active' => true
],
'cohere' => [
'name' => 'Cohere', 'url' => 'https://api.cohere.ai/v1/chat',
'model' => 'command-r', 'type' => 'FREE_QUOTA', 'priority' => 8,
'speed_ms' => 2000, 'quality' => 8, 'limit' => '1000/month', 'active' => true
],
'together' => [
'name' => 'Together AI', 'url' => 'https://api.together.xyz/v1/chat/completions',
'model' => 'meta-llama/Llama-3.3-70B-Instruct-Turbo', 'type' => 'FREE_CREDITS', 'priority' => 9,
'speed_ms' => 2000, 'quality' => 9, 'active' => true
],
'fireworks' => [
'name' => 'Fireworks', 'url' => 'https://api.fireworks.ai/inference/v1/chat/completions',
'model' => 'accounts/fireworks/models/llama-v3p1-70b-instruct', 'type' => 'FREE_CREDITS', 'priority' => 10,
'speed_ms' => 1500, 'quality' => 8, 'active' => true
],
'openrouter' => [
'name' => 'OpenRouter', 'url' => 'https://openrouter.ai/api/v1/chat/completions',
'model' => 'meta-llama/llama-3.1-8b-instruct:free', 'type' => 'FREE_MODELS', 'priority' => 11,
'speed_ms' => 2000, 'quality' => 7, 'active' => true
],
'huggingface' => [
'name' => 'HuggingFace', 'url' => 'https://api-inference.huggingface.co/models/meta-llama/Llama-3.2-3B-Instruct',
'model' => 'Llama-3.2-3B', 'type' => 'FREE_QUOTA', 'priority' => 12,
'speed_ms' => 3000, 'quality' => 6, 'active' => true
],
'novita' => [
'name' => 'Novita AI', 'url' => 'https://api.novita.ai/v3/openai/chat/completions',
'model' => 'llama-3.1-8b', 'type' => 'FREE_CREDITS', 'priority' => 13,
'speed_ms' => 2000, 'quality' => 7, 'active' => true
],
'hyperbolic' => [
'name' => 'Hyperbolic', 'url' => 'https://api.hyperbolic.xyz/v1/chat/completions',
'model' => 'meta-llama/Llama-3.3-70B-Instruct', 'type' => 'FREE_QUOTA', 'priority' => 14,
'speed_ms' => 2000, 'quality' => 8, 'active' => true
],
// 🔴 PAYANTS (Priorité 20+)
'openai' => [
'name' => 'OpenAI', 'url' => 'https://api.openai.com/v1/chat/completions',
'model' => 'gpt-4o-mini', 'type' => 'PAID', 'priority' => 20,
'speed_ms' => 2000, 'quality' => 10, 'active' => false
],
'anthropic' => [
'name' => 'Claude', 'url' => 'https://api.anthropic.com/v1/messages',
'model' => 'claude-3-5-sonnet', 'type' => 'PAID', 'priority' => 21,
'speed_ms' => 3000, 'quality' => 10, 'active' => false
],
// 🖥️ LOCAL
'ollama' => [
'name' => 'Ollama', 'url' => 'http://localhost:11434/api/chat',
'model' => 'llama3.2', 'type' => 'LOCAL', 'priority' => 30,
'speed_ms' => 5000, 'quality' => 7, 'active' => false
],
];
// Clés API depuis DB ou env
function getApiKeys() {
try {
$pdo = new PDO("pgsql:host=localhost;dbname=adx_system", "admin", "admin123");
$stmt = $pdo->query("SELECT config_key, config_value FROM admin.commonia_config WHERE config_key LIKE '%_api_key'");
$keys = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$keys[str_replace('_api_key', '', $row['config_key'])] = $row['config_value'];
}
return $keys;
} catch (Exception $e) {
return [
'cerebras' => 'csk-4wrrhkpr568ry9xx49k9mcynwdx483nx53dd62yh5xedfckh',
'groq' => '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',
'deepseek' => 'sk-a296c24f77a1405d8f80105982991203',
'gemini' => 'AIzaSyBt-qfLETGALpibigmgW-o4vlxQZWaxwcE',
];
}
}
class WevalBrain {
private $providers, $keys, $statusFile = '/tmp/weval_provider_status.json';
public function __construct() {
global $WEVAL_AI_PROVIDERS;
$this->providers = $WEVAL_AI_PROVIDERS;
$this->keys = getApiKeys();
}
public function callWithFailover($message, $system = '') {
foreach ($this->providers as $id => $p) {
if (!$p['active'] || empty($this->keys[$id])) continue;
$result = $this->call($id, $message, $system);
if ($result['success']) {
return array_merge($result, ['provider' => $id, 'model' => $p['model']]);
}
}
return ['success' => false, 'error' => 'All providers failed'];
}
public function call($id, $message, $system = '') {
$p = $this->providers[$id] ?? null;
if (!$p) return ['success' => false];
$key = $this->keys[$id] ?? '';
$start = microtime(true);
$payload = ['model' => $p['model'], 'messages' => [], 'max_tokens' => 2048];
if ($system) $payload['messages'][] = ['role' => 'system', 'content' => $system];
$payload['messages'][] = ['role' => 'user', 'content' => $message];
// Gemini format différent
if ($id === 'gemini') {
$url = $p['url'] . "?key=$key";
$payload = ['contents' => [['parts' => [['text' => ($system ? "$system\n\n" : "") . $message]]]]];
$headers = ['Content-Type: application/json'];
} else {
$url = $p['url'];
$headers = ['Content-Type: application/json', "Authorization: Bearer $key"];
}
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => $headers,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$duration = round((microtime(true) - $start) * 1000);
if ($code >= 200 && $code < 300) {
$data = json_decode($response, true);
$text = $id === 'gemini'
? ($data['candidates'][0]['content']['parts'][0]['text'] ?? null)
: ($data['choices'][0]['message']['content'] ?? null);
if ($text) return ['success' => true, 'response' => $text, 'duration_ms' => $duration];
}
return ['success' => false, 'error' => "HTTP $code", 'duration_ms' => $duration];
}
public function getList() {
$list = [];
foreach ($this->providers as $id => $p) {
$list[$id] = array_merge($p, ['has_key' => !empty($this->keys[$id])]);
}
return $list;
}
public function testAll() {
$results = [];
foreach ($this->providers as $id => $p) {
if (!$p['active']) { $results[$id] = ['status' => 'inactive']; continue; }
$r = $this->call($id, 'Say OK');
$results[$id] = ['status' => $r['success'] ? 'ok' : 'error', 'ms' => $r['duration_ms'] ?? 0];
}
return $results;
}
}
// API Endpoint
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$action = $_GET['action'] ?? $_POST['action'] ?? 'list';
$brain = new WevalBrain();
switch ($action) {
case 'list': echo json_encode(['success' => true, 'providers' => $brain->getList()]); break;
case 'test': echo json_encode(['success' => true, 'results' => $brain->testAll()]); break;
case 'chat':
$msg = $_POST['message'] ?? '';
$sys = $_POST['system_prompt'] ?? '';
echo json_encode($msg ? $brain->callWithFailover($msg, $sys) : ['error' => 'Message required']);
break;
default: echo json_encode(['error' => 'Unknown action']);
}