'Auth required'])." data: [DONE] ";exit;} $q=$_GET['q']??''; if(!$q){echo "data: ".json_encode(['t'=>'No query'])." data: [DONE] ";exit;} $env=[]; foreach(file('/etc/weval/secrets.env',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $l){ if($l[0]==='#'||!strpos($l,'='))continue; [$k,$v]=explode('=',$l,2); $env[trim($k)]=trim($v,'" '); } $sys="'.WEVAL_BRAND_CONTEXT.'Tu es L99 Brain, l'IA souveraine de WEVAL Consulting. Expert DevOps, Lean Six Sigma, architecture cloud. Reponds en francais, concis et actionnable."; $msgs=[['role'=>'system','content'=>$sys],['role'=>'user','content'=>$q]]; // Cascade: Groq → Cerebras → Ollama $providers=[ ['n'=>'SambaNova','u'=>'https://api.sambanova.ai/v1/chat/completions','k'=>$env['SAMBANOVA_KEY']??'','m'=>'Llama-4-Maverick-17B-128E-Instruct'], ['n'=>'SambaNova','u'=>'https://api.sambanova.ai/v1/chat/completions','k'=>$env['SAMBANOVA_KEY']??'','m'=>'Meta-Llama-3.3-70B-Instruct'], ['n'=>'Groq','u'=>'https://api.groq.com/openai/v1/chat/completions','k'=>$env['GROQ_KEY']??'','m'=>'moonshotai/kimi-k2-instruct'], ['n'=>'Mistral','u'=>'https://api.mistral.ai/v1/chat/completions','k'=>$env['MISTRAL_KEY']??'','m'=>'mistral-small-latest'], ['n'=>'Cerebras','u'=>'https://api.cerebras.ai/v1/chat/completions','k'=>$env['CEREBRAS_API_KEY']??'','m'=>'qwen-3-235b-a22b-instruct-2507'], ['n'=>'Groq','u'=>'https://api.groq.com/openai/v1/chat/completions','k'=>$env['GROQ_KEY']??'','m'=>'llama-3.3-70b-versatile'], ]; foreach($providers as $p){ if(!$p['k'])continue; $ch=curl_init($p['u']); curl_setopt_array($ch,[ CURLOPT_POST=>1, CURLOPT_POSTFIELDS=>json_encode(['model'=>$p['m'],'messages'=>$msgs,'stream'=>true,'max_tokens'=>1500]), CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.$p['k']], CURLOPT_RETURNTRANSFER=>0,CURLOPT_TIMEOUT=>25, CURLOPT_WRITEFUNCTION=>function($c,$d)use($p){ foreach(explode(" ",$d) as $line){ $line=trim($line); if(!$line||$line==='data: [DONE]')continue; if(strpos($line,'data: ')===0)$line=substr($line,6); $j=@json_decode($line,1); if(!$j)continue; $t=$j['choices'][0]['delta']['content']??''; if($t){echo "data: ".json_encode(['t'=>$t,'p'=>$p['n']])." ";@ob_flush();flush();} } return strlen($d); } ]); $ok=curl_exec($ch); $code=curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); if($code>=200&&$code<400){echo "data: [DONE] ";exit;} } // Fallback: Ollama local $ch2=curl_init('http://127.0.0.1:11434/api/chat'); curl_setopt_array($ch2,[ CURLOPT_POST=>1, CURLOPT_POSTFIELDS=>json_encode(['model'=>'qwen3:8b','messages'=>$msgs,'stream'=>true]), CURLOPT_HTTPHEADER=>['Content-Type: application/json'], CURLOPT_RETURNTRANSFER=>0,CURLOPT_TIMEOUT=>30, CURLOPT_WRITEFUNCTION=>function($c,$d){ foreach(explode(" ",$d) as $line){ $j=@json_decode(trim($line),1); if($j&&isset($j['message']['content'])){ echo "data: ".json_encode(['t'=>$j['message']['content'],'p'=>'Ollama'])." "; @ob_flush();flush(); } } return strlen($d); } ]); curl_exec($ch2);curl_close($ch2); echo "data: [DONE] ";