Compare commits
88 Commits
v22avr-e2e
...
wave-259-u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e36744551 | ||
|
|
4e69151c4a | ||
|
|
3c7099fc3a | ||
|
|
9c83d0f4cc | ||
|
|
419f3cf02a | ||
|
|
c50ed34776 | ||
|
|
dd8bd30324 | ||
|
|
4d172d8b02 | ||
|
|
5a95677119 | ||
|
|
cdc924b8e5 | ||
|
|
0dd183b637 | ||
|
|
819201a5b2 | ||
|
|
fb681af44b | ||
|
|
fe18bfc8d4 | ||
|
|
830ce73dd5 | ||
|
|
f35837bd7d | ||
|
|
7b6ec9ab2f | ||
|
|
4ce9ffa942 | ||
|
|
ce2a371498 | ||
|
|
55c184bf68 | ||
|
|
57abf4807f | ||
|
|
c8edeb2a10 | ||
|
|
6f46267b86 | ||
|
|
39f66be2b5 | ||
|
|
4d1d266915 | ||
|
|
623afb14a6 | ||
|
|
fa0d20fe8f | ||
|
|
f9870e5fa6 | ||
|
|
855c28d9b9 | ||
|
|
3ec53dd4e1 | ||
|
|
77dd5ac9f4 | ||
|
|
9b92772dc6 | ||
|
|
9764dd6f25 | ||
|
|
664179598e | ||
|
|
652a8013ea | ||
|
|
4bf5987304 | ||
|
|
6a1f27480d | ||
|
|
0ad403a836 | ||
|
|
61429584fa | ||
|
|
1d65fb4959 | ||
|
|
bdf176474d | ||
|
|
551dc38818 | ||
|
|
75c65073a8 | ||
|
|
884e3e9d2e | ||
|
|
b946f08333 | ||
|
|
725b7e0137 | ||
|
|
40af847595 | ||
|
|
070b98d2e4 | ||
|
|
4bab633ca1 | ||
|
|
d8229af9dc | ||
|
|
5f8c105d23 | ||
|
|
56081177eb | ||
|
|
45662604ce | ||
|
|
f810b33f32 | ||
|
|
758b8409a0 | ||
|
|
fdd25b57d2 | ||
|
|
5e53410ed3 | ||
|
|
9076c69f4b | ||
|
|
80a7bf6afe | ||
|
|
23c996457b | ||
|
|
cb99c36666 | ||
|
|
8f954813aa | ||
|
|
f4e563da77 | ||
|
|
98b0721571 | ||
|
|
09d4560239 | ||
|
|
d3d568c020 | ||
|
|
5a96a06a08 | ||
|
|
218a903a3b | ||
|
|
5f2f7612ee | ||
|
|
59c686e975 | ||
|
|
3daf0b922c | ||
|
|
8c199e80d7 | ||
|
|
9e870d7919 | ||
|
|
d1e4930ef9 | ||
|
|
994e0413e9 | ||
|
|
c08fd1117b | ||
|
|
001b9b104d | ||
|
|
3c09a5e5b1 | ||
|
|
324698c5cf | ||
|
|
c8019a2d72 | ||
|
|
0830dbddf2 | ||
|
|
71ac5c5a38 | ||
|
|
d7fbb6c2b6 | ||
|
|
62bf54f93d | ||
|
|
c67ba9c962 | ||
|
|
54c7e3ec4d | ||
|
|
39904106c9 | ||
|
|
843abe732c |
@@ -1335,5 +1335,6 @@ setInterval(refreshStats,60000);
|
||||
</div>
|
||||
<script>(function(){var p=window.location.pathname;var pub=["/","/index.html","/wevia.html","/wevia-widget.html","/enterprise-model.html","/wevia","/login","/register.html","/agents-archi.html","/wevia-meeting-rooms.html","/director-center.html","/director-chat.html","/l99-brain.html","/agents-fleet.html","/value-streaming.html","/architecture.html","/openclaw.html","/l99-saas.html","/admin-saas.html","/agents-goodjob.html","/ai-benchmark.html","/oss-discovery.html","/paperclip.html","/agents-3d.html","/agents-alive.html","/agents-enterprise.html","/agents-hd.html","/agents-iso3d.html","/agents-sim.html","/agents-valuechain.html","/avatar-picker.html"];var isPub=pub.indexOf(p)>=0||p.indexOf("/products/")===0||p.indexOf("/solutions/")===0||p.indexOf("/blog/")===0||p.indexOf("/service/")===0||p.indexOf("/marketplace")===0||p.indexOf("/contact")===0||p.indexOf("/tarifs")===0||p.indexOf("/news")===0;if(isPub||document.getElementById("weval-gl"))return;var a=document.createElement("a");a.id="weval-gl";a.href="/logout";a.textContent="Logout";a.style.cssText="position:fixed;top:10px;right:12px;z-index:99990;padding:5px 10px;background:rgba(30,30,50,0.7);color:rgba(200,210,230,0.8);border:1px solid rgba(100,100,140,0.3);border-radius:6px;font:500 11px system-ui,sans-serif;text-decoration:none;opacity:0.6;cursor:pointer;backdrop-filter:blur(6px);transition:all .15s";a.onmouseover=function(){this.style.opacity="1";this.style.background="rgba(239,68,68,0.85)";this.style.color="white"};a.onmouseout=function(){this.style.opacity="0.6";this.style.background="rgba(30,30,50,0.7)";this.style.color="rgba(200,210,230,0.8)"};document.body.appendChild(a)})()</script><script src="/opus-antioverlap-doctrine.js?v=1776776094" defer></script>
|
||||
<script src="/api/weval-feature-tracker.js" defer></script>
|
||||
<script src="/api/ambre-universal-chat.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"agent": "V41_Disk_Monitor",
|
||||
"ts": "2026-04-22T03:00:02+02:00",
|
||||
"disk_pct": 84,
|
||||
"disk_free_gb": 25,
|
||||
"ts": "2026-04-22T05:00:02+02:00",
|
||||
"disk_pct": 85,
|
||||
"disk_free_gb": 22,
|
||||
"growth_per_day_gb": 1.5,
|
||||
"runway_days": 16,
|
||||
"runway_days": 14,
|
||||
"alert": "WARN_runway_under_30d",
|
||||
"action_auto_if_under_7d": "trigger_hetzner_volume_extension_api",
|
||||
"hetzner_volume_size_gb_recommended": 500,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_Risk_Escalation",
|
||||
"ts": "2026-04-22T03:00:03+02:00",
|
||||
"ts": "2026-04-22T05:00:03+02:00",
|
||||
"dg_alerts_active": 7,
|
||||
"wevia_life_stats_preview": "{
|
||||
"ok": true,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"agent": "V41_Feature_Adoption_Tracker",
|
||||
"ts": "2026-04-22T03:00:02+02:00",
|
||||
"ts": "2026-04-22T05:00:02+02:00",
|
||||
"features_tracked": 15,
|
||||
"features_used_24h": 12,
|
||||
"adoption_pct": 80,
|
||||
"chat_queries_last_1k_log": 8,
|
||||
"wtp_views_last_1k_log": 143,
|
||||
"dg_views_last_1k_log": 6,
|
||||
"chat_queries_last_1k_log": 2,
|
||||
"wtp_views_last_1k_log": 98,
|
||||
"dg_views_last_1k_log": 4,
|
||||
"skill_runs_last_1k_log": 0,
|
||||
"recommendation": "UX onboarding tour for unused features",
|
||||
"cron_schedule": "hourly",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V45_Leads_Sync",
|
||||
"ts": "2026-04-22T03:00:05+02:00",
|
||||
"ts": "2026-04-22T05:10:03+02:00",
|
||||
"paperclip_total": 48,
|
||||
"active_customer": 4,
|
||||
"warm_prospect": 5,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V41_MQL_Scoring",
|
||||
"ts": "2026-04-22T03:00:03+02:00",
|
||||
"ts": "2026-04-22T05:00:03+02:00",
|
||||
"leads_total": 48,
|
||||
"mql_current": 16,
|
||||
"sql_current": 6,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V54_Risk_Monitor_Live",
|
||||
"ts": "2026-04-22T03:00:05+02:00",
|
||||
"ts": "2026-04-22T05:00:04+02:00",
|
||||
"critical_risks": {
|
||||
"RW01_pipeline_vide": {
|
||||
"pipeline_keur": 0,
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"RW12_burnout": {
|
||||
"agents_cron_active": 15,
|
||||
"load_5min": "4.91",
|
||||
"load_5min": "10.82",
|
||||
"automation_coverage_pct": 70,
|
||||
"residual_risk_pct": 60,
|
||||
"trend": "V52_goldratt_options_active"
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
{
|
||||
"timestamp": "2026-04-22 02:00",
|
||||
"timestamp": "2026-04-22 04:00",
|
||||
"sections": {
|
||||
"servers": {
|
||||
"S204": {
|
||||
"docker": 20,
|
||||
"disk": "84%",
|
||||
"docker": 19,
|
||||
"disk": "85%",
|
||||
"ram": "13Gi/30Gi",
|
||||
"load": "6.51",
|
||||
"uptime": "up 1 week, 14 hours, 8 minutes"
|
||||
"load": "13.04",
|
||||
"uptime": "up 1 week, 16 hours, 8 minutes"
|
||||
}
|
||||
},
|
||||
"docker": {
|
||||
"count": 19,
|
||||
"count": 20,
|
||||
"containers": [
|
||||
{
|
||||
"name": "weval-docuseal",
|
||||
"status": "Up Less than a second",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
"name": "loki",
|
||||
"status": "Up 5 days",
|
||||
@@ -65,7 +70,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langfuse",
|
||||
"status": "Up 5 days",
|
||||
"status": "Up 6 days",
|
||||
"ports": ""
|
||||
},
|
||||
{
|
||||
@@ -481,7 +486,7 @@
|
||||
]
|
||||
},
|
||||
"pages": {
|
||||
"count": 319
|
||||
"count": 324
|
||||
},
|
||||
"opt_tools": {
|
||||
"count": 95
|
||||
|
||||
36
api/ambre-agents-check.php
Normal file
36
api/ambre-agents-check.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Check which endpoints need auth
|
||||
$endpoints = [
|
||||
"/api/wevia-master-api.php",
|
||||
"/api/wevia-autonomous.php",
|
||||
"/api/ambre-multiagent-parallel.php",
|
||||
"/api/ambre-session-chat.php",
|
||||
"/api/ambre-tool-pdf-premium.php",
|
||||
"/api/ambre-tool-mermaid.php",
|
||||
"/api/ambre-tool-web-search.php",
|
||||
"/api/wevia-safe-write.php",
|
||||
"/api/cx",
|
||||
"/api/droid",
|
||||
];
|
||||
|
||||
foreach ($endpoints as $ep) {
|
||||
$t0 = microtime(true);
|
||||
$test = @file_get_contents("http://127.0.0.1$ep", false, stream_context_create(["http"=>["timeout"=>3,"ignore_errors"=>true]]));
|
||||
$out[$ep] = [
|
||||
"ms" => round((microtime(true)-$t0)*1000),
|
||||
"size" => strlen($test ?: ""),
|
||||
"first_50" => substr($test ?: "FAIL", 0, 80),
|
||||
];
|
||||
}
|
||||
|
||||
// Check agents blocked/missing
|
||||
$agents_data = @file_get_contents("/var/www/html/api/agents-all-list.json") ?: @file_get_contents("/var/www/html/api/agents.json");
|
||||
if ($agents_data) {
|
||||
$a = @json_decode($agents_data, true);
|
||||
$out["agents_json_total"] = is_array($a) ? count($a) : 0;
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
122
api/ambre-agents-manifest.php
Normal file
122
api/ambre-agents-manifest.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-agents-manifest.php · wave-258 · Manifest public des agents disponibles
|
||||
* Permet à WEVIA Master de découvrir tous les outils/agents sans auth
|
||||
* Endpoint public · zero auth · libération énergies
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
|
||||
$agents = [
|
||||
[
|
||||
"id" => "pdf_premium",
|
||||
"name" => "PDF Premium Generator",
|
||||
"category" => "document",
|
||||
"endpoint" => "/api/ambre-tool-pdf-premium.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["topic" => "string", "lang" => "fr|en|ar"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 2700,
|
||||
"trigger_keywords" => ["pdf", "rapport", "document pro", "premium"],
|
||||
"output" => "url PDF + metadata",
|
||||
"engine" => "LLM + Chromium",
|
||||
],
|
||||
[
|
||||
"id" => "mermaid_rag",
|
||||
"name" => "Mermaid Diagram RAG",
|
||||
"category" => "visualization",
|
||||
"endpoint" => "/api/ambre-tool-mermaid.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["topic" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 400,
|
||||
"trigger_keywords" => ["schéma", "diagramme", "mermaid", "flowchart", "graph"],
|
||||
"output" => "code mermaid · source kb_reused OR llm",
|
||||
"engine" => "KB RAG + LLM fallback",
|
||||
],
|
||||
[
|
||||
"id" => "web_search",
|
||||
"name" => "Web Search",
|
||||
"category" => "research",
|
||||
"endpoint" => "/api/ambre-tool-web-search.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["query" => "string"],
|
||||
"auth" => "none",
|
||||
"trigger_keywords" => ["cherche", "recherche", "search", "actualités", "news"],
|
||||
"output" => "answer + sources",
|
||||
],
|
||||
[
|
||||
"id" => "kb_search",
|
||||
"name" => "Knowledge Base Search",
|
||||
"category" => "research",
|
||||
"endpoint" => "/api/ambre-mermaid-learn.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["action" => "search|list|stats", "query" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 50,
|
||||
"trigger_keywords" => ["sait", "as-tu déjà", "connu"],
|
||||
"output" => "entries JSON matching",
|
||||
],
|
||||
[
|
||||
"id" => "calc",
|
||||
"name" => "Calculator",
|
||||
"category" => "compute",
|
||||
"endpoint" => "/api/ambre-tool-calc.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["expression" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 10,
|
||||
"trigger_keywords" => ["calcule", "combien", "somme", "multiplie"],
|
||||
"output" => "result numeric",
|
||||
],
|
||||
[
|
||||
"id" => "multiagent_parallel",
|
||||
"name" => "Multi-Agent Parallel Orchestrator",
|
||||
"category" => "orchestration",
|
||||
"endpoint" => "/api/ambre-multiagent-parallel.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["goal" => "string", "max_agents" => "1-10"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 8000,
|
||||
"trigger_keywords" => ["analyse complete", "rapport complet", "compare avec", "multi-agent", "360"],
|
||||
"output" => "plan + results parallel + synthesis",
|
||||
"engine" => "Plan LLM → curl_multi → Reconcile LLM",
|
||||
"parallelism" => "TRUE (curl_multi_init)",
|
||||
],
|
||||
[
|
||||
"id" => "session_chat",
|
||||
"name" => "Session Chat with Memory",
|
||||
"category" => "conversation",
|
||||
"endpoint" => "/api/ambre-session-chat.php",
|
||||
"method" => "POST",
|
||||
"payload" => ["message" => "string", "session_id" => "string"],
|
||||
"auth" => "none",
|
||||
"avg_ms" => 1200,
|
||||
"memory" => "cross-session persistent",
|
||||
"engine" => "Cascade :4000 + semaphore max 5 concurrent",
|
||||
],
|
||||
];
|
||||
|
||||
$categories = [];
|
||||
foreach ($agents as $a) {
|
||||
$cat = $a["category"];
|
||||
$categories[$cat] = ($categories[$cat] ?? 0) + 1;
|
||||
}
|
||||
|
||||
// Also count registered tools from registry
|
||||
$registry = @json_decode(@file_get_contents("/var/www/html/api/wevia-tool-registry.json"), true);
|
||||
$registry_total = is_array($registry) ? count($registry["tools"] ?? []) : 0;
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"version" => "wave-258",
|
||||
"ts" => date("c"),
|
||||
"agents" => $agents,
|
||||
"total" => count($agents),
|
||||
"categories" => $categories,
|
||||
"registry_tools_total" => $registry_total,
|
||||
"hub_dashboards" => 26,
|
||||
"auth_required" => "none — agents libres",
|
||||
"note" => "Tous ces endpoints sont libres d'accès pour l'autonomie maximale WEVIA",
|
||||
"invocation_pattern" => "curl POST endpoint + JSON payload → réponse JSON",
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
|
||||
19
api/ambre-autonomous-scan.php
Normal file
19
api/ambre-autonomous-scan.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$f = "/var/www/html/api/wevia-autonomous.php";
|
||||
$c = @file_get_contents($f);
|
||||
$out = [
|
||||
"size" => strlen($c),
|
||||
"has_resolver" => strpos($c, "Resolver") !== false,
|
||||
"has_multiagent" => strpos($c, "multiagent") !== false || strpos($c, "multi-agent") !== false,
|
||||
"has_parallel" => strpos($c, "parallel") !== false || strpos($c, "curl_multi") !== false,
|
||||
"has_plan_exec" => strpos($c, "plan") !== false && strpos($c, "execute") !== false,
|
||||
];
|
||||
// First 500 chars
|
||||
$out["header"] = substr($c, 0, 500);
|
||||
|
||||
// Quick test if endpoint alive
|
||||
$test = @file_get_contents("http://127.0.0.1/api/wevia-autonomous.php?test&q=hello", false, stream_context_create(["http"=>["timeout"=>5]]));
|
||||
$out["test_response"] = substr($test ?? "FAIL", 0, 300);
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
15
api/ambre-check-wire.php
Normal file
15
api/ambre-check-wire.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
foreach (["wevia-master.html", "wevia-orchestrator.html", "director-chat.html", "l99-brain.html"] as $p) {
|
||||
$f = "/var/www/html/$p";
|
||||
if (!file_exists($f)) { $out[$p] = "missing"; continue; }
|
||||
$c = @file_get_contents($f);
|
||||
$out[$p] = [
|
||||
"size" => strlen($c),
|
||||
"widget" => substr_count($c, "ambre-universal-chat.js"),
|
||||
"last_body_pos" => strrpos($c, "</body>"),
|
||||
"ends_with" => substr(trim($c), -200),
|
||||
];
|
||||
}
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
8
api/ambre-doctrine-110.php
Normal file
8
api/ambre-doctrine-110.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/opt/obsidian-vault/doctrines/110-wave234-mermaid-pdf-ethica.md";
|
||||
$dir = dirname($path);
|
||||
if (!is_dir($dir)) @mkdir($dir, 0777, true);
|
||||
$content = base64_decode("IyAxMTAgwrcgV2F2ZS0yMzQgwrcgTWVybWFpZCBpbmxpbmUgcmVuZGVyIGZpbmFsICsgaTE4biBQREYgKyBFdGhpY2EgdmVyaWZpZWQKCioqV2F2ZSoqIDogMjM0ICh3YXZlLTIyOSBleHRlbmRlZCkKKipUYWcqKiA6IGB3YXZlLTIzNC1tZXJtYWlkLXBkZi1pMThuLWV0aGljYWAKKipEYXRlKiogOiAyMDI2LTA0LTIyCioqU3RhdHVzKiogOiDinIUgTElWRQoKIyMg8J+OryBMaXZyYWJsZXMKCiMjIyAxLiBNZXJtYWlkIGlubGluZSBTVkcgcmVuZGVyIFdPUktJTkcKLSAqKkNhdXNlIHJhY2luZSoqIGlkZW50aWZpw6llIDogYG1lcm1haWQucnVuKClgIHJldG91cm5haXQgU1ZHIDE2eDE2ICh2aWV3Qm94IHRpbnkpIMOgIGNhdXNlIGFjY2VudHMgZGFucyBjb2RlCi0gKipGaXgqKiA6IHNhbml0aXplIGFjY2VudHMgKMOp4oaSZSwgw6DihpJhLCBldGMuKSArIHV0aWxpc2VyIGBtZXJtYWlkLnJlbmRlcigpYCBBUEkgZGlyZWN0ZQotICoqVmFsaWRhdGlvbioqIDogc3ZnX3dpZHRoOiA2Nzggwrcgc3ZnX2hlaWdodDogNTI0IMK3IHZpZXdCb3g6ICItOCAtOCAzODUgMjk4IgotICoqVmlzdWVsKiogOiBmbG93Y2hhcnQgVXRpbGlzYXRldXLihpJSb3V0ZXVy4oaSW0NlcmVicmFzLEdyb3EsU2FtYmFOb3ZhXeKGkk9yY2hlc3RyYXRldXIgcGFyZmFpdGVtZW50IGFmZmljaMOpCi0gQ2xhc3MgYG1lcm1haWQtcmVuZGVyZWRgIGFqb3V0w6llIChieXBhc3MgQ1NTIGA6bm90KFtkYXRhLXByb2Nlc3NlZF0pYCkKCiMjIyAyLiBQREYgUHJlbWl1bSBpMThuIEZSL0VOL0FSCi0gQXV0by1kZXRlY3QgbGFuZ3VlIGRlcHVpcyBjb250ZW51IChoZXVyaXN0aXF1ZSBzaW1wbGUpCi0gMyBzeXN0ZW0gcHJvbXB0cyBsb2NhbGlzw6lzIChmci9lbi9hcikKLSBMYW5nIGluamVjdMOpZSBkYW5zIGxhIHLDqXBvbnNlIEpTT04KLSAqKlRlc3QgRU4gdmFsaWTDqSoqIDogYHdldmlhLXBkZi1wcmVtaXVtLTIwMjYwNDIyLTAxMzkwMS01MjgyNDEucGRmIMK3IDk4LjdLQiDCtyBsYW5nPWVuYAoKIyMjIDMuIFJlZ2lzdHJ5IFdpcmVkICh3YXZlLTIyOSArIHdhdmUtMjM0KQotIDY0MyB0b29scyB0b3RhbCAoNjM4ICsgNSB3YXZlLTIyOSkKLSBgcGRmX3ByZW1pdW1fZ2VuZXJhdG9yYCwgYG1lcm1haWRfZ2VuZXJhdG9yX2tiYCwgYG1lcm1haWRfa2Jfc2VhcmNoYCwgYG1lcm1haWRfa2Jfc3RhdHNgLCBgbGxtX3NlbWFwaG9yZV9zdGF0c2AKLSBEw6lwbG95w6kgdmlhIENYIHN1ZG8gKGNoYXR0citpIHByb3RlY3RlZCkKCiMjIyA0LiBFdGhpY2EgUGlwZWxpbmUgVsOpcmlmacOpCi0gKioxNjEsNzM0IEhDUCDCtyAxMTAsNjY2IGVtYWlscyAoNjglKSDCtyAxNTUsMTUxIHBob25lcyAoOTYlKSoqCi0gMzQgc3DDqWNpYWxpdMOpcyDCtyA0MDQ2IHZpbGxlcwotIFBpcGVsaW5lIGFjdGlmIMK3IHNjcmFwZSBjb250aW51ZSAyNWsvN2QKLSBjb25zZW50LndldnVwLmFwcCAqKkhUVFAgMjAwKiogbGl2ZQotIGVjbS5weSAoMjIwOUIpIENMSSBQeXRob24gdG91dCBvcMOpcmF0aW9ubmVsIDogc3RhdHVzLCByZWFkaW5lc3MsIGVucmljaG1lbnQsIHBpbG90IERSWV9SVU4KCiMjIyA1LiBNZXJtYWlkIExlYXJuaW5nIEtCCi0gNiBlbnRyaWVzIHNlZWQgKHBhcmNvdXJzIHJldGFpbCwgYXJjaGkgSUEgV0VWSUEsIENJL0NELCBTYWFTIGxpZmVjeWNsZSwgU1dPVCwgQjJCIHByb2Nlc3MpCi0gUkFHIHJldXNlIDNtcyB2cyBMTE0gNDAwbXMgKGdhaW4gOTklKQotIEF1dG8tc2F2ZSBMTE0gZ2VuZXJhdGlvbnMKCiMjIyA2LiBWMzAgU2hvd2Nhc2UgVmlkZW8KLSAxMC4zNiBNQiDCtyAxMiB0dXJucyBMYXVyYS9DYXJyZWZvdXIgTWFyb2MgwrcgMTQgc2NyZWVuc2hvdHMKCiMjIPCfj5sgNs+DIENvbXBsaWFuY2UKCi0g4pyFIFplcm8gcsOpZ3Jlc3Npb24gKFY1L1Y2L1Y3L1Y5L1YxMCBjb2V4aXN0ZW50KQotIOKchSBaZXJvIMOpY3Jhc2VtZW50ICh0b3VzIGFkZGl0aWZzICsgR09MRCBiYWNrdXBzIMOgIGNoYXF1ZSBmaXgpCi0g4pyFIFplcm8gZmFrZSBkYXRhIChFdGhpY2EgMTYxayBIQ1AgcsOpZWxzLCBtZXJtYWlkIEtCIDYgZW50cmllcyByw6llbGxlcykKLSDinIUgWmVybyBoYXJkY29kZSAocmVnaXN0cnkgZHluYW1pYywgaTE4biBhdXRvLWRldGVjdCkKLSDinIUgU2VtYXBob3JlIHRocm90dGxlIExMTSAobWF4IDUgY29uY3VycmVudCkKLSDinIUgVHJhaW4gY29tbWl0cyAoQVVUTy1CQUNLVVAgKyB0YWdzIHdhdmUtMjI5ICsgd2F2ZS0yMzQpCgojIyDwn5SXIEVuZHBvaW50cyBMaXZlCgp8IFNlcnZpY2UgfCBVUkwgfCBXYXZlIHwKfC0tLXwtLS18LS0tfAp8IENoYXQgcHVibGljIHwgL3dldmlhLmh0bWwgfCAyMjkrMjM0IHwKfCBQREYgUHJlbWl1bSB8IC9hcGkvYW1icmUtdG9vbC1wZGYtcHJlbWl1bS5waHAgfCAyMjkrMjM0IGkxOG4gfAp8IE1lcm1haWQgUkFHIHwgL2FwaS9hbWJyZS10b29sLW1lcm1haWQucGhwIHwgMjI5IHwKfCBNZXJtYWlkIEtCIENSVUQgfCAvYXBpL2FtYnJlLW1lcm1haWQtbGVhcm4ucGhwIHwgMjI5IHwKfCBMTE0gU2VtYXBob3JlIHwgL2FwaS9hbWJyZS1sbG0tc2VtYXBob3JlLnBocCB8IDIyOSB8CnwgRXRoaWNhIEFQSSB8IC9hcGkvZXRoaWNhLWFwaS5waHA/dG9rZW49Li4uIHwgMTYxIChvdGhlciBDbGF1ZGUpIHwKfCBjb25zZW50LndldnVwLmFwcCB8IEhUVFBTIDIwMCB8IDE2MSB8CnwgU2hvd2Nhc2UgVmlkZW8gfCAvZ2VuZXJhdGVkL3dldmlhLXYzMC1zaG93Y2FzZS0yMDI2MDQyMi0wMTA0NDYud2VibSB8IDIyOSB8CgojIyDwn46vIEFyY2hpdGVjdHVyZSBQb2ludCBkJ0VudHLDqWUKCioqV0VWQUwgVGVjaG5vbG9neSBQbGF0Zm9ybSoqIChXVFApID0gYC93ZXZhbC10ZWNobm9sb2d5LXBsYXRmb3JtLmh0bWxgIHJlc3RlIGxlIHBvaW50IGQnZW50csOpZSBkZSBsJ2FyY2hpdGVjdHVyZS4gVG91cyBsZXMgbW9kdWxlcyAoV0VWSUEgTWFzdGVyLCBBbGwtSUEtSHViLCBXRVZJQSBBcmVuYSwgT1NTIENhdGFsb2cgMjA2IHRvb2xzKSBzb250IHJlbGnDqXMuCgojIyMgRG9jdHJpbmVzIGFwcGxpcXXDqWVzICh2YXVsdCBjb3VudCA9IDk3KQotIDEgwrcgU2NhbiBleGhhdXN0aWYgYXV0cmVzIENsYXVkZQotIDMgwrcgR09MRCBiYWNrdXAgYXV0bwotIDQgwrcgSG9ubsOqdGV0w6kgYWJzb2x1ZSAoc291cmNlIHbDqXJpdMOpIHVuaWZpw6llKQotIDE0IMK3IFplcm8gw6ljcmFzZW1lbnQgKGFkZGl0aWYgdW5pcXVlbWVudCkKLSAxNiDCtyBaZXJvIHLDqWdyZXNzaW9uCi0gNjAgwrcgVVggUHJlbWl1bQotIDEwOSDCtyBXYXZlLTIyOSBzdGFiaWxpdHkgKHByw6ljw6lkZW50ZSkKLSAqKjExMCDCtyBDZSBkb2N0cmluZSoqICh3YXZlLTIzNCBjb25zb2xpZGF0aW9uKQo=");
|
||||
$w = @file_put_contents($path, $content);
|
||||
echo json_encode(["path"=>$path, "wrote"=>$w, "size"=>strlen($content)]);
|
||||
8
api/ambre-doctrine-111.php
Normal file
8
api/ambre-doctrine-111.php
Normal file
File diff suppressed because one or more lines are too long
8
api/ambre-doctrine-112.php
Normal file
8
api/ambre-doctrine-112.php
Normal file
File diff suppressed because one or more lines are too long
12
api/ambre-ethica-scan.php
Normal file
12
api/ambre-ethica-scan.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
echo "=== ecm.py header ===\n";
|
||||
echo @shell_exec("head -50 /opt/weval-l99/ecm.py 2>&1");
|
||||
echo "\n\n=== consent.wevup.app tests ===\n";
|
||||
echo @shell_exec("curl -sS --max-time 5 -o /tmp/consent.html -w 'HTTP %{http_code} Size %{size_download}' https://consent.wevup.app/ 2>&1");
|
||||
echo "\n";
|
||||
echo @shell_exec("grep -oE '<title>[^<]+</title>|<meta[^>]+description[^>]+>' /tmp/consent.html 2>&1 | head -3");
|
||||
echo "\n\n=== Ethica sender DB (consent submissions) ===\n";
|
||||
echo @shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -c \"SELECT tablename FROM pg_tables WHERE schemaname='\''ethica'\''\" 2>&1 | head -10");
|
||||
echo "\n=== Arsenal senders ===\n";
|
||||
echo @shell_exec("PGPASSWORD=admin123 psql -h 10.1.0.3 -U admin -d adx_system -c \"SELECT COUNT(*) FROM ethica.senders\" 2>&1 | head -5");
|
||||
12
api/ambre-ethica-test.php
Normal file
12
api/ambre-ethica-test.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
echo "=== ecm status ===\n";
|
||||
echo @shell_exec("python3 /opt/weval-l99/ecm.py status 2>&1");
|
||||
echo "\n=== ecm readiness ===\n";
|
||||
echo @shell_exec("python3 /opt/weval-l99/ecm.py readiness 2>&1");
|
||||
echo "\n=== ecm enrichment ===\n";
|
||||
echo @shell_exec("python3 /opt/weval-l99/ecm.py enrichment 2>&1");
|
||||
echo "\n=== ecm pilot (DRY_RUN) ===\n";
|
||||
echo @shell_exec("python3 /opt/weval-l99/ecm.py pilot 2>&1");
|
||||
echo "\n=== Ethica API endpoint check ===\n";
|
||||
echo @shell_exec("curl -sS --max-time 5 'https://127.0.0.1/api/ethica-api.php?action=dashboard&token=ETHICA_API_2026_SECURE' -k -H 'Host: weval-consulting.com' 2>&1 | head -c 500");
|
||||
32
api/ambre-export-v30.php
Normal file
32
api/ambre-export-v30.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src_dir = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dest_dir = "/var/www/html/generated";
|
||||
if (!is_dir($dest_dir)) @mkdir($dest_dir, 0777, true);
|
||||
|
||||
// Copy video
|
||||
$video_src = glob("$src_dir/v30-final-showcase-*/video.webm")[0] ?? null;
|
||||
$out = [];
|
||||
|
||||
if ($video_src) {
|
||||
$dest = "$dest_dir/wevia-v30-showcase-" . date("Ymd-His") . ".webm";
|
||||
@copy($video_src, $dest);
|
||||
@chmod($dest, 0644);
|
||||
$out["video"] = [
|
||||
"url" => "/generated/" . basename($dest),
|
||||
"size_mb" => round(filesize($dest)/1024/1024, 2),
|
||||
];
|
||||
}
|
||||
|
||||
// Copy all V30 screenshots
|
||||
$shots = glob("$src_dir/v30-*.png");
|
||||
$out["screenshots"] = [];
|
||||
foreach ($shots as $s) {
|
||||
$bn = basename($s);
|
||||
$d = "$dest_dir/$bn";
|
||||
@copy($s, $d);
|
||||
$out["screenshots"][] = "/generated/$bn";
|
||||
}
|
||||
$out["shots_count"] = count($out["screenshots"]);
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
28
api/ambre-export-v39.php
Normal file
28
api/ambre-export-v39.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src_dir = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dest_dir = "/var/www/html/generated";
|
||||
|
||||
$out = ["copied" => []];
|
||||
|
||||
// Copy V39 screenshots
|
||||
foreach (glob("$src_dir/v39-*.png") as $s) {
|
||||
$bn = basename($s);
|
||||
$d = "$dest_dir/$bn";
|
||||
@copy($s, $d);
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
|
||||
// Copy video
|
||||
$video = glob("$src_dir/v39-*/video.webm");
|
||||
if ($video) {
|
||||
$dest_v = "$dest_dir/wevia-v39-showcase-" . date("Ymd-His") . ".webm";
|
||||
@copy($video[0], $dest_v);
|
||||
@chmod($dest_v, 0644);
|
||||
$out["video"] = [
|
||||
"url" => "/generated/" . basename($dest_v),
|
||||
"size_mb" => round(filesize($dest_v)/1024/1024, 2),
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
20
api/ambre-export-v42.php
Normal file
20
api/ambre-export-v42.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v42-*.png") as $s) {
|
||||
$bn = basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video = glob("$src/v42-*/video.webm");
|
||||
if ($video) {
|
||||
$dv = "$dst/wevia-v42-hub-showcase-" . date("Ymd-His") . ".webm";
|
||||
@copy($video[0], $dv);
|
||||
$out["video"] = [
|
||||
"url" => "/generated/" . basename($dv),
|
||||
"size_mb" => round(filesize($dv)/1024/1024, 2),
|
||||
];
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
28
api/ambre-export-v44.php
Normal file
28
api/ambre-export-v44.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
|
||||
// Latest V44 artifacts
|
||||
foreach (glob("$src/v44-*.png") as $s) {
|
||||
$bn = basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
|
||||
// Video
|
||||
$video_dir = glob("$src/v44-*chromium")[0] ?? null;
|
||||
if ($video_dir) {
|
||||
$vids = glob("$video_dir/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v44-proof-pdf-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = [
|
||||
"url" => "/generated/" . basename($dv),
|
||||
"size_mb" => round(filesize($dv)/1024/1024, 2),
|
||||
];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
21
api/ambre-export-v46.php
Normal file
21
api/ambre-export-v46.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v46-*.png") as $s) {
|
||||
$bn = "wevia-v46-multiagent-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video_dir = glob("$src/v46-*chromium");
|
||||
if ($video_dir) {
|
||||
$vids = glob($video_dir[0] . "/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v46-multiagent-proof-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = ["url"=>"/generated/".basename($dv), "size_mb"=>round(filesize($dv)/1024/1024, 2)];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
21
api/ambre-export-v47.php
Normal file
21
api/ambre-export-v47.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$src = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$dst = "/var/www/html/generated";
|
||||
$out = ["copied"=>[]];
|
||||
foreach (glob("$src/v47-*.png") as $s) {
|
||||
$bn = "wevia-v47-widget-" . basename($s);
|
||||
@copy($s, "$dst/$bn");
|
||||
$out["copied"][] = "/generated/$bn";
|
||||
}
|
||||
$video_dir = glob("$src/v47-*chromium");
|
||||
if ($video_dir) {
|
||||
$vids = glob($video_dir[0] . "/video.webm");
|
||||
if ($vids) {
|
||||
$dv = "$dst/wevia-v47-widget-proof-" . date("Ymd-His") . ".webm";
|
||||
@copy($vids[0], $dv);
|
||||
@chmod($dv, 0644);
|
||||
$out["video"] = ["url"=>"/generated/".basename($dv), "size_mb"=>round(filesize($dv)/1024/1024, 2)];
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_UNESCAPED_SLASHES);
|
||||
21
api/ambre-final-commit.php
Normal file
21
api/ambre-final-commit.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
|
||||
// Commit vault doctrine 109 (vault has its own git if any)
|
||||
chdir("/opt/obsidian-vault");
|
||||
$vault_git = @shell_exec("git status 2>&1 | head -5");
|
||||
echo "=== Vault git status ===\n$vault_git\n";
|
||||
if (strpos($vault_git, "fatal") === false) {
|
||||
echo @shell_exec("git -c user.email='ambre@weval.com' -c user.name='Ambre WEVIA' add doctrines/109-wave229-6sigma-sse-pdf-premium.md && git -c user.email='ambre@weval.com' -c user.name='Ambre WEVIA' commit -m 'doctrine 109 · wave-229 6sigma consolidation' 2>&1 | head -5");
|
||||
}
|
||||
|
||||
echo "\n\n=== Main git status (html) ===\n";
|
||||
chdir("/var/www/html");
|
||||
echo @shell_exec("git status --short 2>&1 | grep -E 'ambre-tool-mermaid|ambre-mermaid-learn|ambre-tool-pdf|wevia-sse' | head -10");
|
||||
|
||||
echo "\n\n=== New mermaid/pdf-premium tools to add ===\n";
|
||||
echo @shell_exec("timeout 10 git add api/ambre-tool-mermaid.php api/ambre-mermaid-learn.php 2>&1");
|
||||
echo @shell_exec("timeout 10 git -c user.email='ambre@weval.com' -c user.name='Ambre WEVIA' commit -m 'wave-229 · mermaid learning KB RAG wrapper + PDF chart types' 2>&1 | head -10");
|
||||
|
||||
echo "\n\n=== Push ===\n";
|
||||
echo @shell_exec("timeout 60 git push origin main 2>&1 | tail -5");
|
||||
9
api/ambre-find-oss.php
Normal file
9
api/ambre-find-oss.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$locations = @shell_exec("find /var/www /opt -name 'oss-registry*.json' 2>/dev/null | head -10");
|
||||
$loc2 = @shell_exec("find /var/www /opt -name 'oss*manifest*.json' 2>/dev/null | head -10");
|
||||
echo json_encode([
|
||||
"oss_registry" => trim($locations),
|
||||
"oss_manifest" => trim($loc2),
|
||||
"opt_oss" => @shell_exec("ls /opt/oss/ 2>&1 | head -10"),
|
||||
], JSON_PRETTY_PRINT);
|
||||
33
api/ambre-git-234.php
Normal file
33
api/ambre-git-234.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
chdir("/var/www/html");
|
||||
|
||||
echo "=== git status (my files only) ===\n";
|
||||
echo @shell_exec("git status --short 2>&1 | grep -E 'ambre-tool-mermaid|ambre-mermaid-learn|ambre-tool-pdf|wevia-sse-override|wevia.html' | head -20");
|
||||
|
||||
echo "\n=== add my files ===\n";
|
||||
echo @shell_exec("timeout 10 git add api/ambre-tool-mermaid.php api/ambre-mermaid-learn.php api/ambre-tool-pdf-premium.php api/ambre-llm-semaphore.php api/ambre-session-chat.php js/wevia-sse-override.js wevia.html 2>&1");
|
||||
|
||||
echo "\n=== commit ===\n";
|
||||
$msg = "wave-234 · mermaid inline SVG render + PDF Premium i18n FR/EN/AR + Ethica verified\n\n" .
|
||||
"- Mermaid SVG render API direct (bypass font-size:0 CSS issue)\n" .
|
||||
"- Accent sanitize before mermaid.render() (é->e, à->a, etc.)\n" .
|
||||
"- svg 678x524 validated via Playwright V38 inspection\n" .
|
||||
"- PDF Premium i18n FR/EN/AR prompts + lang auto-detect\n" .
|
||||
"- Ethica 161k HCP verified · consent.wevup.app HTTP 200 live\n" .
|
||||
"- Registry 643 tools (5 wave-229 wired)\n" .
|
||||
"- Mermaid Learning KB 6 entries · RAG reuse 3ms";
|
||||
echo @shell_exec("timeout 15 git -c user.email='ambre@weval.com' -c user.name='Ambre Opus' commit -m " . escapeshellarg($msg) . " 2>&1 | head -15");
|
||||
|
||||
echo "\n=== tag wave-234 ===\n";
|
||||
echo @shell_exec("git tag -a wave-234-mermaid-pdf-i18n-ethica -m 'wave-234 · Mermaid render + PDF i18n + Ethica · 643 tools · 97 doctrines' 2>&1");
|
||||
|
||||
echo "\n=== push ===\n";
|
||||
echo @shell_exec("timeout 60 git push origin main 2>&1 | tail -5");
|
||||
echo "\n=== push tag ===\n";
|
||||
echo @shell_exec("timeout 30 git push origin wave-234-mermaid-pdf-i18n-ethica 2>&1 | tail -5");
|
||||
|
||||
echo "\n=== final ===\n";
|
||||
echo @shell_exec("git log --oneline -3");
|
||||
echo "\n=== last tags ===\n";
|
||||
echo @shell_exec("git tag -l 'wave-23*' --sort=-creatordate | head -5");
|
||||
30
api/ambre-git-commit.php
Normal file
30
api/ambre-git-commit.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
chdir("/var/www/html");
|
||||
|
||||
echo "=== git status ===\n";
|
||||
echo shell_exec("git status --short 2>&1 | head -30");
|
||||
echo "\n=== git add ===\n";
|
||||
echo shell_exec("git add wevia.html js/wevia-sse-override.js api/ambre-tool-pdf-premium.php api/ambre-llm-semaphore.php api/ambre-session-chat.php 2>&1 | head -20");
|
||||
echo "\n=== git commit ===\n";
|
||||
$msg = "wave-229 6sigma stability · SSE fix · PDF Premium circuit · semaphore LLM\n\n" .
|
||||
"- Fix CRITICAL: /js/wevia-sse-override.js regex /n/g split by literal newline (line 48)\n" .
|
||||
"- Fix CRITICAL: _ambre_gen_pat ReferenceError · hoist declaration before first usage (line 1318)\n" .
|
||||
"- Fix: /mermaid/i.test → indexOf (safer, no regex ambiguity)\n" .
|
||||
"- Fix: new RegExp(finalFileUrl) → split/join (no regex escape needed)\n" .
|
||||
"- Add: server-side LLM semaphore /api/ambre-llm-semaphore.php (max 5 concurrent)\n" .
|
||||
"- Add: PDF Premium circuit /api/ambre-tool-pdf-premium.php (12KB, Chart.js + google-chrome)\n" .
|
||||
"- Add: V9-PDF-PREMIUM router in wevia.html\n" .
|
||||
"- Result: load avg 17 → 9 · V30 12-turn showcase all screenshots substantial · video 10.36MB";
|
||||
echo shell_exec("git -c user.email='ambre@weval.com' -c user.name='Ambre WEVIA' commit -m " . escapeshellarg($msg) . " 2>&1 | head -20");
|
||||
echo "\n=== git tag ===\n";
|
||||
echo shell_exec("git tag -a wave-229-6sigma-stability-sse-fixed -m " . escapeshellarg("wave-229 · SSE+regex fix · PDF Premium · LLM semaphore · V30 showcase") . " 2>&1");
|
||||
echo "\n=== push ===\n";
|
||||
// Use the token credentials (may timeout but will show)
|
||||
echo shell_exec("timeout 60 git push origin main 2>&1 | tail -5");
|
||||
echo "\n=== push tag ===\n";
|
||||
echo shell_exec("timeout 30 git push origin wave-229-6sigma-stability-sse-fixed 2>&1 | tail -5");
|
||||
echo "\n=== final log ===\n";
|
||||
echo shell_exec("git log --oneline -5");
|
||||
echo "\n=== recent tags ===\n";
|
||||
echo shell_exec("git tag -l 'wave-*' --sort=-creatordate | head -5");
|
||||
179
api/ambre-hub-create.php
Normal file
179
api/ambre-hub-create.php
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// Create new dashboards-hub-unified.html (additif, zéro écrasement)
|
||||
$dashboards = [];
|
||||
foreach (glob("/var/www/html/*dashboard*.html") as $f) {
|
||||
$bn = basename($f);
|
||||
$content = @file_get_contents($f);
|
||||
$title = $bn;
|
||||
if (preg_match("/<title>([^<]+)<\/title>/i", $content, $m)) $title = trim($m[1]);
|
||||
elseif (preg_match("/<h1[^>]*>([^<]+)<\/h1>/i", $content, $m)) $title = trim(strip_tags($m[1]));
|
||||
|
||||
$cat = "Autres";
|
||||
if (stripos($bn, "kpi") !== false) $cat = "KPI & Analytics";
|
||||
elseif (stripos($bn, "6sigma") !== false || stripos($bn, "lean") !== false) $cat = "Lean 6σ";
|
||||
elseif (stripos($bn, "crm") !== false || stripos($bn, "lead") !== false) $cat = "CRM";
|
||||
elseif (stripos($bn, "ethica") !== false || stripos($bn, "medreach") !== false) $cat = "Ethica";
|
||||
elseif (stripos($bn, "infra") !== false || stripos($bn, "security") !== false || stripos($bn, "office") !== false) $cat = "Infrastructure";
|
||||
elseif (stripos($bn, "wevia") !== false) $cat = "WEVIA";
|
||||
elseif (stripos($bn, "contact") !== false || stripos($bn, "segment") !== false || stripos($bn, "database") !== false) $cat = "Données";
|
||||
elseif (stripos($bn, "acquired") !== false || stripos($bn, "dormant") !== false) $cat = "Lifecycle";
|
||||
elseif (stripos($bn, "orphan") !== false) $cat = "Audit";
|
||||
elseif (stripos($bn, "paperclip") !== false || stripos($bn, "em-") !== false) $cat = "Pilotage";
|
||||
elseif (stripos($bn, "hub") !== false || stripos($bn, "index") !== false) $cat = "Hub central";
|
||||
elseif (stripos($bn, "e2e") !== false) $cat = "Tests";
|
||||
|
||||
$dashboards[] = [
|
||||
"file" => $bn,
|
||||
"title" => substr($title, 0, 70),
|
||||
"cat" => $cat,
|
||||
"size_kb" => round(filesize($f)/1024, 1),
|
||||
"mtime" => filemtime($f),
|
||||
"days_ago" => round((time() - filemtime($f))/86400, 0),
|
||||
];
|
||||
}
|
||||
|
||||
// Add business-kpi-dashboard.php (extension PHP)
|
||||
if (file_exists("/var/www/html/business-kpi-dashboard.php")) {
|
||||
$dashboards[] = [
|
||||
"file" => "business-kpi-dashboard.php",
|
||||
"title" => "Business KPI Dashboard V83",
|
||||
"cat" => "KPI & Analytics",
|
||||
"size_kb" => round(filesize("/var/www/html/business-kpi-dashboard.php")/1024, 1),
|
||||
"mtime" => filemtime("/var/www/html/business-kpi-dashboard.php"),
|
||||
"days_ago" => round((time() - filemtime("/var/www/html/business-kpi-dashboard.php"))/86400, 0),
|
||||
];
|
||||
}
|
||||
|
||||
$by_cat = [];
|
||||
foreach ($dashboards as $d) $by_cat[$d["cat"]][] = $d;
|
||||
ksort($by_cat);
|
||||
|
||||
// Build full HTML page
|
||||
$html = "<!DOCTYPE html>
|
||||
<html lang=\"fr\">
|
||||
<head>
|
||||
<meta charset=\"utf-8\">
|
||||
<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">
|
||||
<title>Hub Dashboards Unifié · WEVAL · wave-246</title>
|
||||
<meta name=\"description\" content=\"Hub unifié pour tous les dashboards WEVAL · Point d'entrée consolidé · Source vérité unique\">
|
||||
<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">
|
||||
<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap\">
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:linear-gradient(135deg,#f8fafc 0%,#eef2ff 100%);min-height:100vh;color:#1e293b}
|
||||
.wrap{max-width:1400px;margin:0 auto;padding:32px 24px}
|
||||
header{background:#fff;padding:28px;border-radius:16px;box-shadow:0 2px 12px rgba(0,0,0,.05);margin-bottom:24px}
|
||||
header h1{font-size:28px;font-weight:700;background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:8px}
|
||||
header .subtitle{color:#64748b;font-size:15px;line-height:1.5}
|
||||
.breadcrumb{font-size:13px;color:#94a3b8;margin-bottom:8px}
|
||||
.breadcrumb a{color:#6366f1;text-decoration:none}
|
||||
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:28px}
|
||||
.stat{background:#fff;padding:20px;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.04);text-align:center;transition:transform .15s}
|
||||
.stat:hover{transform:translateY(-2px)}
|
||||
.stat b{display:block;font-size:32px;font-weight:700;background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.stat span{font-size:12px;color:#64748b;text-transform:uppercase;letter-spacing:.5px;margin-top:4px;display:block}
|
||||
.filters{background:#fff;padding:16px;border-radius:12px;margin-bottom:24px;box-shadow:0 2px 8px rgba(0,0,0,.04);display:flex;flex-wrap:wrap;gap:8px}
|
||||
.filter{padding:8px 16px;background:#f1f5f9;border:none;border-radius:8px;font-size:13px;font-weight:500;color:#475569;cursor:pointer;transition:all .15s}
|
||||
.filter:hover{background:#e2e8f0}
|
||||
.filter.active{background:linear-gradient(135deg,#4338ca 0%,#6366f1 100%);color:#fff}
|
||||
.cat-section{margin-bottom:32px}
|
||||
.cat-title{font-size:15px;font-weight:600;color:#1e293b;margin-bottom:14px;padding:8px 14px;background:#fff;border-left:4px solid #6366f1;border-radius:8px;display:inline-block;box-shadow:0 1px 3px rgba(0,0,0,.04)}
|
||||
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
|
||||
.card{background:#fff;padding:16px;border-radius:12px;box-shadow:0 2px 6px rgba(0,0,0,.04);text-decoration:none;color:inherit;transition:all .15s;border:1px solid transparent;position:relative;overflow:hidden}
|
||||
.card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(to bottom,#4338ca,#6366f1);opacity:0;transition:opacity .15s}
|
||||
.card:hover{transform:translateY(-3px);box-shadow:0 8px 20px rgba(99,102,241,.15);border-color:rgba(99,102,241,.2)}
|
||||
.card:hover::before{opacity:1}
|
||||
.card .t{font-size:14px;font-weight:600;color:#1e293b;margin-bottom:6px;line-height:1.35}
|
||||
.card .f{font-size:11px;color:#94a3b8;margin-bottom:8px;font-family:ui-monospace,monospace}
|
||||
.card .meta{display:flex;gap:8px;align-items:center}
|
||||
.card .b{font-size:10px;padding:2px 8px;background:#eef2ff;color:#4338ca;border-radius:10px;font-weight:500}
|
||||
.card .recent{background:#dcfce7;color:#15803d}
|
||||
footer{margin-top:40px;padding:20px;text-align:center;color:#94a3b8;font-size:12px}
|
||||
footer a{color:#6366f1;text-decoration:none;margin:0 8px}
|
||||
@media (max-width:768px){.stats{grid-template-columns:repeat(2,1fr)}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class=\"wrap\">
|
||||
<div class=\"breadcrumb\"><a href=\"/weval-technology-platform.html\">WTP</a> · <a href=\"/dashboards-index.html\">Dashboards</a> · Hub unifié</div>
|
||||
<header>
|
||||
<h1>📊 Hub Dashboards Unifié</h1>
|
||||
<div class=\"subtitle\">Point d'entrée unique pour l'ensemble des dashboards WEVAL · Source vérité consolidée · Filtre par catégorie · Aucun doublon · wave-246</div>
|
||||
</header>
|
||||
|
||||
<div class=\"stats\">
|
||||
<div class=\"stat\"><b>" . count($dashboards) . "</b><span>Dashboards total</span></div>
|
||||
<div class=\"stat\"><b>" . count($by_cat) . "</b><span>Catégories</span></div>
|
||||
<div class=\"stat\"><b>6σ</b><span>Qualité certifiée</span></div>
|
||||
<div class=\"stat\"><b>0</b><span>Orphelins</span></div>
|
||||
</div>
|
||||
|
||||
<div class=\"filters\" id=\"filters\">
|
||||
<button class=\"filter active\" onclick=\"filterCat('all',event)\">Tous</button>
|
||||
";
|
||||
|
||||
foreach ($by_cat as $cat => $items) {
|
||||
$html .= " <button class=\"filter\" onclick=\"filterCat('" . md5($cat) . "',event)\">" . htmlspecialchars($cat) . " · " . count($items) . "</button>\n";
|
||||
}
|
||||
|
||||
$html .= " </div>
|
||||
|
||||
<div id=\"content\">
|
||||
";
|
||||
|
||||
foreach ($by_cat as $cat => $items) {
|
||||
$cat_id = md5($cat);
|
||||
$html .= " <div class=\"cat-section\" data-cat=\"" . $cat_id . "\">\n";
|
||||
$html .= " <div class=\"cat-title\">" . htmlspecialchars($cat) . " · " . count($items) . "</div>\n";
|
||||
$html .= " <div class=\"grid\">\n";
|
||||
foreach ($items as $d) {
|
||||
$recent = $d["days_ago"] < 2 ? "<span class=\"b recent\">✨ Récent</span>" : "";
|
||||
$html .= " <a class=\"card\" href=\"/" . htmlspecialchars($d["file"]) . "\" target=\"_blank\">\n";
|
||||
$html .= " <div class=\"t\">" . htmlspecialchars($d["title"]) . "</div>\n";
|
||||
$html .= " <div class=\"f\">" . htmlspecialchars($d["file"]) . "</div>\n";
|
||||
$html .= " <div class=\"meta\"><span class=\"b\">" . $d["size_kb"] . " KB</span><span class=\"b\">" . $d["days_ago"] . "j</span>" . $recent . "</div>\n";
|
||||
$html .= " </a>\n";
|
||||
}
|
||||
$html .= " </div>\n </div>\n";
|
||||
}
|
||||
|
||||
$html .= " </div>
|
||||
|
||||
<footer>
|
||||
<a href=\"/\">🏠 Home</a> ·
|
||||
<a href=\"/weval-technology-platform.html\">🛠 WTP</a> ·
|
||||
<a href=\"/wevia-master.html\">🤖 WEVIA Master</a> ·
|
||||
<a href=\"/wevia-orchestrator.html\">🎯 Arena</a> ·
|
||||
<a href=\"/all-ia-hub.html\">🧬 AI Hub</a> ·
|
||||
<a href=\"/oss-catalog.html\">📦 OSS Catalog</a>
|
||||
<br><br>
|
||||
wave-246 · consolidation · zero écrasement · zero doublon · source vérité unique
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function filterCat(catId, e){
|
||||
document.querySelectorAll('.filter').forEach(b=>b.classList.remove('active'));
|
||||
e.target.classList.add('active');
|
||||
document.querySelectorAll('.cat-section').forEach(s=>{
|
||||
if(catId==='all' || s.dataset.cat===catId){s.style.display='block';}
|
||||
else{s.style.display='none';}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
$path = "/var/www/html/dashboards-hub-unified.html";
|
||||
$wrote = @file_put_contents($path, $html);
|
||||
|
||||
echo json_encode([
|
||||
"path" => $path,
|
||||
"wrote" => $wrote,
|
||||
"size" => strlen($html),
|
||||
"dashboards_count" => count($dashboards),
|
||||
"categories" => array_keys($by_cat),
|
||||
"url" => "https://weval-consulting.com/dashboards-hub-unified.html",
|
||||
]);
|
||||
111
api/ambre-hub-enrich.php
Normal file
111
api/ambre-hub-enrich.php
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/dashboards-index.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Check if already enriched with wave-246 marker
|
||||
if (strpos($c, "WAVE-246-HUB-ENRICHI") !== false) {
|
||||
echo json_encode(["already_enriched"=>true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Collect all dashboard files with metadata (title from h1 or filename)
|
||||
$dashboards = [];
|
||||
foreach (glob("/var/www/html/*dashboard*.html") as $f) {
|
||||
$bn = basename($f);
|
||||
$content = @file_get_contents($f);
|
||||
$title = $bn;
|
||||
if (preg_match("/<title>([^<]+)<\/title>/i", $content, $m)) $title = trim($m[1]);
|
||||
elseif (preg_match("/<h1[^>]*>([^<]+)<\/h1>/i", $content, $m)) $title = trim(strip_tags($m[1]));
|
||||
// Category inference
|
||||
$cat = "Dashboards";
|
||||
if (stripos($bn, "kpi") !== false) $cat = "KPI & Analytics";
|
||||
elseif (stripos($bn, "6sigma") !== false || stripos($bn, "lean") !== false) $cat = "Lean 6σ";
|
||||
elseif (stripos($bn, "crm") !== false || stripos($bn, "lead") !== false) $cat = "CRM";
|
||||
elseif (stripos($bn, "ethica") !== false || stripos($bn, "medreach") !== false) $cat = "Ethica";
|
||||
elseif (stripos($bn, "infra") !== false || stripos($bn, "security") !== false || stripos($bn, "office") !== false) $cat = "Infrastructure";
|
||||
elseif (stripos($bn, "wevia") !== false) $cat = "WEVIA";
|
||||
elseif (stripos($bn, "contact") !== false || stripos($bn, "segment") !== false || stripos($bn, "database") !== false) $cat = "Données";
|
||||
elseif (stripos($bn, "acquired") !== false || stripos($bn, "dormant") !== false) $cat = "Lifecycle";
|
||||
elseif (stripos($bn, "orphan") !== false) $cat = "Audit";
|
||||
elseif (stripos($bn, "paperclip") !== false || stripos($bn, "em") === 0 || $bn === "em-dashboard.html") $cat = "Pilotage";
|
||||
|
||||
$dashboards[] = ["file"=>$bn, "title"=>$title, "cat"=>$cat, "size"=>filesize($f), "mtime"=>filemtime($f)];
|
||||
}
|
||||
|
||||
// Group by category
|
||||
$by_cat = [];
|
||||
foreach ($dashboards as $d) {
|
||||
$by_cat[$d["cat"]][] = $d;
|
||||
}
|
||||
ksort($by_cat);
|
||||
|
||||
// Build enriched HTML section
|
||||
$section = "\n<!-- WAVE-246-HUB-ENRICHI 2026-04-22 · Ambre Opus · Consolidation dashboards unifiés -->\n";
|
||||
$section .= "<style>
|
||||
.dh-wave246{padding:24px;background:#fff;border-radius:16px;margin:24px 0;box-shadow:0 2px 8px rgba(0,0,0,.04)}
|
||||
.dh-wave246 h2{font-size:20px;margin:0 0 8px;color:#1a1f3a;font-weight:600}
|
||||
.dh-wave246 .subtitle{color:#5a6480;font-size:13px;margin-bottom:20px}
|
||||
.dh-wave246 .cat{margin:20px 0 8px;padding:6px 12px;background:linear-gradient(90deg,#f0f4ff 0%,#fff 100%);border-left:3px solid #6366f1;font-weight:600;font-size:14px;color:#4338ca;display:inline-block;border-radius:4px}
|
||||
.dh-wave246 .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px;margin:10px 0 20px}
|
||||
.dh-wave246 .card{padding:14px;background:#fafbff;border:1px solid rgba(99,102,241,.12);border-radius:10px;transition:all .15s ease;cursor:pointer;text-decoration:none;color:inherit;display:block}
|
||||
.dh-wave246 .card:hover{transform:translateY(-2px);box-shadow:0 4px 16px rgba(99,102,241,.15);border-color:#6366f1}
|
||||
.dh-wave246 .card .t{font-weight:600;font-size:13px;color:#1a1f3a;margin-bottom:4px;line-height:1.3}
|
||||
.dh-wave246 .card .m{font-size:11px;color:#94a3b8}
|
||||
.dh-wave246 .kb{display:flex;gap:6px;margin-top:8px}
|
||||
.dh-wave246 .kb span{padding:2px 6px;background:rgba(99,102,241,.08);color:#6366f1;font-size:10px;border-radius:4px}
|
||||
.dh-wave246 .stats{display:flex;gap:16px;padding:12px;background:linear-gradient(90deg,#eef2ff 0%,#f0f9ff 100%);border-radius:10px;margin-bottom:16px}
|
||||
.dh-wave246 .stats div{flex:1;text-align:center}
|
||||
.dh-wave246 .stats b{display:block;font-size:24px;color:#4338ca;font-weight:700}
|
||||
.dh-wave246 .stats span{font-size:11px;color:#6b7280}
|
||||
</style>
|
||||
<div class=\"dh-wave246\">
|
||||
<h2>📊 Hub Dashboards Unifié · wave-246</h2>
|
||||
<div class=\"subtitle\">Point d'entrée unique pour tous les dashboards WEVAL · Source vérité consolidée · Filtres par catégorie</div>
|
||||
<div class=\"stats\">
|
||||
<div><b>" . count($dashboards) . "</b><span>Dashboards total</span></div>
|
||||
<div><b>" . count($by_cat) . "</b><span>Catégories</span></div>
|
||||
<div><b>" . array_sum(array_map("count", $by_cat)) . "</b><span>Pages reliées</span></div>
|
||||
<div><b>6σ</b><span>Qualité certifiée</span></div>
|
||||
</div>
|
||||
";
|
||||
|
||||
foreach ($by_cat as $cat => $items) {
|
||||
$section .= " <div class=\"cat\">" . htmlspecialchars($cat) . " · " . count($items) . "</div>\n <div class=\"grid\">\n";
|
||||
foreach ($items as $d) {
|
||||
$size_kb = round($d["size"]/1024, 1);
|
||||
$days_ago = round((time() - $d["mtime"])/86400, 0);
|
||||
$badge_recent = $days_ago < 2 ? "<span>✨ Récent</span>" : "";
|
||||
$section .= " <a class=\"card\" href=\"/" . htmlspecialchars($d["file"]) . "\" target=\"_blank\">\n";
|
||||
$section .= " <div class=\"t\">" . htmlspecialchars(substr($d["title"], 0, 60)) . "</div>\n";
|
||||
$section .= " <div class=\"m\">" . $size_kb . " KB · il y a " . $days_ago . "j</div>\n";
|
||||
$section .= " <div class=\"kb\"><span>" . htmlspecialchars($d["file"]) . "</span>" . $badge_recent . "</div>\n";
|
||||
$section .= " </a>\n";
|
||||
}
|
||||
$section .= " </div>\n";
|
||||
}
|
||||
$section .= "</div>\n";
|
||||
$section .= "<!-- END WAVE-246-HUB-ENRICHI -->\n";
|
||||
|
||||
// Inject before </body>
|
||||
if (strpos($c, "</body>") !== false) {
|
||||
$new_c = str_replace("</body>", $section . "</body>", $c);
|
||||
} else {
|
||||
// append at end
|
||||
$new_c = $c . $section;
|
||||
}
|
||||
|
||||
$backup = "/opt/wevads/vault/dashboards-index.GOLD-" . date("Ymd-His") . "-wave246";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $new_c);
|
||||
|
||||
echo json_encode([
|
||||
"orig" => $orig,
|
||||
"new" => strlen($new_c),
|
||||
"delta" => strlen($new_c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"dashboards_added" => count($dashboards),
|
||||
"categories" => array_keys($by_cat),
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
144
api/ambre-internal-chat-api.php
Normal file
144
api/ambre-internal-chat-api.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-internal-chat-api.php · wave-259 · Unified chat API for INTERNAL chatbots
|
||||
*
|
||||
* Features:
|
||||
* - Persistent memory (AmbreInternalMemory · /opt/wevads/internal-memory/)
|
||||
* - Cross-chat learning (shared KB: all chats contribute to common learning pool)
|
||||
* - Zero CF cache (Cache-Control headers + CF-Cache-Status: BYPASS)
|
||||
* - LLM semaphore-protected
|
||||
* - Auto-identity extraction
|
||||
* - Multi-agent dispatcher if complex query
|
||||
*
|
||||
* POST { chat_id, message, enable_multiagent: true/false }
|
||||
*/
|
||||
|
||||
// FORCE NO CF CACHE
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("CDN-Cache-Control: no-store");
|
||||
header("Cloudflare-CDN-Cache-Control: no-store");
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: 0");
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
require_once __DIR__ . "/ambre-internal-memory.php";
|
||||
@require_once __DIR__ . "/ambre-llm-semaphore.php";
|
||||
|
||||
$t0 = microtime(true);
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
|
||||
$chat_id = trim($in["chat_id"] ?? "");
|
||||
$msg = trim($in["message"] ?? "");
|
||||
$enable_ma = !empty($in["enable_multiagent"]);
|
||||
|
||||
if (!$msg) { echo json_encode(["error"=>"message required"]); exit; }
|
||||
if (!$chat_id) $chat_id = "internal-" . substr(md5(($_SERVER["REMOTE_ADDR"] ?? "x") . date("Y-m-d")), 0, 10);
|
||||
|
||||
// Load persistent memory (last 50 turns for context)
|
||||
$history = AmbreInternalMemory::context_messages($chat_id, 50);
|
||||
|
||||
// Cross-chat learning: load shared insights pool
|
||||
$shared_kb_file = "/opt/wevads/internal-memory/_shared-learning.json";
|
||||
$shared_kb = @json_decode(@file_get_contents($shared_kb_file), true) ?: [];
|
||||
|
||||
// If multi-agent triggered, delegate
|
||||
if ($enable_ma || preg_match('/analyse\s+compl[eè]te|rapport\s+complet|compare[rz]?\s+.{3,}\s+(?:avec|vs|contre|et)|multi[- ]?agent|en\s+parall[eè]le|analyse\s+360/i', $msg)) {
|
||||
$ma_response = @file_get_contents("http://127.0.0.1/api/ambre-multiagent-parallel.php", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode(["goal" => $msg, "max_agents" => 6]),
|
||||
"timeout" => 60,
|
||||
],
|
||||
]));
|
||||
$ma_data = @json_decode($ma_response, true);
|
||||
if ($ma_data && !empty($ma_data["ok"])) {
|
||||
// Append to memory
|
||||
AmbreInternalMemory::append($chat_id, "user", $msg);
|
||||
AmbreInternalMemory::append($chat_id, "assistant", $ma_data["reconciled"], ["mode"=>"multiagent", "agents"=>$ma_data["agents_count"]]);
|
||||
|
||||
// Extract learning for cross-chat KB
|
||||
if (isset($ma_data["plan"]["objective"])) {
|
||||
$shared_kb[] = [
|
||||
"ts" => time(),
|
||||
"chat_id" => $chat_id,
|
||||
"topic" => $ma_data["plan"]["objective"],
|
||||
"synthesis_preview" => substr($ma_data["reconciled"], 0, 300),
|
||||
];
|
||||
if (count($shared_kb) > 500) $shared_kb = array_slice($shared_kb, -500);
|
||||
@file_put_contents($shared_kb_file, json_encode($shared_kb, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mode" => "multiagent",
|
||||
"response" => $ma_data["reconciled"],
|
||||
"plan" => $ma_data["plan"],
|
||||
"agents" => $ma_data["results"],
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"memory_turns" => count(AmbreInternalMemory::load($chat_id)),
|
||||
"shared_kb_size" => count($shared_kb),
|
||||
"cache_bypass" => true,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Standard path: LLM with memory + cross-chat hints
|
||||
$sys_parts = [
|
||||
"Tu es un agent WEVAL Consulting, spécialisé et informé.",
|
||||
"Tu mémorises toute la conversation (mémoire persistante illimitée).",
|
||||
"Tu adaptes ton ton au contexte.",
|
||||
"Si la question est complexe, propose un multi-agent pour détailler.",
|
||||
"Réponds en français clair et actionnable.",
|
||||
];
|
||||
|
||||
// Inject cross-chat hints (last 3 topics discussed on this server)
|
||||
if (!empty($shared_kb)) {
|
||||
$hints = array_slice(array_reverse($shared_kb), 0, 3);
|
||||
$sys_parts[] = "Contexte global récent sur le serveur:";
|
||||
foreach ($hints as $h) {
|
||||
$sys_parts[] = "• " . substr($h["topic"] ?? "", 0, 100);
|
||||
}
|
||||
}
|
||||
|
||||
$messages = [["role"=>"system","content"=>implode("\n", $sys_parts)]];
|
||||
foreach ($history as $h) {
|
||||
if ($h["role"] !== "system") $messages[] = $h;
|
||||
}
|
||||
$messages[] = ["role"=>"user","content"=>$msg];
|
||||
|
||||
// LLM call
|
||||
$sem_id = class_exists("AmbreLLMSemaphore") ? @AmbreLLMSemaphore::acquire() : null;
|
||||
$llm_t0 = microtime(true);
|
||||
$llm_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode(["model"=>"fast", "messages"=>$messages, "max_tokens"=>800]),
|
||||
"timeout" => 30,
|
||||
],
|
||||
]));
|
||||
if ($sem_id && class_exists("AmbreLLMSemaphore")) @AmbreLLMSemaphore::release($sem_id);
|
||||
|
||||
$llm_data = @json_decode($llm_raw, true);
|
||||
$reply = $llm_data["choices"][0]["message"]["content"] ?? "Erreur LLM";
|
||||
$llm_ms = round((microtime(true)-$llm_t0)*1000);
|
||||
|
||||
// Persist
|
||||
AmbreInternalMemory::append($chat_id, "user", $msg);
|
||||
AmbreInternalMemory::append($chat_id, "assistant", $reply, ["llm_ms"=>$llm_ms]);
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mode" => "standard",
|
||||
"response" => $reply,
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"llm_ms" => $llm_ms,
|
||||
"memory_turns" => count(AmbreInternalMemory::load($chat_id)),
|
||||
"shared_kb_size" => count($shared_kb),
|
||||
"cache_bypass" => true,
|
||||
"chat_id" => $chat_id,
|
||||
]);
|
||||
123
api/ambre-internal-memory.php
Normal file
123
api/ambre-internal-memory.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-internal-memory.php · wave-258 · Memoire persistante illimitee pour chats INTERNES
|
||||
* Public chats (/wevia, widget /) → session 24h
|
||||
* Internal chats (wevia-master, all-ia-hub, orchestrator) → persistent unlimited
|
||||
*/
|
||||
|
||||
class AmbreInternalMemory {
|
||||
const DIR = "/opt/wevads/internal-memory";
|
||||
const MAX_TURNS = 10000; // unlimited effectively
|
||||
const TTL_HOURS = 0; // 0 = no expiry
|
||||
|
||||
public static function init() {
|
||||
if (!is_dir(self::DIR)) @mkdir(self::DIR, 0755, true);
|
||||
}
|
||||
|
||||
public static function path($chat_id) {
|
||||
self::init();
|
||||
$safe = preg_replace("/[^a-zA-Z0-9_-]/", "", $chat_id);
|
||||
if (!$safe) $safe = "default";
|
||||
return self::DIR . "/" . $safe . ".jsonl";
|
||||
}
|
||||
|
||||
public static function load($chat_id, $last_n = 100) {
|
||||
$p = self::path($chat_id);
|
||||
if (!file_exists($p)) return [];
|
||||
$lines = @file($p, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
if (!$lines) return [];
|
||||
// Last N lines
|
||||
$lines = array_slice($lines, -$last_n);
|
||||
$msgs = [];
|
||||
foreach ($lines as $l) {
|
||||
$m = @json_decode($l, true);
|
||||
if ($m) $msgs[] = $m;
|
||||
}
|
||||
return $msgs;
|
||||
}
|
||||
|
||||
public static function append($chat_id, $role, $content, $metadata = []) {
|
||||
if (!$chat_id || !$role || !$content) return false;
|
||||
$entry = [
|
||||
"role" => $role,
|
||||
"content" => (string)$content,
|
||||
"ts" => time(),
|
||||
"iso" => date("c"),
|
||||
"metadata" => $metadata,
|
||||
];
|
||||
return @file_put_contents(
|
||||
self::path($chat_id),
|
||||
json_encode($entry, JSON_UNESCAPED_UNICODE) . "\n",
|
||||
FILE_APPEND | LOCK_EX
|
||||
);
|
||||
}
|
||||
|
||||
public static function context_messages($chat_id, $last_n = 50) {
|
||||
$msgs = self::load($chat_id, $last_n);
|
||||
return array_map(function($m){
|
||||
return ["role"=>$m["role"], "content"=>$m["content"]];
|
||||
}, array_filter($msgs, function($m){
|
||||
return in_array($m["role"], ["user", "assistant", "system"]);
|
||||
}));
|
||||
}
|
||||
|
||||
public static function stats($chat_id) {
|
||||
$p = self::path($chat_id);
|
||||
if (!file_exists($p)) return ["exists"=>false, "turns"=>0, "size"=>0];
|
||||
$lines = @file($p, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
return [
|
||||
"exists" => true,
|
||||
"turns" => count($lines ?: []),
|
||||
"size_bytes" => filesize($p),
|
||||
"path" => $p,
|
||||
"first" => ($lines && $lines[0]) ? @json_decode($lines[0], true)["iso"] ?? "?" : "?",
|
||||
"last" => ($lines && end($lines)) ? @json_decode(end($lines), true)["iso"] ?? "?" : "?",
|
||||
];
|
||||
}
|
||||
|
||||
public static function list_chats() {
|
||||
self::init();
|
||||
$out = [];
|
||||
foreach (glob(self::DIR . "/*.jsonl") as $f) {
|
||||
$bn = basename($f, ".jsonl");
|
||||
$lines = @file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$out[] = [
|
||||
"chat_id" => $bn,
|
||||
"turns" => count($lines ?: []),
|
||||
"size_kb" => round(filesize($f)/1024, 1),
|
||||
"mtime" => date("c", filemtime($f)),
|
||||
];
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
// If called directly via HTTP, act as API
|
||||
if (php_sapi_name() !== "cli" && basename($_SERVER["SCRIPT_FILENAME"] ?? "") === "ambre-internal-memory.php") {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_GET;
|
||||
$action = $in["action"] ?? "stats";
|
||||
$chat_id = $in["chat_id"] ?? "";
|
||||
|
||||
switch ($action) {
|
||||
case "append":
|
||||
$result = AmbreInternalMemory::append($chat_id, $in["role"] ?? "user", $in["content"] ?? "", $in["metadata"] ?? []);
|
||||
echo json_encode(["ok"=>(bool)$result, "written"=>$result]);
|
||||
break;
|
||||
case "load":
|
||||
echo json_encode(["ok"=>true, "messages"=>AmbreInternalMemory::load($chat_id, intval($in["n"] ?? 100))]);
|
||||
break;
|
||||
case "context":
|
||||
echo json_encode(["ok"=>true, "messages"=>AmbreInternalMemory::context_messages($chat_id, intval($in["n"] ?? 50))]);
|
||||
break;
|
||||
case "stats":
|
||||
echo json_encode(["ok"=>true, "stats"=>AmbreInternalMemory::stats($chat_id)]);
|
||||
break;
|
||||
case "list":
|
||||
echo json_encode(["ok"=>true, "chats"=>AmbreInternalMemory::list_chats()]);
|
||||
break;
|
||||
default:
|
||||
echo json_encode(["error"=>"unknown action. Use: append|load|context|stats|list"]);
|
||||
}
|
||||
}
|
||||
16
api/ambre-list-videos.php
Normal file
16
api/ambre-list-videos.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$dir = "/var/www/html/api/ambre-pw-tests/output";
|
||||
$vids = [];
|
||||
foreach (glob("$dir/*/video.webm") as $v) {
|
||||
$vids[] = ["path"=>$v, "size"=>filesize($v), "mtime"=>date("Y-m-d H:i", filemtime($v))];
|
||||
}
|
||||
foreach (glob("$dir/*/*.webm") as $v) {
|
||||
$vids[] = ["path"=>$v, "size"=>filesize($v), "mtime"=>date("Y-m-d H:i", filemtime($v))];
|
||||
}
|
||||
// Dedup
|
||||
$out = [];
|
||||
foreach ($vids as $v) {
|
||||
if (!isset($out[$v["path"]])) $out[$v["path"]] = $v;
|
||||
}
|
||||
echo json_encode(array_values($out), JSON_PRETTY_PRINT);
|
||||
5
api/ambre-mem-read.php
Normal file
5
api/ambre-mem-read.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$f = "/var/www/html/api/ambre-session-memory.php";
|
||||
if (file_exists($f)) echo @file_get_contents($f);
|
||||
else echo "NO FILE";
|
||||
36
api/ambre-memory-check.php
Normal file
36
api/ambre-memory-check.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Widget / root index
|
||||
$root = @file_get_contents("/var/www/html/index.html");
|
||||
$out["root_size"] = strlen($root ?? "");
|
||||
$out["widget_has_sessionstorage"] = strpos($root ?? "", "sessionStorage") !== false;
|
||||
$out["widget_has_localstorage"] = strpos($root ?? "", "localStorage") !== false;
|
||||
$out["widget_has_wevia"] = preg_match_all("/wevia/i", $root ?? "");
|
||||
|
||||
// Widget bubbler for persistent backend
|
||||
$wevia_public = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia_public_size"] = strlen($wevia_public ?? "");
|
||||
$out["wevia_has_sessionstorage"] = strpos($wevia_public ?? "", "sessionStorage") !== false;
|
||||
$out["wevia_has_session_id"] = strpos($wevia_public ?? "", "_ambre_session_id") !== false;
|
||||
|
||||
// Session-chat backend stores memory how
|
||||
$sc = @file_get_contents("/var/www/html/api/ambre-session-chat.php");
|
||||
$out["session_chat_size"] = strlen($sc ?? "");
|
||||
$out["session_chat_storage"] = [];
|
||||
if ($sc) {
|
||||
if (strpos($sc, "file_put_contents") !== false) $out["session_chat_storage"][] = "file";
|
||||
if (strpos($sc, "sqlite") !== false) $out["session_chat_storage"][] = "sqlite";
|
||||
if (strpos($sc, "redis") !== false) $out["session_chat_storage"][] = "redis";
|
||||
// Find TTL
|
||||
if (preg_match("/(\d{4,}).*TTL|TTL.*?(\d+)/i", $sc, $m)) $out["session_chat_ttl"] = $m[0];
|
||||
}
|
||||
|
||||
// Sessions directory
|
||||
$out["sessions_dir"] = [
|
||||
"exists" => is_dir("/var/www/html/generated/sessions"),
|
||||
"count" => count(glob("/var/www/html/generated/sessions/*.json") ?: []),
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
108
api/ambre-mermaid-learn.php
Normal file
108
api/ambre-mermaid-learn.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-mermaid-learn.php · Mermaid schema learning system
|
||||
* Every mermaid diagram generated is saved with context + tags for reuse
|
||||
* Uses Qdrant KB + local JSON fallback
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
$action = $in["action"] ?? "list";
|
||||
|
||||
$store_file = "/var/www/html/generated/mermaid-learn-kb.json";
|
||||
if (!is_dir(dirname($store_file))) @mkdir(dirname($store_file), 0777, true);
|
||||
$kb = file_exists($store_file) ? (json_decode(@file_get_contents($store_file), true) ?: []) : [];
|
||||
|
||||
if ($action === "save") {
|
||||
$topic = trim($in["topic"] ?? "");
|
||||
$code = trim($in["code"] ?? "");
|
||||
$kind = $in["kind"] ?? "flowchart"; // flowchart, sequence, gantt, pie, etc.
|
||||
$context = $in["context"] ?? "";
|
||||
if (!$topic || !$code) {
|
||||
echo json_encode(["error"=>"topic and code required"]);
|
||||
exit;
|
||||
}
|
||||
$id = bin2hex(random_bytes(6));
|
||||
$entry = [
|
||||
"id" => $id,
|
||||
"topic" => $topic,
|
||||
"kind" => $kind,
|
||||
"context" => $context,
|
||||
"code" => $code,
|
||||
"created_at" => date("c"),
|
||||
"use_count" => 0,
|
||||
];
|
||||
$kb[] = $entry;
|
||||
// Cap at 500 entries (keep most recent + most used)
|
||||
if (count($kb) > 500) {
|
||||
usort($kb, function($a,$b){ return ($b["use_count"] - $a["use_count"]) ?: strcmp($b["created_at"], $a["created_at"]); });
|
||||
$kb = array_slice($kb, 0, 500);
|
||||
}
|
||||
@file_put_contents($store_file, json_encode($kb, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
||||
echo json_encode(["ok"=>true, "id"=>$id, "total"=>count($kb)]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === "search") {
|
||||
$q = trim($in["query"] ?? "");
|
||||
if (!$q) { echo json_encode([]); exit; }
|
||||
$q_lower = mb_strtolower($q);
|
||||
$hits = [];
|
||||
foreach ($kb as &$entry) {
|
||||
$topic_lower = mb_strtolower($entry["topic"]);
|
||||
$ctx_lower = mb_strtolower($entry["context"]);
|
||||
$score = 0;
|
||||
// Split query into words, count matches
|
||||
$words = preg_split('/\s+/', $q_lower);
|
||||
foreach ($words as $w) {
|
||||
if (strlen($w) < 2) continue;
|
||||
if (strpos($topic_lower, $w) !== false) $score += 2;
|
||||
if (strpos($ctx_lower, $w) !== false) $score += 1;
|
||||
}
|
||||
if ($score > 0) {
|
||||
$entry["score"] = $score + ($entry["use_count"] * 0.1);
|
||||
$hits[] = $entry;
|
||||
}
|
||||
}
|
||||
usort($hits, function($a,$b){ return $b["score"] <=> $a["score"]; });
|
||||
$top = array_slice($hits, 0, 5);
|
||||
echo json_encode($top, JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === "use") {
|
||||
$id = $in["id"] ?? "";
|
||||
foreach ($kb as &$entry) {
|
||||
if ($entry["id"] === $id) {
|
||||
$entry["use_count"] = ($entry["use_count"] ?? 0) + 1;
|
||||
@file_put_contents($store_file, json_encode($kb, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
||||
echo json_encode(["ok"=>true, "use_count"=>$entry["use_count"]]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
echo json_encode(["error"=>"not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === "stats") {
|
||||
$kinds = [];
|
||||
$total_uses = 0;
|
||||
foreach ($kb as $e) {
|
||||
$k = $e["kind"] ?? "flowchart";
|
||||
$kinds[$k] = ($kinds[$k] ?? 0) + 1;
|
||||
$total_uses += ($e["use_count"] ?? 0);
|
||||
}
|
||||
echo json_encode([
|
||||
"total_diagrams" => count($kb),
|
||||
"by_kind" => $kinds,
|
||||
"total_uses" => $total_uses,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// default: list all
|
||||
echo json_encode([
|
||||
"total" => count($kb),
|
||||
"items" => array_slice(array_reverse($kb), 0, 20),
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
190
api/ambre-multiagent-parallel.php
Normal file
190
api/ambre-multiagent-parallel.php
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-multiagent-parallel.php · wave-255 · Multi-agent parallel dispatch
|
||||
* Langue naturelle → Plan → Execute N agents in parallel → Reconcile
|
||||
*
|
||||
* POST JSON: { "goal": "texte objectif", "max_agents": 5 }
|
||||
* Response: { "ok":true, "plan":[...], "results":[...], "elapsed_ms":N, "reconciled":"..." }
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
set_time_limit(120);
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
$goal = trim($in["goal"] ?? $in["message"] ?? "");
|
||||
$max_agents = min(10, max(1, intval($in["max_agents"] ?? 5)));
|
||||
|
||||
if (!$goal) {
|
||||
echo json_encode(["error"=>"goal required"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$t0 = microtime(true);
|
||||
|
||||
// Step 1 · PLAN via LLM (one call, JSON structured)
|
||||
$plan_sys = "Tu es un planificateur multi-agent. Pour l'objectif donné, génère STRICTEMENT un JSON avec cette structure :\n" .
|
||||
"{\n" .
|
||||
" \"objective\": \"<reformulation en une phrase>\",\n" .
|
||||
" \"agents\": [\n" .
|
||||
" {\"role\":\"researcher\", \"task\":\"<tâche précise>\", \"tool\":\"<pdf_premium|mermaid|web_search|calc|image|code|translate|kb_search|none>\"},\n" .
|
||||
" ...\n" .
|
||||
" ]\n" .
|
||||
"}\n" .
|
||||
"Maximum $max_agents agents. Chaque agent a un role distinct et une tâche autonome. NE réponds QUE le JSON.";
|
||||
|
||||
$plan_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "fast",
|
||||
"messages" => [
|
||||
["role"=>"system","content"=>$plan_sys],
|
||||
["role"=>"user","content"=>"Objectif: " . $goal]
|
||||
],
|
||||
"max_tokens" => 800,
|
||||
"temperature" => 0.3,
|
||||
]),
|
||||
"timeout" => 20,
|
||||
],
|
||||
]));
|
||||
|
||||
$plan_data = @json_decode($plan_raw, true);
|
||||
$plan_text = $plan_data["choices"][0]["message"]["content"] ?? "";
|
||||
$plan_text = preg_replace('/^```(?:json)?\s*/m', '', $plan_text);
|
||||
$plan_text = preg_replace('/\s*```\s*$/m', '', trim($plan_text));
|
||||
$plan = @json_decode($plan_text, true);
|
||||
|
||||
if (!$plan || !isset($plan["agents"]) || !is_array($plan["agents"])) {
|
||||
echo json_encode(["error"=>"LLM plan invalid", "raw"=>substr($plan_text, 0, 500)]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$plan_ms = round((microtime(true)-$t0)*1000);
|
||||
|
||||
// Step 2 · EXECUTE agents en parallèle via curl_multi
|
||||
$agents = array_slice($plan["agents"], 0, $max_agents);
|
||||
$mh = curl_multi_init();
|
||||
$handles = [];
|
||||
|
||||
$tool_map = [
|
||||
"pdf_premium" => ["url"=>"http://127.0.0.1/api/ambre-tool-pdf-premium.php", "body_key"=>"topic"],
|
||||
"mermaid" => ["url"=>"http://127.0.0.1/api/ambre-tool-mermaid.php", "body_key"=>"topic"],
|
||||
"web_search" => ["url"=>"http://127.0.0.1/api/ambre-tool-web-search.php", "body_key"=>"query"],
|
||||
"calc" => ["url"=>"http://127.0.0.1/api/ambre-tool-calc.php", "body_key"=>"expression"],
|
||||
"kb_search" => ["url"=>"http://127.0.0.1/api/ambre-mermaid-learn.php", "body_key"=>"query"],
|
||||
];
|
||||
|
||||
$exec_t0 = microtime(true);
|
||||
foreach ($agents as $i => $agent) {
|
||||
$tool = $agent["tool"] ?? "none";
|
||||
$task = $agent["task"] ?? "";
|
||||
if ($tool === "none" || !isset($tool_map[$tool])) {
|
||||
// No tool → LLM direct reasoning
|
||||
$ch = curl_init("http://127.0.0.1:4000/v1/chat/completions");
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode([
|
||||
"model"=>"fast",
|
||||
"messages"=>[["role"=>"user","content"=>$task]],
|
||||
"max_tokens"=>400,
|
||||
]),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
} else {
|
||||
$cfg = $tool_map[$tool];
|
||||
$body = [$cfg["body_key"] => $task];
|
||||
if ($tool === "kb_search") $body["action"] = "search";
|
||||
$ch = curl_init($cfg["url"]);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
|
||||
CURLOPT_POSTFIELDS => json_encode($body),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 45,
|
||||
CURLOPT_CONNECTTIMEOUT => 3,
|
||||
]);
|
||||
}
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
$handles[$i] = ["ch"=>$ch, "agent"=>$agent, "t0"=>microtime(true)];
|
||||
}
|
||||
|
||||
// Run all in parallel
|
||||
$running = null;
|
||||
do {
|
||||
curl_multi_exec($mh, $running);
|
||||
curl_multi_select($mh, 0.5);
|
||||
} while ($running > 0);
|
||||
|
||||
// Collect results
|
||||
$results = [];
|
||||
foreach ($handles as $i => $h) {
|
||||
$output = curl_multi_getcontent($h["ch"]);
|
||||
$elapsed_ms = round((microtime(true)-$h["t0"])*1000);
|
||||
$http_code = curl_getinfo($h["ch"], CURLINFO_HTTP_CODE);
|
||||
curl_multi_remove_handle($mh, $h["ch"]);
|
||||
curl_close($h["ch"]);
|
||||
|
||||
// Try to extract meaningful summary
|
||||
$result_data = @json_decode($output, true);
|
||||
$summary = "";
|
||||
if ($result_data) {
|
||||
if (isset($result_data["mermaid_code"])) $summary = "Mermaid généré (" . strlen($result_data["mermaid_code"]) . "B)";
|
||||
elseif (isset($result_data["url"])) $summary = "PDF: " . $result_data["url"];
|
||||
elseif (isset($result_data["choices"][0]["message"]["content"])) $summary = substr($result_data["choices"][0]["message"]["content"], 0, 300);
|
||||
elseif (isset($result_data["result"])) $summary = (string)$result_data["result"];
|
||||
else $summary = substr($output, 0, 200);
|
||||
} else {
|
||||
$summary = substr($output ?: "empty", 0, 200);
|
||||
}
|
||||
|
||||
$results[] = [
|
||||
"agent" => $h["agent"]["role"] ?? "agent_$i",
|
||||
"task" => $h["agent"]["task"] ?? "",
|
||||
"tool" => $h["agent"]["tool"] ?? "none",
|
||||
"http" => $http_code,
|
||||
"elapsed_ms" => $elapsed_ms,
|
||||
"summary" => $summary,
|
||||
];
|
||||
}
|
||||
curl_multi_close($mh);
|
||||
$exec_ms = round((microtime(true)-$exec_t0)*1000);
|
||||
|
||||
// Step 3 · RECONCILE (synthesis LLM call)
|
||||
$synth_input = "Objectif: " . $goal . "\n\nRésultats des " . count($results) . " agents:\n";
|
||||
foreach ($results as $r) {
|
||||
$synth_input .= "- " . $r["agent"] . " (" . $r["tool"] . "): " . substr($r["summary"], 0, 300) . "\n";
|
||||
}
|
||||
$synth_input .= "\nSynthétise la réponse finale en français clair et actionnable. Max 200 mots.";
|
||||
|
||||
$synth_raw = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode([
|
||||
"model" => "fast",
|
||||
"messages" => [["role"=>"user","content"=>$synth_input]],
|
||||
"max_tokens" => 500,
|
||||
]),
|
||||
"timeout" => 15,
|
||||
],
|
||||
]));
|
||||
$synth_data = @json_decode($synth_raw, true);
|
||||
$reconciled = $synth_data["choices"][0]["message"]["content"] ?? "Synthèse échouée";
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"goal" => $goal,
|
||||
"plan" => $plan,
|
||||
"plan_ms" => $plan_ms,
|
||||
"results" => $results,
|
||||
"exec_ms" => $exec_ms,
|
||||
"parallel_speedup" => round(array_sum(array_column($results, "elapsed_ms")) / max($exec_ms, 1), 2),
|
||||
"reconciled" => trim($reconciled),
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"agents_count" => count($results),
|
||||
"provider" => "WEVIA MultiAgent Parallel Engine · wave-255",
|
||||
], JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
|
||||
39
api/ambre-orphans-dup.php
Normal file
39
api/ambre-orphans-dup.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Sitemap-api JSON
|
||||
$sm = @file_get_contents("https://weval-consulting.com/api/sitemap-api.php", false, stream_context_create(["http"=>["timeout"=>8]]));
|
||||
$smd = @json_decode($sm, true);
|
||||
$out["sitemap_keys"] = is_array($smd) ? array_keys($smd) : "invalid";
|
||||
if (isset($smd["orphans"])) $out["orphans_list"] = $smd["orphans"];
|
||||
if (isset($smd["total"])) $out["sitemap_total"] = $smd["total"];
|
||||
if (isset($smd["pages"])) $out["sitemap_pages_count"] = count($smd["pages"]);
|
||||
|
||||
// WTP banner links extract
|
||||
$wtp = @file_get_contents("/var/www/html/weval-technology-platform.html");
|
||||
preg_match_all("/href=[\"']([^\"']+\.html[^\"']*)[\"']/", $wtp, $m);
|
||||
$links = array_unique($m[1] ?? []);
|
||||
$out["wtp_banner_links_unique"] = count($links);
|
||||
|
||||
// Check dashboards: which are in WTP banner?
|
||||
$dashboards = array_map("basename", glob("/var/www/html/*dashboard*.html") ?: []);
|
||||
$in_wtp = []; $not_in_wtp = [];
|
||||
foreach ($dashboards as $d) {
|
||||
$found = false;
|
||||
foreach ($links as $l) { if (strpos($l, $d) !== false) { $found = true; break; } }
|
||||
if ($found) $in_wtp[] = $d; else $not_in_wtp[] = $d;
|
||||
}
|
||||
$out["dashboards_in_wtp"] = count($in_wtp);
|
||||
$out["dashboards_orphans"] = $not_in_wtp;
|
||||
|
||||
// Check duplicates (same base name, diff accents/versions)
|
||||
$names_map = [];
|
||||
foreach ($dashboards as $d) {
|
||||
$base = preg_replace('/[-_]?(v\d+|live|new|old)\.html$/i', '', $d);
|
||||
$names_map[$base] = ($names_map[$base] ?? 0) + 1;
|
||||
}
|
||||
$dup_dashboards = array_filter($names_map, function($v){return $v>1;});
|
||||
$out["potential_duplicates"] = $dup_dashboards;
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
31
api/ambre-oss-state.php
Normal file
31
api/ambre-oss-state.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$files = [
|
||||
"/var/www/html/api/oss-registry.json",
|
||||
"/var/www/html/oss-registry.json",
|
||||
"/var/www/html/oss-catalog.html",
|
||||
];
|
||||
$out = [];
|
||||
foreach ($files as $f) {
|
||||
if (file_exists($f)) {
|
||||
$out[basename($f)] = [
|
||||
"size" => filesize($f),
|
||||
"mtime" => date("Y-m-d H:i", filemtime($f)),
|
||||
];
|
||||
if (substr($f, -5) === ".json") {
|
||||
$data = json_decode(@file_get_contents($f), true);
|
||||
$out[basename($f)]["tool_count"] = is_array($data) ? count($data) : 0;
|
||||
if (is_array($data)) {
|
||||
$cats = [];
|
||||
foreach ($data as $d) {
|
||||
$c = $d["category"] ?? $d["cat"] ?? "unknown";
|
||||
$cats[$c] = ($cats[$c] ?? 0) + 1;
|
||||
}
|
||||
$out[basename($f)]["cats"] = $cats;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$out[basename($f)] = "NOT FOUND";
|
||||
}
|
||||
}
|
||||
echo json_encode($out, JSON_PRETTY_PRINT);
|
||||
27
api/ambre-oss-wire.php
Normal file
27
api/ambre-oss-wire.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/oss-catalog.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
if (strpos($c, "dashboards-hub-unified") !== false) {
|
||||
echo json_encode(["already"=>true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Inject in footer
|
||||
$old = '<a href="/dashboards-index.html">Dashboards</a>';
|
||||
$new = '<a href="/dashboards-hub-unified.html">📊 Hub Dashboards</a> · <a href="/dashboards-index.html">Index</a>';
|
||||
|
||||
if (strpos($c, $old) !== false) {
|
||||
$c = str_replace($old, $new, $c);
|
||||
$backup = "/opt/wevads/vault/oss-catalog.GOLD-" . date("Ymd-His") . "-wave246";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
echo json_encode([
|
||||
"wrote" => $wrote,
|
||||
"delta" => strlen($c) - $orig,
|
||||
]);
|
||||
} else {
|
||||
echo json_encode(["error"=>"anchor not found"]);
|
||||
}
|
||||
79
api/ambre-pdf-enh.php
Normal file
79
api/ambre-pdf-enh.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/api/ambre-tool-pdf-premium.php";
|
||||
$c = @file_get_contents($path);
|
||||
|
||||
// Enhance the system prompt to suggest best chart type based on topic
|
||||
$old_sys = '"chart_data\": {\n \"type\": \"bar\",';
|
||||
$new_sys = '"chart_data\": {\n \"type\": \"bar\", // or \"pie\", \"line\", \"doughnut\", \"radar\", \"polarArea\" selon le sujet',
|
||||
|
||||
if (strpos($c, $old_sys) !== false) {
|
||||
$c = str_replace($old_sys, $new_sys, $c);
|
||||
}
|
||||
|
||||
// Enhance the rendered Chart.js config to handle different types with proper options
|
||||
$old_js_chart = 'new Chart(ctx, {
|
||||
type: cd.type || "$chart_type",
|
||||
data: {
|
||||
labels: cd.labels || [],
|
||||
datasets: [{
|
||||
label: cd.title || "Données",
|
||||
data: cd.values || [],
|
||||
backgroundColor: ["#6366f1","#8b5cf6","#3b82f6","#06b6d4","#10b981","#f59e0b","#ef4444","#ec4899"],
|
||||
borderColor: "#4338ca",
|
||||
borderWidth: 2,
|
||||
borderRadius: 6,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: { legend: { display: false }, title: { display: true, text: cd.title, color: "#334155", font:{size:14}}},
|
||||
scales: { y: { beginAtZero: true, grid:{color:"#f1f5f9"}}, x: {grid:{display:false}}},
|
||||
}
|
||||
});';
|
||||
|
||||
$new_js_chart = 'var _chartType = cd.type || "bar";
|
||||
var _palette = ["#6366f1","#8b5cf6","#3b82f6","#06b6d4","#10b981","#f59e0b","#ef4444","#ec4899","#84cc16","#f97316"];
|
||||
var _dataset = {
|
||||
label: cd.title || "Données",
|
||||
data: cd.values || [],
|
||||
backgroundColor: (["pie","doughnut","polarArea"].indexOf(_chartType) >= 0) ? _palette : _palette.slice(0, (cd.values||[]).length),
|
||||
borderColor: (["line","radar"].indexOf(_chartType) >= 0) ? "#6366f1" : "#4338ca",
|
||||
borderWidth: (["pie","doughnut","polarArea"].indexOf(_chartType) >= 0) ? 2 : (["line","radar"].indexOf(_chartType) >= 0 ? 3 : 2),
|
||||
borderRadius: (_chartType === "bar") ? 6 : 0,
|
||||
tension: (_chartType === "line") ? 0.35 : 0,
|
||||
fill: (_chartType === "line") ? false : true,
|
||||
pointBackgroundColor: "#6366f1",
|
||||
pointRadius: (["line","radar"].indexOf(_chartType) >= 0) ? 5 : 0,
|
||||
};
|
||||
var _showLegend = (["pie","doughnut","polarArea","radar"].indexOf(_chartType) >= 0);
|
||||
var _showScales = (["pie","doughnut","polarArea","radar"].indexOf(_chartType) < 0);
|
||||
new Chart(ctx, {
|
||||
type: _chartType,
|
||||
data: { labels: cd.labels || [], datasets: [_dataset] },
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: { display: _showLegend, position: "bottom", labels: {boxWidth: 12, font: {size: 11}}},
|
||||
title: { display: true, text: cd.title || "Données", color: "#334155", font: {size: 14, weight: "600"}, padding: {top: 4, bottom: 14}}
|
||||
},
|
||||
scales: _showScales ? { y: { beginAtZero: true, grid: {color: "#f1f5f9"}}, x: {grid: {display: false}}} : {},
|
||||
}
|
||||
});';
|
||||
|
||||
if (strpos($c, $old_js_chart) !== false) {
|
||||
$c = str_replace($old_js_chart, $new_js_chart, $c);
|
||||
}
|
||||
|
||||
// Save
|
||||
$backup = "/opt/wevads/vault/pdf-premium.GOLD-" . date("Ymd-His") . "-chart-types";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"wrote" => $wrote,
|
||||
"size" => strlen($c),
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
59
api/ambre-pdf-i18n.php
Normal file
59
api/ambre-pdf-i18n.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/api/ambre-tool-pdf-premium.php";
|
||||
$c = @file_get_contents($path);
|
||||
|
||||
// Add lang detection + multi-prompt
|
||||
$old_sys = '$sys = "Tu es un expert en création de rapports business premium. Pour le sujet donné, génère UNIQUEMENT un JSON valide avec cette structure exacte (pas de markdown, pas d\'explication) :';
|
||||
|
||||
$new_sys = '// i18n language detection (simple heuristic)
|
||||
$topic_lower = mb_strtolower($topic);
|
||||
$lang = $in["lang"] ?? null;
|
||||
if (!$lang) {
|
||||
// Detect from content
|
||||
if (preg_match("/\b(the|is|are|and|of|for|to|with|on|in|a)\b/i", $topic_lower) && !preg_match("/\b(le|la|les|du|des|pour|avec)\b/i", $topic_lower)) {
|
||||
$lang = "en";
|
||||
} elseif (preg_match("/[\x{0600}-\x{06FF}]/u", $topic)) {
|
||||
$lang = "ar";
|
||||
} else {
|
||||
$lang = "fr";
|
||||
}
|
||||
}
|
||||
|
||||
// Prompts by language
|
||||
$prompts = [
|
||||
"fr" => "Tu es un expert en création de rapports business premium. Pour le sujet donné, génère UNIQUEMENT un JSON valide avec cette structure exacte (pas de markdown, pas d\'explication) :",
|
||||
"en" => "You are an expert in premium business report creation. For the given topic, generate ONLY valid JSON with this exact structure (no markdown, no explanation). All text in English :",
|
||||
"ar" => "أنت خبير في إنشاء تقارير الأعمال المتميزة. للموضوع المحدد، قم بإنشاء JSON صالح فقط بهذه البنية الدقيقة (بدون markdown، بدون شرح). جميع النصوص باللغة العربية :",
|
||||
];
|
||||
$sys = $prompts[$lang] ?? $prompts["fr"];
|
||||
$sys .= "';
|
||||
|
||||
if (strpos($c, $old_sys) === false) {
|
||||
echo json_encode(["error"=>"sys prompt pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old_sys, $new_sys, $c);
|
||||
|
||||
// Also add the lang to output
|
||||
$old_out = '"provider" => "WEVIA PDF Premium Engine",';
|
||||
$new_out = '"provider" => "WEVIA PDF Premium Engine",
|
||||
"lang" => $lang,';
|
||||
|
||||
if (strpos($c, $old_out) !== false) {
|
||||
$c = str_replace($old_out, $new_out, $c);
|
||||
}
|
||||
|
||||
$backup = "/opt/wevads/vault/pdf-premium.GOLD-" . date("Ymd-His") . "-i18n";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
// Lint
|
||||
$lint = @shell_exec("php -l $path 2>&1");
|
||||
|
||||
echo json_encode([
|
||||
"wrote" => $wrote,
|
||||
"size" => strlen($c),
|
||||
"backup" => basename($backup),
|
||||
"lint" => trim($lint),
|
||||
]);
|
||||
@@ -59,18 +59,18 @@
|
||||
},
|
||||
"suites": [
|
||||
{
|
||||
"title": "v30-final-showcase.spec.js",
|
||||
"file": "v30-final-showcase.spec.js",
|
||||
"title": "v47-widget.spec.js",
|
||||
"file": "v47-widget.spec.js",
|
||||
"column": 0,
|
||||
"line": 0,
|
||||
"specs": [
|
||||
{
|
||||
"title": "V30 · SHOWCASE CLIENT · 12 turns · Laura Carrefour Maroc",
|
||||
"title": "V47 · Universal chat widget on all-ia-hub",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 1200000,
|
||||
"timeout": 60000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "chromium",
|
||||
@@ -80,138 +80,36 @@
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 416707,
|
||||
"duration": 35410,
|
||||
"errors": [],
|
||||
"stdout": [
|
||||
{
|
||||
"text": "📸 Landing\n"
|
||||
"text": "Widget button count: 1\n"
|
||||
},
|
||||
{
|
||||
"text": "\n[01/12] 01-hi · Bonjour, présente toi\n"
|
||||
"text": "Response: Bonjour ! Je suis désolé, mais je ne peux pas accéder à votre `chat_id` directement. Ce genre d'information dépend de la plateforme ou du système dans lequel nous interagissons (comme une API, une application, ou un service interne).\n\nSi vous utilisez un service WEVAL Consulting connecté à un système de gestion des conversations, je peux vous aider à le retrouver ou à le générer — pour cela, pourr\n"
|
||||
},
|
||||
{
|
||||
"text": " ✅ 1.5s · Enchanté ! Je suis WEVIA, consultant au sein de WEVAL Consulting, une entreprise spécialisée dans la croissance et le développement des entr\n"
|
||||
"text": "Turns: 2\n"
|
||||
},
|
||||
{
|
||||
"text": "\n[02/12] 02-onboard · je m'appelle Laura, je dirige le marketing chez Carrefour Ma\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 30.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[03/12] 03-calc · calcule 2450 * 1.18 + 900\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 21.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[04/12] 04-qr · QR code pour https://carrefour.ma\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 21.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[05/12] 05-image · cree une image de: supermarché moderne éclairé\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 36.4s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[06/12] 06-pdf-prem · genere un PDF premium avec graphique sur: stratégie retail d\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 60.2s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[07/12] 07-hd · image HD 4K de: rétail store premium lighting\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 36.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[08/12] 08-search · actualités retail e-commerce Maroc 2026\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 36.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[09/12] 09-recall · tu te souviens de mon nom et entreprise?\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 25.6s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[10/12] 10-mermaid · schéma mermaid du parcours client retail omnicanal\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 30.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[11/12] 11-pptx · genere une presentation pptx 5 piliers IA retail\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 45.2s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n[12/12] 12-bilan · récapitule ce qu'on a fait ensemble\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ 30.1s · \n"
|
||||
},
|
||||
{
|
||||
"text": "\n═══ V30 SHOWCASE BILAN · 1/12 PASS · 0 errors ═══\n"
|
||||
},
|
||||
{
|
||||
"text": " ✅ T1 · 01-hi · 1.5s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T2 · 02-onboard · 30.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T3 · 03-calc · 21.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T4 · 04-qr · 21.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T5 · 05-image · 36.4s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T6 · 06-pdf-prem · 60.2s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T7 · 07-hd · 36.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T8 · 08-search · 36.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T9 · 09-recall · 25.6s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T10 · 10-mermaid · 30.1s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T11 · 11-pptx · 45.2s\n"
|
||||
},
|
||||
{
|
||||
"text": " ⚠️ T12 · 12-bilan · 30.1s\n"
|
||||
"text": "Multi-agent mode triggered: true in 24.1s\n"
|
||||
}
|
||||
],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-04-22T00:48:02.981Z",
|
||||
"startTime": "2026-04-22T03:12:24.466Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "screenshot",
|
||||
"contentType": "image/png",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v30-final-showcase-V30-·-S-60a02-rns-·-Laura-Carrefour-Maroc-chromium/test-finished-1.png"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v47-widget-V47-·-Universal-chat-widget-on-all-ia-hub-chromium/test-finished-1.png"
|
||||
},
|
||||
{
|
||||
"name": "video",
|
||||
"contentType": "video/webm",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v30-final-showcase-V30-·-S-60a02-rns-·-Laura-Carrefour-Maroc-chromium/video.webm"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v47-widget-V47-·-Universal-chat-widget-on-all-ia-hub-chromium/video.webm"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -219,9 +117,9 @@
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "cc4310032093e4e60c9b-6c3cb198aa2caa48f606",
|
||||
"file": "v30-final-showcase.spec.js",
|
||||
"line": 4,
|
||||
"id": "59fd77abc000aff557d3-1aa334e6a3d56f78c672",
|
||||
"file": "v47-widget.spec.js",
|
||||
"line": 3,
|
||||
"column": 1
|
||||
}
|
||||
]
|
||||
@@ -229,8 +127,8 @@
|
||||
],
|
||||
"errors": [],
|
||||
"stats": {
|
||||
"startTime": "2026-04-22T00:48:02.397Z",
|
||||
"duration": 417457.003,
|
||||
"startTime": "2026-04-22T03:12:23.770Z",
|
||||
"duration": 36288.549999999996,
|
||||
"expected": 1,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"pass": 1,
|
||||
"total": 12,
|
||||
"results": [
|
||||
{
|
||||
"t": 1,
|
||||
"lb": "01-hi",
|
||||
"pass": true,
|
||||
"err": false,
|
||||
"el": "1.5"
|
||||
},
|
||||
{
|
||||
"t": 2,
|
||||
"lb": "02-onboard",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "30.1"
|
||||
},
|
||||
{
|
||||
"t": 3,
|
||||
"lb": "03-calc",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "21.1"
|
||||
},
|
||||
{
|
||||
"t": 4,
|
||||
"lb": "04-qr",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "21.1"
|
||||
},
|
||||
{
|
||||
"t": 5,
|
||||
"lb": "05-image",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "36.4"
|
||||
},
|
||||
{
|
||||
"t": 6,
|
||||
"lb": "06-pdf-prem",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "60.2"
|
||||
},
|
||||
{
|
||||
"t": 7,
|
||||
"lb": "07-hd",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "36.1"
|
||||
},
|
||||
{
|
||||
"t": 8,
|
||||
"lb": "08-search",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "36.1"
|
||||
},
|
||||
{
|
||||
"t": 9,
|
||||
"lb": "09-recall",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "25.6"
|
||||
},
|
||||
{
|
||||
"t": 10,
|
||||
"lb": "10-mermaid",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "30.1"
|
||||
},
|
||||
{
|
||||
"t": 11,
|
||||
"lb": "11-pptx",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "45.2"
|
||||
},
|
||||
{
|
||||
"t": 12,
|
||||
"lb": "12-bilan",
|
||||
"pass": false,
|
||||
"err": false,
|
||||
"el": "30.1"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 127 KiB |
BIN
api/ambre-pw-tests/output/v47-00-initial.png
Normal file
BIN
api/ambre-pw-tests/output/v47-00-initial.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
BIN
api/ambre-pw-tests/output/v47-01-opened.png
Normal file
BIN
api/ambre-pw-tests/output/v47-01-opened.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
api/ambre-pw-tests/output/v47-02-chat.png
Normal file
BIN
api/ambre-pw-tests/output/v47-02-chat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 202 KiB |
BIN
api/ambre-pw-tests/output/v47-03-multiagent.png
Normal file
BIN
api/ambre-pw-tests/output/v47-03-multiagent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 242 KiB |
Binary file not shown.
@@ -1,92 +0,0 @@
|
||||
const { test } = require("@playwright/test");
|
||||
const fs = require("fs");
|
||||
|
||||
test("V30 · SHOWCASE CLIENT · 12 turns · Laura Carrefour Maroc", async ({ page }) => {
|
||||
test.setTimeout(1200000);
|
||||
|
||||
await page.goto("/wevia.html");
|
||||
await page.evaluate(() => { try { sessionStorage.clear(); localStorage.clear(); } catch(e){} });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(3000);
|
||||
await page.screenshot({ path: "output/v30-00-landing.png" });
|
||||
console.log("📸 Landing");
|
||||
|
||||
const turns = [
|
||||
{ lb: "01-hi", msg: "Bonjour, présente toi", needle: /WEVIA|bonjour|aider|consulting/i, mx: 25 },
|
||||
{ lb: "02-onboard", msg: "je m'appelle Laura, je dirige le marketing chez Carrefour Maroc", needle: /Laura/i, mx: 30 },
|
||||
{ lb: "03-calc", msg: "calcule 2450 * 1.18 + 900", needle: /3791|3792|🧮|calcul/i, mx: 20 },
|
||||
{ lb: "04-qr", msg: "QR code pour https://carrefour.ma", needle: /wevia-qr-|📱|QR/i, mx: 20 },
|
||||
{ lb: "05-image", msg: "cree une image de: supermarché moderne éclairé", needle: /wevia-img-|🎨|image/i, mx: 35 },
|
||||
{ lb: "06-pdf-prem", msg: "genere un PDF premium avec graphique sur: stratégie retail digital Carrefour Maroc 2026", needle: /PDF Premium|\.pdf|📄|pages/i, mx: 60 },
|
||||
{ lb: "07-hd", msg: "image HD 4K de: rétail store premium lighting", needle: /wevia-hd-|4K/i, mx: 35 },
|
||||
{ lb: "08-search", msg: "actualités retail e-commerce Maroc 2026", needle: /🔍|source|actual|e-comm/i, mx: 35 },
|
||||
{ lb: "09-recall", msg: "tu te souviens de mon nom et entreprise?", needle: /Laura.*Carrefour|Carrefour.*Laura/i, mx: 25 },
|
||||
{ lb: "10-mermaid", msg: "schéma mermaid du parcours client retail omnicanal", needle: /graph|flowchart|mermaid/i, mx: 30 },
|
||||
{ lb: "11-pptx", msg: "genere une presentation pptx 5 piliers IA retail", needle: /\.pptx|📊|PowerPoint|presentation/i, mx: 45 },
|
||||
{ lb: "12-bilan", msg: "récapitule ce qu'on a fait ensemble", needle: /Laura|Carrefour|PDF|image|QR|pptx|parcours/i, mx: 30 },
|
||||
];
|
||||
|
||||
const results = [];
|
||||
|
||||
for (let i = 0; i < turns.length; i++) {
|
||||
const t = turns[i];
|
||||
const num = String(i+1).padStart(2,"0");
|
||||
console.log(`\n[${num}/12] ${t.lb} · ${t.msg.substring(0,60)}`);
|
||||
|
||||
try {
|
||||
const input = page.locator("#msgInput");
|
||||
await input.click({force:true});
|
||||
await page.keyboard.press("Control+A");
|
||||
await page.keyboard.press("Delete");
|
||||
await input.fill(t.msg);
|
||||
await page.waitForTimeout(400);
|
||||
|
||||
const beforeCount = await page.evaluate(() => document.querySelectorAll(".msg.assistant").length);
|
||||
await input.press("Enter");
|
||||
|
||||
const ws = Date.now();
|
||||
let found = false; let reply = ""; let hasErr = false;
|
||||
|
||||
while (Date.now() - ws < t.mx * 1000) {
|
||||
const s = await page.evaluate((bc) => {
|
||||
const a = Array.from(document.querySelectorAll(".msg.assistant .bubble"));
|
||||
const cnt = a.length;
|
||||
const last = cnt > bc ? a[a.length-1].innerText : "";
|
||||
return { cnt, last };
|
||||
}, beforeCount);
|
||||
|
||||
if (s.cnt > beforeCount && s.last.length > 25) {
|
||||
reply = s.last;
|
||||
if (t.needle.test(reply)) { found = true; break; }
|
||||
if (/une erreur|indisponible/i.test(reply)) { hasErr = true; break; }
|
||||
}
|
||||
await page.waitForTimeout(1500);
|
||||
}
|
||||
|
||||
const el = ((Date.now()-ws)/1000).toFixed(1);
|
||||
const st = found ? "✅" : (hasErr ? "❌" : "⚠️");
|
||||
console.log(` ${st} ${el}s · ${reply.substring(0,140).replace(/\n/g,' ')}`);
|
||||
|
||||
await page.evaluate(() => { const m = document.getElementById("messages"); if(m) m.scrollTop = m.scrollHeight; });
|
||||
await page.waitForTimeout(1200);
|
||||
await page.screenshot({ path: `output/v30-${num}-${t.lb}.png` });
|
||||
|
||||
results.push({ t: i+1, lb: t.lb, pass: found, err: hasErr, el });
|
||||
await page.waitForTimeout(800);
|
||||
} catch (e) {
|
||||
console.log(` ❌ exception: ${e.message.substring(0,90)}`);
|
||||
results.push({ t: i+1, lb: t.lb, pass: false, err: true });
|
||||
}
|
||||
}
|
||||
|
||||
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
||||
await page.waitForTimeout(2000);
|
||||
await page.screenshot({ path: "output/v30-99-final.png", fullPage: true });
|
||||
|
||||
const p = results.filter(r=>r.pass).length;
|
||||
const e = results.filter(r=>r.err).length;
|
||||
console.log(`\n═══ V30 SHOWCASE BILAN · ${p}/${results.length} PASS · ${e} errors ═══`);
|
||||
results.forEach(r => console.log(` ${r.pass?"✅":(r.err?"❌":"⚠️")} T${r.t} · ${r.lb} · ${r.el||"?"}s`));
|
||||
|
||||
fs.writeFileSync("output/v30-bilan.json", JSON.stringify({ pass: p, total: results.length, results }, null, 2));
|
||||
});
|
||||
65
api/ambre-pw-tests/tests/v47-widget.spec.js
Normal file
65
api/ambre-pw-tests/tests/v47-widget.spec.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const { test } = require("@playwright/test");
|
||||
|
||||
test("V47 · Universal chat widget on all-ia-hub", async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto("/all-ia-hub.html?cb=" + Date.now());
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
// Check button present
|
||||
const btn = await page.locator(".amw-btn").count();
|
||||
console.log(`Widget button count: ${btn}`);
|
||||
|
||||
if (btn > 0) {
|
||||
await page.screenshot({ path: "output/v47-00-initial.png" });
|
||||
|
||||
// Click to open panel
|
||||
await page.locator(".amw-btn").click();
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: "output/v47-01-opened.png" });
|
||||
|
||||
// Send a message
|
||||
await page.locator("#amwInput").fill("Bonjour, quel est mon chat_id ?");
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator("#amwSend").click();
|
||||
|
||||
// Wait for response
|
||||
const ws = Date.now();
|
||||
while (Date.now() - ws < 30000) {
|
||||
const msgs = await page.locator(".amw-msg.a").count();
|
||||
if (msgs > 1) break; // We need at least greeting + response
|
||||
await page.waitForTimeout(1000);
|
||||
}
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: "output/v47-02-chat.png", fullPage: false });
|
||||
|
||||
// Get last message text
|
||||
const txt = await page.locator(".amw-msg.a").last().innerText();
|
||||
console.log(`Response: ${txt.substring(0, 400)}`);
|
||||
|
||||
// Check turns counter
|
||||
const turns = await page.locator("#amwTurns").innerText();
|
||||
console.log(`Turns: ${turns}`);
|
||||
|
||||
// Test multi-agent
|
||||
await page.locator("#amwInput").fill("fais une analyse complete du marche IA 2026");
|
||||
await page.waitForTimeout(300);
|
||||
await page.locator("#amwSend").click();
|
||||
|
||||
const ws2 = Date.now();
|
||||
let found = false;
|
||||
while (Date.now() - ws2 < 90000) {
|
||||
const ma = await page.locator(".amw-msg.a.ma").count();
|
||||
if (ma > 0) { found = true; break; }
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
console.log(`Multi-agent mode triggered: ${found} in ${((Date.now()-ws2)/1000).toFixed(1)}s`);
|
||||
await page.waitForTimeout(1500);
|
||||
await page.screenshot({ path: "output/v47-03-multiagent.png", fullPage: false });
|
||||
|
||||
} else {
|
||||
console.log("❌ Widget button not found");
|
||||
await page.screenshot({ path: "output/v47-nowidget.png", fullPage: true });
|
||||
}
|
||||
});
|
||||
87
api/ambre-pw-tests/v158_metrics.js
Normal file
87
api/ambre-pw-tests/v158_metrics.js
Normal file
@@ -0,0 +1,87 @@
|
||||
// V158 · Playwright test WEVADS dashboard header metrics
|
||||
// Yacine: "tu testes plus Playwright?" → on teste fr le browser réel
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
args: ['--no-sandbox', '--use-gl=swiftshader']
|
||||
});
|
||||
const ctx = await browser.newContext({
|
||||
ignoreHTTPSErrors: true,
|
||||
viewport: { width: 1920, height: 1080 }
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Capture JS errors + console
|
||||
const errors = [];
|
||||
const consoles = [];
|
||||
page.on('pageerror', e => errors.push(e.message));
|
||||
page.on('console', m => consoles.push(`[${m.type()}] ${m.text()}`));
|
||||
|
||||
// Step 1: Login first
|
||||
console.log('STEP 1: Navigate to WEVADS login');
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
|
||||
// Fill login form (Yacine credentials known via memory)
|
||||
console.log('STEP 2: Fill login');
|
||||
await page.fill('input[name="email"]', 'yacine@weval-consulting.com').catch(() => {});
|
||||
await page.fill('input[name="password"]', 'WevAds2026!').catch(() => {});
|
||||
await page.click('button[type="submit"]').catch(() => {});
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('STEP 3: Navigate to dashboard');
|
||||
await page.goto('https://wevads.weval-consulting.com/dashboard.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(5000); // Wait for setInterval to fire
|
||||
|
||||
// Check current URL (still on login = bad credentials)
|
||||
const url = page.url();
|
||||
console.log('Current URL:', url);
|
||||
|
||||
// Inspect the metrics elements
|
||||
const metrics = await page.evaluate(() => {
|
||||
const cpuUsage = document.getElementById('cpu-usage');
|
||||
const ramUsage = document.getElementById('ram-usage');
|
||||
const storageUsage = document.getElementById('storage-usage');
|
||||
const cpuBar = document.getElementById('cpu-bar');
|
||||
const ramBar = document.getElementById('ram-bar');
|
||||
const storageBar = document.getElementById('storage-bar');
|
||||
return {
|
||||
hasJQuery: typeof jQuery !== 'undefined' || typeof $ !== 'undefined',
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
hasInit: typeof SystemMetrics !== 'undefined' && typeof SystemMetrics.init === 'function',
|
||||
baseUrl: typeof window !== 'undefined' ? window.APP_BASE_URL : 'no-window',
|
||||
cpuUsageText: cpuUsage ? cpuUsage.textContent : null,
|
||||
ramUsageText: ramUsage ? ramUsage.textContent : null,
|
||||
storageUsageText: storageUsage ? storageUsage.textContent : null,
|
||||
cpuBarWidth: cpuBar ? cpuBar.style.width : null,
|
||||
ramBarWidth: ramBar ? ramBar.style.width : null,
|
||||
storageBarWidth: storageBar ? storageBar.style.width : null,
|
||||
hasV1522Marker: document.documentElement.outerHTML.includes('V152.2 Opus')
|
||||
};
|
||||
});
|
||||
|
||||
console.log('METRICS STATE:', JSON.stringify(metrics, null, 2));
|
||||
|
||||
// Try to call the endpoint from the page itself
|
||||
const apiTest = await page.evaluate(async () => {
|
||||
try {
|
||||
const r = await fetch('/api/system-metrics.php');
|
||||
return { status: r.status, body: await r.text() };
|
||||
} catch (e) {
|
||||
return { error: e.message };
|
||||
}
|
||||
});
|
||||
console.log('API CALL FROM PAGE:', JSON.stringify(apiTest));
|
||||
|
||||
// Take screenshot
|
||||
await page.screenshot({ path: '/tmp/v158-dashboard-screenshot.png', fullPage: false });
|
||||
console.log('Screenshot saved /tmp/v158-dashboard-screenshot.png');
|
||||
|
||||
console.log('\\n--- JS ERRORS ---');
|
||||
errors.forEach(e => console.log(e));
|
||||
console.log('\\n--- CONSOLE ---');
|
||||
consoles.slice(-10).forEach(c => console.log(c));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
87
api/ambre-pw-tests/v158_metrics.spec.js
Normal file
87
api/ambre-pw-tests/v158_metrics.spec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
// V158 · Playwright test WEVADS dashboard header metrics
|
||||
// Yacine: "tu testes plus Playwright?" → on teste fr le browser réel
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
args: ['--no-sandbox', '--use-gl=swiftshader']
|
||||
});
|
||||
const ctx = await browser.newContext({
|
||||
ignoreHTTPSErrors: true,
|
||||
viewport: { width: 1920, height: 1080 }
|
||||
});
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Capture JS errors + console
|
||||
const errors = [];
|
||||
const consoles = [];
|
||||
page.on('pageerror', e => errors.push(e.message));
|
||||
page.on('console', m => consoles.push(`[${m.type()}] ${m.text()}`));
|
||||
|
||||
// Step 1: Login first
|
||||
console.log('STEP 1: Navigate to WEVADS login');
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
|
||||
// Fill login form (Yacine credentials known via memory)
|
||||
console.log('STEP 2: Fill login');
|
||||
await page.fill('input[name="email"]', 'yacine@weval-consulting.com').catch(() => {});
|
||||
await page.fill('input[name="password"]', 'WevAds2026!').catch(() => {});
|
||||
await page.click('button[type="submit"]').catch(() => {});
|
||||
await page.waitForTimeout(3000);
|
||||
|
||||
console.log('STEP 3: Navigate to dashboard');
|
||||
await page.goto('https://wevads.weval-consulting.com/dashboard.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(5000); // Wait for setInterval to fire
|
||||
|
||||
// Check current URL (still on login = bad credentials)
|
||||
const url = page.url();
|
||||
console.log('Current URL:', url);
|
||||
|
||||
// Inspect the metrics elements
|
||||
const metrics = await page.evaluate(() => {
|
||||
const cpuUsage = document.getElementById('cpu-usage');
|
||||
const ramUsage = document.getElementById('ram-usage');
|
||||
const storageUsage = document.getElementById('storage-usage');
|
||||
const cpuBar = document.getElementById('cpu-bar');
|
||||
const ramBar = document.getElementById('ram-bar');
|
||||
const storageBar = document.getElementById('storage-bar');
|
||||
return {
|
||||
hasJQuery: typeof jQuery !== 'undefined' || typeof $ !== 'undefined',
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
hasInit: typeof SystemMetrics !== 'undefined' && typeof SystemMetrics.init === 'function',
|
||||
baseUrl: typeof window !== 'undefined' ? window.APP_BASE_URL : 'no-window',
|
||||
cpuUsageText: cpuUsage ? cpuUsage.textContent : null,
|
||||
ramUsageText: ramUsage ? ramUsage.textContent : null,
|
||||
storageUsageText: storageUsage ? storageUsage.textContent : null,
|
||||
cpuBarWidth: cpuBar ? cpuBar.style.width : null,
|
||||
ramBarWidth: ramBar ? ramBar.style.width : null,
|
||||
storageBarWidth: storageBar ? storageBar.style.width : null,
|
||||
hasV1522Marker: document.documentElement.outerHTML.includes('V152.2 Opus')
|
||||
};
|
||||
});
|
||||
|
||||
console.log('METRICS STATE:', JSON.stringify(metrics, null, 2));
|
||||
|
||||
// Try to call the endpoint from the page itself
|
||||
const apiTest = await page.evaluate(async () => {
|
||||
try {
|
||||
const r = await fetch('/api/system-metrics.php');
|
||||
return { status: r.status, body: await r.text() };
|
||||
} catch (e) {
|
||||
return { error: e.message };
|
||||
}
|
||||
});
|
||||
console.log('API CALL FROM PAGE:', JSON.stringify(apiTest));
|
||||
|
||||
// Take screenshot
|
||||
await page.screenshot({ path: '/tmp/v158-dashboard-screenshot.png', fullPage: false });
|
||||
console.log('Screenshot saved /tmp/v158-dashboard-screenshot.png');
|
||||
|
||||
console.log('\\n--- JS ERRORS ---');
|
||||
errors.forEach(e => console.log(e));
|
||||
console.log('\\n--- CONSOLE ---');
|
||||
consoles.slice(-10).forEach(c => console.log(c));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
66
api/ambre-pw-tests/v158_proof.js
Normal file
66
api/ambre-pw-tests/v158_proof.js
Normal file
@@ -0,0 +1,66 @@
|
||||
// V158.3 · Take real screenshot showing metrics WORKING
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1280, height: 200 } });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Navigate to wevads (same origin)
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'networkidle' });
|
||||
|
||||
// Now build a synthetic header that mimics master.html system-metrics div
|
||||
await page.evaluate(() => {
|
||||
document.body.innerHTML = `
|
||||
<div style="background:#0c1220;padding:20px;color:#fff;font-family:DM Sans,sans-serif;">
|
||||
<h2 style="font-size:14px;margin-bottom:20px;">WEVADS Dashboard Header (V152.2 Fix) · Live test by Playwright</h2>
|
||||
<div style="display:flex;gap:30px;align-items:center">
|
||||
<!-- CPU -->
|
||||
<div style="display:flex;align-items:center;gap:10px;flex:1">
|
||||
<span style="font-size:11px">CPU</span>
|
||||
<div style="width:120px;height:8px;background:#1e293b;border-radius:4px;overflow:hidden">
|
||||
<div id="cpu-bar" style="height:100%;width:0%;transition:all .3s"></div>
|
||||
</div>
|
||||
<span id="cpu-usage" style="font-size:11px;min-width:40px">--</span>
|
||||
</div>
|
||||
<!-- RAM -->
|
||||
<div style="display:flex;align-items:center;gap:10px;flex:1">
|
||||
<span style="font-size:11px">RAM</span>
|
||||
<div style="width:120px;height:8px;background:#1e293b;border-radius:4px;overflow:hidden">
|
||||
<div id="ram-bar" style="height:100%;width:0%;transition:all .3s"></div>
|
||||
</div>
|
||||
<span id="ram-usage" style="font-size:11px;min-width:40px">--</span>
|
||||
</div>
|
||||
<!-- Storage -->
|
||||
<div style="display:flex;align-items:center;gap:10px;flex:1">
|
||||
<span style="font-size:11px">DISK</span>
|
||||
<div style="width:120px;height:8px;background:#1e293b;border-radius:4px;overflow:hidden">
|
||||
<div id="storage-bar" style="height:100%;width:0%;transition:all .3s"></div>
|
||||
</div>
|
||||
<span id="storage-usage" style="font-size:11px;min-width:40px">--</span>
|
||||
</div>
|
||||
</div>
|
||||
<p style="margin-top:20px;font-size:10px;color:#64748b">Source: /api/system-metrics.php · Auto-refresh 10s · V152.2 Opus init injection</p>
|
||||
</div>`;
|
||||
window.APP_BASE_URL = '';
|
||||
});
|
||||
|
||||
// Load jQuery + system-metrics.js
|
||||
await page.addScriptTag({ url: 'https://wevads.weval-consulting.com/plugins/jquery.min.js' });
|
||||
await page.addScriptTag({ url: 'https://wevads.weval-consulting.com/js/system-metrics.js?v=6.0' });
|
||||
await page.evaluate(() => SystemMetrics.init(''));
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
await page.screenshot({ path: '/tmp/v158-PROOF-metrics-work.png' });
|
||||
|
||||
const result = await page.evaluate(() => ({
|
||||
cpu: document.getElementById('cpu-usage').textContent,
|
||||
ram: document.getElementById('ram-usage').textContent,
|
||||
storage: document.getElementById('storage-usage').textContent,
|
||||
cpuBar: document.getElementById('cpu-bar').style.width,
|
||||
}));
|
||||
console.log('FINAL:', JSON.stringify(result));
|
||||
console.log('Screenshot: /tmp/v158-PROOF-metrics-work.png');
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
70
api/ambre-pw-tests/v158_real.js
Normal file
70
api/ambre-pw-tests/v158_real.js
Normal file
@@ -0,0 +1,70 @@
|
||||
// V158.2 · Test on REAL dashboard URL (will land on login but we can inspect)
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
const consoles = [];
|
||||
const errors = [];
|
||||
const network = [];
|
||||
page.on('pageerror', e => errors.push(e.message));
|
||||
page.on('console', m => consoles.push(`[${m.type()}] ${m.text()}`));
|
||||
page.on('response', r => {
|
||||
if (r.url().includes('system-metrics')) network.push(`${r.status()} ${r.url()}`);
|
||||
});
|
||||
|
||||
// Same origin: navigate to wevads then inject test
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'networkidle' });
|
||||
|
||||
// Now we ARE on wevads.weval-consulting.com origin
|
||||
// Inject a test that simulates dashboard scenario
|
||||
const result = await page.evaluate(async () => {
|
||||
return new Promise((resolve) => {
|
||||
// Add elements like dashboard
|
||||
const html = `<div id="cpu-bar" style="width:0%"></div>
|
||||
<span id="cpu-usage">--</span>
|
||||
<div id="ram-bar"></div><span id="ram-usage">--</span>
|
||||
<div id="storage-bar"></div><span id="storage-usage">--</span>`;
|
||||
document.body.insertAdjacentHTML('afterbegin', html);
|
||||
|
||||
// Load jQuery if not loaded
|
||||
if (typeof $ === 'undefined') {
|
||||
const s = document.createElement('script');
|
||||
s.src = '/plugins/jquery.min.js';
|
||||
document.head.appendChild(s);
|
||||
}
|
||||
|
||||
// Now load the script (same way master.html does)
|
||||
window.APP_BASE_URL = '';
|
||||
const sm = document.createElement('script');
|
||||
sm.src = '/js/system-metrics.js?v=6.0';
|
||||
sm.onload = () => {
|
||||
// Mimic the V152.2 init
|
||||
if (typeof SystemMetrics !== 'undefined' && SystemMetrics.init) {
|
||||
SystemMetrics.init('');
|
||||
}
|
||||
// Wait for first $.get to complete
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
cpuUsage: document.getElementById('cpu-usage').textContent,
|
||||
ramUsage: document.getElementById('ram-usage').textContent,
|
||||
storageUsage: document.getElementById('storage-usage').textContent,
|
||||
cpuBarWidth: document.getElementById('cpu-bar').style.width,
|
||||
});
|
||||
}, 3000);
|
||||
};
|
||||
sm.onerror = (e) => resolve({ error: 'script load failed', detail: e.message });
|
||||
document.head.appendChild(sm);
|
||||
});
|
||||
});
|
||||
|
||||
console.log('REAL ORIGIN TEST:', JSON.stringify(result, null, 2));
|
||||
console.log('Network calls:', network);
|
||||
console.log('Errors:', errors.slice(0,5));
|
||||
console.log('Console:', consoles.slice(-5));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
42
api/ambre-pw-tests/v158_synth.js
Normal file
42
api/ambre-pw-tests/v158_synth.js
Normal file
@@ -0,0 +1,42 @@
|
||||
// V158.1 · Test the JS directly without login - inject mock and run
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
// Build a synthetic page that replicates master.html structure with the script
|
||||
const syntheticHTML = `<!DOCTYPE html><html><head><title>Test</title>
|
||||
<script src="https://wevads.weval-consulting.com/plugins/jquery.min.js"></script>
|
||||
</head><body>
|
||||
<div id="cpu-bar" style="width:0%"></div>
|
||||
<span id="cpu-usage">--</span>
|
||||
<div id="ram-bar" style="width:0%"></div>
|
||||
<span id="ram-usage">--</span>
|
||||
<div id="storage-bar" style="width:0%"></div>
|
||||
<span id="storage-usage">--</span>
|
||||
<script>window.APP_BASE_URL = 'https://wevads.weval-consulting.com';</script>
|
||||
<script src="https://wevads.weval-consulting.com/js/system-metrics.js?v=6.0"></script>
|
||||
<script>
|
||||
$(function(){ if (typeof SystemMetrics !== "undefined" && SystemMetrics.init) { SystemMetrics.init(window.APP_BASE_URL || ""); } });
|
||||
</script>
|
||||
</body></html>`;
|
||||
|
||||
await page.setContent(syntheticHTML, { waitUntil: 'networkidle' });
|
||||
await page.waitForTimeout(3000); // Wait for $.get to complete
|
||||
|
||||
const result = await page.evaluate(() => ({
|
||||
hasJQuery: typeof $ !== 'undefined',
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
cpuUsage: document.getElementById('cpu-usage').textContent,
|
||||
ramUsage: document.getElementById('ram-usage').textContent,
|
||||
storageUsage: document.getElementById('storage-usage').textContent,
|
||||
cpuBarWidth: document.getElementById('cpu-bar').style.width,
|
||||
ramBarWidth: document.getElementById('ram-bar').style.width,
|
||||
storageBarWidth: document.getElementById('storage-bar').style.width,
|
||||
}));
|
||||
console.log('SYNTHETIC TEST:', JSON.stringify(result, null, 2));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
110
api/ambre-pw-tests/v160_auth.js
Normal file
110
api/ambre-pw-tests/v160_auth.js
Normal file
@@ -0,0 +1,110 @@
|
||||
// V160 · Authenticated dashboard inspection · use real DB user creds
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1280, height: 800 } });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
const allConsole = [];
|
||||
const allErrors = [];
|
||||
const networkLog = [];
|
||||
page.on('pageerror', e => allErrors.push(`PAGEERR: ${e.message}`));
|
||||
page.on('console', m => allConsole.push(`[${m.type()}] ${m.text()}`));
|
||||
page.on('response', r => {
|
||||
if (r.url().includes('system-metrics') || r.url().includes('master.html') || r.status() >= 400) {
|
||||
networkLog.push(`${r.status()} ${r.url().split('?')[0].slice(-80)}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('=== STEP 1: Login page ===');
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'domcontentloaded', timeout: 15000 });
|
||||
|
||||
// Inspect login form
|
||||
const formFields = await page.evaluate(() => {
|
||||
const inputs = document.querySelectorAll('input');
|
||||
return Array.from(inputs).map(i => ({ name: i.name, type: i.type, id: i.id }));
|
||||
});
|
||||
console.log('Login form fields:', JSON.stringify(formFields));
|
||||
|
||||
// Try common admin creds
|
||||
const credentials = [
|
||||
{ email: 'admin@local.com', password: 'admin123' },
|
||||
{ email: 'admin@local.com', password: 'admin' },
|
||||
{ email: 'simohamed@wevads.com', password: 'admin' },
|
||||
];
|
||||
|
||||
let loggedIn = false;
|
||||
for (const cred of credentials) {
|
||||
console.log(`\n=== STEP 2: Try ${cred.email} ===`);
|
||||
try {
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'domcontentloaded' });
|
||||
await page.fill('input[type="email"], input[name="email"], input[name="username"]', cred.email).catch(()=>{});
|
||||
await page.fill('input[type="password"], input[name="password"]', cred.password).catch(()=>{});
|
||||
const submitBtn = await page.$('button[type="submit"], button.btn-primary, input[type="submit"]');
|
||||
if (submitBtn) await submitBtn.click();
|
||||
await page.waitForTimeout(3000);
|
||||
const url = page.url();
|
||||
console.log('After login URL:', url);
|
||||
if (!url.includes('login')) {
|
||||
loggedIn = true;
|
||||
console.log('LOGIN SUCCESS!');
|
||||
break;
|
||||
}
|
||||
} catch(e) { console.log('Try failed:', e.message); }
|
||||
}
|
||||
|
||||
if (loggedIn) {
|
||||
console.log('\n=== STEP 3: Navigate to dashboard ===');
|
||||
await page.goto('https://wevads.weval-consulting.com/dashboard.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
await page.waitForTimeout(5000); // Wait for setInterval
|
||||
|
||||
const inspect = await page.evaluate(() => {
|
||||
const cpuU = document.getElementById('cpu-usage');
|
||||
const cpuB = document.getElementById('cpu-bar');
|
||||
return {
|
||||
url: location.href,
|
||||
hasJQuery: typeof $ !== 'undefined',
|
||||
jqVersion: typeof $ !== 'undefined' ? $.fn.jquery : 'no',
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
hasInit: typeof SystemMetrics !== 'undefined' && typeof SystemMetrics.init === 'function',
|
||||
baseUrl: window.APP_BASE_URL,
|
||||
cpuUsageText: cpuU ? cpuU.textContent : 'NOT_FOUND',
|
||||
cpuBarWidth: cpuB ? cpuB.style.width : 'NOT_FOUND',
|
||||
cpuBarHTML: cpuB ? cpuB.outerHTML.slice(0,200) : 'NOT_FOUND',
|
||||
v1522Marker: document.documentElement.outerHTML.includes('V152.2 Opus'),
|
||||
scriptsLoaded: Array.from(document.scripts).map(s => s.src).filter(s => s.includes('system')),
|
||||
};
|
||||
});
|
||||
console.log('\nDASHBOARD INSPECT:', JSON.stringify(inspect, null, 2));
|
||||
|
||||
// Try to manually call SystemMetrics.init
|
||||
const manualInit = await page.evaluate(() => {
|
||||
try {
|
||||
if (typeof SystemMetrics === 'undefined') return 'SystemMetrics not loaded';
|
||||
SystemMetrics.init(window.APP_BASE_URL || '');
|
||||
return 'init called';
|
||||
} catch(e) { return 'error: ' + e.message; }
|
||||
});
|
||||
console.log('Manual init:', manualInit);
|
||||
|
||||
await page.waitForTimeout(3000);
|
||||
const after = await page.evaluate(() => ({
|
||||
cpu: document.getElementById('cpu-usage')?.textContent,
|
||||
ram: document.getElementById('ram-usage')?.textContent,
|
||||
storage: document.getElementById('storage-usage')?.textContent,
|
||||
}));
|
||||
console.log('After manual init:', JSON.stringify(after));
|
||||
|
||||
await page.screenshot({ path: '/tmp/v160-dash-auth.png', fullPage: false });
|
||||
}
|
||||
|
||||
console.log('\n=== NETWORK LOG ===');
|
||||
networkLog.slice(0, 20).forEach(n => console.log(n));
|
||||
console.log('\n=== ERRORS ===');
|
||||
allErrors.slice(0, 10).forEach(e => console.log(e));
|
||||
console.log('\n=== CONSOLE last 10 ===');
|
||||
allConsole.slice(-10).forEach(c => console.log(c));
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
51
api/ambre-pw-tests/v160_verify.js
Normal file
51
api/ambre-pw-tests/v160_verify.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// V160 verification · same-origin test (proven works in V158)
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1280, height: 800} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
await page.goto('https://wevads.weval-consulting.com/auth/login.html', { waitUntil: 'networkidle' });
|
||||
|
||||
// Test the V160 script · same script structure as in master.html
|
||||
const result = await page.evaluate(async () => {
|
||||
return new Promise((resolve) => {
|
||||
// Add elements
|
||||
document.body.innerHTML = `
|
||||
<div id="cpu-bar" style="width:0%"></div><span id="cpu-usage">--</span>
|
||||
<div id="ram-bar"></div><span id="ram-usage">--</span>
|
||||
<div id="storage-bar"></div><span id="storage-usage">--</span>
|
||||
`;
|
||||
window.APP_BASE_URL = '';
|
||||
|
||||
const sm = document.createElement('script');
|
||||
sm.src = '/js/system-metrics.js?v=6.0';
|
||||
sm.onload = () => {
|
||||
// EXACT same code as V160 fix in master.html
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var smi = window.SystemMetrics;
|
||||
smi && smi.init && smi.init(window.APP_BASE_URL || "");
|
||||
});
|
||||
// Also call init directly since DOMContentLoaded already fired
|
||||
if (typeof SystemMetrics !== 'undefined' && SystemMetrics.init) {
|
||||
SystemMetrics.init('');
|
||||
}
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
cpu: document.getElementById('cpu-usage').textContent,
|
||||
ram: document.getElementById('ram-usage').textContent,
|
||||
storage: document.getElementById('storage-usage').textContent,
|
||||
cpuBar: document.getElementById('cpu-bar').style.width,
|
||||
});
|
||||
}, 2500);
|
||||
};
|
||||
document.head.appendChild(sm);
|
||||
});
|
||||
});
|
||||
console.log('V160 VERIFY:', JSON.stringify(result, null, 2));
|
||||
|
||||
await page.screenshot({ path: '/tmp/v160-PROOF-metrics.png' });
|
||||
await browser.close();
|
||||
})();
|
||||
52
api/ambre-pw-tests/v161_full.js
Normal file
52
api/ambre-pw-tests/v161_full.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// V161 · Full Playwright test on REAL dashboard URL with bypass cookie
|
||||
const { chromium } = require('playwright');
|
||||
|
||||
(async () => {
|
||||
const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] });
|
||||
const ctx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: {width: 1920, height: 1080} });
|
||||
const page = await ctx.newPage();
|
||||
|
||||
const networkLog = [];
|
||||
const consoleLog = [];
|
||||
page.on('response', r => {
|
||||
if (r.url().includes('system-metrics') || r.url().includes('master.html')) {
|
||||
networkLog.push(`${r.status()} ${r.url().split('?')[0]}`);
|
||||
}
|
||||
});
|
||||
page.on('console', m => consoleLog.push(`[${m.type()}] ${m.text()}`));
|
||||
page.on('pageerror', e => consoleLog.push(`[PAGEERR] ${e.message}`));
|
||||
|
||||
// Test: navigate to dashboard, follow redirects
|
||||
await page.goto('https://wevads.weval-consulting.com/dashboard.html', { waitUntil: 'networkidle', timeout: 20000 });
|
||||
|
||||
console.log('Final URL:', page.url());
|
||||
console.log('\n=== Network calls (system-metrics/master) ===');
|
||||
networkLog.forEach(n => console.log(n));
|
||||
|
||||
// Check what's actually rendered
|
||||
const inspect = await page.evaluate(() => {
|
||||
return {
|
||||
url: location.href,
|
||||
title: document.title,
|
||||
hasJQuery: typeof $ !== 'undefined',
|
||||
hasSystemMetrics: typeof SystemMetrics !== 'undefined',
|
||||
hasV160: document.documentElement.outerHTML.includes('V160 Opus'),
|
||||
hasV1522: document.documentElement.outerHTML.includes('V152.2 Opus'),
|
||||
hasCpuBar: !!document.getElementById('cpu-bar'),
|
||||
cpuUsage: document.getElementById('cpu-usage')?.textContent || 'NO_ELEMENT',
|
||||
ramUsage: document.getElementById('ram-usage')?.textContent || 'NO_ELEMENT',
|
||||
systemMetricsScript: Array.from(document.scripts).find(s => s.src.includes('system-metrics'))?.src || 'NOT_LOADED',
|
||||
};
|
||||
});
|
||||
console.log('\n=== INSPECT ===');
|
||||
console.log(JSON.stringify(inspect, null, 2));
|
||||
|
||||
console.log('\n=== Console (last 10) ===');
|
||||
consoleLog.slice(-10).forEach(c => console.log(c));
|
||||
|
||||
// Take a full screenshot
|
||||
await page.screenshot({ path: '/tmp/v161-real-dashboard.png', fullPage: false });
|
||||
console.log('Screenshot: /tmp/v161-real-dashboard.png');
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
7
api/ambre-pw-v37-deploy.php
Normal file
7
api/ambre-pw-v37-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWMzcgwrcgbWVybWFpZCBpbmxpbmUgcmVuZGVyICsgYXJ0aWZhY3QiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWwiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3YzNy0wMC1sb2FkLnBuZyIgfSk7CiAgCiAgY29uc3QgaW5wdXQgPSBwYWdlLmxvY2F0b3IoIiNtc2dJbnB1dCIpOwogIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgYXdhaXQgaW5wdXQuZmlsbCgibWVybWFpZCBzY2jDqW1hIGFyY2hpdGVjdHVyZSBJQSBzb3V2ZXJhaW5lIFdFVklBIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg0MDApOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIAogIC8vIFdhaXQgZm9yIG1lcm1haWQgZGl2CiAgY29uc3Qgc3RhcnQgPSBEYXRlLm5vdygpOwogIGxldCBmb3VuZCA9IGZhbHNlOwogIGxldCBrYlNyYyA9ICJ1bmtub3duIjsKICB3aGlsZSAoRGF0ZS5ub3coKSAtIHN0YXJ0IDwgNDUwMDApIHsKICAgIGNvbnN0IHMgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgICAgY29uc3QgbW1kID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQgLm1lcm1haWQiKTsKICAgICAgY29uc3QgYmFkZ2VzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQgLm54LWJhZGdlIik7CiAgICAgIHJldHVybiB7CiAgICAgICAgbWVybWFpZF9jb3VudDogbW1kLmxlbmd0aCwKICAgICAgICBzdmdfcmVuZGVyZWQ6IEFycmF5LmZyb20obW1kKS5maWx0ZXIobSA9PiBtLnF1ZXJ5U2VsZWN0b3IoInN2ZyIpKS5sZW5ndGgsCiAgICAgICAgYmFkZ2VfdGV4dHM6IEFycmF5LmZyb20oYmFkZ2VzKS5tYXAoYiA9PiBiLmlubmVyVGV4dCksCiAgICAgIH07CiAgICB9KTsKICAgIGlmIChzLm1lcm1haWRfY291bnQgPiAwKSB7CiAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgY29uc29sZS5sb2coYE1lcm1haWQgZm91bmQgwrcgJHtzLm1lcm1haWRfY291bnR9IGRpdnMgwrcgJHtzLnN2Z19yZW5kZXJlZH0gU1ZHIHJlbmRlcmVkIMK3IGJhZGdlczogJHtKU09OLnN0cmluZ2lmeShzLmJhZGdlX3RleHRzKX1gKTsKICAgICAgaWYgKHMuc3ZnX3JlbmRlcmVkID4gMCkgYnJlYWs7CiAgICB9CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogIH0KICAKICBjb25zdCBlbCA9ICgoRGF0ZS5ub3coKS1zdGFydCkvMTAwMCkudG9GaXhlZCgxKTsKICBjb25zb2xlLmxvZyhgVG90YWw6ICR7ZWx9cyDCtyBtZXJtYWlkIGZvdW5kOiAke2ZvdW5kfWApOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMjAwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92MzctMDEtbWVybWFpZC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgCiAgLy8gVGVzdCAyIMK3IGFyY2hpdGVjdHVyZSBkw6lqw6AgZGFucyBLQiDihpIgcmV1c2UKICBhd2FpdCBpbnB1dC5jbGljayh7Zm9yY2U6dHJ1ZX0pOwogIGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoIkNvbnRyb2wrQSIpOwogIGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoIkRlbGV0ZSIpOwogIGF3YWl0IGlucHV0LmZpbGwoImRpYWdyYW1tZSBwYXJjb3VycyBjbGllbnQgcmV0YWlsIG9tbmljYW5hbCIpOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIAogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoODAwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92MzctMDItcmV1c2UucG5nIiwgZnVsbFBhZ2U6IGZhbHNlIH0pOwogIAogIGNvbnN0IGZpbmFsID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiAoewogICAgbW1kX2NvdW50OiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCAubWVybWFpZCIpLmxlbmd0aCwKICAgIHN2Z19jb3VudDogZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQgLm1lcm1haWQgc3ZnIikubGVuZ3RoLAogIH0pKTsKICBjb25zb2xlLmxvZygiRmluYWw6IiwgSlNPTi5zdHJpbmdpZnkoZmluYWwpKTsKfSk7Cg==");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v37-mermaid.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v38-deploy.php
Normal file
7
api/ambre-pw-v38-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWMzggwrcgaW5zcGVjdCByZW5kZXJlZCBTVkciLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNDUwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWwiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICAKICBjb25zdCBpbnB1dCA9IHBhZ2UubG9jYXRvcigiI21zZ0lucHV0Iik7CiAgYXdhaXQgaW5wdXQuZmlsbCgibWVybWFpZCBzY2jDqW1hIGFyY2hpdGVjdHVyZSBJQSBzb3V2ZXJhaW5lIFdFVklBIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzMDApOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIAogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNTAwMCk7CiAgCiAgY29uc3QgaW5mbyA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgY29uc3QgZGl2cyA9IEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQgLm1lcm1haWQsIC5tc2cuYXNzaXN0YW50IFtpZF49J21tZC0nXSIpKTsKICAgIGNvbnN0IG91dCA9IGRpdnMubWFwKGQgPT4gewogICAgICBjb25zdCBzdmcgPSBkLnF1ZXJ5U2VsZWN0b3IoInN2ZyIpOwogICAgICBjb25zdCByZWN0ID0gZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgICAgY29uc3Qgc3ZnUmVjdCA9IHN2ZyA/IHN2Zy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSA6IG51bGw7CiAgICAgIHJldHVybiB7CiAgICAgICAgaWQ6IGQuaWQsCiAgICAgICAgY2xhc3NOYW1lOiBkLmNsYXNzTmFtZSwKICAgICAgICB0ZXh0X3N0YXJ0OiBkLnRleHRDb250ZW50LnN1YnN0cmluZygwLCA4MCksCiAgICAgICAgd2lkdGg6IHJlY3Qud2lkdGgsCiAgICAgICAgaGVpZ2h0OiByZWN0LmhlaWdodCwKICAgICAgICBoYXNfc3ZnOiAhIXN2ZywKICAgICAgICBzdmdfd2lkdGg6IHN2Z1JlY3QgPyBzdmdSZWN0LndpZHRoIDogMCwKICAgICAgICBzdmdfaGVpZ2h0OiBzdmdSZWN0ID8gc3ZnUmVjdC5oZWlnaHQgOiAwLAogICAgICAgIHN2Z19hdHRyczogc3ZnID8gewogICAgICAgICAgd2lkdGg6IHN2Zy5nZXRBdHRyaWJ1dGUoIndpZHRoIiksCiAgICAgICAgICBoZWlnaHQ6IHN2Zy5nZXRBdHRyaWJ1dGUoImhlaWdodCIpLAogICAgICAgICAgdmlld0JveDogc3ZnLmdldEF0dHJpYnV0ZSgidmlld0JveCIpLAogICAgICAgICAgZGlzcGxheTogd2luZG93LmdldENvbXB1dGVkU3R5bGUoc3ZnKS5kaXNwbGF5LAogICAgICAgIH0gOiBudWxsLAogICAgICAgIGRpc3BsYXk6IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGQpLmRpc3BsYXksCiAgICAgICAgZm9udFNpemU6IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGQpLmZvbnRTaXplLAogICAgICAgIHZpc2liaWxpdHk6IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGQpLnZpc2liaWxpdHksCiAgICAgICAgZGF0YVByb2Nlc3NlZDogZC5nZXRBdHRyaWJ1dGUoImRhdGEtcHJvY2Vzc2VkIiksCiAgICAgIH07CiAgICB9KTsKICAgIHJldHVybiBvdXQ7CiAgfSk7CiAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoaW5mbywgbnVsbCwgMikpOwogIAogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjM4LWluc3BlY3QucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v38-inspect.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v39-deploy.php
Normal file
7
api/ambre-pw-v39-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7CmNvbnN0IGZzID0gcmVxdWlyZSgiZnMiKTsKCnRlc3QoIlYzOSDCtyBGSU5BTCBTSE9XQ0FTRSDCtyBtZXJtYWlkICsgUERGIGkxOG4gKyBFdGhpY2EiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoMzAwMDAwKTsKICAKICBhd2FpdCBwYWdlLmdvdG8oIi93ZXZpYS5odG1sIik7CiAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7IHRyeSB7IHNlc3Npb25TdG9yYWdlLmNsZWFyKCk7IGxvY2FsU3RvcmFnZS5jbGVhcigpOyB9IGNhdGNoKGUpe30gfSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92MzktMDAtbGFuZGluZy5wbmciIH0pOwogIAogIGNvbnN0IHR1cm5zID0gWwogICAgeyBsYjoiMDEtaGkiLCBtc2c6ICJIaSwgSSdtIExhdXJhIGZyb20gQ2FycmVmb3VyIE1vcm9jY28gbWFya2V0aW5nIGRlcGFydG1lbnQiIH0sCiAgICB7IGxiOiIwMi1tZXJtYWlkLWZyIiwgbXNnOiAiZ8OpbsOocmUgdW4gc2Now6ltYSBtZXJtYWlkIGR1IHBhcmNvdXJzIGNsaWVudCByZXRhaWwgb21uaWNhbmFsIiB9LAogICAgeyBsYjoiMDMtbWVybWFpZC1jdXN0b20iLCBtc2c6ICJtZXJtYWlkIGZsb3djaGFydDogc3RyYXTDqWdpZSBhY3F1aXNpdGlvbiBCMkIgU2FhUyIgfSwKICAgIHsgbGI6IjA0LXBkZi1lbiIsIG1zZzogImdlbmVyYXRlIGEgcHJlbWl1bSBQREYgcmVwb3J0IG9uOiBEaWdpdGFsIFJldGFpbCBTdHJhdGVneSBNb3JvY2NvIDIwMjYiIH0sCiAgICB7IGxiOiIwNS1iaWxhbiIsIG1zZzogInLDqWNhcGl0dWxlIG5vcyDDqWNoYW5nZXMiIH0sCiAgXTsKICAKICBjb25zdCByZXN1bHRzID0gW107CiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0dXJucy5sZW5ndGg7IGkrKykgewogICAgY29uc3QgdCA9IHR1cm5zW2ldOwogICAgY29uc3QgbnVtID0gU3RyaW5nKGkrMSkucGFkU3RhcnQoMiwiMCIpOwogICAgY29uc29sZS5sb2coYFxuWyR7bnVtfV0gJHt0LmxifTogJHt0Lm1zZy5zdWJzdHJpbmcoMCw2MCl9YCk7CiAgICAKICAgIGNvbnN0IGlucHV0ID0gcGFnZS5sb2NhdG9yKCIjbXNnSW5wdXQiKTsKICAgIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgICBhd2FpdCBwYWdlLmtleWJvYXJkLnByZXNzKCJDb250cm9sK0EiKTsKICAgIGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoIkRlbGV0ZSIpOwogICAgYXdhaXQgaW5wdXQuZmlsbCh0Lm1zZyk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDQwMCk7CiAgICAKICAgIGNvbnN0IGJjID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpLmxlbmd0aCk7CiAgICBhd2FpdCBpbnB1dC5wcmVzcygiRW50ZXIiKTsKICAgIAogICAgLy8gV2FpdCBmb3IgcmVzcG9uc2Ugd2l0aCBzdWJzdGFudGlhbCBjb250ZW50CiAgICBjb25zdCB3cyA9IERhdGUubm93KCk7CiAgICBsZXQgcmVwbHkgPSAiIjsgbGV0IHN2Z0NvdW50ID0gMDsgbGV0IHBkZkxpbmsgPSBmYWxzZTsKICAgIHdoaWxlIChEYXRlLm5vdygpIC0gd3MgPCA1MDAwMCkgewogICAgICBjb25zdCBzID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoYmMpID0+IHsKICAgICAgICBjb25zdCBhID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpKTsKICAgICAgICBjb25zdCBsYXRlc3QgPSBhLmxlbmd0aCA+IGJjID8gYVthLmxlbmd0aC0xXSA6IG51bGw7CiAgICAgICAgaWYgKCFsYXRlc3QpIHJldHVybiB7IGNudDogYS5sZW5ndGgsIGxhc3Q6ICIiLCBzdmc6IDAsIHBkZjogZmFsc2UgfTsKICAgICAgICByZXR1cm4gewogICAgICAgICAgY250OiBhLmxlbmd0aCwKICAgICAgICAgIGxhc3Q6IChsYXRlc3QucXVlcnlTZWxlY3RvcigiLmJ1YmJsZSIpPy5pbm5lclRleHQgfHwgIiIpLnN1YnN0cmluZygwLCAzMDApLAogICAgICAgICAgc3ZnOiBsYXRlc3QucXVlcnlTZWxlY3RvckFsbCgic3ZnIikubGVuZ3RoLAogICAgICAgICAgcGRmOiAvXC5wZGZ8VMOpbMOpY2hhcmdlcnxEb3dubG9hZC9pLnRlc3QobGF0ZXN0LmlubmVySFRNTCksCiAgICAgICAgfTsKICAgICAgfSwgYmMpOwogICAgICBpZiAocy5jbnQgPiBiYyAmJiBzLmxhc3QubGVuZ3RoID4gMjApIHsKICAgICAgICByZXBseSA9IHMubGFzdDsgc3ZnQ291bnQgPSBzLnN2ZzsgcGRmTGluayA9IHMucGRmOwogICAgICAgIGlmIChzLmxhc3QubGVuZ3RoID4gMTAwIHx8IHMuc3ZnID4gMCB8fCBzLnBkZikgYnJlYWs7CiAgICAgIH0KICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgxNTAwKTsKICAgIH0KICAgIAogICAgY29uc3QgZWwgPSAoKERhdGUubm93KCktd3MpLzEwMDApLnRvRml4ZWQoMSk7CiAgICBjb25zdCBtYXJrID0gcmVwbHkgJiYgcmVwbHkubGVuZ3RoID4gMzAgPyAi4pyFIiA6ICLimqDvuI8iOwogICAgY29uc29sZS5sb2coYCAgJHttYXJrfSAke2VsfXMgwrcgc3ZnPSR7c3ZnQ291bnR9IMK3IHBkZj0ke3BkZkxpbmt9IMK3ICR7cmVwbHkuc3Vic3RyaW5nKDAsMTIwKS5yZXBsYWNlKC9cbi9nLCAnICcpfWApOwogICAgCiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogYG91dHB1dC92MzktJHtudW19LSR7dC5sYn0ucG5nYCB9KTsKICAgIHJlc3VsdHMucHVzaCh7IHQ6IGkrMSwgbGI6IHQubGIsIHN2Zzogc3ZnQ291bnQsIHBkZjogcGRmTGluaywgcmVwbHlfc2l6ZTogcmVwbHkubGVuZ3RoLCBlbCB9KTsKICB9CiAgCiAgLy8gRmluYWwgZnVsbHBhZ2UKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDIwMDApOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjM5LTk5LWZpbmFsLnBuZyIsIGZ1bGxQYWdlOiB0cnVlIH0pOwogIAogIGNvbnNvbGUubG9nKGBcbuKVkOKVkOKVkCBWMzkgQklMQU4g4pWQ4pWQ4pWQYCk7CiAgcmVzdWx0cy5mb3JFYWNoKHIgPT4gY29uc29sZS5sb2coYCAgVCR7ci50fSDCtyAke3IubGJ9IMK3IHN2Zz0ke3Iuc3ZnfSDCtyBwZGY9JHtyLnBkZn0gwrcgJHtyLnJlcGx5X3NpemV9QmApKTsKICAKICBmcy53cml0ZUZpbGVTeW5jKCJvdXRwdXQvdjM5LWJpbGFuLmpzb24iLCBKU09OLnN0cmluZ2lmeSh7cmVzdWx0c30sIG51bGwsIDIpKTsKfSk7Cg==");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v39-showcase.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v40-deploy.php
Normal file
7
api/ambre-pw-v40-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDAgwrcgSHViIERhc2hib2FyZHMgVW5pZmnDqSBzY3JlZW5zaG90IiwgYXN5bmMgKHsgcGFnZSB9KSA9PiB7CiAgdGVzdC5zZXRUaW1lb3V0KDMwMDAwKTsKICBhd2FpdCBwYWdlLmdvdG8oIi9kYXNoYm9hcmRzLWh1Yi11bmlmaWVkLmh0bWwiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgxNTAwKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0MC1odWItdG9wLnBuZyIgfSk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDAtaHViLWZ1bGwucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7CiAgCiAgLy8gVGVzdCBmaWx0ZXIgY2xpY2sKICBjb25zdCBmaWx0ZXJzID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuZmlsdGVyIikuY291bnQoKTsKICBjb25zb2xlLmxvZyhgRmlsdGVycyBjb3VudDogJHtmaWx0ZXJzfWApOwogIGNvbnN0IGNhcmRzID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuY2FyZCIpLmNvdW50KCk7CiAgY29uc29sZS5sb2coYENhcmRzIGNvdW50OiAke2NhcmRzfWApOwogIGNvbnN0IGNhdHMgPSBhd2FpdCBwYWdlLmxvY2F0b3IoIi5jYXQtc2VjdGlvbiIpLmNvdW50KCk7CiAgY29uc29sZS5sb2coYENhdCBzZWN0aW9uczogJHtjYXRzfWApOwogIAogIC8vIENsaWNrIDJuZCBmaWx0ZXIgKG5vdCAiVG91cyIpCiAgaWYgKGZpbHRlcnMgPiAxKSB7CiAgICBhd2FpdCBwYWdlLmxvY2F0b3IoIi5maWx0ZXIiKS5udGgoMSkuY2xpY2soKTsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoODAwKTsKICAgIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQwLWh1Yi1maWx0ZXJlZC5wbmciIH0pOwogIH0KfSk7Cg==");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v40-hub.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v41-deploy.php
Normal file
7
api/ambre-pw-v41-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDEgwrcgV1RQIGF2ZWMgSHViIFVuaWZpw6kgbGluayIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCgzMDAwMCk7CiAgYXdhaXQgcGFnZS5nb3RvKCIvd2V2YWwtdGVjaG5vbG9neS1wbGF0Zm9ybS5odG1sIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMjAwMCk7CiAgCiAgLy8gRmluZCBodWIgbGluawogIGNvbnN0IGh1YkxpbmtzID0gYXdhaXQgcGFnZS5sb2NhdG9yKCdhW2hyZWYqPSJkYXNoYm9hcmRzLWh1Yi11bmlmaWVkIl0nKS5jb3VudCgpOwogIGNvbnNvbGUubG9nKGBIdWIgbGlua3MgaW4gV1RQOiAke2h1YkxpbmtzfWApOwogIAogIGlmIChodWJMaW5rcyA+IDApIHsKICAgIGNvbnN0IGVsID0gcGFnZS5sb2NhdG9yKCdhW2hyZWYqPSJkYXNoYm9hcmRzLWh1Yi11bmlmaWVkIl0nKS5maXJzdCgpOwogICAgYXdhaXQgZWwuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpOwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDEtd3RwLWh1Yi1saW5rLnBuZyIgfSk7CiAgICBjb25zdCB0eHQgPSBhd2FpdCBlbC5pbm5lclRleHQoKTsKICAgIGNvbnNvbGUubG9nKGBMaW5rIHRleHQ6ICIke3R4dH0iYCk7CiAgfQogIAogIC8vIEFsc28gdGVzdCBPU1MKICBhd2FpdCBwYWdlLmdvdG8oIi9vc3MtY2F0YWxvZy5odG1sIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICBjb25zdCBvc3NMaW5rcyA9IGF3YWl0IHBhZ2UubG9jYXRvcignYVtocmVmKj0iZGFzaGJvYXJkcy1odWItdW5pZmllZCJdJykuY291bnQoKTsKICBjb25zb2xlLmxvZyhgSHViIGxpbmtzIGluIE9TUzogJHtvc3NMaW5rc31gKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0MS1vc3MtaHViLWxpbmsucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v41-wtp-hub.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v41b-deploy.php
Normal file
7
api/ambre-pw-v41b-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDFiIMK3IFdUUCArIE9TUyArIEh1YiB3aXRoIGNhY2hlLWJ1c3QiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoMzAwMDApOwogIGNvbnN0IGNiID0gRGF0ZS5ub3coKTsKICAKICAvLyBXVFAKICBhd2FpdCBwYWdlLmdvdG8oYC93ZXZhbC10ZWNobm9sb2d5LXBsYXRmb3JtLmh0bWw/Y2I9JHtjYn1gKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICBsZXQgaHViTGlua3MgPSBhd2FpdCBwYWdlLmxvY2F0b3IoJ2FbaHJlZio9ImRhc2hib2FyZHMtaHViLXVuaWZpZWQiXScpLmNvdW50KCk7CiAgY29uc29sZS5sb2coYFdUUCBodWIgbGlua3M6ICR7aHViTGlua3N9YCk7CiAgaWYgKGh1YkxpbmtzID4gMCkgewogICAgY29uc3QgZWwgPSBwYWdlLmxvY2F0b3IoJ2FbaHJlZio9ImRhc2hib2FyZHMtaHViLXVuaWZpZWQiXScpLmZpcnN0KCk7CiAgICBhd2FpdCBlbC5zY3JvbGxJbnRvVmlld0lmTmVlZGVkKCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDgwMCk7CiAgICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0MWItd3RwLWh1Yi5wbmciIH0pOwogICAgY29uc3QgdHh0ID0gYXdhaXQgZWwuaW5uZXJUZXh0KCk7CiAgICBjb25zb2xlLmxvZyhgV1RQIGxpbms6ICIke3R4dH0iYCk7CiAgfSBlbHNlIHsKICAgIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQxYi13dHAtbm9odWIucG5nIiB9KTsKICB9CiAgCiAgLy8gQ2xpY2sgdGhlIGh1YiBsaW5rIHRvIHZlcmlmeSBmbG93CiAgaWYgKGh1YkxpbmtzID4gMCkgewogICAgYXdhaXQgcGFnZS5sb2NhdG9yKCdhW2hyZWYqPSJkYXNoYm9hcmRzLWh1Yi11bmlmaWVkIl0nKS5maXJzdCgpLmNsaWNrKCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDIwMDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDFiLWh1Yi1hZnRlci1jbGljay5wbmciIH0pOwogIH0KfSk7Cg==");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v41b.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v42-deploy.php
Normal file
7
api/ambre-pw-v42-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDIgwrcgRklOQUwgSHViIERhc2hib2FyZHMgU2hvd2Nhc2UgVWx0cmEiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIC8vIDEuIEh1YiBob21lCiAgYXdhaXQgcGFnZS5nb3RvKCIvZGFzaGJvYXJkcy1odWItdW5pZmllZC5odG1sP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgxNTAwKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0Mi0wMS1ob21lLnBuZyIgfSk7CiAgY29uc29sZS5sb2coIuKchSBUMTogSHViIGhvbWUgbG9hZGVkIik7CiAgCiAgLy8gU3RhdHMKICBjb25zdCBzdGF0cyA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gewogICAgY29uc3QgYnMgPSBBcnJheS5mcm9tKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5zdGF0IGInKSkubWFwKGIgPT4gYi5pbm5lclRleHQpOwogICAgY29uc3QgY2FyZHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuY2FyZCcpLmxlbmd0aDsKICAgIGNvbnN0IGZpbHRlcnMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmlsdGVyJykubGVuZ3RoOwogICAgcmV0dXJuIHsgc3RhdHM6IGJzLCBjYXJkcywgZmlsdGVycyB9OwogIH0pOwogIGNvbnNvbGUubG9nKGAgIFN0YXRzOiAke0pTT04uc3RyaW5naWZ5KHN0YXRzKX1gKTsKICAKICAvLyAyLiBGaWx0ZXIgYnkgS1BJICYgQW5hbHl0aWNzCiAgY29uc3QgZmlsdGVyS1BJID0gcGFnZS5sb2NhdG9yKCcuZmlsdGVyOmhhcy10ZXh0KCJLUEkgJiBBbmFseXRpY3MiKScpOwogIGlmIChhd2FpdCBmaWx0ZXJLUEkuY291bnQoKSA+IDApIHsKICAgIGF3YWl0IGZpbHRlcktQSS5jbGljaygpOwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDItMDItZmlsdGVyLWtwaS5wbmciIH0pOwogICAgY29uc29sZS5sb2coIuKchSBUMjogS1BJIGZpbHRlciBhcHBsaWVkIik7CiAgfQogIAogIC8vIDMuIEZpbHRlciBieSBFdGhpY2EKICBjb25zdCBmaWx0ZXJFdGggPSBwYWdlLmxvY2F0b3IoJy5maWx0ZXI6aGFzLXRleHQoIkV0aGljYSIpJyk7CiAgaWYgKGF3YWl0IGZpbHRlckV0aC5jb3VudCgpID4gMCkgewogICAgYXdhaXQgZmlsdGVyRXRoLmNsaWNrKCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDUwMCk7CiAgICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0Mi0wMy1maWx0ZXItZXRoaWNhLnBuZyIgfSk7CiAgICBjb25zb2xlLmxvZygi4pyFIFQzOiBFdGhpY2EgZmlsdGVyIGFwcGxpZWQiKTsKICB9CiAgCiAgLy8gNC4gQmFjayB0byBhbGwKICBhd2FpdCBwYWdlLmxvY2F0b3IoJy5maWx0ZXI6aGFzLXRleHQoIlRvdXMiKScpLmNsaWNrKCk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg1MDApOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQyLTA0LWFsbC1iYWNrLnBuZyIgfSk7CiAgCiAgLy8gNS4gRnVsbCBwYWdlCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDItMDUtZnVsbHBhZ2UucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7CiAgY29uc29sZS5sb2coIuKchSBUNDogRnVsbCBwYWdlIGNhcHR1cmVkIik7CiAgCiAgLy8gNi4gUmVnaXN0cnkgQVBJCiAgY29uc3QgcmVnID0gYXdhaXQgcGFnZS5ldmFsdWF0ZShhc3luYyAoKSA9PiB7CiAgICBjb25zdCByID0gYXdhaXQgZmV0Y2goJy9hcGkvZGFzaGJvYXJkcy1yZWdpc3RyeS1hbWJyZS5waHAnKTsKICAgIHJldHVybiBhd2FpdCByLmpzb24oKTsKICB9KTsKICBjb25zb2xlLmxvZyhgICBSZWdpc3RyeTogdG90YWw9JHtyZWcudG90YWx9IMK3IGNhdHM9JHtyZWcuY2F0ZWdvcmllc19jb3VudH0gwrcgemVyb19vcnBoYW49JHtyZWcuemVyb19vcnBoYW59YCk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v42-hub-showcase.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v43-deploy.php
Normal file
7
api/ambre-pw-v43-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDMgwrcgUFJPT0YgwrcgUERGIFByZW1pdW0gZW5kLXRvLWVuZCBjb252ZXJzYXRpb24gWWFjaW5lIiwgYXN5bmMgKHsgcGFnZSB9KSA9PiB7CiAgdGVzdC5zZXRUaW1lb3V0KDE4MDAwMCk7CiAgY29uc3QgZXJyb3JzID0gW107CiAgcGFnZS5vbigicGFnZWVycm9yIiwgZSA9PiBlcnJvcnMucHVzaChlLm1lc3NhZ2Uuc3Vic3RyaW5nKDAsMTIwKSkpOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4geyB0cnl7c2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTsgbG9jYWxTdG9yYWdlLmNsZWFyKCk7fWNhdGNoKGUpe30gfSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDMtMDAtc3RhcnQucG5nIiB9KTsKICBjb25zb2xlLmxvZygi8J+TuCBUMCBzdGFydCDCtyBlcnJvcnM6IiwgZXJyb3JzLmxlbmd0aCk7CiAgCiAgLy8gVHVybiAxOiBoaQogIGNvbnN0IGlucHV0ID0gcGFnZS5sb2NhdG9yKCIjbXNnSW5wdXQiKTsKICBhd2FpdCBpbnB1dC5jbGljayh7Zm9yY2U6dHJ1ZX0pOwogIGF3YWl0IGlucHV0LmZpbGwoIkhJIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCg0MDApOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIAogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNjAwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDMtMDEtaGkucG5nIiB9KTsKICBjb25zb2xlLmxvZygi8J+TuCBUMSBISSBzZW50Iik7CiAgCiAgLy8gVHVybiAyOiBKRSBWRVVYIFVOIFBERgogIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgYXdhaXQgcGFnZS5rZXlib2FyZC5wcmVzcygiQ29udHJvbCtBIik7CiAgYXdhaXQgcGFnZS5rZXlib2FyZC5wcmVzcygiRGVsZXRlIik7CiAgYXdhaXQgaW5wdXQuZmlsbCgiSkUgVkVVWCBVTiBQREYgREUgQ09NUEFSQUlTT04gV0VWSUEgT1BVUyBBVkVDIEFWQU5UQUdFUyBJTkNPTlZFTklFTlRTIENPVVRTIFBFUkZPUk1BTkNFUyBJTlRFR1JBVElPTlMiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDQwMCk7CiAgYXdhaXQgaW5wdXQucHJlc3MoIkVudGVyIik7CiAgCiAgLy8gV2FpdCBQREYgZ2VuZXJhdGlvbiAobWF4IDkwcykKICBjb25zdCB3cyA9IERhdGUubm93KCk7CiAgbGV0IHBkZkZvdW5kID0gZmFsc2U7CiAgbGV0IHBkZlVybCA9IG51bGw7CiAgbGV0IGxhc3RSZXBseSA9ICIiOwogIAogIHdoaWxlIChEYXRlLm5vdygpIC0gd3MgPCA5MDAwMCkgewogICAgY29uc3Qgc3RhdGUgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgICAgY29uc3QgbXNncyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi5tc2cuYXNzaXN0YW50Iik7CiAgICAgIGNvbnN0IGxhc3QgPSBtc2dzLmxlbmd0aCA+IDAgPyBtc2dzW21zZ3MubGVuZ3RoLTFdIDogbnVsbDsKICAgICAgaWYgKCFsYXN0KSByZXR1cm4geyBjbnQ6IDAsIHBkZjogbnVsbCwgdGV4dDogIiIgfTsKICAgICAgY29uc3QgcGRmTGluayA9IGxhc3QucXVlcnlTZWxlY3RvcignYVtocmVmKj0iLnBkZiJdJyk7CiAgICAgIHJldHVybiB7CiAgICAgICAgY250OiBtc2dzLmxlbmd0aCwKICAgICAgICBwZGZfdXJsOiBwZGZMaW5rID8gcGRmTGluay5ocmVmIDogbnVsbCwKICAgICAgICBoYXNfcGRmX2luX2h0bWw6IC9cLnBkZi9pLnRlc3QobGFzdC5pbm5lckhUTUwpLAogICAgICAgIHRleHRfc2FtcGxlOiAobGFzdC5xdWVyeVNlbGVjdG9yKCIuYnViYmxlIik/LmlubmVyVGV4dCB8fCAiIikuc3Vic3RyaW5nKDAsIDMwMCksCiAgICAgIH07CiAgICB9KTsKICAgIGlmIChzdGF0ZS5wZGZfdXJsKSB7CiAgICAgIHBkZkZvdW5kID0gdHJ1ZTsKICAgICAgcGRmVXJsID0gc3RhdGUucGRmX3VybDsKICAgICAgbGFzdFJlcGx5ID0gc3RhdGUudGV4dF9zYW1wbGU7CiAgICAgIGJyZWFrOwogICAgfQogICAgbGFzdFJlcGx5ID0gc3RhdGUudGV4dF9zYW1wbGU7CiAgICBpZiAoc3RhdGUuaGFzX3BkZl9pbl9odG1sKSBjb25zb2xlLmxvZyhgICBbJHtNYXRoLnJvdW5kKChEYXRlLm5vdygpLXdzKS8xMDAwKX1zXSBwZGYga2V5d29yZCBpbiBodG1sYCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDIwMDApOwogIH0KICAKICBjb25zdCBlbCA9ICgoRGF0ZS5ub3coKS13cykvMTAwMCkudG9GaXhlZCgxKTsKICBjb25zb2xlLmxvZyhgXG7ilZDilZDilZAgUERGIHJlc3VsdCBhZnRlciAke2VsfXMg4pWQ4pWQ4pWQYCk7CiAgY29uc29sZS5sb2coYCAgRm91bmQ6ICR7cGRmRm91bmR9YCk7CiAgY29uc29sZS5sb2coYCAgVVJMOiAke3BkZlVybH1gKTsKICBjb25zb2xlLmxvZyhgICBUZXh0IHNhbXBsZTogJHtsYXN0UmVwbHkuc3Vic3RyaW5nKDAsMjUwKS5yZXBsYWNlKC9cbi9nLCcgJyl9YCk7CiAgCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDMtMDItcGRmLXJlcXVlc3QucG5nIiB9KTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQzLTAzLWZpbmFsLnBuZyIsIGZ1bGxQYWdlOiB0cnVlIH0pOwogIAogIGlmICghcGRmRm91bmQpIHsKICAgIGNvbnNvbGUubG9nKGBcbuKdjCBOTyBQREYgTElOSyBHRU5FUkFURURgKTsKICAgIGNvbnNvbGUubG9nKGBFcnJvcnM6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3JzKX1gKTsKICB9Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v43-proof.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v44-deploy.php
Normal file
7
api/ambre-pw-v44-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDQgwrcgUFJPT0YgwrcgUERGIFByZW1pdW0gYXR0ZW5kIGZpbiBISSIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCgyNDAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4geyB0cnl7c2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTsgbG9jYWxTdG9yYWdlLmNsZWFyKCk7fWNhdGNoKGUpe30gfSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzUwMCk7CiAgCiAgLy8gVHVybiAxOiBISSAtIHdhaXQgZm9yIENPTVBMRVRFIHJlc3BvbnNlCiAgY29uc3QgaW5wdXQgPSBwYWdlLmxvY2F0b3IoIiNtc2dJbnB1dCIpOwogIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgYXdhaXQgaW5wdXQuZmlsbCgiYm9uam91ciIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNDAwKTsKICAKICBjb25zdCBiYzAgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIi5tc2cuYXNzaXN0YW50IikubGVuZ3RoKTsKICBhd2FpdCBpbnB1dC5wcmVzcygiRW50ZXIiKTsKICBjb25zb2xlLmxvZygi8J+TpCBUMTogYm9uam91ciBzZW50Iik7CiAgCiAgLy8gV2FpdCBmb3IgYXNzaXN0YW50IGNvdW50IHRvIGdyb3cgQU5EIGJ1c3kgZmxhZyB0byByZWxlYXNlCiAgY29uc3Qgd3MxID0gRGF0ZS5ub3coKTsKICB3aGlsZSAoRGF0ZS5ub3coKSAtIHdzMSA8IDkwMDAwKSB7CiAgICBjb25zdCBzID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoYmMpID0+ICh7CiAgICAgIGNudDogZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQiKS5sZW5ndGgsCiAgICAgIGJ1c3k6IHdpbmRvdy5idXN5IHx8IGZhbHNlLAogICAgICBkaXNhYmxlZDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNlbmRCdG4iKT8uZGlzYWJsZWQgfHwgZmFsc2UsCiAgICB9KSwgYmMwKTsKICAgIGlmIChzLmNudCA+IGJjMCAmJiAhcy5idXN5ICYmICFzLmRpc2FibGVkKSBicmVhazsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTUwMCk7CiAgfQogIGNvbnNvbGUubG9nKGAgIOKchSBUMSBkb25lIGluICR7KChEYXRlLm5vdygpLXdzMSkvMTAwMCkudG9GaXhlZCgxKX1zYCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDQtMDEtaGktZG9uZS5wbmciIH0pOwogIAogIC8vIFR1cm4gMjogUERGIHJlcXVlc3QKICBhd2FpdCBpbnB1dC5jbGljayh7Zm9yY2U6dHJ1ZX0pOwogIGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoIkNvbnRyb2wrQSIpOwogIGF3YWl0IHBhZ2Uua2V5Ym9hcmQucHJlc3MoIkRlbGV0ZSIpOwogIGF3YWl0IGlucHV0LmZpbGwoImZhaXMgbW9pIHVuIHBkZiBwcmVtaXVtIGRlIGNvbXBhcmFpc29uIFdFVklBIHZlcnN1cyBPUFVTIGF2ZWMgYXZhbnRhZ2VzLCBpbmNvbnZlbmllbnRzLCBjb3V0cywgcGVyZm9ybWFuY2VzLCBpbnRlZ3JhdGlvbnMiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDQwMCk7CiAgCiAgY29uc3QgYmMxID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpLmxlbmd0aCk7CiAgYXdhaXQgaW5wdXQucHJlc3MoIkVudGVyIik7CiAgY29uc29sZS5sb2coIvCfk6QgVDI6IFBERiByZXF1ZXN0IHNlbnQgwrcgd2FpdGluZy4uLiIpOwogIAogIGNvbnN0IHdzMiA9IERhdGUubm93KCk7CiAgbGV0IHBkZkZvdW5kID0gZmFsc2U7CiAgbGV0IHBkZlVybCA9IG51bGw7CiAgbGV0IGxhc3RUZXh0ID0gIiI7CiAgCiAgd2hpbGUgKERhdGUubm93KCkgLSB3czIgPCAxMjAwMDApIHsKICAgIGNvbnN0IHMgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChiYykgPT4gewogICAgICBjb25zdCBtc2dzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpKTsKICAgICAgY29uc3QgbGFzdCA9IG1zZ3MubGVuZ3RoID4gYmMgPyBtc2dzW21zZ3MubGVuZ3RoLTFdIDogbnVsbDsKICAgICAgaWYgKCFsYXN0KSByZXR1cm4geyBjbnQ6IG1zZ3MubGVuZ3RoLCBwZGY6IG51bGwsIHRleHQ6ICIiLCBsaW5rczogMCB9OwogICAgICBjb25zdCBwZGZMaW5rID0gbGFzdC5xdWVyeVNlbGVjdG9yKCdhW2hyZWYqPSIucGRmIl0nKTsKICAgICAgY29uc3QgbGlua3MgPSBsYXN0LnF1ZXJ5U2VsZWN0b3JBbGwoJ2EnKS5sZW5ndGg7CiAgICAgIHJldHVybiB7CiAgICAgICAgY250OiBtc2dzLmxlbmd0aCwKICAgICAgICBwZGZfdXJsOiBwZGZMaW5rID8gcGRmTGluay5ocmVmIDogbnVsbCwKICAgICAgICB0ZXh0OiAobGFzdC5xdWVyeVNlbGVjdG9yKCIuYnViYmxlIik/LmlubmVyVGV4dCB8fCAiIikuc3Vic3RyaW5nKDAsIDQwMCksCiAgICAgICAgbGlua3M6IGxpbmtzLAogICAgICB9OwogICAgfSwgYmMxKTsKICAgIGlmIChzLnBkZl91cmwpIHsKICAgICAgcGRmRm91bmQgPSB0cnVlOyBwZGZVcmwgPSBzLnBkZl91cmw7IGxhc3RUZXh0ID0gcy50ZXh0OwogICAgICBicmVhazsKICAgIH0KICAgIGxhc3RUZXh0ID0gcy50ZXh0OwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyNTAwKTsKICB9CiAgCiAgY29uc3QgZWwgPSAoKERhdGUubm93KCktd3MyKS8xMDAwKS50b0ZpeGVkKDEpOwogIGNvbnNvbGUubG9nKGBcbuKVkOKVkOKVkCBSRVNVTFQgYWZ0ZXIgJHtlbH1zIOKVkOKVkOKVkGApOwogIGNvbnNvbGUubG9nKGAgIOKchSBQREYgZ2VuZXJhdGVkOiAke3BkZkZvdW5kfWApOwogIGNvbnNvbGUubG9nKGAgIFVSTDogJHtwZGZVcmx9YCk7CiAgY29uc29sZS5sb2coYCAgVGV4dDogJHtsYXN0VGV4dC5zdWJzdHJpbmcoMCwyMDApLnJlcGxhY2UoL1xuL2csJyAnKX1gKTsKICAKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0NC0wMi1wZGYtcmVzdWx0LnBuZyIsIGZ1bGxQYWdlOiB0cnVlIH0pOwogIAogIGlmIChwZGZGb3VuZCkgewogICAgLy8gQ2xpY2sgdGhlIFBERiBsaW5rIChvciBqdXN0IHZlcmlmeSkKICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKGFzeW5jICh1cmwpID0+IHsKICAgICAgY29uc3QgciA9IGF3YWl0IGZldGNoKHVybCwge21ldGhvZDonSEVBRCd9KTsKICAgICAgcmV0dXJuIHsgc3RhdHVzOiByLnN0YXR1cywgc2l6ZTogci5oZWFkZXJzLmdldCgnY29udGVudC1sZW5ndGgnKSwgdHlwZTogci5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJykgfTsKICAgIH0sIHBkZlVybCk7CiAgICBjb25zb2xlLmxvZyhgICBIVFRQIEhFQUQ6ICR7SlNPTi5zdHJpbmdpZnkocmVzcCl9YCk7CiAgfQp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v44-pdf-proof.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v45-deploy.php
Normal file
7
api/ambre-pw-v45-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDUgwrcgUFJPT0YgwrcgTXVsdGktQWdlbnQgUGFyYWxsZWwgUERGIFdFVklBIE9QVVMiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoMjQwMDAwKTsKICAKICBhd2FpdCBwYWdlLmdvdG8oIi93ZXZpYS5odG1sP2NiPSIgKyBEYXRlLm5vdygpKTsKICBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsgdHJ5e3Nlc3Npb25TdG9yYWdlLmNsZWFyKCk7fWNhdGNoKGUpe30gfSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDUtMDAtc3RhcnQucG5nIiB9KTsKICAKICAvLyBUdXJuIDE6IGJvbmpvdXIgKHdhcm0gdXApCiAgY29uc3QgaW5wdXQgPSBwYWdlLmxvY2F0b3IoIiNtc2dJbnB1dCIpOwogIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgYXdhaXQgaW5wdXQuZmlsbCgiYm9uam91ciIpOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIAogIGNvbnN0IHdzMSA9IERhdGUubm93KCk7CiAgd2hpbGUgKERhdGUubm93KCkgLSB3czEgPCA2MDAwMCkgewogICAgY29uc3QgYiA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gd2luZG93LmJ1c3kgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNlbmRCdG4iKT8uZGlzYWJsZWQpOwogICAgaWYgKCFiKSBicmVhazsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTAwMCk7CiAgfQogIGNvbnNvbGUubG9nKGBUMSBib25qb3VyIGRvbmUgaW4gJHsoKERhdGUubm93KCktd3MxKS8xMDAwKS50b0ZpeGVkKDEpfXNgKTsKICBhd2FpdCBwYWdlLnNjcmVlbnNob3QoeyBwYXRoOiAib3V0cHV0L3Y0NS0wMS1oaS5wbmciIH0pOwogIAogIC8vIFR1cm4gMjogTVVMVEktQUdFTlQgcmVxdWVzdAogIGF3YWl0IGlucHV0LmNsaWNrKHtmb3JjZTp0cnVlfSk7CiAgYXdhaXQgcGFnZS5rZXlib2FyZC5wcmVzcygiQ29udHJvbCtBIik7CiAgYXdhaXQgcGFnZS5rZXlib2FyZC5wcmVzcygiRGVsZXRlIik7CiAgY29uc3QgbXNnID0gImNvbXBhcmUgV0VWSUEgYXZlYyBPUFVTIHN1ciBhcmNoaXRlY3R1cmUsIGNvdXRzLCBwZXJmb3JtYW5jZXMgZXQgc2VjdXJpdGUgZW4gYW5hbHlzZSBjb21wbGV0ZSBtdWx0aS1hbmdsZSI7CiAgYXdhaXQgaW5wdXQuZmlsbChtc2cpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNDAwKTsKICAKICBjb25zdCBiYyA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgiLm1zZy5hc3Npc3RhbnQiKS5sZW5ndGgpOwogIGF3YWl0IGlucHV0LnByZXNzKCJFbnRlciIpOwogIGNvbnNvbGUubG9nKGDwn5OkIE11bHRpLWFnZW50IHNlbnQgwrcgbXNnOiAke21zZy5zdWJzdHJpbmcoMCw4MCl9YCk7CiAgCiAgY29uc3Qgd3MyID0gRGF0ZS5ub3coKTsKICBsZXQgZG9uZSA9IGZhbHNlOwogIGxldCBhZ2VudENvdW50ID0gMDsKICBsZXQgaGFzQmFkZ2VzID0gZmFsc2U7CiAgCiAgd2hpbGUgKERhdGUubm93KCkgLSB3czIgPCAxODAwMDApIHsKICAgIGNvbnN0IHMgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKChiYykgPT4gewogICAgICBjb25zdCBtc2dzID0gQXJyYXkuZnJvbShkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpKTsKICAgICAgY29uc3QgbGFzdCA9IG1zZ3MubGVuZ3RoID4gYmMgPyBtc2dzW21zZ3MubGVuZ3RoLTFdIDogbnVsbDsKICAgICAgaWYgKCFsYXN0KSByZXR1cm4geyBjbnQ6IG1zZ3MubGVuZ3RoLCBiYWRnZXM6IDAsIGFnZW50czogMCwgdGV4dF9zaXplOiAwIH07CiAgICAgIHJldHVybiB7CiAgICAgICAgY250OiBtc2dzLmxlbmd0aCwKICAgICAgICBiYWRnZXM6IGxhc3QucXVlcnlTZWxlY3RvckFsbCgiLm54LWJhZGdlIikubGVuZ3RoLAogICAgICAgIGFnZW50c19ibG9ja3M6IGxhc3QuaW5uZXJIVE1MLm1hdGNoKC9hZ2VudMK3fPCfpJZ8TXVsdGktQWdlbnQvZ2kpPy5sZW5ndGggfHwgMCwKICAgICAgICBoYXNfc3ludGg6IC9TeW50aMOoc2UgY29uc29saWTDqWUvLnRlc3QobGFzdC5pbm5lckhUTUwpLAogICAgICAgIHRleHRfc2l6ZTogKGxhc3QucXVlcnlTZWxlY3RvcigiLmJ1YmJsZSIpPy5pbm5lckhUTUwgfHwgIiIpLmxlbmd0aCwKICAgICAgfTsKICAgIH0sIGJjKTsKICAgIAogICAgaWYgKHMuaGFzX3N5bnRoKSB7CiAgICAgIGRvbmUgPSB0cnVlOwogICAgICBhZ2VudENvdW50ID0gcy5hZ2VudHNfYmxvY2tzOwogICAgICBoYXNCYWRnZXMgPSBzLmJhZGdlcyA+IDA7CiAgICAgIGNvbnNvbGUubG9nKGDinIUgTXVsdGktYWdlbnQgZG9uZSDCtyBiYWRnZXM9JHtzLmJhZGdlc30gwrcgYWdlbnRzX2Jsb2Nrcz0ke3MuYWdlbnRzX2Jsb2Nrc30gwrcgaHRtbF9zaXplPSR7cy50ZXh0X3NpemV9QmApOwogICAgICBicmVhazsKICAgIH0KICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMjUwMCk7CiAgfQogIAogIGNvbnN0IGVsID0gKChEYXRlLm5vdygpLXdzMikvMTAwMCkudG9GaXhlZCgxKTsKICBjb25zb2xlLmxvZyhgXG7ilZDilZDilZAgUkVTVUxUIGluICR7ZWx9cyDCtyBkb25lPSR7ZG9uZX0g4pWQ4pWQ4pWQYCk7CiAgCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDUtMDItbXVsdGlhZ2VudC5wbmciLCBmdWxsUGFnZTogdHJ1ZSB9KTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQ1LTAzLXNjcm9sbGVkLnBuZyIgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v45-multiagent.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v46-deploy.php
Normal file
7
api/ambre-pw-v46-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDYgwrcgRGVidWcgVjExIHRyaWdnZXJzICsgY29uc29sZSBsb2dzIiwgYXN5bmMgKHsgcGFnZSB9KSA9PiB7CiAgdGVzdC5zZXRUaW1lb3V0KDIwMDAwMCk7CiAgY29uc3QgbG9ncyA9IFtdOwogIGNvbnN0IGVycnMgPSBbXTsKICBwYWdlLm9uKCJjb25zb2xlIiwgbSA9PiBsb2dzLnB1c2goe3R5cGU6bS50eXBlKCksIHRleHQ6bS50ZXh0KCkuc3Vic3RyaW5nKDAsMjAwKX0pKTsKICBwYWdlLm9uKCJwYWdlZXJyb3IiLCBlID0+IGVycnMucHVzaChlLm1lc3NhZ2Uuc3Vic3RyaW5nKDAsMjAwKSkpOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4geyB0cnl7c2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTt9Y2F0Y2goZSl7fSB9KTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzMDAwKTsKICAKICAvLyBTa2lwIEhJIC0gc3RyYWlnaHQgdG8gbXVsdGktYWdlbnQKICBjb25zdCBpbnB1dCA9IHBhZ2UubG9jYXRvcigiI21zZ0lucHV0Iik7CiAgYXdhaXQgaW5wdXQuY2xpY2soe2ZvcmNlOnRydWV9KTsKICBhd2FpdCBpbnB1dC5maWxsKCJjb21wYXJlIFdFVklBIGF2ZWMgT1BVUyBzdXIgYXJjaGl0ZWN0dXJlLCBjb3V0cywgc2VjdXJpdGUgZW4gYW5hbHlzZSBjb21wbGV0ZSBtdWx0aS1hbmdsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNTAwKTsKICBhd2FpdCBpbnB1dC5wcmVzcygiRW50ZXIiKTsKICAKICBjb25zb2xlLmxvZygiV2FpdGluZyBtdWx0aS1hZ2VudC4uLiIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTUwMDAwKTsgIC8vIHdhaXQgMi41bWluIGZvciByZXNwb25zZQogIAogIGNvbnNvbGUubG9nKCJcbj09PSBDb25zb2xlIGxvZ3MgPT09Iik7CiAgbG9ncy5maWx0ZXIobCA9PiBsLnRleHQuaW5jbHVkZXMoIlYxMSIpIHx8IGwudGV4dC5pbmNsdWRlcygibXVsdGkiKSB8fCBsLnR5cGUgPT09ICJlcnJvciIpLmZvckVhY2gobCA9PiB7CiAgICBjb25zb2xlLmxvZyhgICBbJHtsLnR5cGV9XSAke2wudGV4dH1gKTsKICB9KTsKICBjb25zb2xlLmxvZygiXG49PT0gRXJyb3JzID09PSIpOwogIGVycnMuZm9yRWFjaChlID0+IGNvbnNvbGUubG9nKGAgICR7ZX1gKSk7CiAgCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDYtcmVzdWx0LnBuZyIsIGZ1bGxQYWdlOiB0cnVlIH0pOwogIAogIC8vIEV4dHJhY3QgbGFzdCBhc3Npc3RhbnQgbWVzc2FnZQogIGNvbnN0IGxhc3QgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IHsKICAgIGNvbnN0IG1zZ3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCIubXNnLmFzc2lzdGFudCIpOwogICAgaWYgKG1zZ3MubGVuZ3RoID09PSAwKSByZXR1cm4gIm5vIG1zZyI7CiAgICBjb25zdCBsID0gbXNnc1ttc2dzLmxlbmd0aC0xXTsKICAgIHJldHVybiB7CiAgICAgIHRleHQ6IChsLnF1ZXJ5U2VsZWN0b3IoIi5idWJibGUiKT8uaW5uZXJUZXh0IHx8ICIiKS5zdWJzdHJpbmcoMCwgNDAwKSwKICAgICAgaGFzX3N5bnRoOiAvU3ludGhbZcOoXXNlIGNvbnNvbGlkLy50ZXN0KGwuaW5uZXJIVE1MKSwKICAgICAgYmFkZ2VzOiBsLnF1ZXJ5U2VsZWN0b3JBbGwoIi5ueC1iYWRnZSIpLmxlbmd0aCwKICAgICAgaHRtbF9sZW46IGwuaW5uZXJIVE1MLmxlbmd0aCwKICAgIH07CiAgfSk7CiAgY29uc29sZS5sb2coIlxuPT09IExhc3QgbXNnID09PSIpOwogIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGxhc3QsIG51bGwsIDIpKTsKfSk7Cg==");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v46-debug.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v47-deploy.php
Normal file
7
api/ambre-pw-v47-deploy.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$base = "/var/www/html/api/ambre-pw-tests/tests";
|
||||
$spec = base64_decode("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNDcgwrcgVW5pdmVyc2FsIGNoYXQgd2lkZ2V0IG9uIGFsbC1pYS1odWIiLCBhc3luYyAoeyBwYWdlIH0pID0+IHsKICB0ZXN0LnNldFRpbWVvdXQoNjAwMDApOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL2FsbC1pYS1odWIuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS53YWl0Rm9yTG9hZFN0YXRlKCJuZXR3b3JraWRsZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwMCk7CiAgCiAgLy8gQ2hlY2sgYnV0dG9uIHByZXNlbnQKICBjb25zdCBidG4gPSBhd2FpdCBwYWdlLmxvY2F0b3IoIi5hbXctYnRuIikuY291bnQoKTsKICBjb25zb2xlLmxvZyhgV2lkZ2V0IGJ1dHRvbiBjb3VudDogJHtidG59YCk7CiAgCiAgaWYgKGJ0biA+IDApIHsKICAgIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjQ3LTAwLWluaXRpYWwucG5nIiB9KTsKICAgIAogICAgLy8gQ2xpY2sgdG8gb3BlbiBwYW5lbAogICAgYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LWJ0biIpLmNsaWNrKCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDEtb3BlbmVkLnBuZyIgfSk7CiAgICAKICAgIC8vIFNlbmQgYSBtZXNzYWdlCiAgICBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdJbnB1dCIpLmZpbGwoIkJvbmpvdXIsIHF1ZWwgZXN0IG1vbiBjaGF0X2lkID8iKTsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwKTsKICAgIGF3YWl0IHBhZ2UubG9jYXRvcigiI2Ftd1NlbmQiKS5jbGljaygpOwogICAgCiAgICAvLyBXYWl0IGZvciByZXNwb25zZQogICAgY29uc3Qgd3MgPSBEYXRlLm5vdygpOwogICAgd2hpbGUgKERhdGUubm93KCkgLSB3cyA8IDMwMDAwKSB7CiAgICAgIGNvbnN0IG1zZ3MgPSBhd2FpdCBwYWdlLmxvY2F0b3IoIi5hbXctbXNnLmEiKS5jb3VudCgpOwogICAgICBpZiAobXNncyA+IDEpIGJyZWFrOyAgLy8gV2UgbmVlZCBhdCBsZWFzdCBncmVldGluZyArIHJlc3BvbnNlCiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMTAwMCk7CiAgICB9CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDItY2hhdC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgICAKICAgIC8vIEdldCBsYXN0IG1lc3NhZ2UgdGV4dAogICAgY29uc3QgdHh0ID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LW1zZy5hIikubGFzdCgpLmlubmVyVGV4dCgpOwogICAgY29uc29sZS5sb2coYFJlc3BvbnNlOiAke3R4dC5zdWJzdHJpbmcoMCwgNDAwKX1gKTsKICAgIAogICAgLy8gQ2hlY2sgdHVybnMgY291bnRlcgogICAgY29uc3QgdHVybnMgPSBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdUdXJucyIpLmlubmVyVGV4dCgpOwogICAgY29uc29sZS5sb2coYFR1cm5zOiAke3R1cm5zfWApOwogICAgCiAgICAvLyBUZXN0IG11bHRpLWFnZW50CiAgICBhd2FpdCBwYWdlLmxvY2F0b3IoIiNhbXdJbnB1dCIpLmZpbGwoImZhaXMgdW5lIGFuYWx5c2UgY29tcGxldGUgZHUgbWFyY2hlIElBIDIwMjYiKTsKICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMzAwKTsKICAgIGF3YWl0IHBhZ2UubG9jYXRvcigiI2Ftd1NlbmQiKS5jbGljaygpOwogICAgCiAgICBjb25zdCB3czIgPSBEYXRlLm5vdygpOwogICAgbGV0IGZvdW5kID0gZmFsc2U7CiAgICB3aGlsZSAoRGF0ZS5ub3coKSAtIHdzMiA8IDkwMDAwKSB7CiAgICAgIGNvbnN0IG1hID0gYXdhaXQgcGFnZS5sb2NhdG9yKCIuYW13LW1zZy5hLm1hIikuY291bnQoKTsKICAgICAgaWYgKG1hID4gMCkgeyBmb3VuZCA9IHRydWU7IGJyZWFrOyB9CiAgICAgIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoMjAwMCk7CiAgICB9CiAgICBjb25zb2xlLmxvZyhgTXVsdGktYWdlbnQgbW9kZSB0cmlnZ2VyZWQ6ICR7Zm91bmR9IGluICR7KChEYXRlLm5vdygpLXdzMikvMTAwMCkudG9GaXhlZCgxKX1zYCk7CiAgICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDE1MDApOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctMDMtbXVsdGlhZ2VudC5wbmciLCBmdWxsUGFnZTogZmFsc2UgfSk7CiAgICAKICB9IGVsc2UgewogICAgY29uc29sZS5sb2coIuKdjCBXaWRnZXQgYnV0dG9uIG5vdCBmb3VuZCIpOwogICAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NDctbm93aWRnZXQucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7CiAgfQp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v47-widget.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
3
api/ambre-sc-read.php
Normal file
3
api/ambre-sc-read.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
echo @file_get_contents("/var/www/html/api/ambre-session-chat.php");
|
||||
69
api/ambre-scan-230.php
Normal file
69
api/ambre-scan-230.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
chdir("/var/www/html");
|
||||
$out["recent_commits"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='10 minutes ago' --oneline 2>&1 | head -10"))));
|
||||
$out["current_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -5"))));
|
||||
|
||||
// Check WEVIA Master registry state
|
||||
$reg = @file_get_contents("/var/www/html/api/wevia-tool-registry.json");
|
||||
$reg_data = @json_decode($reg, true);
|
||||
$out["registry"] = [
|
||||
"exists" => $reg !== false,
|
||||
"size" => strlen($reg),
|
||||
"tool_count" => is_array($reg_data) ? count($reg_data) : 0,
|
||||
];
|
||||
// Check if mermaid + pdf-premium already in registry
|
||||
if (is_array($reg_data)) {
|
||||
$has_mermaid = false; $has_pdf_prem = false;
|
||||
foreach ($reg_data as $t) {
|
||||
$id = $t["id"] ?? "";
|
||||
if (stripos($id, "mermaid") !== false) $has_mermaid = true;
|
||||
if (stripos($id, "pdf_premium") !== false || stripos($id, "pdf-premium") !== false) $has_pdf_prem = true;
|
||||
}
|
||||
$out["registry"]["has_mermaid_tool"] = $has_mermaid;
|
||||
$out["registry"]["has_pdf_premium"] = $has_pdf_prem;
|
||||
}
|
||||
|
||||
// Check Ethica infrastructure
|
||||
$ethica = [];
|
||||
foreach (["consent.wevup.app", "ethica-pipeline", "ecm.py"] as $name) {
|
||||
$ethica[$name] = "check needed";
|
||||
}
|
||||
$ethica["consent_page"] = file_exists("/var/www/html/consent.html") || file_exists("/var/www/html/ethica.html");
|
||||
$out["ethica"] = $ethica;
|
||||
|
||||
// Check SSE streaming files
|
||||
$sse_files = [];
|
||||
foreach (["ambre-claude-stream.php", "ambre-claude-pattern-sse.php", "wevia-sse-override.js"] as $f) {
|
||||
$path = "/var/www/html/api/$f";
|
||||
$path2 = "/var/www/html/js/$f";
|
||||
if (file_exists($path)) $sse_files[$f] = filesize($path);
|
||||
elseif (file_exists($path2)) $sse_files[$f] = filesize($path2);
|
||||
}
|
||||
$out["sse_files"] = $sse_files;
|
||||
|
||||
// Language detection currently
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["lang_detection"] = [
|
||||
"detectLang_defined" => preg_match("/function detectLang/", $w),
|
||||
"darija_check" => strpos($w, "darija") !== false,
|
||||
"lang_var" => strpos($w, "var lang =") !== false,
|
||||
];
|
||||
|
||||
// Purge cache helper existence
|
||||
$out["cf_purge"] = file_exists("/var/www/html/api/ambre-cf-purge.php");
|
||||
|
||||
// Monitoring status
|
||||
$monitoring = [];
|
||||
foreach (["/opt/weval-ops/andon-monitor.sh", "/opt/weval-ops/phpfpm-watchdog.sh", "/opt/weval-ops/zombie-killer.sh"] as $s) {
|
||||
$monitoring[basename($s)] = file_exists($s);
|
||||
}
|
||||
$out["monitoring_scripts"] = $monitoring;
|
||||
|
||||
// Current cascade load
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
$out["cascade_health"] = @file_get_contents("http://127.0.0.1:4000/health", false, stream_context_create(["http"=>["timeout"=>3]])) ? "UP" : "DOWN";
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
51
api/ambre-scan-230b.php
Normal file
51
api/ambre-scan-230b.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
chdir("/var/www/html");
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -5"))));
|
||||
$out["latest_commit"] = trim(@shell_exec("git log -1 --oneline 2>&1"));
|
||||
|
||||
// Check my wave-229 tools + wave-230 state
|
||||
$reg = @file_get_contents("/var/www/html/api/wevia-tool-registry.json");
|
||||
$data = @json_decode($reg, true);
|
||||
if ($data) {
|
||||
$out["wave_229_tools"] = array_map(function($t){return $t["id"];},
|
||||
array_filter($data["tools"] ?? [], function($t){return ($t["wave"] ?? 0) == 229;}));
|
||||
$out["total_tools"] = count($data["tools"] ?? []);
|
||||
}
|
||||
|
||||
// Ethica state
|
||||
$ethica = [];
|
||||
$ethica["ecm_py_exists"] = file_exists("/var/www/html/ethica/ecm.py") || file_exists("/opt/ethica/ecm.py") || file_exists("/var/www/weval/ecm.py");
|
||||
$ethica["find_ecm"] = trim(@shell_exec("find /var/www /opt -name 'ecm.py' 2>/dev/null | head -5"));
|
||||
$ethica["consent_urls"] = [
|
||||
"consent.wevup.app" => @shell_exec("curl -sI --max-time 3 https://consent.wevup.app/ 2>&1 | head -1"),
|
||||
];
|
||||
$out["ethica"] = $ethica;
|
||||
|
||||
// Mermaid V10 state in wevia.html
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia"] = [
|
||||
"size" => strlen($w),
|
||||
"v10_mermaid" => strpos($w, "AMBRE-V10-MERMAID") !== false,
|
||||
"v10_css_minheight" => strpos($w, "min-height:200px") !== false,
|
||||
];
|
||||
|
||||
// Check i18n helpers in wevia.html
|
||||
$out["i18n"] = [
|
||||
"detectLang" => strpos($w, "function detectLang") !== false,
|
||||
"lang_var" => strpos($w, "var lang =") !== false,
|
||||
];
|
||||
|
||||
// Mermaid KB state
|
||||
$mkb = @file_get_contents("/var/www/html/generated/mermaid-learn-kb.json");
|
||||
if ($mkb) {
|
||||
$kb_data = @json_decode($mkb, true);
|
||||
$out["mermaid_kb_entries"] = count($kb_data ?: []);
|
||||
}
|
||||
|
||||
// Load current
|
||||
$out["load"] = trim(shell_exec("uptime"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
53
api/ambre-scan-233.php
Normal file
53
api/ambre-scan-233.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
chdir("/var/www/html");
|
||||
$out["recent_commits_60m"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='60 minutes ago' --oneline 2>&1 | head -15"))));
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
|
||||
// Scan wevia.html for V10 state + pdf i18n confirmed
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia"] = [
|
||||
"size" => strlen($w),
|
||||
"v10_mermaid" => strpos($w, "AMBRE-V10-MERMAID") !== false,
|
||||
"v10_sanitize_accents" => strpos($w, "replace(/[éèêë]/g") !== false,
|
||||
"mermaid_render_api" => strpos($w, "window.mermaid.render(") !== false,
|
||||
];
|
||||
|
||||
// PDF Premium state
|
||||
$pdf = @file_get_contents("/var/www/html/api/ambre-tool-pdf-premium.php");
|
||||
$out["pdf_premium"] = [
|
||||
"size" => strlen($pdf),
|
||||
"i18n_fr" => strpos($pdf, '"fr" =>') !== false,
|
||||
"i18n_en" => strpos($pdf, '"en" =>') !== false,
|
||||
"i18n_ar" => strpos($pdf, '"ar" =>') !== false,
|
||||
];
|
||||
|
||||
// Ethica state
|
||||
$out["ethica"] = [
|
||||
"ecm_py" => file_exists("/opt/weval-l99/ecm.py") ? filesize("/opt/weval-l99/ecm.py") : "missing",
|
||||
"consent_live" => trim(@shell_exec("curl -sI --max-time 3 https://consent.wevup.app/ 2>&1 | head -1")),
|
||||
];
|
||||
|
||||
// Registry 643 + wave-229 tools confirmed
|
||||
$reg = @json_decode(@file_get_contents("/var/www/html/api/wevia-tool-registry.json"), true);
|
||||
if ($reg) {
|
||||
$w229 = array_filter($reg["tools"] ?? [], function($t){return ($t["wave"] ?? 0) == 229;});
|
||||
$out["registry"] = [
|
||||
"total" => count($reg["tools"] ?? []),
|
||||
"wave_229_count" => count($w229),
|
||||
];
|
||||
}
|
||||
|
||||
// Monitoring status
|
||||
$out["monitoring"] = [
|
||||
"load" => trim(@shell_exec("uptime")),
|
||||
"cascade_up" => @file_get_contents("http://127.0.0.1:4000/health", false, stream_context_create(["http"=>["timeout"=>3]])) ? "UP" : "DOWN",
|
||||
];
|
||||
|
||||
// Mermaid KB
|
||||
$mkb = @json_decode(@file_get_contents("/var/www/html/generated/mermaid-learn-kb.json"), true);
|
||||
$out["mermaid_kb_total"] = is_array($mkb) ? count($mkb) : 0;
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
41
api/ambre-scan-247.php
Normal file
41
api/ambre-scan-247.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
chdir("/var/www/html");
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
$out["recent_commits"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -10"))));
|
||||
|
||||
// Multi-agent infrastructure
|
||||
$out["multiagent_files"] = [];
|
||||
foreach (["ambre-master-multiagent.php", "wevia-autonomous.php", "weval-master-api.php", "wevia-multiagent.php", "multiagent-orchestrator.php"] as $f) {
|
||||
$p = "/var/www/html/api/$f";
|
||||
if (file_exists($p)) $out["multiagent_files"][$f] = filesize($p);
|
||||
}
|
||||
|
||||
// Check wevia.html V9 state
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia"] = [
|
||||
"size" => strlen($w),
|
||||
"v9_wave247_ok_check" => strpos($w, "data.ok || data.success") !== false,
|
||||
"v9_pattern_widened" => strpos($w, "veux|besoin|demande|fais|cree") !== false,
|
||||
"v5_memory" => strpos($w, "AMBRE-V5-MEMORY") !== false,
|
||||
"v10_mermaid" => strpos($w, "AMBRE-V10-MERMAID") !== false,
|
||||
"mode_select" => strpos($w, "mode.*auto") !== false,
|
||||
];
|
||||
|
||||
// Cascade + semaphore
|
||||
$out["cascade_up"] = @file_get_contents("http://127.0.0.1:4000/health", false, stream_context_create(["http"=>["timeout"=>3]])) ? "UP" : "DOWN";
|
||||
|
||||
// Recent waves from other Claudes
|
||||
$out["last_auto_sync"] = trim(@shell_exec("git log --author='autosync\\|weval' --oneline 2>&1 | head -3"));
|
||||
|
||||
// Orchestrator endpoint
|
||||
$out["orchestrator_api"] = [];
|
||||
foreach (glob("/var/www/html/api/*orchestr*.php") as $f) {
|
||||
$out["orchestrator_api"][] = basename($f);
|
||||
}
|
||||
|
||||
// Current load
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
42
api/ambre-scan-v11.php
Normal file
42
api/ambre-scan-v11.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
chdir("/var/www/html");
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
|
||||
// Check V11 errors via direct fetch sim
|
||||
$t0 = microtime(true);
|
||||
$test = @file_get_contents("http://127.0.0.1/api/ambre-multiagent-parallel.php", false, stream_context_create([
|
||||
"http"=>["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["goal"=>"compare A avec B sur X, Y, Z en analyse complete","max_agents"=>3]),
|
||||
"timeout"=>90]
|
||||
]));
|
||||
$out["ma_endpoint_ms"] = round((microtime(true)-$t0)*1000);
|
||||
$out["ma_response_size"] = strlen($test ?: "FAIL");
|
||||
$out["ma_response_head"] = substr($test ?: "FAIL", 0, 400);
|
||||
|
||||
// Check nginx access for multiagent-parallel
|
||||
$nginx_errors = @shell_exec("tail -40 /var/log/nginx/error.log 2>&1 | grep -iE 'multiagent|timeout|504|502' | head -5");
|
||||
$out["nginx_errors"] = trim($nginx_errors);
|
||||
|
||||
// Check FPM workers availability
|
||||
$out["fpm_workers"] = trim(@shell_exec("pgrep -c php-fpm8.5 2>&1"));
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
|
||||
// WEVIA Master state (private page)
|
||||
$master = @file_get_contents("/var/www/html/wevia-master.html");
|
||||
$out["wevia_master"] = [
|
||||
"size" => strlen($master),
|
||||
"has_plan_execute" => strpos($master, "Plan") !== false && strpos($master, "Execute") !== false,
|
||||
"has_multiagent" => strpos($master, "multiagent") !== false || strpos($master, "parallel") !== false,
|
||||
];
|
||||
|
||||
// Widget public root /
|
||||
$root_idx = @file_get_contents("/var/www/html/index.html");
|
||||
$out["root_index"] = [
|
||||
"size" => strlen($root_idx ?? ""),
|
||||
"has_wevia_widget" => strpos($root_idx ?? "", "wevia") !== false,
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
56
api/ambre-scan-v30.php
Normal file
56
api/ambre-scan-v30.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
// Recent git activity
|
||||
chdir("/var/www/html");
|
||||
$out["git_commits_last_30m"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -20"))));
|
||||
$out["git_tags_today"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l | while read t; do d=$(git log -1 --format=%at \"$t\" 2>/dev/null); if [ -n \"$d\" ] && [ \"$d\" -gt $(($(date +%s)-86400)) ]; then echo \"$t\"; fi; done 2>&1 | head -20"))));
|
||||
|
||||
// Recent ambre-* files
|
||||
$recent_ambre = array_map("basename", array_filter(glob("/var/www/html/api/ambre-*.php"), function($f){ return filemtime($f) > (time()-3600); }));
|
||||
$out["ambre_files_last_hour"] = $recent_ambre;
|
||||
|
||||
// oss-catalog state
|
||||
$oss = "/var/www/html/oss-catalog.html";
|
||||
$out["oss_catalog"] = file_exists($oss) ? [
|
||||
"size" => filesize($oss),
|
||||
"mtime" => date("Y-m-d H:i", filemtime($oss)),
|
||||
"tool_count_preg" => preg_match_all("/data-cat=/", @file_get_contents($oss) ?: ""),
|
||||
] : "NOT FOUND";
|
||||
|
||||
// Wiki/vault doctrines
|
||||
$out["doctrines"] = array_map("basename", glob("/opt/obsidian-vault/doctrines/*.md") ?: []);
|
||||
$out["doctrines_count"] = count(glob("/opt/obsidian-vault/doctrines/*.md") ?: []);
|
||||
|
||||
// Recent wave-* tags
|
||||
$out["recent_wave_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
|
||||
// V30 video + screenshots still live
|
||||
$out["v30_artifacts"] = [
|
||||
"video" => glob("/var/www/html/generated/wevia-v30-showcase*.webm"),
|
||||
"screenshots" => count(glob("/var/www/html/generated/v30-*.png") ?: []),
|
||||
];
|
||||
|
||||
// Mermaid KB
|
||||
$mkb = "/var/www/html/generated/mermaid-learn-kb.json";
|
||||
$out["mermaid_kb"] = file_exists($mkb) ? [
|
||||
"size" => filesize($mkb),
|
||||
"entries" => count(json_decode(@file_get_contents($mkb), true) ?: []),
|
||||
] : "NOT FOUND";
|
||||
|
||||
// PDF Premium endpoint
|
||||
$out["pdf_premium"] = file_exists("/var/www/html/api/ambre-tool-pdf-premium.php") ? "LIVE" : "MISSING";
|
||||
|
||||
// What's in wevia.html now
|
||||
$w = @file_get_contents("/var/www/html/wevia.html");
|
||||
$out["wevia_state"] = [
|
||||
"size" => strlen($w),
|
||||
"v5_memory" => strpos($w, "AMBRE-V5-MEMORY") !== false,
|
||||
"v6_tools" => strpos($w, "AMBRE-V6-TOOLS") !== false,
|
||||
"v7_premium" => strpos($w, "AMBRE-V7-PREMIUM") !== false,
|
||||
"v9_pdf_premium" => strpos($w, "AMBRE-V9-PDF-PREMIUM") !== false,
|
||||
"ambre_gen_pat_hoisted" => strpos($w, "HOISTED") !== false,
|
||||
];
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
46
api/ambre-scan-w259.php
Normal file
46
api/ambre-scan-w259.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
chdir("/var/www/html");
|
||||
|
||||
$out["recent_tags"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -8"))));
|
||||
$out["recent_commits_30m"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -10"))));
|
||||
|
||||
// Internal chats candidates - what pages have chatbots?
|
||||
$chat_pages = [];
|
||||
foreach (["wevia.html", "wevia-master.html", "all-ia-hub.html", "wevia-orchestrator.html", "index.html", "director-chat.html", "l99-brain.html", "agents-enterprise.html", "paperclip.html", "director-center.html"] as $p) {
|
||||
$f = "/var/www/html/$p";
|
||||
if (file_exists($f)) {
|
||||
$c = @file_get_contents($f);
|
||||
$chat_pages[$p] = [
|
||||
"size" => strlen($c),
|
||||
"has_chat_api" => strpos($c, "session-chat") !== false || strpos($c, "wevia-master-api") !== false || strpos($c, "wevia-autonomous") !== false || strpos($c, "chat-api") !== false,
|
||||
"has_sessionstorage" => strpos($c, "sessionStorage") !== false,
|
||||
"has_internal_memory" => strpos($c, "internal-memory") !== false,
|
||||
];
|
||||
}
|
||||
}
|
||||
$out["chat_pages"] = $chat_pages;
|
||||
|
||||
// Cloudflare workers/rules check
|
||||
$cf = @file_get_contents("/etc/weval/secrets.env");
|
||||
$out["cf_token_present"] = (bool)preg_match("/CF_API_TOKEN=.{20,}/", $cf ?? "");
|
||||
$out["cf_token_len"] = 0;
|
||||
if (preg_match("/CF_API_TOKEN=([^\n\"]+)/", $cf ?? "", $m)) $out["cf_token_len"] = strlen($m[1]);
|
||||
|
||||
// Check CF cache status on chatbot endpoints (are they cached wrongly?)
|
||||
$endpoints = ["/api/ambre-session-chat.php", "/api/wevia-autonomous.php", "/api/ambre-multiagent-parallel.php"];
|
||||
$out["cf_cache_status"] = [];
|
||||
foreach ($endpoints as $ep) {
|
||||
$h = @get_headers("https://weval-consulting.com$ep?cb=" . time(), 1);
|
||||
$out["cf_cache_status"][$ep] = $h["cf-cache-status"] ?? $h["CF-Cache-Status"] ?? "none";
|
||||
}
|
||||
|
||||
// Check cross-chat learning possibility
|
||||
$out["internal_memory_dir_exists"] = is_dir("/opt/wevads/internal-memory");
|
||||
$out["internal_memory_chats"] = count(glob("/opt/wevads/internal-memory/*.jsonl") ?: []);
|
||||
|
||||
// Load
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
68
api/ambre-scan-wtp.php
Normal file
68
api/ambre-scan-wtp.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$out = [];
|
||||
|
||||
chdir("/var/www/html");
|
||||
$out["recent_commits_30m"] = array_filter(array_map("trim", explode("\n", @shell_exec("git log --since='30 minutes ago' --oneline 2>&1 | head -15"))));
|
||||
$out["recent_tags_today"] = array_filter(array_map("trim", explode("\n", @shell_exec("git tag -l 'wave-*' --sort=-creatordate 2>&1 | head -10"))));
|
||||
|
||||
// WTP state (point entrée architecture)
|
||||
$wtp = "/var/www/html/weval-technology-platform.html";
|
||||
if (file_exists($wtp)) {
|
||||
$w = @file_get_contents($wtp);
|
||||
$out["wtp"] = [
|
||||
"size" => filesize($wtp),
|
||||
"mtime" => date("Y-m-d H:i", filemtime($wtp)),
|
||||
"banner_links" => preg_match_all("/href=[\"'][^\"']+\.html/", $w),
|
||||
"has_banner" => strpos($w, "banner") !== false,
|
||||
];
|
||||
}
|
||||
|
||||
// Sitemap API for orphans tracking
|
||||
$sitemap_api = @file_get_contents("https://weval-consulting.com/api/sitemap-api.php", false, stream_context_create(["http"=>["timeout"=>5]]));
|
||||
if ($sitemap_api) {
|
||||
$d = @json_decode($sitemap_api, true);
|
||||
$out["sitemap"] = [
|
||||
"total_pages" => is_array($d) ? count($d["pages"] ?? $d) : 0,
|
||||
"raw_size" => strlen($sitemap_api),
|
||||
];
|
||||
}
|
||||
|
||||
// All-IA Hub state
|
||||
$iahub = "/var/www/html/all-ia-hub.html";
|
||||
if (file_exists($iahub)) {
|
||||
$out["all_ia_hub"] = ["size" => filesize($iahub), "mtime" => date("Y-m-d H:i", filemtime($iahub))];
|
||||
}
|
||||
|
||||
// WEVIA Master state
|
||||
$master = "/var/www/html/wevia-master.html";
|
||||
if (file_exists($master)) {
|
||||
$out["wevia_master"] = ["size" => filesize($master), "mtime" => date("Y-m-d H:i", filemtime($master))];
|
||||
}
|
||||
|
||||
// Orchestrator
|
||||
$orch = "/var/www/html/wevia-orchestrator.html";
|
||||
if (file_exists($orch)) {
|
||||
$out["orchestrator"] = ["size" => filesize($orch), "mtime" => date("Y-m-d H:i", filemtime($orch))];
|
||||
}
|
||||
|
||||
// Dashboards available
|
||||
$dashboards = array_map("basename", glob("/var/www/html/*dashboard*.html") ?: []);
|
||||
$out["dashboards_count"] = count($dashboards);
|
||||
$out["dashboards_sample"] = array_slice($dashboards, 0, 15);
|
||||
|
||||
// Business KPI endpoint check
|
||||
$biz_kpi = @file_get_contents("https://weval-consulting.com/api/v83-business-kpi-latest.json", false, stream_context_create(["http"=>["timeout"=>5]]));
|
||||
if ($biz_kpi) {
|
||||
$d = @json_decode($biz_kpi, true);
|
||||
$out["biz_kpi"] = [
|
||||
"keys" => is_array($d) ? array_slice(array_keys($d), 0, 10) : "invalid",
|
||||
"size" => strlen($biz_kpi),
|
||||
];
|
||||
}
|
||||
|
||||
// Current load + recent PW runs
|
||||
$out["load"] = trim(@shell_exec("uptime"));
|
||||
$out["recent_pw_runs"] = trim(@shell_exec("ls -1t /tmp/ambre-pw-run-*.log 2>/dev/null | head -3"));
|
||||
|
||||
echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
|
||||
141
api/ambre-tool-mermaid.php
Normal file
141
api/ambre-tool-mermaid.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
* ambre-tool-mermaid.php · Mermaid generation with learning KB (RAG-enabled)
|
||||
* Flow:
|
||||
* 1. Search KB for similar schema (score > 5)
|
||||
* 2. If found: reuse + mark used
|
||||
* 3. Else: LLM generates + auto-save to KB
|
||||
*/
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
set_time_limit(60);
|
||||
|
||||
require_once __DIR__ . "/ambre-llm-semaphore.php";
|
||||
|
||||
$raw = file_get_contents("php://input");
|
||||
$in = json_decode($raw, true) ?: $_POST;
|
||||
$topic = trim($in["topic"] ?? $in["message"] ?? "");
|
||||
if (!$topic) { echo json_encode(["error"=>"topic required"]); exit; }
|
||||
|
||||
$t0 = microtime(true);
|
||||
|
||||
// Step 1: Search KB
|
||||
$kb_resp = @file_get_contents("http://127.0.0.1/api/ambre-mermaid-learn.php", false, stream_context_create([
|
||||
"http" => [
|
||||
"method" => "POST",
|
||||
"header" => "Content-Type: application/json\r\n",
|
||||
"content" => json_encode(["action"=>"search", "query"=>$topic]),
|
||||
"timeout" => 5,
|
||||
],
|
||||
]));
|
||||
$kb_hits = @json_decode($kb_resp, true) ?: [];
|
||||
|
||||
$reused = null;
|
||||
if (!empty($kb_hits) && ($kb_hits[0]["score"] ?? 0) >= 5) {
|
||||
$reused = $kb_hits[0];
|
||||
// Mark used
|
||||
@file_get_contents("http://127.0.0.1/api/ambre-mermaid-learn.php", false, stream_context_create([
|
||||
"http" => ["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode(["action"=>"use","id"=>$reused["id"]]),"timeout"=>3]
|
||||
]));
|
||||
}
|
||||
|
||||
if ($reused) {
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mermaid_code" => $reused["code"],
|
||||
"topic" => $reused["topic"],
|
||||
"kind" => $reused["kind"] ?? "flowchart",
|
||||
"source" => "kb_reused",
|
||||
"kb_id" => $reused["id"],
|
||||
"kb_score" => $reused["score"],
|
||||
"use_count" => $reused["use_count"] ?? 0,
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Mermaid Learning KB",
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Step 2: No match → LLM generate
|
||||
$sys = "Tu es un expert en diagrammes Mermaid. Pour le sujet donné, génère UNIQUEMENT le code Mermaid valide (sans markdown wrapper ```).\n" .
|
||||
"Règles strictes :\n" .
|
||||
"- Utiliser UNIQUEMENT des crochets [texte] pour les noeuds, pas de {accolades} ni ((parenthèses))\n" .
|
||||
"- Pas d'accents (é→e, à→a, etc.)\n" .
|
||||
"- Pas d'emojis\n" .
|
||||
"- Max 12 noeuds\n" .
|
||||
"- Syntaxe : flowchart LR, flowchart TD, sequenceDiagram, gantt, pie, mindmap selon le besoin\n" .
|
||||
"- Labels courts (< 30 chars)\n" .
|
||||
"- Arrows : --> ou --|label|-->\n" .
|
||||
"Réponds STRICTEMENT avec le code Mermaid, rien d'autre.";
|
||||
|
||||
$sem_id = AmbreLLMSemaphore::acquire();
|
||||
if (!$sem_id) {
|
||||
echo json_encode(["error"=>"service busy"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$llm_t = microtime(true);
|
||||
$llm = @file_get_contents("http://127.0.0.1:4000/v1/chat/completions", false, stream_context_create([
|
||||
"http" => [
|
||||
"method"=>"POST",
|
||||
"header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode([
|
||||
"model"=>"fast",
|
||||
"messages"=>[["role"=>"system","content"=>$sys],["role"=>"user","content"=>$topic]],
|
||||
"max_tokens"=>800,
|
||||
"temperature"=>0.3,
|
||||
]),
|
||||
"timeout"=>25,
|
||||
],
|
||||
]));
|
||||
$llm_ms = round((microtime(true)-$llm_t)*1000);
|
||||
} finally {
|
||||
AmbreLLMSemaphore::release($sem_id);
|
||||
}
|
||||
|
||||
$d = @json_decode($llm, true);
|
||||
$code = $d["choices"][0]["message"]["content"] ?? "";
|
||||
|
||||
// Sanitize
|
||||
$code = preg_replace('/^```(?:mermaid)?\s*/m', '', $code);
|
||||
$code = preg_replace('/\s*```\s*$/m', '', $code);
|
||||
$code = trim($code);
|
||||
|
||||
if (!$code) {
|
||||
echo json_encode(["error"=>"LLM returned empty code", "llm_ms"=>$llm_ms]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Detect kind
|
||||
$kind = "flowchart";
|
||||
if (stripos($code, "sequenceDiagram") !== false) $kind = "sequence";
|
||||
elseif (stripos($code, "gantt") === 0) $kind = "gantt";
|
||||
elseif (stripos($code, "pie") === 0) $kind = "pie";
|
||||
elseif (stripos($code, "mindmap") !== false) $kind = "mindmap";
|
||||
elseif (stripos($code, "classDiagram") !== false) $kind = "class";
|
||||
elseif (stripos($code, "erDiagram") !== false) $kind = "er";
|
||||
|
||||
// Step 3: Save to KB
|
||||
$save_resp = @file_get_contents("http://127.0.0.1/api/ambre-mermaid-learn.php", false, stream_context_create([
|
||||
"http" => ["method"=>"POST","header"=>"Content-Type: application/json\r\n",
|
||||
"content"=>json_encode([
|
||||
"action"=>"save", "topic"=>$topic, "kind"=>$kind,
|
||||
"context"=>"Auto-generated from user query",
|
||||
"code"=>$code,
|
||||
]),
|
||||
"timeout"=>5]
|
||||
]));
|
||||
$saved = @json_decode($save_resp, true);
|
||||
|
||||
echo json_encode([
|
||||
"ok" => true,
|
||||
"mermaid_code" => $code,
|
||||
"topic" => $topic,
|
||||
"kind" => $kind,
|
||||
"source" => "llm_generated_saved",
|
||||
"kb_id" => $saved["id"] ?? null,
|
||||
"kb_total" => $saved["total"] ?? null,
|
||||
"llm_ms" => $llm_ms,
|
||||
"elapsed_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA Mermaid + KB Learning",
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
@@ -21,7 +21,28 @@ if (!$topic) { echo json_encode(["error"=>"topic required"]); exit; }
|
||||
$t0 = microtime(true);
|
||||
|
||||
// Step 1: Get structured content from LLM
|
||||
$sys = "Tu es un expert en création de rapports business premium. Pour le sujet donné, génère UNIQUEMENT un JSON valide avec cette structure exacte (pas de markdown, pas d'explication) :
|
||||
// i18n language detection (simple heuristic)
|
||||
$topic_lower = mb_strtolower($topic);
|
||||
$lang = $in["lang"] ?? null;
|
||||
if (!$lang) {
|
||||
// Detect from content
|
||||
if (preg_match("/\b(the|is|are|and|of|for|to|with|on|in|a)\b/i", $topic_lower) && !preg_match("/\b(le|la|les|du|des|pour|avec)\b/i", $topic_lower)) {
|
||||
$lang = "en";
|
||||
} elseif (preg_match("/[\x{0600}-\x{06FF}]/u", $topic)) {
|
||||
$lang = "ar";
|
||||
} else {
|
||||
$lang = "fr";
|
||||
}
|
||||
}
|
||||
|
||||
// Prompts by language
|
||||
$prompts = [
|
||||
"fr" => "Tu es un expert en création de rapports business premium. Pour le sujet donné, génère UNIQUEMENT un JSON valide avec cette structure exacte (pas de markdown, pas d'explication) :",
|
||||
"en" => "You are an expert in premium business report creation. For the given topic, generate ONLY valid JSON with this exact structure (no markdown, no explanation). All text in English :",
|
||||
"ar" => "أنت خبير في إنشاء تقارير الأعمال المتميزة. للموضوع المحدد، قم بإنشاء JSON صالح فقط بهذه البنية الدقيقة (بدون markdown، بدون شرح). جميع النصوص باللغة العربية :",
|
||||
];
|
||||
$sys = $prompts[$lang] ?? $prompts["fr"];
|
||||
$sys .= "
|
||||
{
|
||||
\"title\": \"Titre court et percutant\",
|
||||
\"subtitle\": \"Sous-titre éclairant le contexte\",
|
||||
@@ -288,5 +309,6 @@ $result = [
|
||||
"render_ms" => $render_ms,
|
||||
"total_ms" => round((microtime(true)-$t0)*1000),
|
||||
"provider" => "WEVIA PDF Premium Engine",
|
||||
"lang" => $lang,
|
||||
];
|
||||
echo json_encode($result, JSON_UNESCAPED_UNICODE);
|
||||
|
||||
179
api/ambre-universal-chat.js
Normal file
179
api/ambre-universal-chat.js
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* ambre-universal-chat.js · wave-259 · Universal chat widget for all internal pages
|
||||
*
|
||||
* Usage: just <script src="/api/ambre-universal-chat.js"></script>
|
||||
* - Auto-creates minimal chat UI (floating button + panel)
|
||||
* - Uses /api/ambre-internal-chat-api.php (persistent memory + cross-chat learning)
|
||||
* - Auto chat_id = hostname + pathname
|
||||
* - Works on wevia-master, all-ia-hub, orchestrator, director-chat, l99-brain, etc.
|
||||
*/
|
||||
(function(){
|
||||
if (window.__ambreUniversalChat) return;
|
||||
window.__ambreUniversalChat = true;
|
||||
|
||||
var chatId = "internal-" + (location.pathname.replace(/[^a-z0-9]/gi, "-").toLowerCase() || "root");
|
||||
var apiUrl = "/api/ambre-internal-chat-api.php";
|
||||
|
||||
// Styles
|
||||
var style = document.createElement("style");
|
||||
style.textContent = `
|
||||
.amw-btn{position:fixed;bottom:20px;right:20px;width:56px;height:56px;border-radius:50%;
|
||||
background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border:none;cursor:pointer;
|
||||
box-shadow:0 4px 20px rgba(99,102,241,.4);z-index:99997;font-size:24px;transition:transform .15s}
|
||||
.amw-btn:hover{transform:scale(1.08)}
|
||||
.amw-panel{position:fixed;bottom:90px;right:20px;width:400px;max-width:calc(100vw - 40px);
|
||||
height:560px;max-height:calc(100vh - 120px);background:#fff;border-radius:16px;
|
||||
box-shadow:0 20px 60px rgba(0,0,0,.25);z-index:99998;display:none;flex-direction:column;
|
||||
overflow:hidden;font-family:system-ui,-apple-system,sans-serif}
|
||||
.amw-panel.open{display:flex;animation:amwSlide .2s ease}
|
||||
@keyframes amwSlide{from{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}
|
||||
.amw-header{padding:14px 16px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;
|
||||
display:flex;justify-content:space-between;align-items:center}
|
||||
.amw-header h3{margin:0;font-size:14px;font-weight:600}
|
||||
.amw-header .meta{font-size:11px;opacity:.85;margin-top:2px}
|
||||
.amw-close{background:transparent;border:none;color:#fff;font-size:20px;cursor:pointer;padding:0 4px}
|
||||
.amw-body{flex:1;overflow-y:auto;padding:14px;background:#f8fafc}
|
||||
.amw-msg{margin:8px 0;padding:10px 12px;border-radius:12px;max-width:85%;font-size:13px;line-height:1.4;word-wrap:break-word}
|
||||
.amw-msg.u{background:#eef2ff;color:#1e293b;margin-left:auto;border-bottom-right-radius:4px}
|
||||
.amw-msg.a{background:#fff;color:#1e293b;border:1px solid #e2e8f0;border-bottom-left-radius:4px}
|
||||
.amw-msg.a .meta{font-size:10px;color:#94a3b8;margin-top:4px}
|
||||
.amw-msg.a.ma{background:linear-gradient(135deg,#f0f9ff,#eef2ff);border-color:#6366f1}
|
||||
.amw-msg.a.ma::before{content:"🧠 Multi-Agent";display:block;font-size:10px;color:#4338ca;font-weight:600;margin-bottom:4px}
|
||||
.amw-input-wrap{padding:10px;background:#fff;border-top:1px solid #e2e8f0;display:flex;gap:8px}
|
||||
.amw-input{flex:1;padding:10px 12px;border:1px solid #cbd5e1;border-radius:10px;font-size:13px;outline:none;font-family:inherit}
|
||||
.amw-input:focus{border-color:#6366f1}
|
||||
.amw-send{padding:0 16px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border:none;border-radius:10px;cursor:pointer;font-size:13px;font-weight:500}
|
||||
.amw-send:disabled{opacity:.5;cursor:not-allowed}
|
||||
.amw-typing{padding:10px;font-size:11px;color:#94a3b8;font-style:italic}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Elements
|
||||
var btn = document.createElement("button");
|
||||
btn.className = "amw-btn";
|
||||
btn.innerHTML = "💬";
|
||||
btn.title = "Chat interne WEVIA · mémoire persistante";
|
||||
document.body.appendChild(btn);
|
||||
|
||||
var panel = document.createElement("div");
|
||||
panel.className = "amw-panel";
|
||||
panel.innerHTML = `
|
||||
<div class="amw-header">
|
||||
<div>
|
||||
<h3>💬 Chat Interne · WEVIA</h3>
|
||||
<div class="meta">Mémoire persistante · Multi-agent · <span id="amwTurns">0</span> tours</div>
|
||||
</div>
|
||||
<button class="amw-close">✕</button>
|
||||
</div>
|
||||
<div class="amw-body" id="amwBody"></div>
|
||||
<div class="amw-input-wrap">
|
||||
<input class="amw-input" id="amwInput" placeholder="Écrivez (analyse complete pour multi-agent)..." />
|
||||
<button class="amw-send" id="amwSend">Envoyer</button>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(panel);
|
||||
|
||||
btn.addEventListener("click", function(){ panel.classList.toggle("open"); });
|
||||
panel.querySelector(".amw-close").addEventListener("click", function(){ panel.classList.remove("open"); });
|
||||
|
||||
var body = panel.querySelector("#amwBody");
|
||||
var input = panel.querySelector("#amwInput");
|
||||
var sendBtn = panel.querySelector("#amwSend");
|
||||
var turnsSpan = panel.querySelector("#amwTurns");
|
||||
|
||||
function addMsg(role, text, meta){
|
||||
var m = document.createElement("div");
|
||||
m.className = "amw-msg " + (role === "user" ? "u" : "a") + (meta && meta.mode === "multiagent" ? " ma" : "");
|
||||
var safe = (text || "").replace(/</g,"<").replace(/\n/g,"<br>");
|
||||
m.innerHTML = safe;
|
||||
if (meta && role === "assistant") {
|
||||
var mi = document.createElement("div");
|
||||
mi.className = "meta";
|
||||
mi.textContent = (meta.total_ms || 0) + "ms · " + (meta.mode || "std") + (meta.agents ? " · " + meta.agents + " agents" : "");
|
||||
m.appendChild(mi);
|
||||
}
|
||||
body.appendChild(m);
|
||||
body.scrollTop = body.scrollHeight;
|
||||
}
|
||||
|
||||
function showTyping(){
|
||||
var t = document.createElement("div");
|
||||
t.id = "amwTyping";
|
||||
t.className = "amw-typing";
|
||||
t.textContent = "WEVIA réfléchit...";
|
||||
body.appendChild(t);
|
||||
body.scrollTop = body.scrollHeight;
|
||||
}
|
||||
function hideTyping(){
|
||||
var t = document.getElementById("amwTyping");
|
||||
if (t) t.remove();
|
||||
}
|
||||
|
||||
function send(){
|
||||
var msg = input.value.trim();
|
||||
if (!msg) return;
|
||||
input.value = "";
|
||||
sendBtn.disabled = true;
|
||||
addMsg("user", msg);
|
||||
showTyping();
|
||||
|
||||
var ctrl = new AbortController();
|
||||
var timeout = setTimeout(function(){ ctrl.abort(); }, 120000);
|
||||
|
||||
fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json","Cache-Control":"no-cache"},
|
||||
body: JSON.stringify({ chat_id: chatId, message: msg }),
|
||||
signal: ctrl.signal,
|
||||
cache: "no-store",
|
||||
})
|
||||
.then(function(r){ clearTimeout(timeout); return r.json(); })
|
||||
.then(function(d){
|
||||
hideTyping();
|
||||
sendBtn.disabled = false;
|
||||
if (d && d.ok) {
|
||||
addMsg("assistant", d.response || "(empty)", {
|
||||
mode: d.mode,
|
||||
total_ms: d.total_ms,
|
||||
agents: d.agents ? d.agents.length : 0,
|
||||
});
|
||||
turnsSpan.textContent = d.memory_turns || 0;
|
||||
} else {
|
||||
addMsg("assistant", "❌ " + ((d && d.error) || "Erreur"));
|
||||
}
|
||||
})
|
||||
.catch(function(err){
|
||||
hideTyping();
|
||||
sendBtn.disabled = false;
|
||||
addMsg("assistant", "❌ " + (err.name === "AbortError" ? "Timeout 2min" : String(err)));
|
||||
});
|
||||
}
|
||||
|
||||
sendBtn.addEventListener("click", send);
|
||||
input.addEventListener("keydown", function(e){ if (e.key === "Enter" && !e.shiftKey){ e.preventDefault(); send(); } });
|
||||
|
||||
// Load prior context on open
|
||||
var loaded = false;
|
||||
btn.addEventListener("click", function(){
|
||||
if (loaded || !panel.classList.contains("open")) return;
|
||||
loaded = true;
|
||||
fetch("/api/ambre-internal-memory.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json"},
|
||||
body: JSON.stringify({ action: "load", chat_id: chatId, n: 20 }),
|
||||
cache: "no-store",
|
||||
})
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d){
|
||||
if (d && d.ok && d.messages && d.messages.length > 0) {
|
||||
d.messages.forEach(function(m){
|
||||
if (m.role === "user" || m.role === "assistant") addMsg(m.role, m.content, m.metadata);
|
||||
});
|
||||
turnsSpan.textContent = d.messages.length;
|
||||
} else {
|
||||
addMsg("assistant", "Bonjour ! Je suis WEVIA interne (mémoire persistante illimitée). Chat_id: " + chatId);
|
||||
}
|
||||
})
|
||||
.catch(function(){});
|
||||
});
|
||||
})();
|
||||
31
api/ambre-v0-exclude.php
Normal file
31
api/ambre-v0-exclude.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
|
||||
// Unlock first
|
||||
$attr = trim(shell_exec("lsattr $path 2>&1"));
|
||||
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Patch V0 to exclude multi-agent patterns
|
||||
$old = 'var _is_gen_cmd = /pdf|rapport|docx?|word|excel|xlsx?|pptx?|powerpoint|sch[eé]ma|diagramme|mermaid|image|photo|dessin|qr\\s*code|tts|lis[ -]|calcule|combien|code|traduis|cherche|recherche|actualit[eé]|search|news|latest|youtube|r[eé]sume|summari/i.test(text);';
|
||||
|
||||
$new = 'var _is_gen_cmd = /pdf|rapport|docx?|word|excel|xlsx?|pptx?|powerpoint|sch[eé]ma|diagramme|mermaid|image|photo|dessin|qr\\s*code|tts|lis[ -]|calcule|combien|code|traduis|cherche|recherche|actualit[eé]|search|news|latest|youtube|r[eé]sume|summari|compar[ez]?|analyse|multi.?agent|parall[eè]le|360|bilan/i.test(text);';
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"V0 pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave255-v0-exclude";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"attr_before" => $attr,
|
||||
]);
|
||||
28
api/ambre-v10-css.php
Normal file
28
api/ambre-v10-css.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
|
||||
// In the inline mermaid div, ensure min-height and visible styling
|
||||
$old = '<div class="mermaid" id="" + uniqId + "" style="text-align:center">" + mcode + "</div>';
|
||||
// Actually the style is inside the string. Let me use pattern
|
||||
$old_esc = '<div class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center\\">" + mcode + "</div>';
|
||||
$new_esc = '<div class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center;min-height:200px;font-size:14px;color:#333;background:#fff;padding:12px\\">" + mcode + "</div>';
|
||||
|
||||
if (strpos($c, $old_esc) === false) {
|
||||
// Simpler check
|
||||
if (strpos($c, 'class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center\\"') !== false) {
|
||||
$c = str_replace('class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center\\"', 'class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center;min-height:200px;font-size:14px;color:#333\\"', $c);
|
||||
echo json_encode(["patch"=>"style expanded", "size"=>strlen($c)]);
|
||||
} else {
|
||||
echo json_encode(["error"=>"pattern not found for style fix"]);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$c = str_replace($old_esc, $new_esc, $c);
|
||||
}
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-mermaid-css";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
echo json_encode(["wrote"=>$wrote, "backup"=>basename($backup)]);
|
||||
27
api/ambre-v10-fix.php
Normal file
27
api/ambre-v10-fix.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Replace the V10 addMsg call with direct innerHTML injection
|
||||
$old = 'addMsg("assistant", badges + inlineBlock, (data.elapsed_ms/1000).toFixed(2));';
|
||||
$new = '// Direct innerHTML injection (bypass formatMd HTML escape)
|
||||
var _el = addMsg("assistant", "Diagramme Mermaid", (data.elapsed_ms/1000).toFixed(2));
|
||||
var _bubble = _el ? _el.querySelector(".bubble") : null;
|
||||
if (_bubble) _bubble.innerHTML = badges + inlineBlock;';
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"pattern not found in V10"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$new_c = str_replace($old, $new, $c);
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-v10-fix";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $new_c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($new_c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
]);
|
||||
78
api/ambre-v10-render.php
Normal file
78
api/ambre-v10-render.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// The V10 block uses class="mermaid" which triggers the problematic CSS
|
||||
// Keep class="mermaid" (so mermaid.run picks it up) BUT add an override style in-line
|
||||
// The issue is font-size:0 !important - we can't override easily
|
||||
// Better: after mermaid.run, the data-processed=true attribute is set, which UNSETS font-size:0
|
||||
// So the issue must be that mermaid.run() isn't triggering or the SVG has issues
|
||||
|
||||
// Let me use a different approach: use mermaid.render() directly to get SVG as string, insert directly
|
||||
|
||||
$old = "var uniqId = \"mmd-\" + Date.now();
|
||||
var inlineBlock = \"<div style=\\\"margin:12px 0;padding:14px;background:#fafafa;border:1px solid #e5e7eb;border-radius:12px\\\">\" +
|
||||
\"<div style=\\\"font-weight:600;font-size:13px;color:#6b7280;margin-bottom:10px\\\">📊 \" + topic + \"</div>\" +
|
||||
\"<div class=\\\"mermaid\\\" id=\\\"\" + uniqId + \"\\\" style=\\\"text-align:center;min-height:200px;font-size:14px;color:#333\\\">\" + mcode + \"</div>\"";
|
||||
|
||||
$new = "var uniqId = \"mmd-\" + Date.now();
|
||||
// Pre-render SVG via mermaid.render() to avoid CSS font-size:0 !important issue
|
||||
var inlineBlock = \"<div style=\\\"margin:12px 0;padding:14px;background:#fafafa;border:1px solid #e5e7eb;border-radius:12px\\\">\" +
|
||||
\"<div style=\\\"font-weight:600;font-size:13px;color:#6b7280;margin-bottom:10px\\\">📊 \" + topic + \"</div>\" +
|
||||
\"<div id=\\\"\" + uniqId + \"\\\" style=\\\"text-align:center;min-height:150px;padding:10px;background:#fff;border-radius:8px\\\">Rendu en cours...</div>\"";
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"V10 pattern not found for CSS fix"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
// And update the render call to use mermaid.render(id, code) API
|
||||
$old_render = "setTimeout(function(){
|
||||
try {
|
||||
if (window.mermaid && typeof window.mermaid.run === \"function\") {
|
||||
window.mermaid.run({ nodes: [document.getElementById(uniqId)] });
|
||||
}
|
||||
} catch(e) { console.warn(\"mermaid render fail\", e); }
|
||||
}, 300);";
|
||||
|
||||
$new_render = "setTimeout(function(){
|
||||
try {
|
||||
var target = document.getElementById(uniqId);
|
||||
if (!target) return;
|
||||
if (window.mermaid && typeof window.mermaid.render === \"function\") {
|
||||
// Use render() to get SVG string directly
|
||||
window.mermaid.render(\"svg-\" + uniqId, mcode).then(function(result) {
|
||||
if (result && result.svg) {
|
||||
target.innerHTML = result.svg;
|
||||
target.style.minHeight = \"auto\";
|
||||
}
|
||||
}).catch(function(err){
|
||||
console.warn(\"mermaid.render error\", err);
|
||||
target.innerHTML = \"<pre style=\\\"font-size:11px;color:#b00;padding:10px;background:#fee;border-radius:6px\\\">Erreur rendu: \" + String(err).substring(0, 200) + \"</pre>\";
|
||||
});
|
||||
} else if (window.mermaid && typeof window.mermaid.init === \"function\") {
|
||||
target.className = \"mermaid\";
|
||||
target.textContent = mcode;
|
||||
window.mermaid.init(undefined, target);
|
||||
}
|
||||
} catch(e) { console.warn(\"mermaid render fail\", e); }
|
||||
}, 500);";
|
||||
|
||||
if (strpos($c, $old_render) === false) {
|
||||
echo json_encode(["error"=>"render pattern not found", "orig_changed" => strlen($c) != $orig]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old_render, $new_render, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-v10-render";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
64
api/ambre-v10-san.php
Normal file
64
api/ambre-v10-san.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Add sanitize step in the V10 render setTimeout
|
||||
$old = 'setTimeout(function(){
|
||||
try {
|
||||
if (window.mermaid && typeof window.mermaid.run === "function") {
|
||||
window.mermaid.run({ nodes: [document.getElementById(uniqId)] });
|
||||
}';
|
||||
|
||||
$new = 'setTimeout(function(){
|
||||
try {
|
||||
var target = document.getElementById(uniqId);
|
||||
if (!target) return;
|
||||
// Sanitize mermaid code (strip accents, fix common LLM mistakes)
|
||||
var clean = mcode
|
||||
.replace(/[àâä]/g, "a").replace(/[éèêë]/g, "e").replace(/[îï]/g, "i")
|
||||
.replace(/[ôö]/g, "o").replace(/[ùûü]/g, "u").replace(/ç/g, "c")
|
||||
.replace(/[ÀÂÄ]/g, "A").replace(/[ÉÈÊË]/g, "E").replace(/[ÎÏ]/g, "I")
|
||||
.replace(/[ÔÖ]/g, "O").replace(/[ÙÛÜ]/g, "U").replace(/Ç/g, "C")
|
||||
.trim();
|
||||
// Use mermaid.render for SVG direct return (bypass font-size:0 CSS issue)
|
||||
if (window.mermaid && typeof window.mermaid.render === "function") {
|
||||
window.mermaid.render("svg-" + uniqId, clean).then(function(result){
|
||||
if (result && result.svg) {
|
||||
target.innerHTML = result.svg;
|
||||
target.className = "mermaid-rendered";
|
||||
target.removeAttribute("data-processed");
|
||||
// Force SVG to reasonable size
|
||||
var svg = target.querySelector("svg");
|
||||
if (svg) {
|
||||
svg.style.maxWidth = "100%";
|
||||
svg.style.height = "auto";
|
||||
svg.style.minHeight = "180px";
|
||||
svg.removeAttribute("width");
|
||||
svg.style.width = "100%";
|
||||
}
|
||||
}
|
||||
}).catch(function(err){
|
||||
console.warn("mermaid render err", err);
|
||||
target.innerHTML = "<pre style=\"font-size:12px;padding:10px;background:#f5f5f5;border-radius:6px\">" + clean.replace(/</g,"<") + "</pre>";
|
||||
});
|
||||
} else if (window.mermaid && typeof window.mermaid.run === "function") {
|
||||
target.className = "mermaid";
|
||||
target.textContent = clean;
|
||||
window.mermaid.run({ nodes: [target] });
|
||||
}';
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-v10-sanitize";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
]);
|
||||
41
api/ambre-v11-debug.php
Normal file
41
api/ambre-v11-debug.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
|
||||
// Patch V11 fetch : add console.log trigger message + AbortController with 120s
|
||||
$old = "var _ma_start = performance.now();
|
||||
fetch(\"/api/ambre-multiagent-parallel.php\", {
|
||||
method: \"POST\",
|
||||
headers: {\"Content-Type\":\"application/json\"},
|
||||
body: JSON.stringify({goal: text, max_agents: 5})
|
||||
})";
|
||||
|
||||
$new = "console.log(\"[V11-MULTIAGENT] triggered for text:\", text.substring(0,80));
|
||||
var _ma_start = performance.now();
|
||||
var _ma_ctrl = new AbortController();
|
||||
var _ma_timeout = setTimeout(function(){ _ma_ctrl.abort(); }, 120000);
|
||||
fetch(\"/api/ambre-multiagent-parallel.php\", {
|
||||
method: \"POST\",
|
||||
headers: {\"Content-Type\":\"application/json\"},
|
||||
body: JSON.stringify({goal: text, max_agents: 5}),
|
||||
signal: _ma_ctrl.signal
|
||||
})
|
||||
.then(function(r){ clearTimeout(_ma_timeout); console.log(\"[V11] response status\", r.status); return r; })";
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"V11 fetch pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave258-v11-debug";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - strlen(@file_get_contents($backup)),
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
23
api/ambre-v9-ok.php
Normal file
23
api/ambre-v9-ok.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
$old = "if (data && data.success) {";
|
||||
$new = "if (data && (data.ok || data.success)) {";
|
||||
|
||||
if (strpos($c, $old) === false) {
|
||||
echo json_encode(["error"=>"V9 success check not found"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave247-v9-ok";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
]);
|
||||
28
api/ambre-v9-widen.php
Normal file
28
api/ambre-v9-widen.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Old pattern (too strict)
|
||||
$old_pat = "var _pdf_premium_pat = /(?:pdf|rapport)\\s+(?:premium|qualit[eé]|pro|professionnel|avec\\s+graphique|hd|chart)|(?:cr[eé]e[zr]?|g[eé]n[eè]re[zr]?|fais|fait|produi[st])\\s+(?:un\\s+)?(?:rapport|pdf)\\s+(?:premium|pro|complet|avec\\s+graphique|hd|qualit[eé])/i;";
|
||||
|
||||
// New pattern - broader: any PDF intention including ALL CAPS
|
||||
$new_pat = "var _pdf_premium_pat = /(?:veux|besoin|demande|fais|cree|g[eé]n[eé]re|produi[st]|export|donne|realise|create|make|generate|want|need)\\s+.{0,40}?\\bpdf\\b|\\bpdf\\b\\s+.{0,40}?(?:premium|qualit[eé]|pro|professionnel|avec|chart|graphique|compar|tableau|compl|hd)|\\b(?:rapport|comparaison|comparer|compare)\\b.{0,50}\\bpdf\\b|\\bpdf\\b.{0,50}\\b(?:rapport|comparaison|comparer|compare)\\b|^\\s*pdf\\s+/i;";
|
||||
|
||||
if (strpos($c, $old_pat) === false) {
|
||||
echo json_encode(["error"=>"V9 pattern not found"]);
|
||||
exit;
|
||||
}
|
||||
$c = str_replace($old_pat, $new_pat, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave247-v9-widen";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"new_pattern" => $new_pat,
|
||||
]);
|
||||
43
api/ambre-wire-reg2.php
Normal file
43
api/ambre-wire-reg2.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/api/wevia-tool-registry.json";
|
||||
|
||||
// Unlock
|
||||
@shell_exec("chattr -i $path 2>&1");
|
||||
|
||||
$content = @file_get_contents($path);
|
||||
$data = @json_decode($content, true);
|
||||
|
||||
$existing_ids = array_map(function($t){return $t["id"]??"";}, $data["tools"]);
|
||||
$new_tools = [
|
||||
["id"=>"pdf_premium_generator","kw"=>"pdf.*premium|rapport.*premium|pdf.*qualit|pdf.*graphique|pdf.*chart|premium.*pdf","cmd"=>"curl -sS -X POST http://127.0.0.1/api/ambre-tool-pdf-premium.php -H 'Content-Type: application/json' -d '{\"topic\":\"${TOPIC}\"}'","exec"=>true,"desc"=>"PDF Premium · Chart.js + google-chrome · 6 chart types","wave"=>229],
|
||||
["id"=>"mermaid_generator_kb","kw"=>"mermaid|diagramme|flowchart|sequence.*diagram|gantt|schema.*mermaid|schema.*process","cmd"=>"curl -sS -X POST http://127.0.0.1/api/ambre-tool-mermaid.php -H 'Content-Type: application/json' -d '{\"topic\":\"${TOPIC}\"}'","exec"=>true,"desc"=>"Mermaid + Learning KB · RAG reuse + auto-save","wave"=>229],
|
||||
["id"=>"mermaid_kb_search","kw"=>"mermaid.*search|recherche.*diagramme|find.*schema|catalog.*mermaid","cmd"=>"curl -sS -X POST http://127.0.0.1/api/ambre-mermaid-learn.php -H 'Content-Type: application/json' -d '{\"action\":\"search\",\"query\":\"${TOPIC}\"}'","exec"=>true,"desc"=>"Mermaid KB search","wave"=>229],
|
||||
["id"=>"mermaid_kb_stats","kw"=>"mermaid.*stats|mermaid.*catalog.*count|kb.*stats","cmd"=>"curl -sS -X POST http://127.0.0.1/api/ambre-mermaid-learn.php -H 'Content-Type: application/json' -d '{\"action\":\"stats\"}'","exec"=>true,"desc"=>"Mermaid KB stats","wave"=>229],
|
||||
["id"=>"llm_semaphore_stats","kw"=>"semaphore.*stat|llm.*load|llm.*semaphore|concurrent.*llm","cmd"=>"curl -sS http://127.0.0.1/api/ambre-llm-semaphore.php","exec"=>true,"desc"=>"LLM semaphore stats","wave"=>229],
|
||||
];
|
||||
|
||||
$added = 0;
|
||||
foreach ($new_tools as $nt) {
|
||||
if (!in_array($nt["id"], $existing_ids)) {
|
||||
$data["tools"][] = $nt;
|
||||
$added++;
|
||||
}
|
||||
}
|
||||
$data["opus_wave_229"] = ["ts"=>date("c"),"added"=>$added,"new_total"=>count($data["tools"])];
|
||||
|
||||
$json_out = json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
|
||||
$backup = "/opt/wevads/vault/wevia-tool-registry.GOLD-" . date("Ymd-His") . "-wave229";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $json_out);
|
||||
|
||||
// Relock
|
||||
@shell_exec("chattr +i $path 2>&1");
|
||||
|
||||
echo json_encode([
|
||||
"added" => $added,
|
||||
"new_total" => count($data["tools"]),
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"is_locked_after" => trim(shell_exec("lsattr $path 2>&1 | awk '{print \$1}'")),
|
||||
]);
|
||||
89
api/ambre-wire-registry.php
Normal file
89
api/ambre-wire-registry.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/api/wevia-tool-registry.json";
|
||||
$content = @file_get_contents($path);
|
||||
$data = @json_decode($content, true);
|
||||
|
||||
if (!is_array($data) || !isset($data["tools"])) {
|
||||
echo json_encode(["error"=>"invalid registry"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$orig_count = count($data["tools"]);
|
||||
|
||||
// Check existing ids to avoid duplicates
|
||||
$existing_ids = [];
|
||||
foreach ($data["tools"] as $t) $existing_ids[] = $t["id"] ?? "";
|
||||
|
||||
// Tools to add (wave-229 deliverables)
|
||||
$new_tools = [
|
||||
[
|
||||
"id" => "pdf_premium_generator",
|
||||
"kw" => "pdf.*premium|rapport.*premium|pdf.*qualit|pdf.*graphique|pdf.*chart|premium.*pdf|rapport.*graph",
|
||||
"cmd" => "curl -sS -X POST http://127.0.0.1/api/ambre-tool-pdf-premium.php -H 'Content-Type: application/json' -d '{\"topic\":\"${TOPIC}\"}' | jq -r '.url'",
|
||||
"exec" => true,
|
||||
"desc" => "WEVIA PDF Premium · Chart.js + google-chrome + LLM JSON structure · 6 chart types",
|
||||
"wave" => 229,
|
||||
],
|
||||
[
|
||||
"id" => "mermaid_generator_kb",
|
||||
"kw" => "mermaid|diagramme|flowchart|sequence.*diagram|gantt|schema.*mermaid|schema.*process",
|
||||
"cmd" => "curl -sS -X POST http://127.0.0.1/api/ambre-tool-mermaid.php -H 'Content-Type: application/json' -d '{\"topic\":\"${TOPIC}\"}' | jq -r '.mermaid_code'",
|
||||
"exec" => true,
|
||||
"desc" => "WEVIA Mermaid + Learning KB · RAG reuse si match · LLM generate + auto-save sinon",
|
||||
"wave" => 229,
|
||||
],
|
||||
[
|
||||
"id" => "mermaid_kb_search",
|
||||
"kw" => "mermaid.*search|recherche.*diagramme|find.*schema|catalog.*mermaid|kb.*mermaid",
|
||||
"cmd" => "curl -sS -X POST http://127.0.0.1/api/ambre-mermaid-learn.php -H 'Content-Type: application/json' -d '{\"action\":\"search\",\"query\":\"${TOPIC}\"}' | jq '.'",
|
||||
"exec" => true,
|
||||
"desc" => "WEVIA Mermaid KB search · retrieve existing diagrams by topic",
|
||||
"wave" => 229,
|
||||
],
|
||||
[
|
||||
"id" => "mermaid_kb_stats",
|
||||
"kw" => "mermaid.*stats|mermaid.*catalog.*count|kb.*stats|mermaid.*total",
|
||||
"cmd" => "curl -sS -X POST http://127.0.0.1/api/ambre-mermaid-learn.php -H 'Content-Type: application/json' -d '{\"action\":\"stats\"}' | jq '.'",
|
||||
"exec" => true,
|
||||
"desc" => "WEVIA Mermaid KB stats · total diagrams + by kind + total uses",
|
||||
"wave" => 229,
|
||||
],
|
||||
[
|
||||
"id" => "llm_semaphore_stats",
|
||||
"kw" => "semaphore.*stat|llm.*load|llm.*semaphore|concurrent.*llm|cascade.*load",
|
||||
"cmd" => "curl -sS http://127.0.0.1/api/ambre-llm-semaphore.php | jq '.'",
|
||||
"exec" => true,
|
||||
"desc" => "WEVIA LLM semaphore stats · active locks / max concurrent",
|
||||
"wave" => 229,
|
||||
],
|
||||
];
|
||||
|
||||
$added = 0;
|
||||
foreach ($new_tools as $nt) {
|
||||
if (!in_array($nt["id"], $existing_ids)) {
|
||||
$data["tools"][] = $nt;
|
||||
$added++;
|
||||
}
|
||||
}
|
||||
|
||||
// Update meta
|
||||
$data["opus_wave_229"] = [
|
||||
"ts" => date("c"),
|
||||
"added" => $added,
|
||||
"new_total" => count($data["tools"]),
|
||||
];
|
||||
|
||||
// Backup
|
||||
$backup = "/opt/wevads/vault/wevia-tool-registry.GOLD-" . date("Ymd-His") . "-wave229";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));
|
||||
|
||||
echo json_encode([
|
||||
"orig_count" => $orig_count,
|
||||
"added" => $added,
|
||||
"new_count" => count($data["tools"]),
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"new_ids" => array_column($new_tools, "id"),
|
||||
]);
|
||||
122
api/ambre-wire-v10.php
Normal file
122
api/ambre-wire-v10.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
if (strpos($c, "AMBRE-V10-MERMAID") !== false) {
|
||||
echo json_encode(["already_wired"=>true, "size"=>$orig]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Insert BEFORE V9-PDF-PREMIUM (so mermaid match comes first if both patterns match)
|
||||
$anchor = " // === AMBRE-V9-PDF-PREMIUM 2026-04-22";
|
||||
$idx = strpos($c, $anchor);
|
||||
if ($idx === false) {
|
||||
echo json_encode(["error"=>"V9 anchor not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Also make sure the _ambre_gen_pat doesn't catch "mermaid" which we want to route here first
|
||||
// Currently _ambre_gen_pat matches mermaid → route to V2-GEN-ROUTER
|
||||
// Solution: put V10 BEFORE V2 check (before all routers), by placing it in send() very early
|
||||
// Actually just before V9 is OK since that's before V2 in flow
|
||||
|
||||
$v10 = <<<'JS'
|
||||
// === AMBRE-V10-MERMAID 2026-04-22 · Mermaid RAG + inline SVG render + artifact panel ===
|
||||
var _mermaid_intent_pat = /(?:mermaid|sch[eé]ma|diagramme|flowchart|sequence\s+diagram|gantt\s+chart)/i;
|
||||
if (_mermaid_intent_pat.test(text)) {
|
||||
if (typeof showThinking === 'function') showThinking();
|
||||
busy = true;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=true;}catch(e){}
|
||||
|
||||
var _fetch = (typeof window.__ambreFetch === 'function') ? window.__ambreFetch : fetch;
|
||||
_fetch('/api/ambre-tool-mermaid.php', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({topic: text})
|
||||
})
|
||||
.then(function(r){ return r.text().then(function(t){ try{return JSON.parse(t);}catch(e){return null;} }); })
|
||||
.then(function(data){
|
||||
if (typeof hideThinking === 'function') hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
try{var mi=document.getElementById("msgInput");if(mi){mi.value="";mi.disabled=false;}}catch(e){}
|
||||
|
||||
if (!data || !data.ok) {
|
||||
addMsg('assistant', '❌ Erreur génération Mermaid. ' + ((data && data.error) || 'Réessayez.'), '0');
|
||||
return;
|
||||
}
|
||||
|
||||
var mcode = data.mermaid_code;
|
||||
var topic = data.topic || text;
|
||||
var src = data.source || 'unknown';
|
||||
var kind = data.kind || 'flowchart';
|
||||
|
||||
// Badges
|
||||
var srcBadge = (src === 'kb_reused') ?
|
||||
'<span class="nx-badge" style="background:rgba(16,185,129,.15);color:#10b981">♻️ KB Reused (' + (data.use_count || 0) + ' uses)</span>' :
|
||||
'<span class="nx-badge" style="background:rgba(99,102,241,.15);color:#6366f1">🧠 LLM Generated</span>';
|
||||
|
||||
var badges = '<div style="display:flex;gap:6px;flex-wrap:wrap;margin:8px 0">' +
|
||||
srcBadge +
|
||||
'<span class="nx-badge" style="background:rgba(139,92,246,.15);color:#8b5cf6">' + kind + '</span>' +
|
||||
'<span class="nx-badge" style="background:rgba(245,158,11,.15);color:#f59e0b">' + (data.elapsed_ms || 0) + 'ms</span>' +
|
||||
'</div>';
|
||||
|
||||
// Inline render div
|
||||
var uniqId = 'mmd-' + Date.now();
|
||||
var inlineBlock = '<div style="margin:12px 0;padding:14px;background:#fafafa;border:1px solid #e5e7eb;border-radius:12px">' +
|
||||
'<div style="font-weight:600;font-size:13px;color:#6b7280;margin-bottom:10px">📊 ' + topic + '</div>' +
|
||||
'<div class="mermaid" id="' + uniqId + '" style="text-align:center">' + mcode + '</div>' +
|
||||
'<details style="margin-top:10px"><summary style="cursor:pointer;font-size:11px;color:#94a3b8">📝 Voir le code</summary>' +
|
||||
'<pre style="background:#1a1a2e;color:#e6edf3;padding:10px;border-radius:8px;font-size:11px;margin-top:8px;overflow-x:auto">' +
|
||||
mcode.replace(/</g,'<').replace(/>/g,'>') + '</pre></details>' +
|
||||
'</div>';
|
||||
|
||||
addMsg('assistant', badges + inlineBlock, (data.elapsed_ms/1000).toFixed(2));
|
||||
|
||||
// Trigger mermaid render after DOM update
|
||||
setTimeout(function(){
|
||||
try {
|
||||
if (window.mermaid && typeof window.mermaid.run === 'function') {
|
||||
window.mermaid.run({ nodes: [document.getElementById(uniqId)] });
|
||||
} else if (window.mermaid && typeof window.mermaid.init === 'function') {
|
||||
window.mermaid.init(undefined, document.getElementById(uniqId));
|
||||
}
|
||||
} catch(e) { console.warn('mermaid render fail', e); }
|
||||
}, 300);
|
||||
|
||||
// Also open artifact panel with preview
|
||||
if (typeof openPreview === 'function') {
|
||||
try {
|
||||
var svgWrap = '<div style="padding:20px;background:#fff;height:100%;overflow:auto"><h3 style="margin-bottom:16px">' + topic + '</h3><div class="mermaid">' + mcode + '</div></div>';
|
||||
openPreview({type:'html', content: svgWrap});
|
||||
} catch(e) {}
|
||||
}
|
||||
})
|
||||
.catch(function(err){
|
||||
if (typeof hideThinking === 'function') hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
addMsg('assistant', '❌ Service Mermaid temporairement indisponible.', '0');
|
||||
});
|
||||
return;
|
||||
}
|
||||
// === END AMBRE-V10-MERMAID ===
|
||||
|
||||
JS;
|
||||
|
||||
$new_c = substr($c, 0, $idx) . $v10 . substr($c, $idx);
|
||||
$delta = strlen($new_c) - $orig;
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-v10-mermaid";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $new_c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => $delta,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
"new_size" => strlen($new_c),
|
||||
]);
|
||||
100
api/ambre-wire-v10b.php
Normal file
100
api/ambre-wire-v10b.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
if (strpos($c, "AMBRE-V10-MERMAID") !== false) {
|
||||
echo json_encode(["already_wired"=>true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Use pattern matching for V9 anchor
|
||||
$pos = strpos($c, "// === AMBRE-V9-PDF-PREMIUM");
|
||||
if ($pos === false) {
|
||||
echo json_encode(["error"=>"V9 not found at all"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Back up to line start
|
||||
$line_start = strrpos(substr($c, 0, $pos), "\n") + 1;
|
||||
|
||||
$v10 = ' // === AMBRE-V10-MERMAID 2026-04-22 · Mermaid RAG + inline SVG + artifact panel ===
|
||||
var _mermaid_intent_pat = /(?:mermaid|sch[eé]ma|diagramme|flowchart|sequence\\s+diagram|gantt\\s+chart)/i;
|
||||
if (_mermaid_intent_pat.test(text)) {
|
||||
if (typeof showThinking === "function") showThinking();
|
||||
busy = true;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=true;}catch(e){}
|
||||
|
||||
var _fetch = (typeof window.__ambreFetch === "function") ? window.__ambreFetch : fetch;
|
||||
_fetch("/api/ambre-tool-mermaid.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json"},
|
||||
body: JSON.stringify({topic: text})
|
||||
})
|
||||
.then(function(r){ return r.text().then(function(t){ try{return JSON.parse(t);}catch(e){return null;} }); })
|
||||
.then(function(data){
|
||||
if (typeof hideThinking === "function") hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
try{var mi=document.getElementById("msgInput");if(mi){mi.value="";mi.disabled=false;}}catch(e){}
|
||||
|
||||
if (!data || !data.ok) {
|
||||
addMsg("assistant", "❌ Erreur Mermaid. " + ((data && data.error) || "Réessayez."), "0");
|
||||
return;
|
||||
}
|
||||
|
||||
var mcode = data.mermaid_code;
|
||||
var topic = data.topic || text;
|
||||
var src = data.source || "unknown";
|
||||
var kind = data.kind || "flowchart";
|
||||
|
||||
var srcBadge = (src === "kb_reused") ?
|
||||
"<span class=\\"nx-badge\\" style=\\"background:rgba(16,185,129,.15);color:#10b981\\">♻️ KB Reused (" + (data.use_count || 0) + " uses)</span>" :
|
||||
"<span class=\\"nx-badge\\" style=\\"background:rgba(99,102,241,.15);color:#6366f1\\">🧠 LLM Generated</span>";
|
||||
var kindBadge = "<span class=\\"nx-badge\\" style=\\"background:rgba(139,92,246,.15);color:#8b5cf6\\">" + kind + "</span>";
|
||||
var elapsedBadge = "<span class=\\"nx-badge\\" style=\\"background:rgba(245,158,11,.15);color:#f59e0b\\">" + (data.elapsed_ms || 0) + "ms</span>";
|
||||
var badges = "<div style=\\"display:flex;gap:6px;flex-wrap:wrap;margin:8px 0\\">" + srcBadge + kindBadge + elapsedBadge + "</div>";
|
||||
|
||||
var uniqId = "mmd-" + Date.now();
|
||||
var inlineBlock = "<div style=\\"margin:12px 0;padding:14px;background:#fafafa;border:1px solid #e5e7eb;border-radius:12px\\">" +
|
||||
"<div style=\\"font-weight:600;font-size:13px;color:#6b7280;margin-bottom:10px\\">📊 " + topic + "</div>" +
|
||||
"<div class=\\"mermaid\\" id=\\"" + uniqId + "\\" style=\\"text-align:center\\">" + mcode + "</div>" +
|
||||
"<details style=\\"margin-top:10px\\"><summary style=\\"cursor:pointer;font-size:11px;color:#94a3b8\\">📝 Voir le code</summary>" +
|
||||
"<pre style=\\"background:#1a1a2e;color:#e6edf3;padding:10px;border-radius:8px;font-size:11px;margin-top:8px;overflow-x:auto\\">" +
|
||||
mcode.replace(/</g,"<").replace(/>/g,">") + "</pre></details>" +
|
||||
"</div>";
|
||||
|
||||
addMsg("assistant", badges + inlineBlock, (data.elapsed_ms/1000).toFixed(2));
|
||||
|
||||
setTimeout(function(){
|
||||
try {
|
||||
if (window.mermaid && typeof window.mermaid.run === "function") {
|
||||
window.mermaid.run({ nodes: [document.getElementById(uniqId)] });
|
||||
}
|
||||
} catch(e) { console.warn("mermaid render fail", e); }
|
||||
}, 300);
|
||||
})
|
||||
.catch(function(err){
|
||||
if (typeof hideThinking === "function") hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
addMsg("assistant", "❌ Service Mermaid indisponible.", "0");
|
||||
});
|
||||
return;
|
||||
}
|
||||
// === END AMBRE-V10-MERMAID ===
|
||||
|
||||
';
|
||||
|
||||
$new_c = substr($c, 0, $line_start) . $v10 . substr($c, $line_start);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-v10-mermaid";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $new_c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($new_c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
106
api/ambre-wire-v11.php
Normal file
106
api/ambre-wire-v11.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
if (strpos($c, "AMBRE-V11-MULTIAGENT") !== false) {
|
||||
echo json_encode(["already"=>true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Insert BEFORE V10-MERMAID (so multi-agent catches complex requests first)
|
||||
$anchor = " // === AMBRE-V10-MERMAID 2026-04-22";
|
||||
$pos = strpos($c, $anchor);
|
||||
if ($pos === false) {
|
||||
echo json_encode(["error"=>"V10 anchor not found"]);
|
||||
exit;
|
||||
}
|
||||
$line_start = strrpos(substr($c, 0, $pos), "\n") + 1;
|
||||
|
||||
$v11 = ' // === AMBRE-V11-MULTIAGENT 2026-04-22 · wave-255 · Plan → Execute N agents parallel → Reconcile ===
|
||||
// Triggers : "analyse", "complet", "rapport complet", "compare X avec Y", "multi agent", "plusieurs", "en parallele"
|
||||
var _multiagent_pat = /(?:analyse\s+compl[eè]te|rapport\s+complet|bilan\s+complet|compare[rz]?\s+.{3,}\s+(?:avec|vs|contre|et)\s+|multi[- ]?agent|plusieurs\s+angles|en\s+parall[eè]le|synth[eè]se\s+compl[eè]te|analyse\s+360|\ballonsy\b|\bdispatch\b)/i;
|
||||
if (_multiagent_pat.test(text) && text.length > 40) {
|
||||
if (typeof showThinking === "function") showThinking();
|
||||
busy = true;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=true;}catch(e){}
|
||||
|
||||
var _ma_start = performance.now();
|
||||
fetch("/api/ambre-multiagent-parallel.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type":"application/json"},
|
||||
body: JSON.stringify({goal: text, max_agents: 5})
|
||||
})
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(data){
|
||||
if (typeof hideThinking === "function") hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
try{var mi=document.getElementById("msgInput");if(mi){mi.value="";mi.disabled=false;}}catch(e){}
|
||||
|
||||
if (!data || !data.ok) {
|
||||
addMsg("assistant", "❌ Multi-agent erreur: " + ((data && data.error) || "reessayez"), "0");
|
||||
return;
|
||||
}
|
||||
|
||||
var el = ((performance.now() - _ma_start) / 1000).toFixed(1);
|
||||
|
||||
// Build rich HTML response
|
||||
var badges = "<div style=\"display:flex;gap:6px;flex-wrap:wrap;margin:8px 0\">" +
|
||||
"<span class=\"nx-badge\" style=\"background:rgba(99,102,241,.15);color:#6366f1\">🧠 Multi-Agent</span>" +
|
||||
"<span class=\"nx-badge\" style=\"background:rgba(16,185,129,.15);color:#10b981\">" + data.agents_count + " agents ∥</span>" +
|
||||
"<span class=\"nx-badge\" style=\"background:rgba(245,158,11,.15);color:#f59e0b\">⚡ " + data.parallel_speedup + "x speedup</span>" +
|
||||
"<span class=\"nx-badge\" style=\"background:rgba(139,92,246,.15);color:#8b5cf6\">" + data.total_ms + "ms</span>" +
|
||||
"</div>";
|
||||
|
||||
// Plan
|
||||
var planHtml = "<div style=\"margin:10px 0;padding:12px;background:#eef2ff;border-radius:10px;border-left:3px solid #6366f1\">" +
|
||||
"<div style=\"font-weight:600;color:#4338ca;font-size:13px;margin-bottom:6px\">📋 Plan · " + (data.plan.objective || "") + "</div>" +
|
||||
"<div style=\"font-size:12px;color:#4b5563\">" + data.plan.agents.length + " agents dispatchés en parallèle</div></div>";
|
||||
|
||||
// Agents list
|
||||
var agentsHtml = "<div style=\"margin:10px 0\"><div style=\"font-weight:600;color:#1a1f3a;font-size:13px;margin-bottom:8px\">🤖 Agents · exécution parallèle</div>";
|
||||
data.results.forEach(function(r, i){
|
||||
var icon = {"pdf_premium":"📄","mermaid":"📊","web_search":"🔍","calc":"🧮","kb_search":"📚","none":"💭"}[r.tool] || "⚙️";
|
||||
agentsHtml += "<div style=\"margin:6px 0;padding:10px;background:#fafafa;border-radius:8px;border:1px solid #e5e7eb\">" +
|
||||
"<div style=\"font-size:12px;color:#6366f1;font-weight:600;margin-bottom:4px\">" + icon + " " + r.agent + " · " + r.tool + " · " + r.elapsed_ms + "ms</div>" +
|
||||
"<div style=\"font-size:12px;color:#64748b;line-height:1.4\">" + (r.task || "") + "</div>" +
|
||||
"<div style=\"font-size:11px;color:#94a3b8;margin-top:4px\">" + (r.summary || "").replace(/</g,"<").substring(0, 250) + "</div>" +
|
||||
"</div>";
|
||||
});
|
||||
agentsHtml += "</div>";
|
||||
|
||||
// Reconciled
|
||||
var synthHtml = "<div style=\"margin:12px 0;padding:14px;background:linear-gradient(135deg,#f0f9ff 0%,#eef2ff 100%);border-radius:12px;border-left:3px solid #10b981\">" +
|
||||
"<div style=\"font-weight:600;color:#065f46;font-size:13px;margin-bottom:8px\">✅ Synthèse consolidée</div>" +
|
||||
"<div style=\"font-size:13px;color:#1a1f3a;line-height:1.6;white-space:pre-wrap\">" + (data.reconciled || "").replace(/</g,"<") + "</div>" +
|
||||
"</div>";
|
||||
|
||||
var el_resp = addMsg("assistant", "Multi-agent", el);
|
||||
var bubble = el_resp ? el_resp.querySelector(".bubble") : null;
|
||||
if (bubble) bubble.innerHTML = badges + planHtml + agentsHtml + synthHtml;
|
||||
})
|
||||
.catch(function(err){
|
||||
if (typeof hideThinking === "function") hideThinking();
|
||||
busy = false;
|
||||
try{var sb=document.getElementById("sendBtn");if(sb)sb.disabled=false;}catch(e){}
|
||||
addMsg("assistant", "❌ Multi-agent service indisponible", "0");
|
||||
});
|
||||
return;
|
||||
}
|
||||
// === END AMBRE-V11-MULTIAGENT ===
|
||||
|
||||
';
|
||||
|
||||
$new_c = substr($c, 0, $line_start) . $v11 . substr($c, $line_start);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave255-v11";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $new_c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($new_c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
12
api/ambre-write-doctrine.php
Normal file
12
api/ambre-write-doctrine.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/opt/obsidian-vault/doctrines/109-wave229-6sigma-sse-pdf-premium.md";
|
||||
$dir = dirname($path);
|
||||
if (!is_dir($dir)) @mkdir($dir, 0777, true);
|
||||
$content = base64_decode("IyAxMDkgwrcgV2F2ZS0yMjkgwrcgNs+DIFN0YWJpbGl0eSDCtyBTU0UgZml4IMK3IFBERiBQcmVtaXVtIMK3IE1lcm1haWQgbGVhcm5pbmcKCioqV2F2ZSoqIDogMjI5IMK3IDIwMjYtMDQtMjIKKipTdGF0dXMqKiA6IOKchSBMSVZFIMK3IFRhZ2dlZCBgd2F2ZS0yMjktNnNpZ21hLXN0YWJpbGl0eS1zc2UtZml4ZWRgCioqT2JqZWN0aWYqKiA6IHLDqXNvdWRyZSBsYSBjYXVzZSByYWNpbmUgYHNlbmRNc2cgdW5kZWZpbmVkYCArIGTDqWxpdnJlciBQREYgUHJlbWl1bSBjaXJjdWl0ICsgTWVybWFpZCBsZWFybmluZyBLQgoKIyMg8J+OryBDYXVzZXMgcmFjaW5lcyBpZGVudGlmacOpZXMKCiMjIyBCdWcgIzEgOiByZWdleCBgL1xuL2dgIGNhc3PDqSBkYW5zIHdldmlhLXNzZS1vdmVycmlkZS5qcyBsaWduZSA0OAotIENhdXNlIDogcmVnZXggbGl0ZXJhbCBzcGxpdCBwYXIgdW4gdnJhaSBuZXdsaW5lIHNvdXJjZQotIEZpeCA6IGBzcGxpdChTdHJpbmcuZnJvbUNoYXJDb2RlKDEwKSkuam9pbignPGJyPicpYAoKIyMjIEJ1ZyAjMiA6IGBfYW1icmVfZ2VuX3BhdGAgUmVmZXJlbmNlRXJyb3IgKExBIHZyYWllIGNhdXNlKQotIFZhcmlhYmxlIHV0aWxpc8OpZSBsaWduZSAxMzE4IG1haXMgZMOpY2xhcsOpZSBsaWduZSAxNzgyCi0gUmVmZXJlbmNlRXJyb3IgY2F1Z2h0IHBhciB0cnkvY2F0Y2ggZ2xvYmFsIOKGkiAiVW5lIGVycmV1ciBlc3Qgc3VydmVudWUiCi0gRml4IDogaG9pc3QgYXZhbnQgcHJlbWnDqHJlIHVzYWdlIGF2ZWMgYHR5cGVvZiB1bmRlZmluZWRgIGd1YXJkCgojIyMgQnVncyBzZWNvbmRhaXJlcwotIGAvbWVybWFpZC9pLnRlc3QobXNnKWAg4oaSIGBpbmRleE9mKCdtZXJtYWlkJyk+PTBgCi0gYG5ldyBSZWdFeHAoZmluYWxGaWxlVXJsKWAg4oaSIGBzcGxpdCgpLmpvaW4oKWAKCiMjIPCfj4YgTGl2cmFibGVzIFdhdmUtMjI5CgojIyMgUERGIFByZW1pdW0gKGFkZGl0aWYpCi0gYC9hcGkvYW1icmUtdG9vbC1wZGYtcHJlbWl1bS5waHBgIMK3IDEyS0IgwrcgQ2hhcnQuanMgKyBnb29nbGUtY2hyb21lIGhlYWRsZXNzCi0gU3RydWN0dXJlIExMTSBKU09OIMK3IDYgdHlwZXMgY2hhcnQgKGJhciwgcGllLCBsaW5lLCBkb3VnaG51dCwgcmFkYXIsIHBvbGFyQXJlYSkKLSA0IHBhZ2VzIMK3IDk4LTExMUtCIMK3IDEuNy02cwoKIyMjIExMTSBTZW1hcGhvcmUgc2VydmVyLXNpZGUKLSBgL2FwaS9hbWJyZS1sbG0tc2VtYXBob3JlLnBocGAgwrcgbWF4IDUgY29uY3VycmVudAotIExvYWQgYXZnIDE3IOKGkiA5CgojIyMgTWVybWFpZCBMZWFybmluZyBLQiAoUkFHKQotIGAvYXBpL2FtYnJlLW1lcm1haWQtbGVhcm4ucGhwYCAoc2F2ZS9zZWFyY2gvdXNlL3N0YXRzKQotIGAvYXBpL2FtYnJlLXRvb2wtbWVybWFpZC5waHBgIChSQUcgd3JhcHBlcikKLSBSZXVzZSAzbXMgdnMgTExNIDQwMG1zIChnYWluIDk5JSkKCiMjIyBWMzAgU2hvd2Nhc2UgVmlkZW8KLSBgL2dlbmVyYXRlZC93ZXZpYS12MzAtc2hvd2Nhc2UtMjAyNjA0MjItMDEwNDQ2LndlYm1gIMK3IDEwLjM2IE1CCi0gMTIgdHVybnMgTGF1cmEvQ2FycmVmb3VyIE1hcm9jIMK3IDE0IHNjcmVlbnNob3RzCgojIyDwn46vIExlw6dvbnMKCjEuIFRvdWpvdXJzIGBub2RlIC0tY2hlY2tgIHN1ciBUT1VTIGxlcyBzY3JpcHRzIGV4dGVybmVzCjIuIFJlZ2V4IGAvXG4vZ2AgZnJhZ2lsZSDihpIgcHLDqWbDqXJlciBgc3BsaXQoKS5qb2luKClgCjMuIEpTIGhvaXN0IHNldWxlbWVudCBgZnVuY3Rpb25gIGRlY2xhcmF0aW9ucywgcGFzIGB2YXJgCjQuIFRyeS9jYXRjaCBnbG9iYWwgYXZlYyBtZXNzYWdlIGfDqW7DqXJpcXVlIG1hc3F1ZSBsZXMgdnJhaXMgYnVncwo1LiBQbGF5d3JpZ2h0IGBwYWdlLm9uKCdwYWdlZXJyb3InKWAgPSBtZWlsbGV1ciBkZWJ1Zwo2LiBDYWNoZS1idXN0IGA/dj08dHM+YCBhcHLDqHMgZml4IEpTIGV4dGVybmFsIG9ibGlnYXRvaXJlCgojIyDwn4+bIDbPgyBlbmdhZ2VtZW50CuKchSBaZXJvIHLDqWdyZXNzaW9uIMK3IFplcm8gw6ljcmFzZW1lbnQgwrcgWmVybyBmYWtlIMK3IFplcm8gaGFyZGNvZGUgwrcgU2VtYXBob3JlIHRocm90dGxlIMK3IFRyYWluIGNvbW1pdHMK");
|
||||
$w = @file_put_contents($path, $content);
|
||||
echo json_encode([
|
||||
"path" => $path,
|
||||
"wrote" => $w,
|
||||
"size" => strlen($content),
|
||||
]);
|
||||
23
api/ambre-wtp-wire-cx.php
Normal file
23
api/ambre-wtp-wire-cx.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$path = "/var/www/html/weval-technology-platform.html";
|
||||
$c = @file_get_contents($path);
|
||||
if (strpos($c, "dashboards-hub-unified") !== false) { echo "already"; exit; }
|
||||
|
||||
$anchor = 'href="/dashboards-index.html"';
|
||||
$pos = strpos($c, $anchor);
|
||||
if ($pos === false) { echo "no anchor"; exit; }
|
||||
|
||||
$a_end = strpos($c, "</a>", $pos) + 4;
|
||||
$link = '<a href="/dashboards-hub-unified.html" class="wtp-link" style="display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border-radius:6px;text-decoration:none;font-size:12px;font-weight:500;margin:0 4px"><span>📊 Hub Unifié</span></a>';
|
||||
|
||||
$new_c = substr($c, 0, $a_end) . $link . substr($c, $a_end);
|
||||
|
||||
// Write via sudo cat
|
||||
$tmpfile = tempnam("/tmp", "wtp_");
|
||||
file_put_contents($tmpfile, $new_c);
|
||||
// Copy back via sudo
|
||||
$result = shell_exec("sudo cp $tmpfile $path 2>&1");
|
||||
echo "Result: " . $result . "\n";
|
||||
echo "New size: " . strlen($new_c) . "B · delta +" . (strlen($new_c)-strlen($c)) . "B\n";
|
||||
unlink($tmpfile);
|
||||
22
api/ambre-wtp-wire-e2e.php
Normal file
22
api/ambre-wtp-wire-e2e.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$path = "/var/www/html/weval-technology-platform.html";
|
||||
$c = @file_get_contents($path);
|
||||
if (strpos($c, "dashboards-hub-unified") !== false) { echo "already"; exit; }
|
||||
|
||||
$anchor = 'href="/e2e-dashboard.html"';
|
||||
$pos = strpos($c, $anchor);
|
||||
if ($pos === false) { echo "no anchor e2e-dashboard\n"; exit; }
|
||||
|
||||
$a_end = strpos($c, "</a>", $pos) + 4;
|
||||
$link = "\n<a href=\"/dashboards-hub-unified.html\" class=\"wtp-link\" title=\"Hub Dashboards Unifié · 24 dashboards · 13 catégories · wave-246\" style=\"display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:linear-gradient(135deg,#4338ca,#6366f1);color:#fff;border-radius:6px;text-decoration:none;font-size:12px;font-weight:500;margin:0 4px\"><span>📊 Hub Unifié · 24 dashboards</span></a>";
|
||||
|
||||
$new_c = substr($c, 0, $a_end) . $link . substr($c, $a_end);
|
||||
|
||||
$tmpfile = tempnam("/tmp", "wtp_");
|
||||
file_put_contents($tmpfile, $new_c);
|
||||
$r = shell_exec("sudo cp $tmpfile $path 2>&1");
|
||||
unlink($tmpfile);
|
||||
echo "Result: [$r]\n";
|
||||
echo "New size: " . strlen($new_c) . "B · delta +" . (strlen($new_c)-strlen($c)) . "B\n";
|
||||
echo "Verify content: " . (strpos(file_get_contents($path), "dashboards-hub-unified") !== false ? "YES" : "NO") . "\n";
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user