"no message"]); exit; } // 1. Load tool registry $registry = json_decode(file_get_contents(__DIR__ . "/wevia-tool-registry.json"), true); $tools = $registry["tools"] ?? []; // 2. Build tool catalog for LLM $catalog = "TOOLS DISPONIBLES (appelle-en 1 ou plusieurs):\n"; foreach ($tools as $i => $t) { $catalog .= ($i+1) . ". " . $t["name"] . " — " . $t["desc"] . "\n"; } $catalog .= "\nRéponds UNIQUEMENT en JSON: {\"tools\":[\"tool_name1\",\"tool_name2\"],\"summary\":\"ce que tu fais\"}\n"; $catalog .= "Si aucun outil ne correspond, réponds: {\"tools\":[\"arena_chat\"],\"summary\":\"question generale\"}\n"; // 3. Ask LLM which tools to call (fast: Groq or NIM) $env = []; foreach (file("/etc/weval/secrets.env") as $l) { $l = trim($l); if ($l && $l[0] !== "#" && strpos($l, "=")) { list($k, $v) = explode("=", $l, 2); $env[trim($k)] = trim($v); } } $llm_prompt = $catalog . "\nMessage utilisateur: " . $msg; $tool_names = []; // Try Groq first (fastest) $groq_key = $env["GROQ_KEY"] ?? ""; if ($groq_key) { $ch = curl_init("https://api.groq.com/openai/v1/chat/completions"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_TIMEOUT => 8, CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Authorization: Bearer $groq_key"], CURLOPT_POSTFIELDS => json_encode([ "model" => "llama-3.3-70b-versatile", "messages" => [ ["role" => "system", "content" => "Tu es un routeur. Analyse le message et choisis le(s) outil(s) a appeler. Reponds UNIQUEMENT en JSON valide."], ["role" => "user", "content" => $llm_prompt] ], "max_tokens" => 200, "temperature" => 0 ]) ]); $r = curl_exec($ch); $d = json_decode($r, true); $text = $d["choices"][0]["message"]["content"] ?? ""; // Extract JSON from response if (preg_match("/\{.*\}/s", $text, $m)) { $parsed = json_decode($m[0], true); $tool_names = $parsed["tools"] ?? []; $summary = $parsed["summary"] ?? ""; } } // 4. Execute selected tools $results = []; $base_url = "https://weval-consulting.com"; foreach ($tool_names as $tn) { $tool = null; foreach ($tools as $t) { if ($t["name"] === $tn) { $tool = $t; break; } } if (!$tool) continue; $endpoint = $tool["endpoint"]; $method = $tool["method"] ?? "GET"; // Handle static responses if ($endpoint === "STATIC" && isset($tool["response"])) { $results[$tn] = $tool["response"]; continue; } // Build URL $url = (strpos($endpoint, "http") === 0) ? $endpoint : $base_url . $endpoint; $ch = curl_init($url); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 15, CURLOPT_SSL_VERIFYPEER => false]); if ($method === "POST") { curl_setopt($ch, CURLOPT_POST, true); $body = ["message" => $msg]; if (isset($tool["model"])) $body["model"] = $tool["model"]; if ($tn === "multiagent") $body = ["task" => $msg, "agents" => ["wevia-master", "nim-llama", "alibaba-qwen"]]; curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); } $r = curl_exec($ch); $d = json_decode($r, true); // Extract useful content if (isset($d["content"])) $results[$tn] = $d["content"]; elseif (isset($d["response"])) $results[$tn] = $d["response"]; elseif (isset($d["pass"])) $results[$tn] = "PASS:" . $d["pass"] . "/" . $d["total"] . " (" . $d["pct"] . "%)"; elseif (isset($d["alive"])) $results[$tn] = "ALIVE:" . $d["alive"] . "/" . $d["total"] . " (" . $d["pct"] . "%)"; elseif (isset($d["warming"])) $results[$tn] = "Office: " . $d["warming"] . " warming | " . $d["active"] . " active | " . $d["health"]; elseif (is_string($r) && strlen($r) > 5) $results[$tn] = substr($r, 0, 500); else $results[$tn] = "executed"; } // 5. Format response $output = ""; foreach ($results as $tn => $r) { $output .= strtoupper($tn) . ":\n" . $r . "\n\n"; } echo json_encode([ "content" => trim($output) ?: "Aucun outil correspondant", "tools_called" => array_keys($results), "tools_count" => count($results), "routing" => "LLM tool-use (Groq llama-3.3-70b)", "summary" => $summary ?? "" ]); ?>