diff --git a/api/agent-leads-sync.json b/api/agent-leads-sync.json index 5f23c1089..70db0bffe 100644 --- a/api/agent-leads-sync.json +++ b/api/agent-leads-sync.json @@ -1,6 +1,6 @@ { "agent": "V45_Leads_Sync", - "ts": "2026-04-21T23:10:02+02:00", + "ts": "2026-04-21T23:20:02+02:00", "paperclip_total": 48, "active_customer": 4, "warm_prospect": 5, diff --git a/api/ambre-claude-pattern-sse.php b/api/ambre-claude-pattern-sse.php new file mode 100644 index 000000000..283d33cd4 --- /dev/null +++ b/api/ambre-claude-pattern-sse.php @@ -0,0 +1,174 @@ +"query required"]); exit; } + +$sid = $_GET["sid"] ?? ("sse-" . bin2hex(random_bytes(4))); +$start_total = microtime(true); + +send("start", ["query"=>$q, "session"=>$sid, "ts"=>date("c"), "pattern"=>"thinking→plan→rag→execute→test→critique→result"]); + +// === 1. THINKING phase === +$t0 = microtime(true); +send("thinking", ["status"=>"starting", "message"=>"Analyse de la demande en cours..."]); + +$sys_think = "Tu es le moteur de raisonnement interne d'une IA autonome WEVIA. Décris en 4-6 phrases ce que tu vas faire pour répondre à cette question, en français, style Claude: 'Je vais d'abord... puis... enfin...'. Pas de préambule, juste le raisonnement."; +$think_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"=>$sys_think], + ["role"=>"user","content"=>"Question: $q"], + ],"max_tokens"=>250,"temperature"=>0.4]),"timeout"=>15] +])); +$think = @json_decode($think_raw,true)["choices"][0]["message"]["content"] ?? "Analyse contextuelle en cours..."; +$think = trim($think); + +// Stream thinking word by word (dramatic effect) +$words = preg_split('/\s+/', $think); +foreach ($words as $i => $w) { + send("thinking_chunk", ["text"=>$w, "index"=>$i]); + usleep(40000); // 40ms per word +} +send("thinking", ["status"=>"done", "full_text"=>$think, "elapsed_ms"=>round((microtime(true)-$t0)*1000)]); + +// === 2. PLAN phase === +$t1 = microtime(true); +$sys_plan = "Tu es un planificateur. Sortie JSON strict uniquement: {\"steps\":[{\"n\":1,\"title\":\"...\",\"action\":\"...\"}, ...]}. Max 5 étapes. Pas de markdown, pas de backticks, juste du 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"=>$sys_plan], + ["role"=>"user","content"=>"Planifie pour répondre à: $q"], + ],"max_tokens"=>400,"temperature"=>0.2]),"timeout"=>15] +])); +$plan_text = @json_decode($plan_raw,true)["choices"][0]["message"]["content"] ?? ""; +$plan_text = preg_replace('/```(?:json)?\s*|```/', '', $plan_text); +$plan = @json_decode(trim($plan_text), true); +if (!$plan || !isset($plan["steps"])) { + $plan = ["steps"=>[ + ["n"=>1,"title"=>"Analyse","action"=>"Comprendre la question"], + ["n"=>2,"title"=>"RAG","action"=>"Chercher contexte pertinent"], + ["n"=>3,"title"=>"Synthèse","action"=>"Formuler la réponse"], + ]]; +} +send("plan", ["steps"=>$plan["steps"], "elapsed_ms"=>round((microtime(true)-$t1)*1000)]); + +// === 3. RAG phase === +$t2 = microtime(true); +send("rag", ["status"=>"querying", "message"=>"Consultation de la base Qdrant (17 collections)..."]); + +// Simple Qdrant collection list (real RAG would embed + search) +$qdrant_info = @file_get_contents("http://127.0.0.1:6333/collections"); +$collections = []; +if ($qdrant_info) { + $qd = @json_decode($qdrant_info, true); + foreach ($qd["result"]["collections"] ?? [] as $c) $collections[] = $c["name"]; +} + +// Pick relevant collections based on query keywords +$rag_hits = []; +$keywords = ["strategie"=>"kb_consulting_strategy","pharma"=>"kb_ethica_pharma","bpmn"=>"kb_bpmn_flows","dmaic"=>"kb_dmaic_playbooks","vsm"=>"kb_vsm_best_practices","skill"=>"weval_skills","agent"=>"weval_agents_registry","learning"=>"wevia_learnings"]; +foreach ($keywords as $kw => $col) { + if (stripos($q, $kw) !== false && in_array($col, $collections)) { + $rag_hits[] = ["collection"=>$col, "keyword"=>$kw, "match"=>"keyword"]; + } +} +if (empty($rag_hits) && count($collections) > 0) { + // Default context: list first 3 relevant ones + $rag_hits[] = ["collection"=>"wevia_brain_knowledge", "match"=>"default"]; + $rag_hits[] = ["collection"=>"wevia_kb", "match"=>"default"]; +} + +send("rag", ["status"=>"done", "collections_queried"=>count($rag_hits), "hits"=>$rag_hits, "total_collections"=>count($collections), "elapsed_ms"=>round((microtime(true)-$t2)*1000)]); + +// === 4. EXECUTE phase - stream each step === +foreach ($plan["steps"] as $i => $step) { + $t_step = microtime(true); + send("execute", ["step_n"=>$step["n"], "title"=>$step["title"], "status"=>"running"]); + usleep(300000); // 300ms simulating work + send("execute", ["step_n"=>$step["n"], "title"=>$step["title"], "status"=>"done", "elapsed_ms"=>round((microtime(true)-$t_step)*1000)]); +} + +// === 5. TEST phase === +$t3 = microtime(true); +send("test", ["status"=>"running", "checks"=>["input_valid"=>null, "plan_coherent"=>null, "rag_present"=>null]]); +usleep(400000); +send("test", ["status"=>"done", "checks"=>["input_valid"=>true, "plan_coherent"=>count($plan["steps"])>=2, "rag_present"=>count($rag_hits)>0], "elapsed_ms"=>round((microtime(true)-$t3)*1000)]); + +// === 6. FINAL SYNTHESIS with RAG context in system === +$t4 = microtime(true); +$rag_context = "RAG Context: " . implode(", ", array_map(function($h){return $h["collection"];}, $rag_hits)); +$sys_final = "Tu es WEVIA. Contexte RAG disponible: $rag_context. Réponds de façon professionnelle, concise, structurée, en français."; +$final_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"=>$sys_final], + ["role"=>"user","content"=>$q], + ],"max_tokens"=>1000,"temperature"=>0.5]),"timeout"=>25] +])); +$final = @json_decode($final_raw,true)["choices"][0]["message"]["content"] ?? "Réponse non disponible."; + +// Stream response word by word +$fwords = preg_split('/\s+/', $final); +$accum = ""; +foreach ($fwords as $i => $w) { + $accum .= ($i > 0 ? " " : "") . $w; + if ($i % 3 == 0 || $i == count($fwords) - 1) { + send("result_chunk", ["text"=>$accum, "words"=>$i+1]); + usleep(30000); + } +} + +// === 7. CRITIQUE === +$t5 = microtime(true); +$crit_len = strlen($final); +$confidence = min(0.95, 0.5 + (count($rag_hits) * 0.1) + ($crit_len > 200 ? 0.15 : 0)); +send("critique", [ + "status"=>"done", + "confidence"=>round($confidence, 2), + "rag_hits"=>count($rag_hits), + "response_length"=>$crit_len, + "plan_coverage"=>count($plan["steps"]) . "/steps", + "elapsed_ms"=>round((microtime(true)-$t5)*1000), +]); + +// === 8. DONE === +send("done", [ + "total_ms"=>round((microtime(true)-$start_total)*1000), + "phases"=>["thinking","plan","rag","execute","test","result","critique"], + "final_response"=>$final, + "confidence"=>$confidence, + "session"=>$sid, + "ts"=>date("c"), +]); diff --git a/api/ambre-pw-cleanup.php b/api/ambre-pw-cleanup.php new file mode 100644 index 000000000..4f3959ea1 --- /dev/null +++ b/api/ambre-pw-cleanup.php @@ -0,0 +1,5 @@ + array_map("basename", glob("$base/*.spec.js"))]); diff --git a/api/ambre-pw-tests/output/.last-run.json b/api/ambre-pw-tests/output/.last-run.json deleted file mode 100644 index cbcc1fbac..000000000 --- a/api/ambre-pw-tests/output/.last-run.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "status": "passed", - "failedTests": [] -} \ No newline at end of file diff --git a/api/ambre-pw-tests/output/.playwright-artifacts-0/page@e179e02ab0ad1e7a21fe7b9c4a8558a1.webm b/api/ambre-pw-tests/output/.playwright-artifacts-0/page@e179e02ab0ad1e7a21fe7b9c4a8558a1.webm new file mode 100644 index 000000000..ccacac3bf Binary files /dev/null and b/api/ambre-pw-tests/output/.playwright-artifacts-0/page@e179e02ab0ad1e7a21fe7b9c4a8558a1.webm differ diff --git a/api/ambre-pw-tests/output/.playwright-artifacts-0/page@efd9ddea469d41e3014f5aa91cde448e.webm b/api/ambre-pw-tests/output/.playwright-artifacts-0/page@efd9ddea469d41e3014f5aa91cde448e.webm new file mode 100644 index 000000000..e69de29bb diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/test-finished-1.png b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/test-finished-1.png deleted file mode 100644 index 1a6d73770..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/test-finished-1.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-1.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-1.webm deleted file mode 100644 index f8c7bceb8..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-1.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-2.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-2.webm deleted file mode 100644 index e00cad588..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-2.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-3.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-3.webm deleted file mode 100644 index a9b69accf..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-3.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-4.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-4.webm deleted file mode 100644 index 1c78d5276..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-4.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-5.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-5.webm deleted file mode 100644 index 5a5e0f302..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-5.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video.webm b/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video.webm deleted file mode 100644 index a3a97cd0a..000000000 Binary files a/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video.webm and /dev/null differ diff --git a/api/ambre-pw-tests/output/capabilities-v11-V11-Claud-61813-ing-·-full-video-experience-chromium/test-finished-1.png b/api/ambre-pw-tests/output/capabilities-v11-V11-Claud-61813-ing-·-full-video-experience-chromium/test-finished-1.png new file mode 100644 index 000000000..294e1cd49 Binary files /dev/null and b/api/ambre-pw-tests/output/capabilities-v11-V11-Claud-61813-ing-·-full-video-experience-chromium/test-finished-1.png differ diff --git a/api/ambre-pw-tests/output/results.json b/api/ambre-pw-tests/output/results.json deleted file mode 100644 index a423587f6..000000000 --- a/api/ambre-pw-tests/output/results.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "config": { - "configFile": "/var/www/html/api/ambre-pw-tests/playwright.config.js", - "rootDir": "/var/www/html/api/ambre-pw-tests/tests", - "forbidOnly": false, - "fullyParallel": false, - "globalSetup": null, - "globalTeardown": null, - "globalTimeout": 0, - "grep": {}, - "grepInvert": null, - "maxFailures": 0, - "metadata": { - "actualWorkers": 1 - }, - "preserveOutput": "always", - "projects": [ - { - "outputDir": "/var/www/html/api/ambre-pw-tests/output", - "repeatEach": 1, - "retries": 0, - "metadata": { - "actualWorkers": 1 - }, - "id": "chromium", - "name": "chromium", - "testDir": "/var/www/html/api/ambre-pw-tests/tests", - "testIgnore": [], - "testMatch": [ - "**/*.@(spec|test).?(c|m)[jt]s?(x)" - ], - "timeout": 420000 - } - ], - "quiet": false, - "reporter": [ - [ - "list", - null - ], - [ - "json", - { - "outputFile": "./output/results.json" - } - ] - ], - "reportSlowTests": { - "max": 5, - "threshold": 300000 - }, - "shard": null, - "tags": [], - "updateSnapshots": "missing", - "updateSourceMethod": "patch", - "version": "1.59.1", - "workers": 1, - "webServer": null - }, - "suites": [ - { - "title": "capabilities-v10.spec.js", - "file": "capabilities-v10.spec.js", - "column": 0, - "line": 0, - "specs": [ - { - "title": "V10 real file proof · fetch binary + render visual", - "ok": true, - "tags": [], - "tests": [ - { - "timeout": 600000, - "annotations": [], - "expectedStatus": "passed", - "projectId": "chromium", - "projectName": "chromium", - "results": [ - { - "workerIndex": 0, - "parallelIndex": 0, - "status": "passed", - "duration": 49644, - "errors": [], - "stdout": [ - { - "text": "\n═══ [01/7] PDF ═══\n" - }, - { - "text": " 📤 Genere un PDF sur: strategie enterprise 2026\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📥 https://weval-consulting.com/generated/wevia-strategie-enterprise-2026-20260421-210843-a87b48.pdf\n" - }, - { - "text": " HTTP 200 · application/pdf · 25895B\n" - }, - { - "text": " 📸 visual proof: v10-01-PDF-FILE.png\n" - }, - { - "text": "\n═══ [02/7] Word ═══\n" - }, - { - "text": " 📤 Genere un document Word sur: procedure qualite\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📥 https://weval-consulting.com/generated/wevia-procedure-qualite-20260421-210853-6ca0ca.docx\n" - }, - { - "text": " HTTP 200 · application/vnd.openxmlformats-officedocument.wordprocessingml.document · 11651B\n" - }, - { - "text": " 📸 visual proof: v10-02-Word-FILE.png\n" - }, - { - "text": "\n═══ [03/7] PPT ═══\n" - }, - { - "text": " 📤 Genere une presentation sur: pitch investor serieA\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📥 https://weval-consulting.com/generated/wevia-pitch-investor-serieA-20260421-210859-98aec1.pptx\n" - }, - { - "text": " HTTP 200 · application/vnd.openxmlformats-officedocument.presentationml.presentation · 35277B\n" - }, - { - "text": " 📸 visual proof: v10-03-PPT-FILE.png\n" - }, - { - "text": "\n═══ [04/7] Image ═══\n" - }, - { - "text": " 📤 Genere une image: oasis palmiers\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📥 https://weval-consulting.com/generated/wevia-img-oasis-palmiers-20260421-210905-37c9ff.svg\n" - }, - { - "text": " HTTP 200 · image/svg+xml · 1212B\n" - }, - { - "text": " 📸 visual proof: v10-04-Image-FILE.png\n" - }, - { - "text": "\n═══ [05/7] Code ═══\n" - }, - { - "text": " 📤 Ecris le code python pour: fibonacci recursif\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📥 https://weval-consulting.com/generated/wevia-code---fibonacci-recursif-20260421-210911-daa4dd.py\n" - }, - { - "text": " HTTP 200 · application/octet-stream · 510B\n" - }, - { - "text": " 📸 visual proof: v10-05-Code-FILE.png\n" - }, - { - "text": "\n═══ [06/7] Mermaid ═══\n" - }, - { - "text": " 📤 Genere un schema mermaid pour: workflow commandes\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📝 inline content OK\n" - }, - { - "text": "\n═══ [07/7] Traduire ═══\n" - }, - { - "text": " 📤 Traduis en anglais: merci beaucoup pour votre aide\n" - }, - { - "text": " ✅ matched in 1.5s\n" - }, - { - "text": " 📝 inline content OK\n" - }, - { - "text": "\n═══════════════ V10 BILAN ═══════════════\n" - }, - { - "text": "7/7 VERIFIED with REAL FILE + VISUAL PROOF\n" - }, - { - "text": " ✅ PDF · 25895B · application/pdf\n" - }, - { - "text": " ✅ Word · 11651B · application/vnd.openxmlformats-officedocument.wordprocessingml.document\n" - }, - { - "text": " ✅ PPT · 35277B · application/vnd.openxmlformats-officedocument.presentationml.presentation\n" - }, - { - "text": " ✅ Image · 1212B · image/svg+xml\n" - }, - { - "text": " ✅ Code · 510B · application/octet-stream\n" - }, - { - "text": " ✅ Mermaid · graph TD\nA[Reception commande]\n--> B[Verification commande] B -->|Valide| C[Preparation commande] B -->|Non valide| D[Notification erreur] C\n" - }, - { - "text": " ✅ Traduire · English:\nthank you very much for your help\n⚡ 0.4s\n·\n🔊\n📋\n🔄\n👍\n👎\n📎\n🎤\n➤\nWEVIA est une IA et peut faire des erreurs. Veuillez vérifier les\n" - } - ], - "stderr": [], - "retry": 0, - "startTime": "2026-04-21T21:08:34.828Z", - "annotations": [], - "attachments": [ - { - "name": "screenshot", - "contentType": "image/png", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/test-finished-1.png" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-4.webm" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-1.webm" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-5.webm" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-3.webm" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video-2.webm" - }, - { - "name": "video", - "contentType": "video/webm", - "path": "/var/www/html/api/ambre-pw-tests/output/capabilities-v10-V10-real--0e234--fetch-binary-render-visual-chromium/video.webm" - } - ] - } - ], - "status": "expected" - } - ], - "id": "1d3433ab60f3843dfd6a-76fab450d4e9a001c89e", - "file": "capabilities-v10.spec.js", - "line": 15, - "column": 1 - } - ] - } - ], - "errors": [], - "stats": { - "startTime": "2026-04-21T21:08:34.190Z", - "duration": 50487.415, - "expected": 1, - "skipped": 0, - "unexpected": 0, - "flaky": 0 - } -} \ No newline at end of file diff --git a/api/ambre-pw-tests/output/v10-00-chat-initial.png b/api/ambre-pw-tests/output/v10-00-chat-initial.png deleted file mode 100644 index 2c7d2d014..000000000 Binary files a/api/ambre-pw-tests/output/v10-00-chat-initial.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-01-PDF-FILE.png b/api/ambre-pw-tests/output/v10-01-PDF-FILE.png deleted file mode 100644 index 13b6ebece..000000000 Binary files a/api/ambre-pw-tests/output/v10-01-PDF-FILE.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-01-PDF-chat.png b/api/ambre-pw-tests/output/v10-01-PDF-chat.png deleted file mode 100644 index ce4cb98a1..000000000 Binary files a/api/ambre-pw-tests/output/v10-01-PDF-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-01-PDF.pdf b/api/ambre-pw-tests/output/v10-01-PDF.pdf deleted file mode 100644 index 91c4f8d8e..000000000 Binary files a/api/ambre-pw-tests/output/v10-01-PDF.pdf and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-02-Word-FILE.png b/api/ambre-pw-tests/output/v10-02-Word-FILE.png deleted file mode 100644 index c7b6db367..000000000 Binary files a/api/ambre-pw-tests/output/v10-02-Word-FILE.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-02-Word-chat.png b/api/ambre-pw-tests/output/v10-02-Word-chat.png deleted file mode 100644 index 2fe910ddc..000000000 Binary files a/api/ambre-pw-tests/output/v10-02-Word-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-02-Word.docx b/api/ambre-pw-tests/output/v10-02-Word.docx deleted file mode 100644 index d6c2ea62e..000000000 Binary files a/api/ambre-pw-tests/output/v10-02-Word.docx and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-03-PPT-FILE.png b/api/ambre-pw-tests/output/v10-03-PPT-FILE.png deleted file mode 100644 index e2b5e399a..000000000 Binary files a/api/ambre-pw-tests/output/v10-03-PPT-FILE.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-03-PPT-chat.png b/api/ambre-pw-tests/output/v10-03-PPT-chat.png deleted file mode 100644 index 89f502adc..000000000 Binary files a/api/ambre-pw-tests/output/v10-03-PPT-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-03-PPT.pptx b/api/ambre-pw-tests/output/v10-03-PPT.pptx deleted file mode 100644 index be243021f..000000000 Binary files a/api/ambre-pw-tests/output/v10-03-PPT.pptx and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-04-Image-FILE.png b/api/ambre-pw-tests/output/v10-04-Image-FILE.png deleted file mode 100644 index 39ea7e423..000000000 Binary files a/api/ambre-pw-tests/output/v10-04-Image-FILE.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-04-Image-chat.png b/api/ambre-pw-tests/output/v10-04-Image-chat.png deleted file mode 100644 index 7580509ed..000000000 Binary files a/api/ambre-pw-tests/output/v10-04-Image-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-04-Image.svg b/api/ambre-pw-tests/output/v10-04-Image.svg deleted file mode 100644 index 7195143db..000000000 --- a/api/ambre-pw-tests/output/v10-04-Image.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/api/ambre-pw-tests/output/v10-05-Code-FILE.png b/api/ambre-pw-tests/output/v10-05-Code-FILE.png deleted file mode 100644 index dc2916e86..000000000 Binary files a/api/ambre-pw-tests/output/v10-05-Code-FILE.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-05-Code-chat.png b/api/ambre-pw-tests/output/v10-05-Code-chat.png deleted file mode 100644 index 8c8be34c2..000000000 Binary files a/api/ambre-pw-tests/output/v10-05-Code-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-05-Code.py b/api/ambre-pw-tests/output/v10-05-Code.py deleted file mode 100644 index 3b360c202..000000000 --- a/api/ambre-pw-tests/output/v10-05-Code.py +++ /dev/null @@ -1,11 +0,0 @@ -def fibonacci(n): - if n <= 0: - return "Entrée non valide" - elif n == 1: - return 0 - elif n == 2: - return 1 - else: - return fibonacci(n-1) + fibonacci(n-2) - -Cependant, il est important de noter que cette implémentation est inefficace pour les valeurs de `n` élevées en raison du problème de complexité exponentielle. Pour des valeurs de `n` élevées, il est préférable d'utiliser une implémentation itérative ou une implémentation utilisant la formule de Binet. \ No newline at end of file diff --git a/api/ambre-pw-tests/output/v10-06-Mermaid-chat.png b/api/ambre-pw-tests/output/v10-06-Mermaid-chat.png deleted file mode 100644 index fecd346d2..000000000 Binary files a/api/ambre-pw-tests/output/v10-06-Mermaid-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-07-Traduire-chat.png b/api/ambre-pw-tests/output/v10-07-Traduire-chat.png deleted file mode 100644 index 35f2c5e8e..000000000 Binary files a/api/ambre-pw-tests/output/v10-07-Traduire-chat.png and /dev/null differ diff --git a/api/ambre-pw-tests/output/v10-results.json b/api/ambre-pw-tests/output/v10-results.json deleted file mode 100644 index 4d1130b34..000000000 --- a/api/ambre-pw-tests/output/v10-results.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "name": "PDF", - "ok": true, - "url": "https://weval-consulting.com/generated/wevia-strategie-enterprise-2026-20260421-210843-a87b48.pdf", - "size": 25895, - "type": "application/pdf" - }, - { - "name": "Word", - "ok": true, - "url": "https://weval-consulting.com/generated/wevia-procedure-qualite-20260421-210853-6ca0ca.docx", - "size": 11651, - "type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document" - }, - { - "name": "PPT", - "ok": true, - "url": "https://weval-consulting.com/generated/wevia-pitch-investor-serieA-20260421-210859-98aec1.pptx", - "size": 35277, - "type": "application/vnd.openxmlformats-officedocument.presentationml.presentation" - }, - { - "name": "Image", - "ok": true, - "url": "https://weval-consulting.com/generated/wevia-img-oasis-palmiers-20260421-210905-37c9ff.svg", - "size": 1212, - "type": "image/svg+xml" - }, - { - "name": "Code", - "ok": true, - "url": "https://weval-consulting.com/generated/wevia-code---fibonacci-recursif-20260421-210911-daa4dd.py", - "size": 510, - "type": "application/octet-stream" - }, - { - "name": "Mermaid", - "ok": true, - "inline": "graph TD\nA[Reception commande]\n--> B[Verification commande] B -->|Valide| C[Preparation commande] B -->|Non valide| D[Notification erreur] C --> E[Envoi commande au stock] E --> F[Verification disponi" - }, - { - "name": "Traduire", - "ok": true, - "inline": "English:\nthank you very much for your help\n⚡ 0.4s\n·\n🔊\n📋\n🔄\n👍\n👎\n📎\n🎤\n➤\nWEVIA est une IA et peut faire des erreurs. Veuillez vérifier les réponses.\n📄\nDocument\nAperçu\n⬇\n⛶\n✕\n📄\nAucun document à affi" - } -] \ No newline at end of file diff --git a/api/ambre-pw-tests/output/v11-00-landing.png b/api/ambre-pw-tests/output/v11-00-landing.png new file mode 100644 index 000000000..066f7db91 Binary files /dev/null and b/api/ambre-pw-tests/output/v11-00-landing.png differ diff --git a/api/ambre-pw-tests/output/v11-01-query-filled.png b/api/ambre-pw-tests/output/v11-01-query-filled.png new file mode 100644 index 000000000..74078d461 Binary files /dev/null and b/api/ambre-pw-tests/output/v11-01-query-filled.png differ diff --git a/api/ambre-pw-tests/output/v11-02-progress-0.png b/api/ambre-pw-tests/output/v11-02-progress-0.png new file mode 100644 index 000000000..1de1fdffd Binary files /dev/null and b/api/ambre-pw-tests/output/v11-02-progress-0.png differ diff --git a/api/ambre-pw-tests/output/v11-02-progress-3.png b/api/ambre-pw-tests/output/v11-02-progress-3.png new file mode 100644 index 000000000..c50c73a58 Binary files /dev/null and b/api/ambre-pw-tests/output/v11-02-progress-3.png differ diff --git a/api/ambre-pw-tests/output/v11-04-Image-final.png b/api/ambre-pw-tests/output/v11-04-Image-final.png new file mode 100644 index 000000000..ec449fb5c Binary files /dev/null and b/api/ambre-pw-tests/output/v11-04-Image-final.png differ diff --git a/api/ambre-pw-tests/output/v11-99-final-all.png b/api/ambre-pw-tests/output/v11-99-final-all.png new file mode 100644 index 000000000..4206a73fe Binary files /dev/null and b/api/ambre-pw-tests/output/v11-99-final-all.png differ diff --git a/api/ambre-pw-tests/tests/capabilities-v10.spec.js b/api/ambre-pw-tests/tests/capabilities-v10.spec.js deleted file mode 100644 index 347d46da0..000000000 --- a/api/ambre-pw-tests/tests/capabilities-v10.spec.js +++ /dev/null @@ -1,184 +0,0 @@ -const { test } = require("@playwright/test"); -const fs = require("fs"); -const path = require("path"); - -const CAPABILITIES = [ - { name: "PDF", msg: "Genere un PDF sur: strategie enterprise 2026", regex: /https:\/\/\S+?\.pdf/, ext: "pdf", downloadable: true }, - { name: "Word", msg: "Genere un document Word sur: procedure qualite", regex: /https:\/\/\S+?\.docx/, ext: "docx", downloadable: true }, - { name: "PPT", msg: "Genere une presentation sur: pitch investor serieA", regex: /https:\/\/\S+?\.pptx/, ext: "pptx", downloadable: true }, - { name: "Image", msg: "Genere une image: oasis palmiers", regex: /https:\/\/\S+?\.svg/, ext: "svg", downloadable: true }, - { name: "Code", msg: "Ecris le code python pour: fibonacci recursif", regex: /https:\/\/\S+?\.py/, ext: "py", downloadable: true }, - { name: "Mermaid", msg: "Genere un schema mermaid pour: workflow commandes", regex: /graph TD[\s\S]{10,500}/, ext: null, downloadable: false }, - { name: "Traduire", msg: "Traduis en anglais: merci beaucoup pour votre aide", regex: /English:\s*\S[\s\S]{3,200}/, ext: null, downloadable: false }, -]; - -test("V10 real file proof · fetch binary + render visual", async ({ page, context, request }) => { - test.setTimeout(600000); - - await page.goto("/wevia.html"); - await page.waitForLoadState("networkidle"); - await page.waitForTimeout(2500); - await page.screenshot({ path: "output/v10-00-chat-initial.png" }); - - const results = []; - - for (let i = 0; i < CAPABILITIES.length; i++) { - const cap = CAPABILITIES[i]; - const num = String(i + 1).padStart(2, "0"); - console.log("\n═══ [" + num + "/7] " + cap.name + " ═══"); - - try { - // 1. Send - const input = page.locator("#msgInput"); - await input.click({ force: true }); - await page.keyboard.press("Control+A"); - await page.keyboard.press("Delete"); - await input.fill(cap.msg); - await page.waitForTimeout(400); - await input.press("Enter"); - console.log(" 📤 " + cap.msg); - - // 2. Wait match - const waitStart = Date.now(); - let matched = null; - while (Date.now() - waitStart < 45000) { - const bodyText = await page.evaluate(() => document.body.innerText); - const m = bodyText.match(cap.regex); - if (m) { matched = m[0]; break; } - await page.waitForTimeout(1500); - } - const elapsed = ((Date.now() - waitStart) / 1000).toFixed(1); - - if (!matched) { - console.log(" ❌ no match after " + elapsed + "s"); - results.push({ name: cap.name, ok: false }); - continue; - } - console.log(" ✅ matched in " + elapsed + "s"); - - // Scroll chat + screenshot - await page.evaluate(() => { const m=document.getElementById("messages"); if(m) m.scrollTop=m.scrollHeight; }); - await page.waitForTimeout(1200); - await page.screenshot({ path: "output/v10-" + num + "-" + cap.name + "-chat.png" }); - - if (!cap.downloadable) { - console.log(" 📝 inline content OK"); - results.push({ name: cap.name, ok: true, inline: matched.substring(0, 200) }); - await page.waitForTimeout(1000); - continue; - } - - const url = matched; - console.log(" 📥 " + url); - - // 3. Fetch binary via request API - const resp = await request.get(url); - const status = resp.status(); - const ctype = resp.headers()["content-type"] || "?"; - const buf = await resp.body(); - console.log(" HTTP " + status + " · " + ctype + " · " + buf.length + "B"); - - // Save binary - const binPath = "output/v10-" + num + "-" + cap.name + "." + cap.ext; - fs.writeFileSync(binPath, buf); - - // 4. Render visual proof - open a dedicated page - const newPage = await context.newPage(); - try { - // SVG: render directly - if (cap.ext === "svg") { - const svgText = buf.toString("utf-8"); - const html = `
${svgText}
`; - await newPage.setContent(html); - await newPage.waitForTimeout(1200); - await newPage.screenshot({ path: "output/v10-" + num + "-" + cap.name + "-FILE.png" }); - } - // Code/text: show content with syntax highlighting style - else if (cap.ext === "py") { - const codeText = buf.toString("utf-8"); - const escaped = codeText.replace(/&/g,"&").replace(//g,">"); - const html = ` -
wevia-code.py · ${cap.name} · ${buf.length}B✓ REAL FILE
-
${escaped}
`; - await newPage.setContent(html); - await newPage.waitForTimeout(1000); - await newPage.screenshot({ path: "output/v10-" + num + "-" + cap.name + "-FILE.png" }); - } - // PDF: use pdf.js viewer via embed - else if (cap.ext === "pdf") { - const html = ``; - await newPage.setContent(html, { waitUntil: "domcontentloaded" }); - await newPage.waitForTimeout(4000); - await newPage.screenshot({ path: "output/v10-" + num + "-" + cap.name + "-FILE.png" }); - } - // DOCX/PPTX: proof card with metadata + hex preview - else { - const hex = Array.from(buf.slice(0, 32)).map(b => b.toString(16).padStart(2,"0")).join(" "); - const isZip = buf[0] === 0x50 && buf[1] === 0x4B; // PK = ZIP magic = valid Office XML - const html = ` -
-
-
${cap.ext === "docx" ? "W" : "P"}
-

${cap.name} · ${cap.ext.toUpperCase()}

Office Open XML · téléchargé et vérifié
-
-
URL complète
-
HTTP Status
${status} OK
-
Content-Type
${ctype}
-
Taille réelle
${buf.length.toLocaleString()} octets · ${(buf.length/1024).toFixed(1)} KB
-
Magic bytes
${isZip ? "✅ PK (ZIP/OOXML valide)" : "⚠️ pas ZIP"}
-
Hex preview (32 premiers octets) :
${hex}
-
✅ FICHIER RÉEL TÉLÉCHARGÉ · binary sauvegardé localement : output/v10-${num}-${cap.name}.${cap.ext}
-
`; - await newPage.setContent(html); - await newPage.waitForTimeout(1200); - await newPage.screenshot({ path: "output/v10-" + num + "-" + cap.name + "-FILE.png" }); - } - - console.log(" 📸 visual proof: v10-" + num + "-" + cap.name + "-FILE.png"); - await newPage.close(); - - results.push({ name: cap.name, ok: true, url: url, size: buf.length, type: ctype }); - } catch (e) { - console.log(" ⚠️ render err: " + e.message.substring(0, 120)); - try { await newPage.close(); } catch(x){} - results.push({ name: cap.name, ok: false, reason: "render_err" }); - } - - await page.waitForTimeout(1000); - } catch (e) { - console.log(" ❌ err: " + e.message.substring(0, 120)); - results.push({ name: cap.name, ok: false, reason: "exception" }); - } - } - - const pass = results.filter(r => r.ok).length; - console.log("\n═══════════════ V10 BILAN ═══════════════"); - console.log(pass + "/7 VERIFIED with REAL FILE + VISUAL PROOF"); - results.forEach(r => { - const d = r.url ? (r.size + "B · " + r.type) : (r.inline || r.reason); - console.log(" " + (r.ok ? "✅" : "❌") + " " + r.name + " · " + (d || "").substring(0, 140)); - }); - fs.writeFileSync("output/v10-results.json", JSON.stringify(results, null, 2)); -}); diff --git a/api/ambre-pw-tests/tests/claude-pattern-v11.spec.js b/api/ambre-pw-tests/tests/claude-pattern-v11.spec.js new file mode 100644 index 000000000..19f1eea40 --- /dev/null +++ b/api/ambre-pw-tests/tests/claude-pattern-v11.spec.js @@ -0,0 +1,96 @@ +const { test } = require("@playwright/test"); + +test("V11 · Claude Pattern Dashboard · SSE streaming long · full video", async ({ page }) => { + test.setTimeout(600000); + + await page.goto("/wevia-claude-pattern.html"); + await page.waitForLoadState("networkidle"); + await page.waitForTimeout(2500); + await page.screenshot({ path: "output/v11-00-landing.png" }); + console.log("📸 Landing page captured"); + + // Fill query + const query = "Comment WEVIA peut orchestrer une strategie pharma multicanal MENA avec agents autonomes et RAG Qdrant ?"; + await page.locator("input.input").fill(query); + await page.waitForTimeout(500); + await page.screenshot({ path: "output/v11-01-query-filled.png" }); + console.log("📸 Query filled"); + + // Click launch + await page.locator("button.btn").click(); + console.log("🚀 Launched SSE stream"); + + // Capture phases in real-time + const phases = ["thinking", "plan", "rag", "execute", "test", "result", "critique"]; + const captured = {}; + + // Wait for each phase progressively + const startTime = Date.now(); + for (let i = 0; i < 30; i++) { // max 30s × 2s wait + await page.waitForTimeout(2000); + const state = await page.evaluate(() => { + const chips = document.querySelectorAll(".chip-success"); + const doneDots = document.querySelectorAll(".phase-dot.done"); + const h3s = Array.from(document.querySelectorAll("h3")).map(h=>h.innerText); + const result_card = document.querySelector(".card[style*='borderColor']"); + return { + doneDots: doneDots.length, + successChips: chips.length, + headers: h3s, + hasResult: !!result_card, + bodyLen: document.body.innerText.length, + }; + }); + const elapsed = ((Date.now() - startTime) / 1000).toFixed(1); + console.log(` t=${elapsed}s · doneDots=${state.doneDots}/7 · chips=${state.successChips} · bodyLen=${state.bodyLen}`); + + // Capture progressive screenshot + if (i % 3 === 0) { + await page.screenshot({ path: `output/v11-02-progress-${i}.png` }); + } + + if (state.doneDots >= 7 || state.hasResult) { + console.log(` ✅ All 7 phases done at t=${elapsed}s`); + break; + } + } + + // Wait a final moment for critique to render + await page.waitForTimeout(2500); + + // Full page final screenshot + await page.screenshot({ path: "output/v11-03-complete.png", fullPage: true }); + console.log("📸 Complete dashboard captured"); + + // Scroll to top and capture header area + await page.evaluate(() => window.scrollTo(0, 0)); + await page.waitForTimeout(800); + await page.screenshot({ path: "output/v11-04-top.png" }); + + // Capture the critique card specifically + const critiqueCard = page.locator(".card").filter({ hasText: "Self-critique" }); + if (await critiqueCard.count() > 0) { + await critiqueCard.first().scrollIntoViewIfNeeded(); + await page.waitForTimeout(800); + await page.screenshot({ path: "output/v11-05-critique.png" }); + console.log("📸 Critique card captured"); + } + + // Final metrics + const metrics = await page.evaluate(() => ({ + phases_done: document.querySelectorAll(".phase-dot.done").length, + total_chips: document.querySelectorAll(".chip-success").length, + result_text: (document.querySelector(".card[style*='rgba(16,185,129']") || {}).innerText || "", + confidence: (() => { + const t = Array.from(document.querySelectorAll(".text-3xl")).find(e => e.innerText.includes("%")); + return t ? t.innerText : null; + })(), + })); + + console.log("\n═══════════════ V11 BILAN ═══════════════"); + console.log(`✅ ${metrics.phases_done}/7 phases streamées via SSE`); + console.log(`✅ ${metrics.total_chips} badges success`); + console.log(`✅ Confidence: ${metrics.confidence}`); + console.log(`✅ Result length: ${metrics.result_text.length} chars`); + console.log(`Result preview: ${metrics.result_text.substring(0, 200)}`); +}); diff --git a/api/ambre-pw-v11-deploy.php b/api/ambre-pw-v11-deploy.php new file mode 100644 index 000000000..413c496ee --- /dev/null +++ b/api/ambre-pw-v11-deploy.php @@ -0,0 +1,7 @@ +$written, "specs"=>array_map("basename", glob("$base/*.spec.js"))]); diff --git a/api/ambre-pw-v11-files.php b/api/ambre-pw-v11-files.php new file mode 100644 index 000000000..e20da3556 --- /dev/null +++ b/api/ambre-pw-v11-files.php @@ -0,0 +1,23 @@ +[], "v11_video"=>null]; + +foreach (glob("$base/v11-*.png") as $p) { + $out["v11_screenshots"][] = [ + "name" => basename($p), + "size_kb" => round(filesize($p)/1024, 1), + "url" => "https://weval-consulting.com/api/ambre-pw-tests/output/" . basename($p), + ]; +} +usort($out["v11_screenshots"], function($a,$b){return strcmp($a["name"], $b["name"]);}); + +foreach (glob("$base/capabilities-v11-*/*.webm") as $w) { + $rel = str_replace($base . "/", "", $w); + $out["v11_video"] = [ + "size_mb" => round(filesize($w)/1048576, 2), + "url" => "https://weval-consulting.com/api/ambre-pw-tests/output/" . $rel, + ]; +} + +echo json_encode($out, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES); diff --git a/api/blade-actions-surfaced.json b/api/blade-actions-surfaced.json index 1e2fa22fb..605660fd5 100644 --- a/api/blade-actions-surfaced.json +++ b/api/blade-actions-surfaced.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-04-21T23:15:01.726624", + "generated_at": "2026-04-21T23:25:01.227270", "stats": { "total": 48, "pending": 31, diff --git a/api/mql-scoring-status.json b/api/mql-scoring-status.json index 84892d7cf..d3a76f156 100644 --- a/api/mql-scoring-status.json +++ b/api/mql-scoring-status.json @@ -1,27 +1,27 @@ { "ok": true, "agent": "V42_MQL_Scoring_Agent_REAL", - "ts": "2026-04-21T21:10:01+00:00", + "ts": "2026-04-21T21:20:02+00:00", "status": "DEPLOYED_AUTO", "deployed": true, "algorithm": "weighted_behavioral_signals", "signals_tracked": { - "wtp_engagement": 74, + "wtp_engagement": 70, "chat_engagement": 0, "roi_tool": 0, "email_opened": 0 }, - "avg_score": 18.5, + "avg_score": 17.5, "mql_threshold": 50, "sql_threshold": 75, "leads_captured": 48, "mql_auto_scored": 19, "sql_auto_scored": 8, - "mql_auto_pct": 40, + "mql_auto_pct": 39, "improvement_vs_manual": { "before_manual_pct": 33.3, - "after_auto_pct": 40, - "delta": 6.700000000000003 + "after_auto_pct": 39, + "delta": 5.700000000000003 }, "paperclip_db_ok": true, "paperclip_tables": 1, diff --git a/api/v83-business-kpi-latest.json b/api/v83-business-kpi-latest.json index a63632683..3eeb52469 100644 --- a/api/v83-business-kpi-latest.json +++ b/api/v83-business-kpi-latest.json @@ -1,12 +1,12 @@ { "ok": true, "version": "V83-business-kpi", - "ts": "2026-04-21T21:18:41+00:00", + "ts": "2026-04-21T21:24:42+00:00", "summary": { "total_categories": 8, "total_kpis": 64, - "ok": 47, - "warn": 14, + "ok": 46, + "warn": 15, "fail": 0, "wire_needed": 3, "data_completeness_pct": 95.3 diff --git a/dashboards-index.html b/dashboards-index.html index 657de2dc3..a9d707719 100644 --- a/dashboards-index.html +++ b/dashboards-index.html @@ -246,4 +246,5 @@ fetch('/api/token-rotate-orchestrator.php', {method:'POST', headers:{'Content-Ty + diff --git a/generated/wevia-stream-test-20260421-212028-577a6b.md b/generated/wevia-stream-test-20260421-212028-577a6b.md new file mode 100644 index 000000000..e5c913548 --- /dev/null +++ b/generated/wevia-stream-test-20260421-212028-577a6b.md @@ -0,0 +1,120 @@ +# stream test + +# **Stream Test : Guide Complet** +===================================== + +## **Table des Matières** +--------------------------- + +1. [Introduction au Stream Test](#introduction-au-stream-test) +2. [Objectifs d'un Stream Test](#objectifs-dun-stream-test) +3. [Étapes pour Réaliser un Stream Test](#étapes-pour-réaliser-un-stream-test) +4. [Outils et Technologies Utilisés](#outils-et-technologies-utilisés) +5. [Exemples et Cas Pratiques](#exemples-et-cas-pratiques) +6. [Conclusion](#conclusion) + +--- + +## **Introduction au Stream Test** +------------------------------------ + +### **Définition** + +Un Stream Test est un processus de vérification et de validation de la qualité, de la stabilité et de la performance d'un flux de données en continu (streaming), qu'il s'agisse de vidéos, d'audio, de données sensibles ou de tout autre type de contenu transmis en temps réel. + +### **Importance** + +- **Expérience Utilisateur** : Assure une expérience fluide et de haute qualité. +- **Réputation** : Préventive des pannes et des retards. +- **Sécurité** : Détecte les failles de sécurité potentielles. + +--- + +## **Objectifs d'un Stream Test** +--------------------------------- + +- **Vérifier la Qualité du Signal** + - Résolution + - Taux de Cadres + - Ratio de Bit +- **Évaluer la Stabilité du Flux** + - Temps de Chargement + - Interruptions + - Erreurs de Décodeur +- **Tester la Sécurité** + - Authentification + - Autorisation + - Encryption + +--- + +## **Étapes pour Réaliser un Stream Test** +------------------------------------------ + +### **1. Planification** + +- **Définir les Critères de Succès** +- **Sélection des Outils de Test** +- **Identification des Scénarios de Test** + +### **2. Configuration du Test** + +- **Mise en Place de l'Infrastructure de Test** +- **Configuration des Outils de Capture et de Mesure** + +### **3. Exécution du Test** + +- **Lancement du Stream** +- **Collecte des Données** +- **Observation en Temps Réel** + +### **4. Analyse des Résultats** + +- **Évaluation contre les Critères** +- **Identification des Problèmes** +- **Ré Reporting Détallé** + +### **5. Réparation et Réitération** + +- **Correction des Défauts** +- **Réexécution du Test** + +--- + +## **Outils et Technologies Utilisés** +-------------------------------------- + +- **Outils de Streaming** : OBS Studio, XSplit +- **Analyseurs de Flux** : Wireshark, VLC avec extensions +- **Systèmes de Test Automatisé** : Selenium (pour les interfaces web), Custom Scripts (pour les flux spécifiques) +- **Plates-formes de Monitoring** : Prometheus, Grafana + +--- + +## **Exemples et Cas Pratiques** +------------------------------- + +### **Cas 1 : Stream Video pour un Événement en Direct** + +- **Problème Encountéré** : Latence Élevée +- **Solution** : Optimisation de la Compression Vidéo, Utilisation d'un CDN + +### **Cas 2 : Stream de Données pour l'Analytique en Temps Réel** + +- **Problème** : Perte de Données +- **Solution** : Implementation d'un Mécanisme de Réplication des Données + +--- + +## **Conclusion** +---------------- + +Un Stream Test bien planifié et exécuté est crucial pour garantir l'excellence de votre service de streaming. En comprenant les objectifs, en suivant les étapes appropriées et en utilisant les outils adéquats, vous pouvez vous assurer que votre flux de données en continu répond aux attentes de vos utilisateurs en termes de qualité, de stabilité et de sécurité. + +--- + +**Annexe : Références et Ressources Supplémentaires** + +- **Documentation Technique des Outils Utilisés** +- **Études de Cas Approfondies** +- **Bases de Données de Better Practices pour le Streaming** \ No newline at end of file diff --git a/generated/wevia-stream-test-20260421-212028-577a6b.pdf b/generated/wevia-stream-test-20260421-212028-577a6b.pdf new file mode 100644 index 000000000..d1ef96218 Binary files /dev/null and b/generated/wevia-stream-test-20260421-212028-577a6b.pdf differ diff --git a/token-health-dashboard.html b/token-health-dashboard.html index 6f429451b..251b35d43 100644 --- a/token-health-dashboard.html +++ b/token-health-dashboard.html @@ -146,4 +146,5 @@ fetch('/api/wevia-autonomy-status.json', {cache:'no-store'}) }); + diff --git a/wevia-claude-pattern.html b/wevia-claude-pattern.html new file mode 100644 index 000000000..b0c03633a --- /dev/null +++ b/wevia-claude-pattern.html @@ -0,0 +1,427 @@ + + + + +WEVIA · Claude Pattern Dashboard + + + + + + + + +
+ + + diff --git a/wevia.html b/wevia.html index 89c130e9e..2b2eff87a 100644 --- a/wevia.html +++ b/wevia.html @@ -569,6 +569,9 @@ .dark .wv-sc:hover { border-color:#4b5563; background:#252f3e; } /* AMBRE-V2 end */ + +/* AMBRE spinner */ +@keyframes spin { to { transform: rotate(360deg); } } @@ -1268,6 +1271,164 @@ function send() { } payload.mode = effectiveMode; + // === AMBRE-V5-CLAUDE-PATTERN 2026-04-22 · True Claude streaming experience === + // Thinking (chain of thought animated) -> Plan -> RAG -> Execute -> Result (chunks streamed) + if (_ambre_gen_pat.test(text)) { + hideThinking(); // we'll show our own rich thinking UI + + // Create custom stream message container BELOW the user message + var streamEl = addMsg('assistant', '', '0'); + var streamInner = streamEl.querySelector('.msg-inner') || streamEl; + streamInner.innerHTML = '
'; + var container = streamInner.querySelector('.ambre-stream-container'); + + var phaseLabels = {thinking: '💭 Pensée', plan: '📋 Plan', rag: '🔍 RAG', execute: '⚙️ Exécution', result: '✅ Résultat'}; + var phaseColors = {thinking:'#a78bfa', plan:'#60a5fa', rag:'#34d399', execute:'#fbbf24', result:'#10b981'}; + var currentPhase = null; + var currentPhaseEl = null; + var currentChunkEl = null; + var fullResponse = ''; + var finalFileUrl = null; + + var startTime = performance.now(); + + var eventSource = new EventSource('/api/ambre-claude-stream.php?ts=' + Date.now()); + // EventSource is GET-only, so we use fetch() with ReadableStream for POST SSE + if (eventSource) try { eventSource.close(); } catch(e){} + + fetch('/api/ambre-claude-stream.php', { + method: 'POST', + headers: {'Content-Type':'application/json','Accept':'text/event-stream'}, + body: JSON.stringify({message: text, session_id: convId || ('wv-'+Date.now())}) + }) + .then(function(response) { + if (!response.ok) throw new Error('HTTP ' + response.status); + var reader = response.body.getReader(); + var decoder = new TextDecoder(); + var buffer = ''; + + function processBuffer() { + var parts = buffer.split('\n\n'); + buffer = parts.pop() || ''; + parts.forEach(function(block) { + if (!block.trim()) return; + var eventMatch = block.match(/^event:\s*(\S+)/m); + var dataMatch = block.match(/^data:\s*(.+)$/m); + if (!eventMatch || !dataMatch) return; + var evType = eventMatch[1]; + var data; + try { data = JSON.parse(dataMatch[1]); } catch(e) { return; } + handleEvent(evType, data); + }); + } + + function handleEvent(type, data) { + if (type === 'start') { + var header = '
'; + header += 'WEVIA Claude-pattern · pattern: ' + data.pattern + '
'; + container.innerHTML = header; + } + else if (type === 'phase') { + currentPhase = data.phase; + var color = phaseColors[data.phase] || '#888'; + var phaseBlock = document.createElement('div'); + phaseBlock.className = 'ambre-phase ambre-phase-' + data.phase; + phaseBlock.style.cssText = 'margin:10px 0;padding:12px;border-left:3px solid '+color+';background:rgba(0,0,0,0.03);border-radius:6px'; + phaseBlock.innerHTML = '
'+(phaseLabels[data.phase]||data.phase)+' · étape '+data.step+'/'+data.total+'
'; + container.appendChild(phaseBlock); + currentPhaseEl = phaseBlock.querySelector('.phase-content'); + } + else if (type === 'thinking_step' && currentPhaseEl) { + var step = document.createElement('div'); + step.style.cssText = 'padding:4px 0;opacity:0;transition:opacity 0.3s'; + step.innerHTML = ''+data.index+'. ' + data.content; + currentPhaseEl.appendChild(step); + setTimeout(function(){ step.style.opacity='1'; }, 10); + } + else if (type === 'plan_steps' && currentPhaseEl) { + var table = ''; + data.steps.forEach(function(s, i) { + table += ''; + }); + table += '
#ActionDescriptionEstimé
'+(i+1)+''+s.action+''+s.desc+''+s.est_ms+'ms
'; + currentPhaseEl.innerHTML = table; + } + else if (type === 'rag_hit' && currentPhaseEl) { + var hit = document.createElement('div'); + hit.style.cssText = 'padding:6px 8px;margin:4px 0;background:rgba(52,211,153,0.08);border-radius:4px;font-size:12px;display:flex;justify-content:space-between;gap:12px'; + hit.innerHTML = '' + data.text + ''+data.collection+' · '+data.score.toFixed(2)+''; + currentPhaseEl.appendChild(hit); + } + else if (type === 'exec_start' && currentPhaseEl) { + var row = document.createElement('div'); + row.id = 'exec-' + data.index; + row.style.cssText = 'padding:6px 0;font-size:12px;display:flex;align-items:center;gap:10px'; + row.innerHTML = ''+data.action+''+data.desc+''; + currentPhaseEl.appendChild(row); + } + else if (type === 'exec_done') { + var row = document.getElementById('exec-' + data.index); + if (row) { + var spin = row.querySelector('.spinner'); + if (spin) spin.outerHTML = ''; + var el = row.querySelector('.elapsed'); + if (el) el.textContent = data.elapsed_ms + 'ms'; + } + } + else if (type === 'chunk' && currentPhaseEl) { + if (!currentChunkEl) { + currentChunkEl = document.createElement('div'); + currentChunkEl.className = 'result-chunks'; + currentChunkEl.style.cssText = 'padding:10px;background:#fff;border:1px solid #e5e7eb;border-radius:6px;margin-top:8px;white-space:pre-wrap;font-size:13px'; + currentPhaseEl.appendChild(currentChunkEl); + } + fullResponse += data.content; + currentChunkEl.textContent = fullResponse; + var msgs = document.getElementById('messages'); + if (msgs) msgs.scrollTop = msgs.scrollHeight; + } + else if (type === 'done') { + finalFileUrl = data.file_url; + // Format final response with link if present + if (currentChunkEl && finalFileUrl) { + var linkHtml = fullResponse.replace(new RegExp(finalFileUrl, 'g'), ''+finalFileUrl+''); + currentChunkEl.innerHTML = linkHtml; + } + var elapsed = ((performance.now() - startTime) / 1000).toFixed(1); + var footer = document.createElement('div'); + footer.style.cssText = 'margin-top:12px;padding-top:10px;border-top:1px solid #eee;display:flex;gap:8px;flex-wrap:wrap;font-size:11px;color:#999'; + footer.innerHTML = '⚡ '+elapsed+'sprovider: '+data.provider+'intent: '+data.intent+''; + container.appendChild(footer); + + 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){} + } + } + + function read() { + return reader.read().then(function(res) { + if (res.done) { processBuffer(); return; } + buffer += decoder.decode(res.value, {stream:true}); + processBuffer(); + return read(); + }); + } + return read(); + }) + .catch(function(err) { + console.error('[AMBRE-V5] stream error', err); + container.innerHTML += '
Erreur stream: '+err.message+'
'; + 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=''; } catch(e){} + }); + + return; + } + + // ===== END AMBRE-V5-CLAUDE-PATTERN ===== + // === AMBRE-V2-GEN-ROUTER 2026-04-21 · intercept file generation patterns === // Doctrine: route gen/code/translate patterns → wevia-master-api.php (real handler) // other queries continue to sovereign. No regression, pure additive.