/dev/null | cut -d= -f2")); if($_k) define('TOGETHER_KEY',$_k); } if (!defined('COHERE_KEY')) { $_k=trim(shell_exec("grep COHERE_KEY /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('COHERE_KEY',$_k); } if (!defined('NVIDIA_NIM_KEY')) { $_k=trim(shell_exec("grep NVIDIA_NIM_KEY /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('NVIDIA_NIM_KEY',$_k); } if (!defined('OPENROUTER_KEY')) { $_k=trim(shell_exec("grep OPENROUTER_KEY /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('OPENROUTER_KEY',$_k); } if (!defined('HF_TOKEN')) { $_k=trim(shell_exec("grep HF_TOKEN /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('HF_TOKEN',$_k); } if (!defined('ZHIPU_KEY')) { $_k=trim(shell_exec("grep ZHIPU_KEY /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('ZHIPU_KEY',$_k); } if (!defined('REPLICATE_KEY')) { $_k=trim(shell_exec("grep REPLICATE_KEY /etc/weval/secrets.env 2>/dev/null | cut -d= -f2")); if($_k) define('REPLICATE_KEY',$_k); } $PROVIDERS = [ 'groq' => ['name'=>'Groq','tier'=>'free','speed'=>'ultra', 'base_url'=>'https://api.groq.com/openai/v1', 'api_key'=>defined('GROQ_KEY')?GROQ_KEY:'', 'models'=>['llama-3.3-70b-versatile'=>'Llama 3.3 70B','llama-3.1-8b-instant'=>'Llama 3.1 8B Instant','meta-llama/llama-4-scout-17b-16e-instruct'=>'Llama 4 Scout 17B Vision','gemma2-9b-it'=>'Gemma 2 9B','mixtral-8x7b-32768'=>'Mixtral 8x7B']], 'cerebras' => ['name'=>'Cerebras','tier'=>'free','speed'=>'ultra', 'base_url'=>'https://api.cerebras.ai/v1', 'api_key'=>defined('CEREBRAS_KEY')?CEREBRAS_KEY:'', 'models'=>['qwen-3-235b-a22b-instruct-2507'=>'Qwen 3 235B','llama-3.3-70b'=>'Llama 3.3 70B','llama-3.1-8b'=>'Llama 3.1 8B']], 'sambanova' => ['name'=>'SambaNova','tier'=>'free','speed'=>'ultra', 'base_url'=>'https://api.sambanova.ai/v1', 'api_key'=>defined('SAMBANOVA_KEY')?SAMBANOVA_KEY:'', 'models'=>['Meta-Llama-3.3-70B-Instruct'=>'Llama 3.3 70B','Meta-Llama-3.1-8B-Instruct'=>'Llama 3.1 8B','DeepSeek-V3.1'=>'DeepSeek V3.1','DeepSeek-R1'=>'DeepSeek R1 Reasoning']], 'mistral' => ['name'=>'Mistral AI','tier'=>'free','speed'=>'fast', 'base_url'=>'https://api.mistral.ai/v1', 'api_key'=>defined('MISTRAL_KEY')?MISTRAL_KEY:'', 'models'=>['mistral-small-latest'=>'Mistral Small','open-mistral-nemo'=>'Mistral Nemo 12B','codestral-latest'=>'Codestral Code']], 'deepseek' => ['name'=>'DeepSeek','tier'=>'free','speed'=>'fast', 'base_url'=>'https://api.deepseek.com', 'api_key'=>defined('DEEPSEEK_KEY')?DEEPSEEK_KEY:'', 'models'=>['deepseek-chat'=>'DeepSeek V3 Chat','deepseek-reasoner'=>'DeepSeek R1 Reasoner']], 'gemini' => ['name'=>'Google Gemini','tier'=>'free','speed'=>'fast', 'base_url'=>'https://generativelanguage.googleapis.com/v1beta/openai', 'api_key'=>defined('GEMINI_KEY')?GEMINI_KEY:'', 'models'=>['gemini-2.0-flash'=>'Gemini 2.0 Flash','gemini-2.0-flash-lite'=>'Gemini 2.0 Flash Lite','gemini-1.5-pro'=>'Gemini 1.5 Pro']], 'alibaba' => ['name'=>'Alibaba Qwen','tier'=>'free','speed'=>'fast', 'base_url'=>'https://dashscope-intl.aliyuncs.com/compatible-mode/v1', 'api_key'=>defined('DASHSCOPE_KEY')?DASHSCOPE_KEY:'', 'models'=>['qwen-turbo-latest'=>'Qwen Turbo','qwen-plus-latest'=>'Qwen Plus','qwen-max'=>'Qwen Max']], 'anthropic' => ['name'=>'Anthropic Claude','tier'=>'paid','speed'=>'fast', 'base_url'=>'https://api.anthropic.com/v1', 'api_key'=>defined('ANTHROPIC_KEY')?ANTHROPIC_KEY:'', 'models'=>['claude-sonnet-4-20250514'=>'Claude Sonnet 4','claude-haiku-4-5-20251001'=>'Claude Haiku 4.5'], 'custom_format'=>'anthropic'], 'together' => ['name'=>'Together AI','tier'=>'free','speed'=>'fast', 'base_url'=>'https://api.together.xyz/v1', 'api_key'=>defined('TOGETHER_KEY')?TOGETHER_KEY:'', 'models'=>['meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo'=>'Llama 3.1 70B Turbo','mistralai/Mixtral-8x22B-Instruct-v0.1'=>'Mixtral 8x22B','Qwen/Qwen2.5-72B-Instruct-Turbo'=>'Qwen 2.5 72B']], 'cohere' => ['name'=>'Cohere','tier'=>'free','speed'=>'fast', 'base_url'=>'https://api.cohere.com/v2', 'api_key'=>defined('COHERE_KEY')?COHERE_KEY:'', 'models'=>['command-r-plus'=>'Command R+','command-r'=>'Command R','command-light'=>'Command Light'], 'custom_format'=>'cohere'], 'nvidia' => ['name'=>'NVIDIA NIM','tier'=>'free','speed'=>'fast', 'base_url'=>'https://integrate.api.nvidia.com/v1', 'api_key'=>defined('NVIDIA_NIM_KEY')?NVIDIA_NIM_KEY:'', 'models'=>['meta/llama-3.3-70b-instruct'=>'Llama 3.3 70B','nvidia/llama-3.1-nemotron-70b-instruct'=>'Nemotron 70B','deepseek-ai/deepseek-r1'=>'DeepSeek R1']], 'openrouter' => ['name'=>'OpenRouter','tier'=>'free','speed'=>'fast', 'base_url'=>'https://openrouter.ai/api/v1', 'api_key'=>defined('OPENROUTER_KEY')?OPENROUTER_KEY:'', 'models'=>['meta-llama/llama-3.3-70b-instruct:free'=>'Llama 3.3 70B Free','google/gemma-2-9b-it:free'=>'Gemma 2 9B Free','qwen/qwen-2.5-72b-instruct:free'=>'Qwen 2.5 72B Free']], 'huggingface' => ['name'=>'HuggingFace','tier'=>'free','speed'=>'slow', 'base_url'=>'https://api-inference.huggingface.co/models', 'api_key'=>defined('HF_TOKEN')?HF_TOKEN:'', 'models'=>['meta-llama/Llama-3.1-8B-Instruct'=>'Llama 3.1 8B','mistralai/Mistral-7B-Instruct-v0.3'=>'Mistral 7B','Qwen/Qwen2.5-7B-Instruct'=>'Qwen 2.5 7B'], 'custom_format'=>'huggingface'], 'zhipu' => ['name'=>'ZhiPu GLM','tier'=>'free','speed'=>'fast', 'base_url'=>'https://open.bigmodel.cn/api/paas/v4', 'api_key'=>defined('ZHIPU_KEY')?ZHIPU_KEY:'', 'models'=>['glm-4-flash'=>'GLM-4 Flash','glm-4-air'=>'GLM-4 Air','glm-4'=>'GLM-4']], 'replicate' => ['name'=>'Replicate','tier'=>'free','speed'=>'slow', 'base_url'=>'https://api.replicate.com/v1', 'api_key'=>defined('REPLICATE_KEY')?REPLICATE_KEY:'', 'models'=>['meta/meta-llama-3-70b-instruct'=>'Llama 3 70B','mistralai/mixtral-8x7b-instruct-v0.1'=>'Mixtral 8x7B'], 'custom_format'=>'replicate'], 'ollama-s204' => ['name'=>'Ollama S204 Sovereign','tier'=>'sovereign','speed'=>'slow', 'base_url'=>'http://127.0.0.1:4000/v1', 'api_key'=>'ollama', 'models'=>['qwen3:8b'=>'Qwen 3 8B','qwen3:4b'=>'Qwen 3 4B','qwen2.5:7b'=>'Qwen 2.5 7B','qwen3.5:0.8b'=>'Qwen 3.5 0.8B Tiny','granite4:latest'=>'IBM Granite 4','mistral:latest'=>'Mistral 7B','glm4:9b'=>'GLM-4 9B Zhipu','medllama2:latest'=>'MedLlama 2 Medical','meditron:7b'=>'Meditron 7B Medical','weval-brain:latest'=>'WEVAL Brain Custom']], 'ollama-s151' => ['name'=>'Ollama S151 OVH','tier'=>'sovereign','speed'=>'slow', 'base_url'=>'http://127.0.0.1:4000/v1', 'api_key'=>'ollama', 'models'=>['qwen3:4b'=>'Qwen 3 4B','qwen3.5:0.8b'=>'Qwen 3.5 0.8B','granite4:latest'=>'IBM Granite 4','phi4-mini:latest'=>'Microsoft Phi-4 Mini','smollm2:135m'=>'SmolLM2 135M Ultra-tiny']], ]; if ($_SERVER['REQUEST_METHOD'] === 'GET') { header('Content-Type: application/json'); $out = []; $tm = 0; foreach ($PROVIDERS as $id => $p) { $models = []; foreach ($p['models'] as $mid => $mname) { $models[] = ['id'=>$mid,'name'=>$mname]; $tm++; } $out[] = ['id'=>$id,'name'=>$p['name'],'tier'=>$p['tier'],'speed'=>$p['speed'],'models'=>$models,'has_key'=>!empty($p['api_key'])&&strlen($p['api_key'])>5]; } echo json_encode(['providers'=>$out,'total_models'=>$tm]); exit; } header('Content-Type: application/json'); $input = json_decode(file_get_contents('php://input'), true); if (!$input) { http_response_code(400); echo json_encode(['error'=>'Invalid JSON']); exit; } $provider_id = $input['provider'] ?? 'cerebras'; $model = $input['model'] ?? ''; $messages = $input['messages'] ?? []; $stream = $input['stream'] ?? false; $system = $input['system'] ?? ''; if (!isset($PROVIDERS[$provider_id])) { http_response_code(400); echo json_encode(['error'=>'Unknown provider']); exit; } $provider = $PROVIDERS[$provider_id]; if (empty($provider['api_key'])||strlen($provider['api_key'])<5) { http_response_code(400); echo json_encode(['error'=>'No API key for '.$provider['name']]); exit; } if ($model==="auto"||!$model) $model = array_key_first($provider['models']); $msgs = $messages; if (!$system) $system = WEVAL_BRAND_CONTEXT.'Tu es un assistant IA.'; if ($system) array_unshift($msgs, ['role'=>'system','content'=>$system]); if (($provider['custom_format'] ?? '') === 'anthropic') { $url = $provider['base_url'].'/messages'; $user_msgs = array_values(array_filter($msgs, fn($m)=>$m['role']!=='system')); $payload = json_encode(['model'=>$model,'max_tokens'=>intval($input['max_tokens']??4096),'system'=>$system?:'You are a helpful assistant.','messages'=>$user_msgs,'stream'=>$stream]); $headers = ['Content-Type: application/json','x-api-key: '.$provider['api_key'],'anthropic-version: 2023-06-01']; } else { $url = $provider['base_url'].'/chat/completions'; $payload = json_encode(['model'=>$model,'messages'=>$msgs,'stream'=>$stream,'max_tokens'=>intval($input['max_tokens']??4096),'temperature'=>floatval($input['temperature']??0.7)]); $headers = ['Content-Type: application/json','Authorization: Bearer '.$provider['api_key']]; } if ($stream) { header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); $ch = curl_init($url); curl_setopt_array($ch, [CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$payload,CURLOPT_HTTPHEADER=>$headers,CURLOPT_RETURNTRANSFER=>false,CURLOPT_TIMEOUT=>120,CURLOPT_SSL_VERIFYPEER=>false, CURLOPT_WRITEFUNCTION=>function($ch,$data){echo $data;if(ob_get_level())ob_flush();flush();return strlen($data);}]); curl_exec($ch); curl_close($ch); } else { $ch = curl_init($url); curl_setopt_array($ch, [CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>$payload,CURLOPT_HTTPHEADER=>$headers,CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>120,CURLOPT_SSL_VERIFYPEER=>false]); $resp = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (($provider['custom_format']??'')==='anthropic') { $d = json_decode($resp, true); if (isset($d['content'][0]['text'])) $resp = json_encode(['choices'=>[['message'=>['role'=>'assistant','content'=>$d['content'][0]['text']]]],'model'=>$d['model']??$model,'usage'=>$d['usage']??[]]); } http_response_code($code?:500); echo $resp; }