true, CURLOPT_POST=>true, CURLOPT_POSTFIELDS=>json_encode(["token"=>$token]), CURLOPT_HTTPHEADER=>["Content-Type: application/json"], CURLOPT_TIMEOUT=>5]); $r = curl_exec($ch); echo json_encode(["status"=>"token_saved","length"=>strlen($token),"ds_web"=>$r?:"ok"]); exit; } if (($raw['action'] ?? '') === 'ds_token_status') { $has = file_exists("/etc/weval/deepseek-web-token.txt") && strlen(trim(@file_get_contents("/etc/weval/deepseek-web-token.txt"))) > 10; echo json_encode(["has_token"=>$has]); exit; } $input = json_decode(file_get_contents("php://input"), true); $message = $input['message'] ?? ''; $mode = $input['mode'] ?? 'instant'; $model = $input['model'] ?? 'auto'; $history = $input['history'] ?? []; $temp = floatval($input['temperature'] ?? 0.7); // === DEEPSEEK WEB DIRECT (port 8901) — FREE UNLIMITED === if ($model === 'deepseek-web' || $model === 'deepseek-web-think' || $model === 'deepseek-web-search') { $ds_mode = 'instant'; if ($model === 'deepseek-web-think' || $mode === 'deepthink') $ds_mode = 'deepthink'; if ($model === 'deepseek-web-search' || $mode === 'search') $ds_mode = 'search'; if ($mode === 'deepthink-search') { $ds_mode = 'deepthink'; } // DeepSeek Web: think takes priority, search via SearXNG $ds_payload = json_encode(["message" => $message, "mode" => $ds_mode], JSON_UNESCAPED_UNICODE); $ch = curl_init("http://localhost:8901/chat"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $ds_payload, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_TIMEOUT => 5 ]); $r = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($code === 200) { $d = @json_decode($r, true); if (isset($d['content'])) { $d['provider'] = 'DeepSeek Web UNLIMITED'; $d['model'] = 'deepseek-web-' . $ds_mode; $d['cost'] = '0€ illimité'; echo json_encode($d); exit; } } // If DeepSeek Web fails (no token), fall through to cascade $model = 'auto'; // FALLTHROUGH: use cascade when DS Web fails } // === GEMINI NATIVE DEEPTHINK (with thinking chain) === if (($mode === 'deepthink' || $mode === 'deepthink-search') && $model !== 'deepseek-web-think') { $env2 = @file_get_contents("/etc/weval/secrets.env") ?: ""; $gkey = ""; if (preg_match("/GEMINI_KEY=(.+)/", $env2, $gm)) $gkey = trim($gm[1]); if ($gkey) { $prompt = $message; // If search mode too, enrich with SearXNG if ($mode === 'deepthink-search') { $enc = urlencode($message); $sch = curl_init("http://localhost:8888/search?q=$enc&format=json&categories=general"); curl_setopt_array($sch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 6]); $sr = curl_exec($sch); $sd = @json_decode($sr, true); $web = []; foreach (array_slice($sd["results"] ?? [], 0, 5) as $wr) { $web[] = $wr["title"] . ": " . substr($wr["content"] ?? "", 0, 120); } if ($web) $prompt .= "\n\nResultats web:\n" . implode("\n", $web); } $payload = json_encode([ "contents" => [["parts" => [["text" => $prompt]]]], "systemInstruction" => ["parts" => [["text" => "Tu es WEVIA DeepSeek en mode DeepThink. COMMENCE TOUJOURS par une section de reflexion entre balises et ou tu raisonnes etape par etape, analyses les hypotheses, explores les pistes. PUIS donne ta reponse finale APRES la balise . Format: \nRaisonnement...\n\nReponse finale."]]], "generationConfig" => [ "thinkingConfig" => ["thinkingBudget" => 2048], "maxOutputTokens" => 4000 ] ], JSON_UNESCAPED_UNICODE); $t0 = microtime(true); $ch = curl_init("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$gkey"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $payload, CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_TIMEOUT => 45, CURLOPT_SSL_VERIFYPEER => false]); $r = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($code === 200) { $d = @json_decode($r, true); $parts = $d["candidates"][0]["content"]["parts"] ?? []; $thinking = ""; $answer = ""; $full = ""; foreach ($parts as $p) { if (isset($p["text"])) $full .= $p["text"]; } // Parse ... tags if (preg_match('/(.*?)<\/think>/s', $full, $tm)) { $thinking = trim($tm[1]); $answer = trim(preg_replace('/.*?<\/think>/s', '', $full)); } else { // Fallback: try to split on even without matching regex if (strpos($full, '') !== false) { $split = explode('', $full, 2); $thinking = trim(str_replace('', '', $split[0])); $answer = trim($split[1] ?? ''); } elseif (strpos($full, '') !== false) { // exists but no closing tag - treat first 40% as thinking $thinking = trim(str_replace('', '', substr($full, 0, intval(strlen($full)*0.4)))); $answer = trim(substr($full, intval(strlen($full)*0.4))); } else { $answer = $full; } } $elapsed = round((microtime(true) - $t0) * 1000); $usage = $d["usageMetadata"] ?? []; echo json_encode([ "content" => $answer ?: ($thinking ?: "No response"), "thinking" => $thinking, "provider" => "Gemini 2.5 Flash DeepThink", "model" => "gemini-2.5-flash-thinking", "mode" => $mode, "tokens" => ($usage["totalTokenCount"] ?? 0), "latency_ms" => $elapsed, "cost" => "0EUR", "has_thinking" => strlen($thinking) > 0 ]); exit; } } } $max_tokens = intval($input['max_tokens'] ?? 2000); if (!$message) { echo json_encode(["error" => "no message"]); exit; } $env = @file_get_contents("/etc/weval/secrets.env") ?: ""; // System prompts by mode $systems = [ 'instant' => "Tu es WEVIA DeepSeek, IA souveraine. Reponds de facon concise et precise.", 'deepthink-search' => "Tu es WEVIA DeepSeek en mode DeepThink+Search. RAISONNE etape par etape ET utilise les resultats de recherche web pour enrichir ton analyse.", 'deepthink' => "Tu es WEVIA DeepSeek en mode DeepThink. RAISONNE etape par etape:\n1. Analyse le probleme\n2. Identifie les hypotheses\n3. Explore chaque piste\n4. Synthetise\n5. Conclus\nSois rigoureux et structure.", 'search' => "Tu es WEVIA DeepSeek avec acces web.", 'expert' => "Tu es WEVIA DeepSeek Expert. PhD-level. Reponds avec rigueur scientifique, citations, formules si necessaire. Profondeur maximale.", 'code' => "Tu es WEVCODE, expert code souverain. Code COMPLET, FONCTIONNEL, documente. Python/PHP/JS/SQL/Bash. Tests inclus.", 'creative' => "Tu es un ecrivain creatif de talent. Style riche, evocateur, immersif. Francais soutenu.", ]; $system = $systems[$mode] ?? $systems['instant']; // Search mode: enrich with SearXNG if ($mode === 'search' || $mode === 'deepthink-search') { $enc = urlencode($message); $ch = curl_init("http://localhost:8888/search?q=$enc&format=json&categories=general"); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8]); $sr = curl_exec($ch); $sd = @json_decode($sr, true); $results = []; foreach (array_slice($sd['results'] ?? [], 0, 6) as $r) { $results[] = "- " . ($r['title'] ?? '') . ": " . substr($r['content'] ?? '', 0, 150); } if ($results) { $system .= "\n\nRESULTATS WEB:\n" . implode("\n", $results) . "\n\nSynthetise ces resultats dans ta reponse."; } } // Model routing $samba_key = ""; $gemini_key = ""; $groq_key = ""; $cerebras_key = ""; if (preg_match("/SAMBANOVA_KEY=(.+)/", $env, $m)) $samba_key = trim($m[1]); if (preg_match("/GEMINI_KEY=(.+)/", $env, $m)) $gemini_key = trim($m[1]); if (preg_match("/GROQ_KEY=(.+)/", $env, $m)) $groq_key = trim($m[1]); if (preg_match("/CEREBRAS_API_KEY=(.+)/", $env, $m)) $cerebras_key = trim($m[1]); // Auto model selection based on mode $model_map = [ 'auto' => [ 'instant' => ['DeepSeek-V3.2', 'samba'], 'deepthink-search' => "Tu es WEVIA DeepSeek en mode DeepThink+Search. RAISONNE etape par etape ET utilise les resultats de recherche web pour enrichir ton analyse.", 'deepthink' => ['DeepSeek-R1-0528', 'samba'], 'search' => ['DeepSeek-V3.2', 'samba'], 'expert' => ['gemini-2.5-pro', 'gemini'], 'code' => ['DeepSeek-V3.2', 'samba'], 'creative' => ['Meta-Llama-3.3-70B-Instruct', 'samba'], ], ]; // Build provider list based on model selection $providers = []; if ($model === 'auto') { $auto = $model_map['auto'][$mode] ?? ['DeepSeek-V3.2', 'samba']; // Primary based on mode if ($auto[1] === 'samba' && $samba_key) { $providers[] = ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => $auto[0], "name" => "SambaNova " . $auto[0]]; } if ($auto[1] === 'gemini' && $gemini_key) { $providers[] = ["url" => "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", "key" => $gemini_key, "model" => $auto[0], "name" => "Google " . $auto[0]]; } // Fallbacks if ($samba_key) $providers[] = ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "DeepSeek-V3.2", "name" => "SambaNova DeepSeek-V3.2"]; if ($gemini_key) $providers[] = ["url" => "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", "key" => $gemini_key, "model" => "gemini-2.5-flash", "name" => "Gemini 2.5 Flash"]; if ($groq_key) $providers[] = ["url" => "https://api.groq.com/openai/v1/chat/completions", "key" => $groq_key, "model" => "llama-3.3-70b-versatile", "name" => "Groq Llama-3.3-70B"]; if ($cerebras_key) $providers[] = ["url" => "https://api.cerebras.ai/v1/chat/completions", "key" => $cerebras_key, "model" => "llama3.1-8b", "name" => "Cerebras Llama-8B"]; } else { // Specific model selected $specific_models = [ 'deepseek-r1' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "DeepSeek-R1-0528"], 'deepseek-v3.2' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "DeepSeek-V3.2"], 'deepseek-v3.1' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "DeepSeek-V3.1"], 'llama-4' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "Llama-4-Maverick-17B-128E-Instruct"], 'gpt-oss-120b' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "gpt-oss-120b"], 'minimax' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "MiniMax-M2.5"], 'gemma-3' => ["url" => "https://api.sambanova.ai/v1/chat/completions", "key" => $samba_key, "model" => "gemma-3-12b-it"], 'gemini-2.5-pro' => ["url" => "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", "key" => $gemini_key, "model" => "gemini-2.5-pro"], 'gemini-2.5-flash' => ["url" => "https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", "key" => $gemini_key, "model" => "gemini-2.5-flash"], 'groq-llama' => ["url" => "https://api.groq.com/openai/v1/chat/completions", "key" => $groq_key, "model" => "llama-3.3-70b-versatile"], ]; if (isset($specific_models[$model])) { $p = $specific_models[$model]; $p["name"] = ucfirst(str_replace('-', ' ', $model)); $providers[] = $p; } } // Adjust max_tokens for DeepThink if ($mode === 'deepthink') $max_tokens = max($max_tokens, 4000); if ($mode === 'expert') $max_tokens = max($max_tokens, 3000); $messages = [["role" => "system", "content" => $system]]; foreach (array_slice($history, -12) as $h) { $messages[] = ["role" => $h['role'], "content" => $h['content']]; } $messages[] = ["role" => "user", "content" => $message]; $t0 = microtime(true); // === TIER 0: DeepSeek Web FREE UNLIMITED === require_once __DIR__ . chr(47) . "deepseek-web-bridge.php"; foreach ($providers as $p) { if (!$p['key']) continue; $data = json_encode(["model" => $p["model"], "messages" => $messages, "max_tokens" => $max_tokens, "temperature" => $temp], JSON_UNESCAPED_UNICODE); $ch = curl_init($p["url"]); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $data, CURLOPT_HTTPHEADER => ["Content-Type: application/json", "Authorization: Bearer " . $p["key"]], CURLOPT_TIMEOUT => 30, CURLOPT_SSL_VERIFYPEER => false]); $r = curl_exec($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($code === 200) { $d = @json_decode($r, true); $content = $d["choices"][0]["message"]["content"] ?? null; $usage = $d["usage"] ?? []; if ($content) { $elapsed = round((microtime(true) - $t0) * 1000); echo json_encode([ "content" => $content, "provider" => $p["name"], "model" => $p["model"], "mode" => $mode, "tokens" => ($usage["total_tokens"] ?? 0), "prompt_tokens" => ($usage["prompt_tokens"] ?? 0), "completion_tokens" => ($usage["completion_tokens"] ?? 0), "latency_ms" => $elapsed, "cost" => "0€" ]); exit; } } } echo json_encode(["error" => "All providers failed", "content" => "Providers indisponibles. Reessayez."]);