Files
html/api/ambre-tool-sql.php
Opus d7871f7f73 feat(wevia-godmode-v3): 17 generators auto-intent router + 7 new premium APIs
NEW GENERATORS (V3 GODMODE):
- ambre-tool-3d.php: Three.js r128 scenes interactives (OrbitControls + anim loop + fog)
- ambre-tool-dataviz.php: Dashboards Plotly.js (3-4 charts + KPI cards + responsive grid)
- ambre-tool-site.php: Landing pages SaaS COMPLETES 10 sections (header/hero/features/pricing/FAQ/footer)
- ambre-tool-sql.php: NL -> SQL multi-dialect (PG/MySQL/SQLite) avec explanation + indexes suggested
- ambre-tool-brainstorm.php: Multi-IA PARALLELE 5 providers (cerebras+groq+sambanova+gemini+cloudflare) + synthese
- ambre-tool-image-gen.php: Text2Image avec cascade sovereign + fallback ambre-image
- ambre-tool-translate-code.php: Code translator multi-langages (Python/JS/TS/Go/Rust/Java/Ruby)

ROUTER V3:
- 17 generators catalogues (4 docs + 7 GODMODE + 6 utilities)
- detectIntent() NL regex français/anglais
- extractPayload() nettoyage intelligent
- Rendering adapte par kind: docx/xlsx/pptx/react (preview panel), 3d (three.js iframe), image (inline img), code (pre+copy btn), json (summary card OR brainstorm providers_used), inline (calc), audio (player)

SAFETY PUBLIC:
- Zero secret WEVAL divulgue dans prompts
- Zero acces vault/credentials/serveurs internes
- Sovereign cascade uniquement (0€ LLM cost)
- Tous prompts contraints 'info generique safe'

TESTED LIVE:
- SQL generator PostgreSQL validated (json_agg + INNER JOIN + GROUP BY)
- DOCX 7 sections + XLSX 3 sheets + PPTX 10 slides + REACT standalone (all previously tested 1d24e243c commit)

17 intents auto-detectes dans wevia.html public widget.
WEVIA public maintenant aussi capable qu'un copilot grand public tout en restant safe sur secrets WEVAL.
2026-04-24 21:44:55 +02:00

80 lines
3.0 KiB
PHP

<?php
/**
* ambre-tool-sql.php — NL → SQL generator
*/
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['ok'=>false,'error'=>'POST only']); exit; }
$input = json_decode(file_get_contents('php://input'), true);
$query = trim($input['query'] ?? $input['topic'] ?? '');
$dialect = $input['dialect'] ?? 'postgresql';
if (strlen($query) < 3) { echo json_encode(['ok'=>false,'error'=>'query too short']); exit; }
$query = substr($query, 0, 800);
$prompt = "Expert SQL $dialect. Traduis la demande en langue naturelle en SQL:\n\n\"$query\"\n\n"
. "Retourne UNIQUEMENT un JSON:\n"
. "{\n"
. " \"sql\": \"SELECT ... FROM ... WHERE ...;\",\n"
. " \"explanation\": \"Bref explication de ce que fait la requete\",\n"
. " \"tables_needed\": [\"table1\",\"table2\"],\n"
. " \"dialect\": \"$dialect\",\n"
. " \"complexity\": \"simple|medium|complex\",\n"
. " \"suggested_indexes\": [\"CREATE INDEX ...\"]\n"
. "}\n\n"
. "IMPORTANT:\n"
. "- SQL valide et optimise\n"
. "- Utiliser jointures appropriees (INNER/LEFT/RIGHT)\n"
. "- Mettre ORDER BY si sens\n"
. "- Preciser LIMIT si pertinent\n"
. "- Si agrecation, utiliser GROUP BY + HAVING\n"
. "- Explanation en francais\n"
. "- JSON UNIQUEMENT, aucun texte avant/apres";
$ch = curl_init('http://127.0.0.1:4000/v1/chat/completions');
curl_setopt_array($ch, [
CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => json_encode([
'model' => 'auto',
'messages' => [['role'=>'user', 'content'=>$prompt]],
'max_tokens' => 2000, 'temperature' => 0.3
]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_TIMEOUT => 60,
]);
$resp = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http !== 200) { echo json_encode(['ok'=>false,'error'=>"LLM HTTP $http"]); exit; }
$data = json_decode($resp, true);
$content_raw = $data['choices'][0]['message']['content'] ?? '';
// Balanced JSON extract
if (preg_match('/```(?:json)?\s*\n?(.*?)\n?```/s', $content_raw, $m)) { $content_raw = $m[1]; }
$jstart = strpos($content_raw, '{');
if ($jstart !== false) {
$depth = 0; $jend = -1;
for ($i = $jstart; $i < strlen($content_raw); $i++) {
if ($content_raw[$i] === '{') $depth++;
elseif ($content_raw[$i] === '}') { $depth--; if ($depth === 0) { $jend = $i; break; } }
}
if ($jend > $jstart) $content_raw = substr($content_raw, $jstart, $jend - $jstart + 1);
}
$result = json_decode($content_raw, true);
if (!$result || !isset($result['sql'])) {
echo json_encode(['ok'=>false,'error'=>'invalid JSON','raw'=>substr($content_raw,0,300)]); exit;
}
echo json_encode([
'ok' => true,
'sql' => $result['sql'],
'explanation' => $result['explanation'] ?? '',
'tables_needed' => $result['tables_needed'] ?? [],
'dialect' => $result['dialect'] ?? $dialect,
'complexity' => $result['complexity'] ?? 'medium',
'suggested_indexes' => $result['suggested_indexes'] ?? [],
'result' => $result['sql'], // for inline kind render
]);