&1'); exit; } if ($action === 'analyze') { $reg = json_decode(file_get_contents(__DIR__ . '/growth-engine-registry.json'), true); if (!$reg) { echo json_encode(['error'=>'no registry']); exit; } // Load secrets same way as wevia-json-api.php $secrets = []; foreach (file('/etc/weval/secrets.env', FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES) as $l) { if (empty(trim($l))||$l[0]==='#') continue; $p = strpos($l,'='); if ($p) $secrets[trim(substr($l,0,$p))] = trim(substr($l,$p+1)," \t\"'"); } $summary = array_map(function($a) { return $a['name'].'|'.($a['type']??'?').'|'.($a['status']??'?').'|mat:'.($a['maturity']??'?'); }, $reg['assets']); $prompt = "Inventaire reel des assets techniques. Infra: disque ".$reg['infra']['disk']['pct'].", ".count($reg['assets'])." assets, ".$reg['infra']['crons']." crons, ".$reg['infra']['tool_registry']['count']." tools.\n\nAssets:\n".implode("\n",$summary)."\n\nAnalyse: TOP 5 quick wins revenue (<2sem effort), TOP 3 gaps commercialisation, score maturite 0-100. JSON only: {quick_wins:[],gaps:[],score:N,summary:str}"; $payload = json_encode(['model'=>'llama-3.3-70b','messages'=>[['role'=>'user','content'=>$prompt]],'max_tokens'=>1500,'temperature'=>0.3]); // Try Cerebras $ch = curl_init('https://api.cerebras.ai/v1/chat/completions'); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true, CURLOPT_TIMEOUT=>30, CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.($secrets['CEREBRAS_API_KEY']??'')], CURLOPT_POSTFIELDS=>$payload]); $result = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); $prov = 'Cerebras'; $text = ''; if ($code===200) { $d = json_decode($result,true); $text = $d['choices'][0]['message']['content'] ?? ''; } // Fallback Groq if (!$text) { $payload2 = json_encode(['model'=>'llama-3.3-70b-versatile','messages'=>[['role'=>'user','content'=>$prompt]],'max_tokens'=>1500,'temperature'=>0.3]); $ch = curl_init('https://api.groq.com/openai/v1/chat/completions'); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true, CURLOPT_TIMEOUT=>30, CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.($secrets['GROQ_KEY']??'')], CURLOPT_POSTFIELDS=>$payload2]); $result = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code===200) { $d=json_decode($result,true); $text=$d['choices'][0]['message']['content']??''; $prov='Groq'; } } // Fallback Mistral if (!$text) { $payload3 = json_encode(['model'=>'mistral-small-latest','messages'=>[['role'=>'user','content'=>$prompt]],'max_tokens'=>1500,'temperature'=>0.3]); $ch = curl_init('https://api.mistral.ai/v1/chat/completions'); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_POST=>true, CURLOPT_TIMEOUT=>30, CURLOPT_HTTPHEADER=>['Content-Type: application/json','Authorization: Bearer '.($secrets['MISTRAL_KEY']??'')], CURLOPT_POSTFIELDS=>$payload3]); $result = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($code===200) { $d=json_decode($result,true); $text=$d['choices'][0]['message']['content']??''; $prov='Mistral'; } } echo json_encode(['analysis'=>$text,'provider'=>$prov,'assets'=>count($reg['assets']),'scanned'=>$reg['scanned_at']], JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT); exit; } echo json_encode(['actions'=>['registry','scan','analyze']]);