['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'], 'ollama-s204' => ['name'=>'Ollama S204 Sovereign','tier'=>'sovereign','speed'=>'slow', 'base_url'=>'http://localhost:11434/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://151.80.235.110:11434/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'] ?? 'groq'; $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) $model = array_key_first($provider['models']); $msgs = $messages; 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; }