Compare commits
4 Commits
wave-265-o
...
v169-opus-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98d99bfe4d | ||
|
|
3a24dc48f9 | ||
|
|
5dd0b5f015 | ||
|
|
835e1f316b |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"agent": "V45_Leads_Sync",
|
||||
"ts": "2026-04-22T11:00:04+02:00",
|
||||
"ts": "2026-04-22T11:10:03+02:00",
|
||||
"paperclip_total": 48,
|
||||
"active_customer": 4,
|
||||
"warm_prospect": 5,
|
||||
|
||||
72
api/ambre-mermaid-wire.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
header("Content-Type: application/json");
|
||||
$path = "/var/www/html/wevia.html";
|
||||
$c = @file_get_contents($path);
|
||||
$orig = strlen($c);
|
||||
|
||||
// Find the done handler and augment it with mermaid rendering
|
||||
// The anchor: 'else if (type === \'done\') {' to its closing brace
|
||||
$anchor = "else if (type === 'done') {
|
||||
finalFileUrl = data.file_url;";
|
||||
|
||||
if (strpos($c, $anchor) === false) {
|
||||
echo json_encode(["error"=>"done handler anchor not found"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Replace with enhanced version that renders mermaid when detected
|
||||
$new = "else if (type === 'done') {
|
||||
finalFileUrl = data.file_url;
|
||||
// === AMBRE-V5-MERMAID-RENDER wave-263 ===
|
||||
// If fullResponse contains mermaid code → render SVG inline
|
||||
try {
|
||||
var _mcode = null;
|
||||
if (data.mermaid_code) _mcode = data.mermaid_code;
|
||||
else if (fullResponse) {
|
||||
// Detect mermaid patterns at start of response
|
||||
var _fr = fullResponse.trim();
|
||||
if (/^(sequenceDiagram|flowchart|graph\s+[A-Z]{1,2}|classDiagram|stateDiagram|erDiagram|gantt|pie|journey|gitGraph|mindmap|timeline)\b/.test(_fr)) {
|
||||
_mcode = _fr;
|
||||
} else {
|
||||
// Search inside for ``` mermaid block
|
||||
var _m = fullResponse.match(/```mermaid\\s*([\\s\\S]+?)```/);
|
||||
if (_m) _mcode = _m[1].trim();
|
||||
else {
|
||||
// or raw mermaid after 'Schema Mermaid:' label
|
||||
var _m2 = fullResponse.match(/(?:Schema Mermaid|Diagramme)[^\\n]*\\n([\\s\\S]+)$/i);
|
||||
if (_m2 && /^(sequenceDiagram|flowchart|graph|classDiagram|stateDiagram)/.test(_m2[1].trim())) _mcode = _m2[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_mcode && window.mermaid && currentPhaseEl) {
|
||||
// Sanitize accents for mermaid parser
|
||||
var _clean = _mcode.normalize ? _mcode.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '') : _mcode;
|
||||
var _svgId = 'wv-mermaid-' + Date.now() + '-' + Math.floor(Math.random()*999);
|
||||
var _mContainer = document.createElement('div');
|
||||
_mContainer.id = _svgId + '-wrap';
|
||||
_mContainer.style.cssText = 'margin-top:12px;padding:16px;background:#fafafa;border:1px solid #e5e7eb;border-radius:8px;overflow-x:auto';
|
||||
currentPhaseEl.appendChild(_mContainer);
|
||||
try {
|
||||
window.mermaid.render(_svgId, _clean).then(function(r){
|
||||
_mContainer.innerHTML = r.svg;
|
||||
}).catch(function(err){
|
||||
_mContainer.innerHTML = '<pre style=\"color:#b91c1c;font-size:11px\">Mermaid render error: ' + (err.message||err) + '\\n\\n' + _clean.replace(/</g,'<') + '</pre>';
|
||||
});
|
||||
} catch(e) {
|
||||
_mContainer.innerHTML = '<pre style=\"font-size:11px\">' + _clean.replace(/</g,'<') + '</pre>';
|
||||
}
|
||||
}
|
||||
} catch(eMermaid) { console.warn('[V5-MERMAID-RENDER]', eMermaid); }
|
||||
// === END AMBRE-V5-MERMAID-RENDER ===";
|
||||
|
||||
$c = str_replace($anchor, $new, $c);
|
||||
|
||||
$backup = "/opt/wevads/vault/wevia.html.GOLD-" . date("Ymd-His") . "-wave263-mermaid";
|
||||
@copy($path, $backup);
|
||||
$wrote = @file_put_contents($path, $c);
|
||||
|
||||
echo json_encode([
|
||||
"delta" => strlen($c) - $orig,
|
||||
"wrote" => $wrote,
|
||||
"backup" => basename($backup),
|
||||
]);
|
||||
@@ -59,18 +59,18 @@
|
||||
},
|
||||
"suites": [
|
||||
{
|
||||
"title": "v53-final.spec.js",
|
||||
"file": "v53-final.spec.js",
|
||||
"title": "v55-scroll.spec.js",
|
||||
"file": "v55-scroll.spec.js",
|
||||
"column": 0,
|
||||
"line": 0,
|
||||
"specs": [
|
||||
{
|
||||
"title": "V53 · Final proof widget clean (no Claude Pattern panel)",
|
||||
"title": "V55 · scroll to see mermaid SVG",
|
||||
"ok": true,
|
||||
"tags": [],
|
||||
"tests": [
|
||||
{
|
||||
"timeout": 60000,
|
||||
"timeout": 90000,
|
||||
"annotations": [],
|
||||
"expectedStatus": "passed",
|
||||
"projectId": "chromium",
|
||||
@@ -80,30 +80,27 @@
|
||||
"workerIndex": 0,
|
||||
"parallelIndex": 0,
|
||||
"status": "passed",
|
||||
"duration": 5678,
|
||||
"duration": 15641,
|
||||
"errors": [],
|
||||
"stdout": [
|
||||
{
|
||||
"text": "{\n \"visible_claude_pattern_text\": false,\n \"opus_pattern_badge\": false,\n \"opus_pattern_modal\": false,\n \"opus_pattern_box\": false,\n \"seven_phases_visible\": false,\n \"sse_live_visible\": false,\n \"lancer_visible\": false,\n \"shield_loaded\": true,\n \"opusPatternOpen_neutralized\": true\n}\n"
|
||||
},
|
||||
{
|
||||
"text": "After __opusPatternOpen call: NO_MODAL\n"
|
||||
"text": "SVG rendered: {\n \"svg_visible\": true,\n \"svg_width\": 190.8125,\n \"svg_height\": 879,\n \"svg_html_size\": 16978,\n \"wrapper_id\": \"wv-mermaid-1776848871993-216-wrap\"\n}\n"
|
||||
}
|
||||
],
|
||||
"stderr": [],
|
||||
"retry": 0,
|
||||
"startTime": "2026-04-22T08:52:02.487Z",
|
||||
"startTime": "2026-04-22T09:07:39.425Z",
|
||||
"annotations": [],
|
||||
"attachments": [
|
||||
{
|
||||
"name": "screenshot",
|
||||
"contentType": "image/png",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v53-final-V53-·-Final-proo-30656-an-no-Claude-Pattern-panel--chromium/test-finished-1.png"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v55-scroll-V55-·-scroll-to-see-mermaid-SVG-chromium/test-finished-1.png"
|
||||
},
|
||||
{
|
||||
"name": "video",
|
||||
"contentType": "video/webm",
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v53-final-V53-·-Final-proo-30656-an-no-Claude-Pattern-panel--chromium/video.webm"
|
||||
"path": "/var/www/html/api/ambre-pw-tests/output/v55-scroll-V55-·-scroll-to-see-mermaid-SVG-chromium/video.webm"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -111,8 +108,8 @@
|
||||
"status": "expected"
|
||||
}
|
||||
],
|
||||
"id": "a68cb5b10367b04264f0-176af6e8656af5fdd5ea",
|
||||
"file": "v53-final.spec.js",
|
||||
"id": "a80a3706a9346f0b6665-b8967c5b4350315cdbe0",
|
||||
"file": "v55-scroll.spec.js",
|
||||
"line": 3,
|
||||
"column": 1
|
||||
}
|
||||
@@ -121,8 +118,8 @@
|
||||
],
|
||||
"errors": [],
|
||||
"stats": {
|
||||
"startTime": "2026-04-22T08:52:01.850Z",
|
||||
"duration": 6481.4439999999995,
|
||||
"startTime": "2026-04-22T09:07:38.817Z",
|
||||
"duration": 16424.367,
|
||||
"expected": 1,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 64 KiB |
BIN
api/ambre-pw-tests/output/v55-full.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 87 KiB |
BIN
api/ambre-pw-tests/output/v55-scrolled.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
@@ -1,38 +0,0 @@
|
||||
const { test } = require("@playwright/test");
|
||||
|
||||
test("V53 · Final proof widget clean (no Claude Pattern panel)", async ({ page }) => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
await page.goto("/wevia-widget.html?cb=" + Date.now());
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(4000);
|
||||
|
||||
const state = await page.evaluate(() => {
|
||||
const bodyText = document.body.innerText;
|
||||
return {
|
||||
visible_claude_pattern_text: /Claude\s*Pattern/i.test(bodyText),
|
||||
opus_pattern_badge: !!document.getElementById('opus-pattern-badge') && document.getElementById('opus-pattern-badge').offsetParent !== null,
|
||||
opus_pattern_modal: !!document.getElementById('opus-pattern-modal') && document.getElementById('opus-pattern-modal').offsetParent !== null,
|
||||
opus_pattern_box: !!document.getElementById('opus-pattern-box') && document.getElementById('opus-pattern-box').offsetParent !== null,
|
||||
seven_phases_visible: /7 phases REAL/i.test(bodyText),
|
||||
sse_live_visible: /SSE live/i.test(bodyText),
|
||||
lancer_visible: /Lancer \(SSE/i.test(bodyText),
|
||||
shield_loaded: !!document.getElementById('ambre-confidential-shield'),
|
||||
opusPatternOpen_neutralized: (typeof window.__opusPatternOpen === 'function') && window.__opusPatternOpen.toString().length < 30,
|
||||
};
|
||||
});
|
||||
console.log(JSON.stringify(state, null, 2));
|
||||
|
||||
await page.screenshot({ path: "output/v53-final-widget.png", fullPage: false });
|
||||
|
||||
// Try call __opusPatternOpen to see if neutralized
|
||||
const openResult = await page.evaluate(() => {
|
||||
try {
|
||||
window.__opusPatternOpen();
|
||||
const modal = document.getElementById('opus-pattern-modal');
|
||||
return modal ? (modal.offsetParent !== null ? "OPENED_VISIBLE" : "HIDDEN") : "NO_MODAL";
|
||||
} catch(e) { return "ERROR: " + e.message; }
|
||||
});
|
||||
console.log("After __opusPatternOpen call:", openResult);
|
||||
await page.screenshot({ path: "output/v53-after-open-attempt.png" });
|
||||
});
|
||||
47
api/ambre-pw-tests/tests/v55-scroll.spec.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const { test } = require("@playwright/test");
|
||||
|
||||
test("V55 · scroll to see mermaid SVG", async ({ page }) => {
|
||||
test.setTimeout(90000);
|
||||
|
||||
await page.goto("/wevia.html?cb=" + Date.now());
|
||||
await page.evaluate(() => { try{sessionStorage.clear();}catch(e){} });
|
||||
await page.waitForLoadState("networkidle");
|
||||
await page.waitForTimeout(3500);
|
||||
|
||||
const input = page.locator("#msgInput");
|
||||
await input.click({force:true});
|
||||
await input.fill("Genere un schema mermaid pour: architecture WEVIA souveraine");
|
||||
await page.waitForTimeout(400);
|
||||
await input.press("Enter");
|
||||
|
||||
// Wait for completion
|
||||
const ws = Date.now();
|
||||
while (Date.now() - ws < 60000) {
|
||||
const busy = await page.evaluate(() => window.busy || document.getElementById('sendBtn')?.disabled);
|
||||
const svgs = await page.locator('[id^="wv-mermaid-"] svg, .phase-content svg').count();
|
||||
if (!busy && svgs > 0) break;
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Scroll to the SVG
|
||||
const scrolled = await page.evaluate(() => {
|
||||
const svg = document.querySelector('[id^="wv-mermaid-"] svg, .phase-content svg');
|
||||
if (svg) {
|
||||
svg.scrollIntoView({block:'center', behavior:'instant'});
|
||||
return {
|
||||
svg_visible: svg.getBoundingClientRect().width > 10,
|
||||
svg_width: svg.getBoundingClientRect().width,
|
||||
svg_height: svg.getBoundingClientRect().height,
|
||||
svg_html_size: svg.outerHTML.length,
|
||||
wrapper_id: svg.parentElement?.id,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
});
|
||||
console.log("SVG rendered:", JSON.stringify(scrolled, null, 2));
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: "output/v55-scrolled.png", fullPage: false });
|
||||
await page.screenshot({ path: "output/v55-full.png", fullPage: true });
|
||||
});
|
||||
7
api/ambre-pw-v54.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("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTQgwrcgTWVybWFpZCBTVkcgcmVuZGVyIGluIHBoYXNlIDUvNSIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCg5MDAwMCk7CiAgY29uc3QgbG9ncyA9IFtdOwogIHBhZ2Uub24oImNvbnNvbGUiLCBtID0+IGxvZ3MucHVzaChtLnRleHQoKS5zdWJzdHJpbmcoMCwgMjAwKSkpOwogIAogIGF3YWl0IHBhZ2UuZ290bygiL3dldmlhLmh0bWw/Y2I9IiArIERhdGUubm93KCkpOwogIGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4geyB0cnl7c2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTt9Y2F0Y2goZSl7fSB9KTsKICBhd2FpdCBwYWdlLndhaXRGb3JMb2FkU3RhdGUoIm5ldHdvcmtpZGxlIik7CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgzNTAwKTsKICAKICBjb25zdCBpbnB1dCA9IHBhZ2UubG9jYXRvcigiI21zZ0lucHV0Iik7CiAgYXdhaXQgaW5wdXQuY2xpY2soe2ZvcmNlOnRydWV9KTsKICBhd2FpdCBpbnB1dC5maWxsKCJHZW5lcmUgdW4gc2NoZW1hIG1lcm1haWQgcG91cjogd2V2aWEiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDQwMCk7CiAgYXdhaXQgaW5wdXQucHJlc3MoIkVudGVyIik7CiAgY29uc29sZS5sb2coIlNlbnQgbWVybWFpZCByZXF1ZXN0Iik7CiAgCiAgLy8gV2FpdCBmb3IgY29tcGxldGlvbgogIGNvbnN0IHdzID0gRGF0ZS5ub3coKTsKICBsZXQgcmVuZGVyZWQgPSBmYWxzZTsKICB3aGlsZSAoRGF0ZS5ub3coKSAtIHdzIDwgNjAwMDApIHsKICAgIGNvbnN0IHN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICAgIC8vIExvb2sgZm9yIGEgcmVuZGVyZWQgU1ZHIGluIGFueSBhbWJyZS1waGFzZS1yZXN1bHQgb3IgcmVzdWx0IGJsb2NrCiAgICAgIGNvbnN0IHN2Z3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuYW1icmUtcGhhc2UtcmVzdWx0IHN2ZywgLnBoYXNlLWNvbnRlbnQgc3ZnLCBbaWRePSJ3di1tZXJtYWlkLSJdIHN2ZycpOwogICAgICBjb25zdCBoYXNTdmcgPSBzdmdzLmxlbmd0aCA+IDA7CiAgICAgIC8vIENoZWNrIFdFVklBLXBhdHRlcm4gdnMgQ2xhdWRlLXBhdHRlcm4gaW4gcmVuZGVyZWQgSFRNTAogICAgICBjb25zdCBodG1sID0gZG9jdW1lbnQuYm9keS5pbm5lckhUTUw7CiAgICAgIHJldHVybiB7CiAgICAgICAgcGhhc2VfY291bnQ6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbWJyZS1waGFzZScpLmxlbmd0aCwKICAgICAgICBzdmdfY291bnQ6IHN2Z3MubGVuZ3RoLAogICAgICAgIGhhc193ZXZpYV9wYXR0ZXJuOiAvV0VWSUFbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICAgIGhhc19jbGF1ZGVfcGF0dGVybjogL0NsYXVkZVstIF0/cGF0dGVybi9pLnRlc3QoaHRtbCksCiAgICAgICAgYnVzeTogISF3aW5kb3cuYnVzeSB8fCAhIWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzZW5kQnRuJyk/LmRpc2FibGVkLAogICAgICB9OwogICAgfSk7CiAgICBpZiAoc3RhdGUuc3ZnX2NvdW50ID4gMCAmJiAhc3RhdGUuYnVzeSkgeyByZW5kZXJlZCA9IHRydWU7IGNvbnNvbGUubG9nKGBTVkcgcmVuZGVyZWQhIHN0YXRlPSR7SlNPTi5zdHJpbmdpZnkoc3RhdGUpfWApOyBicmVhazsgfQogICAgaWYgKCFzdGF0ZS5idXN5ICYmIHN0YXRlLnBoYXNlX2NvdW50ID49IDUpIHsKICAgICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICAgICAgY29uc3QgczIgPSBhd2FpdCBwYWdlLmV2YWx1YXRlKCgpID0+IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5hbWJyZS1waGFzZS1yZXN1bHQgc3ZnLCAucGhhc2UtY29udGVudCBzdmcsIFtpZF49Ind2LW1lcm1haWQtIl0gc3ZnJykubGVuZ3RoKTsKICAgICAgY29uc29sZS5sb2coYEFmdGVyIHdhaXQ6ICR7czJ9IFNWR3MsIGJ1c3k9JHtzdGF0ZS5idXN5fWApOwogICAgICBpZiAoczIgPiAwKSByZW5kZXJlZCA9IHRydWU7CiAgICAgIGJyZWFrOwogICAgfQogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyNTAwKTsKICB9CiAgCiAgY29uc3QgZWxhcHNlZCA9ICgoRGF0ZS5ub3coKS13cykvMTAwMCkudG9GaXhlZCgxKTsKICBjb25zdCBmaW5hbFN0YXRlID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICBjb25zdCBodG1sID0gZG9jdW1lbnQuYm9keS5pbm5lckhUTUw7CiAgICBjb25zdCBzdmdzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmFtYnJlLXBoYXNlLXJlc3VsdCBzdmcsIC5waGFzZS1jb250ZW50IHN2ZywgW2lkXj0id3YtbWVybWFpZC0iXSBzdmcnKTsKICAgIHJldHVybiB7CiAgICAgIHN2Z192aXNpYmxlOiBBcnJheS5mcm9tKHN2Z3MpLmZpbHRlcihzID0+IHMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggPiAxMCkubGVuZ3RoLAogICAgICBzdmdfaHRtbF9sZW46IHN2Z3MubGVuZ3RoID4gMCA/IHN2Z3NbMF0ub3V0ZXJIVE1MLmxlbmd0aCA6IDAsCiAgICAgIGhhc193ZXZpYV9wYXR0ZXJuOiAvV0VWSUFbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICBoYXNfY2xhdWRlX3BhdHRlcm46IC9DbGF1ZGVbLSBdP3BhdHRlcm4vaS50ZXN0KGh0bWwpLAogICAgICBoYXNfbWVybWFpZF9jb2RlX3JhdzogL3NlcXVlbmNlRGlhZ3JhbXxmbG93Y2hhcnR8Z3JhcGhccytbQS1aXS9pLnRlc3QoaHRtbCksCiAgICB9OwogIH0pOwogIGNvbnNvbGUubG9nKGBcbuKVkOKVkOKVkCBGSU5BTCBpbiAke2VsYXBzZWR9cyDCtyByZW5kZXJlZD0ke3JlbmRlcmVkfSDilZDilZDilZBgKTsKICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmaW5hbFN0YXRlLCBudWxsLCAyKSk7CiAgCiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NTQtbWVybWFpZC1maW5hbC5wbmciLCBmdWxsUGFnZTogdHJ1ZSB9KTsKICAKICAvLyBBbHNvIGNoZWNrIHJlbGV2YW50IGxvZ3MKICBsb2dzLmZpbHRlcihsID0+IC9tZXJtYWlkfE1FUk1BSUR8cmVuZGVyfFY1L2kudGVzdChsKSkuZm9yRWFjaChsID0+IGNvbnNvbGUubG9nKCJMT0c6IiwgbCkpOwp9KTsK");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v54-mermaid.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
7
api/ambre-pw-v55.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("Y29uc3QgeyB0ZXN0IH0gPSByZXF1aXJlKCJAcGxheXdyaWdodC90ZXN0Iik7Cgp0ZXN0KCJWNTUgwrcgc2Nyb2xsIHRvIHNlZSBtZXJtYWlkIFNWRyIsIGFzeW5jICh7IHBhZ2UgfSkgPT4gewogIHRlc3Quc2V0VGltZW91dCg5MDAwMCk7CiAgCiAgYXdhaXQgcGFnZS5nb3RvKCIvd2V2aWEuaHRtbD9jYj0iICsgRGF0ZS5ub3coKSk7CiAgYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7IHRyeXtzZXNzaW9uU3RvcmFnZS5jbGVhcigpO31jYXRjaChlKXt9IH0pOwogIGF3YWl0IHBhZ2Uud2FpdEZvckxvYWRTdGF0ZSgibmV0d29ya2lkbGUiKTsKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDM1MDApOwogIAogIGNvbnN0IGlucHV0ID0gcGFnZS5sb2NhdG9yKCIjbXNnSW5wdXQiKTsKICBhd2FpdCBpbnB1dC5jbGljayh7Zm9yY2U6dHJ1ZX0pOwogIGF3YWl0IGlucHV0LmZpbGwoIkdlbmVyZSB1biBzY2hlbWEgbWVybWFpZCBwb3VyOiBhcmNoaXRlY3R1cmUgV0VWSUEgc291dmVyYWluZSIpOwogIGF3YWl0IHBhZ2Uud2FpdEZvclRpbWVvdXQoNDAwKTsKICBhd2FpdCBpbnB1dC5wcmVzcygiRW50ZXIiKTsKICAKICAvLyBXYWl0IGZvciBjb21wbGV0aW9uCiAgY29uc3Qgd3MgPSBEYXRlLm5vdygpOwogIHdoaWxlIChEYXRlLm5vdygpIC0gd3MgPCA2MDAwMCkgewogICAgY29uc3QgYnVzeSA9IGF3YWl0IHBhZ2UuZXZhbHVhdGUoKCkgPT4gd2luZG93LmJ1c3kgfHwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlbmRCdG4nKT8uZGlzYWJsZWQpOwogICAgY29uc3Qgc3ZncyA9IGF3YWl0IHBhZ2UubG9jYXRvcignW2lkXj0id3YtbWVybWFpZC0iXSBzdmcsIC5waGFzZS1jb250ZW50IHN2ZycpLmNvdW50KCk7CiAgICBpZiAoIWJ1c3kgJiYgc3ZncyA+IDApIGJyZWFrOwogICAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICB9CiAgYXdhaXQgcGFnZS53YWl0Rm9yVGltZW91dCgyMDAwKTsKICAKICAvLyBTY3JvbGwgdG8gdGhlIFNWRwogIGNvbnN0IHNjcm9sbGVkID0gYXdhaXQgcGFnZS5ldmFsdWF0ZSgoKSA9PiB7CiAgICBjb25zdCBzdmcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbaWRePSJ3di1tZXJtYWlkLSJdIHN2ZywgLnBoYXNlLWNvbnRlbnQgc3ZnJyk7CiAgICBpZiAoc3ZnKSB7CiAgICAgIHN2Zy5zY3JvbGxJbnRvVmlldyh7YmxvY2s6J2NlbnRlcicsIGJlaGF2aW9yOidpbnN0YW50J30pOwogICAgICByZXR1cm4gewogICAgICAgIHN2Z192aXNpYmxlOiBzdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGggPiAxMCwKICAgICAgICBzdmdfd2lkdGg6IHN2Zy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCwKICAgICAgICBzdmdfaGVpZ2h0OiBzdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0LAogICAgICAgIHN2Z19odG1sX3NpemU6IHN2Zy5vdXRlckhUTUwubGVuZ3RoLAogICAgICAgIHdyYXBwZXJfaWQ6IHN2Zy5wYXJlbnRFbGVtZW50Py5pZCwKICAgICAgfTsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0pOwogIGNvbnNvbGUubG9nKCJTVkcgcmVuZGVyZWQ6IiwgSlNPTi5zdHJpbmdpZnkoc2Nyb2xsZWQsIG51bGwsIDIpKTsKICAKICBhd2FpdCBwYWdlLndhaXRGb3JUaW1lb3V0KDUwMCk7CiAgYXdhaXQgcGFnZS5zY3JlZW5zaG90KHsgcGF0aDogIm91dHB1dC92NTUtc2Nyb2xsZWQucG5nIiwgZnVsbFBhZ2U6IGZhbHNlIH0pOwogIGF3YWl0IHBhZ2Uuc2NyZWVuc2hvdCh7IHBhdGg6ICJvdXRwdXQvdjU1LWZ1bGwucG5nIiwgZnVsbFBhZ2U6IHRydWUgfSk7Cn0pOwo=");
|
||||
foreach (glob("$base/*.spec.js") as $old) @unlink($old);
|
||||
$written = @file_put_contents("$base/v55-scroll.spec.js", $spec);
|
||||
echo json_encode(["written" => $written]);
|
||||
15
api/ambre-sse2.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
echo "size: " . strlen($c) . "\n";
|
||||
echo "Claude count: " . substr_count($c, "Claude") . "\n";
|
||||
echo "WEVIA-pattern: " . preg_match_all("/WEVIA[- ]?[pP]attern/", $c) . "\n";
|
||||
|
||||
// Find around "phase" type handling
|
||||
$pos = strpos($c, "type === 'header'");
|
||||
if ($pos === false) $pos = strpos($c, 'type==="header"');
|
||||
if ($pos === false) $pos = strpos($c, "'header'");
|
||||
echo "header pos: $pos\n";
|
||||
if ($pos !== false) {
|
||||
echo substr($c, $pos, 2500);
|
||||
}
|
||||
11
api/ambre-sse3.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
|
||||
// Find WEVIA-pattern header rendering - that's the SSE handler for 'header' type
|
||||
$pos = strpos($c, "WEVIA-pattern");
|
||||
echo "WEVIA-pattern 1st at: $pos\n\n";
|
||||
if ($pos !== false) {
|
||||
echo "=== Context (go back to find handler start) ===\n";
|
||||
echo substr($c, max(0, $pos - 1500), 3000);
|
||||
}
|
||||
9
api/ambre-sse4.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
header("Content-Type: text/plain");
|
||||
$c = @file_get_contents("/var/www/html/wevia.html");
|
||||
// Get the rest of handleEvent (from WEVIA-pattern onwards to end of function)
|
||||
$pos = strpos($c, "WEVIA-pattern");
|
||||
$end = strpos($c, "eventSource.close", $pos);
|
||||
if ($end === false) $end = $pos + 6000;
|
||||
echo "=== handleEvent from 96870 to " . ($pos + 6000) . " ===\n";
|
||||
echo substr($c, $pos + 1800, 5000);
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generated_at": "2026-04-22T11:00:01.889900",
|
||||
"generated_at": "2026-04-22T11:10:02.122058",
|
||||
"stats": {
|
||||
"total": 50,
|
||||
"pending": 32,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"agent": "V42_MQL_Scoring_Agent_REAL",
|
||||
"ts": "2026-04-22T09:00:01+00:00",
|
||||
"ts": "2026-04-22T09:10:02+00:00",
|
||||
"status": "DEPLOYED_AUTO",
|
||||
"deployed": true,
|
||||
"algorithm": "weighted_behavioral_signals",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"timestamp": "2026-04-22T10:30:13",
|
||||
"timestamp": "2026-04-22T11:00:13",
|
||||
"features": {
|
||||
"total": 36,
|
||||
"pass": 35
|
||||
@@ -13,7 +13,7 @@
|
||||
"score": 97.2,
|
||||
"log": [
|
||||
"=== UX AGENT v1.0 ===",
|
||||
"Time: 2026-04-22 10:30:02",
|
||||
"Time: 2026-04-22 11:00:01",
|
||||
" core: 4/4",
|
||||
" layout: 3/4",
|
||||
" interaction: 6/6",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"ok": true,
|
||||
"version": "V83-business-kpi",
|
||||
"ts": "2026-04-22T08:59:09+00:00",
|
||||
"ts": "2026-04-22T09:11:34+00:00",
|
||||
"summary": {
|
||||
"total_categories": 8,
|
||||
"total_kpis": 64,
|
||||
|
||||
@@ -88,5 +88,14 @@
|
||||
"code": "sequenceDiagram\n participant A as Client\n participant B as Serveur\n A->>B: Demande de connexion\n B->>A: Réponse de connexion\n A->>B: Envoi de données\n B->>A: Réponse de données\n A->>B: Demande de fermeture\n B->>A: Réponse de fermeture",
|
||||
"created_at": "2026-04-22T08:58:07+00:00",
|
||||
"use_count": 0
|
||||
},
|
||||
{
|
||||
"id": "402ceef86d9e",
|
||||
"topic": "wevia",
|
||||
"kind": "sequence",
|
||||
"context": "Auto-generated from user query",
|
||||
"code": "sequenceDiagram\n participant U as Utilisateur\n participant S as Serveur\n U->>S: Demande de connexion\n S->>U: Réponse de connexion\n U->>S: Envoi de données\n S->>U: Traitement des données\n U->>S: Demande de données\n S->>U: Envoi de données",
|
||||
"created_at": "2026-04-22T09:09:05+00:00",
|
||||
"use_count": 0
|
||||
}
|
||||
]
|
||||
BIN
generated/wevia-img-chat-20260422-090906-7eef2e.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
103
generated/wevia-pdf-premium-20260422-090903-2fabbd.html
Normal file
@@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Amélioration des performances</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<style>
|
||||
@page { margin: 0; size: A4; }
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: 'Helvetica Neue', Arial, sans-serif; color: #1a1a2e; line-height: 1.6; }
|
||||
.cover { height: 297mm; background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #3b82f6 100%); color: #fff; padding: 80px 70px; display: flex; flex-direction: column; justify-content: space-between; page-break-after: always; }
|
||||
.cover .brand { font-size: 14px; letter-spacing: 4px; text-transform: uppercase; opacity: 0.9; }
|
||||
.cover h1 { font-size: 56px; line-height: 1.1; font-weight: 800; margin: 40px 0 20px; }
|
||||
.cover .subt { font-size: 22px; font-weight: 300; opacity: 0.92; max-width: 80%; }
|
||||
.cover .meta { font-size: 13px; opacity: 0.85; border-top: 1px solid rgba(255,255,255,0.3); padding-top: 24px; }
|
||||
.page { padding: 40px 55px 55px; min-height: 297mm; page-break-after: always; }
|
||||
.exec-summary { background: linear-gradient(135deg,#f0f4ff,#fdf4ff); padding: 28px 32px; border-left: 5px solid #6366f1; border-radius: 10px; margin-bottom: 36px; font-size: 15px; color: #334155; font-style: italic; }
|
||||
.kpis { display: flex; gap: 16px; margin: 32px 0; }
|
||||
.kpi { flex: 1; background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 24px 20px; text-align: center; box-shadow: 0 2px 8px rgba(99,102,241,0.08); }
|
||||
.kpi-value { font-size: 36px; font-weight: 800; color: #6366f1; margin-bottom: 6px; }
|
||||
.kpi-label { font-size: 13px; color: #64748b; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
|
||||
.kpi-trend { font-size: 12px; color: #10b981; font-weight: 600; }
|
||||
.chart-wrap { background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 28px; margin: 32px 0; }
|
||||
.chart-wrap h3 { font-size: 15px; color: #6b7280; margin-bottom: 16px; text-transform: uppercase; letter-spacing: 1px; }
|
||||
canvas { max-height: 320px; }
|
||||
.sec { margin-bottom: 32px; break-inside: avoid; }
|
||||
.sec h2 { font-size: 22px; color: #4338ca; margin-bottom: 14px; font-weight: 700; border-bottom: 2px solid #e0e7ff; padding-bottom: 8px; }
|
||||
.sec p { font-size: 14.5px; color: #334155; margin-bottom: 12px; }
|
||||
.sec ul { margin-left: 24px; }
|
||||
.sec li { font-size: 14px; color: #475569; margin-bottom: 6px; padding-left: 4px; }
|
||||
.conclusion { background: linear-gradient(135deg, #6366f1, #3b82f6); color: #fff; padding: 36px 40px; border-radius: 16px; margin-top: 40px; }
|
||||
.conclusion h2 { font-size: 22px; margin-bottom: 14px; }
|
||||
.conclusion p { font-size: 15.5px; line-height: 1.65; }
|
||||
.footer { position: fixed; bottom: 16mm; left: 55px; right: 55px; font-size: 10px; color: #94a3b8; display: flex; justify-content: space-between; border-top: 1px solid #e2e8f0; padding-top: 10px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Cover page -->
|
||||
<div class="cover">
|
||||
<div>
|
||||
<div class="brand">WEVAL Consulting · Rapport Premium</div>
|
||||
<h1>Amélioration des performances</h1>
|
||||
<div class="subt">Analyse de la croissance et des opportunités de développement</div>
|
||||
</div>
|
||||
<div class="meta">Généré le 22 April 2026 · WEVIA Enterprise Intelligence</div>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="page">
|
||||
<div class="exec-summary">Notre analyse a révélé une augmentation de 15% des ventes sur les 6 derniers mois, avec un taux de croissance stable.</div>
|
||||
|
||||
<div class="kpis"><div class='kpi'><div class='kpi-value'>15%</div><div class='kpi-label'>Taux de croissance</div><div class='kpi-trend'>stable</div></div><div class='kpi'><div class='kpi-value'>1 800</div><div class='kpi-label'>Nombre de clients</div><div class='kpi-trend'>+12%</div></div><div class='kpi'><div class='kpi-value'>90/100</div><div class='kpi-label'>Score de satisfaction client</div><div class='kpi-trend'>+5pts</div></div></div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<h3>Visualisation des données</h3>
|
||||
<canvas id="mainChart"></canvas>
|
||||
</div>
|
||||
|
||||
<section class='sec'><h2>1. Stratégie de croissance</h2><p>Nous avons identifié trois axes clés pour améliorer les performances : la mise en place d'une stratégie de marketing efficace, l'optimisation des processus internes et la recherche de partenariats stratégiques.</p><ul><li>Développement d'une stratégie de contenu solide</li><li>Amélioration de la visibilité en ligne</li><li>Renforcement des relations avec les clients</li></ul></section><section class='sec'><h2>2. Analyse des résultats</h2><p>Les données montrent une augmentation significative des ventes sur les 6 derniers mois, avec un taux de croissance stable.</p><ul><li>Augmentation des ventes de 15%</li><li>Stabilité du taux de croissance</li><li>Mise en place d'un système de suivi efficace</li></ul></section><section class='sec'><h2>3. Plan d'action</h2><p>Nous recommandons la mise en place d'une stratégie de croissance à long terme, avec des objectifs clairs et des indicateurs de performance.</p><ul><li>Développement d'une stratégie de croissance à long terme</li><li>Mise en place d'indicateurs de performance clairs</li><li>Suivi régulier des résultats</li></ul></section>
|
||||
|
||||
<div class="conclusion">
|
||||
<h2>Conclusion & recommandations</h2>
|
||||
<p>Nous recommandons la mise en place d'une stratégie de croissance à long terme, avec des objectifs clairs et des indicateurs de performance, pour améliorer les performances et atteindre les objectifs fixés.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<span>WEVAL Consulting · weval-consulting.com</span>
|
||||
<span>Confidentiel · Usage interne</span>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.addEventListener("load", function(){
|
||||
try {
|
||||
var cd = {"type":"bar","title":"Évolution des ventes sur les 6 derniers mois","labels":["Janvier","Février","Mars","Avril","Mai","Juin"],"values":[45,62,78,71,89,92]};
|
||||
if (!cd) return;
|
||||
var ctx = document.getElementById("mainChart").getContext("2d");
|
||||
new Chart(ctx, {
|
||||
type: cd.type || "bar",
|
||||
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}}},
|
||||
}
|
||||
});
|
||||
window._wevia_chart_ready = true;
|
||||
} catch(e) { console.error("chart fail", e); }
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
generated/wevia-pdf-premium-20260422-090903-2fabbd.pdf
Normal file
BIN
generated/wevia-qr-test-20260422-090906-1a4ef1.png
Normal file
|
After Width: | Height: | Size: 517 B |
BIN
generated/wevia-tts-bonjour-20260422-090906-fdfb7f.mp3
Normal file
BIN
screenshots/wave265-top.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
91
wevia.html
@@ -1434,11 +1434,102 @@ function send() {
|
||||
}
|
||||
else if (type === 'done') {
|
||||
finalFileUrl = data.file_url;
|
||||
// === AMBRE-V5-MERMAID-RENDER wave-263 ===
|
||||
// If fullResponse contains mermaid code → render SVG inline
|
||||
try {
|
||||
var _mcode = null;
|
||||
if (data.mermaid_code) _mcode = data.mermaid_code;
|
||||
else if (fullResponse) {
|
||||
// Detect mermaid patterns at start of response
|
||||
var _fr = fullResponse.trim();
|
||||
if (/^(sequenceDiagram|flowchart|graph\s+[A-Z]{1,2}|classDiagram|stateDiagram|erDiagram|gantt|pie|journey|gitGraph|mindmap|timeline)\b/.test(_fr)) {
|
||||
_mcode = _fr;
|
||||
} else {
|
||||
// Search inside for ``` mermaid block
|
||||
var _m = fullResponse.match(/```mermaid\s*([\s\S]+?)```/);
|
||||
if (_m) _mcode = _m[1].trim();
|
||||
else {
|
||||
// or raw mermaid after 'Schema Mermaid:' label
|
||||
var _m2 = fullResponse.match(/(?:Schema Mermaid|Diagramme)[^\n]*\n([\s\S]+)$/i);
|
||||
if (_m2 && /^(sequenceDiagram|flowchart|graph|classDiagram|stateDiagram)/.test(_m2[1].trim())) _mcode = _m2[1].trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_mcode && window.mermaid && currentPhaseEl) {
|
||||
// Sanitize accents for mermaid parser
|
||||
var _clean = _mcode.normalize ? _mcode.normalize('NFD').replace(/[\u0300-\u036f]/g, '') : _mcode;
|
||||
var _svgId = 'wv-mermaid-' + Date.now() + '-' + Math.floor(Math.random()*999);
|
||||
var _mContainer = document.createElement('div');
|
||||
_mContainer.id = _svgId + '-wrap';
|
||||
_mContainer.style.cssText = 'margin-top:12px;padding:16px;background:#fafafa;border:1px solid #e5e7eb;border-radius:8px;overflow-x:auto';
|
||||
currentPhaseEl.appendChild(_mContainer);
|
||||
try {
|
||||
window.mermaid.render(_svgId, _clean).then(function(r){
|
||||
_mContainer.innerHTML = r.svg;
|
||||
}).catch(function(err){
|
||||
_mContainer.innerHTML = '<pre style="color:#b91c1c;font-size:11px">Mermaid render error: ' + (err.message||err) + '\n\n' + _clean.replace(/</g,'<') + '</pre>';
|
||||
});
|
||||
} catch(e) {
|
||||
_mContainer.innerHTML = '<pre style="font-size:11px">' + _clean.replace(/</g,'<') + '</pre>';
|
||||
}
|
||||
}
|
||||
} catch(eMermaid) { console.warn('[V5-MERMAID-RENDER]', eMermaid); }
|
||||
// === END AMBRE-V5-MERMAID-RENDER ===
|
||||
// V169 code-artifact-preview · detect code blocks + wrap <pre><code> + trigger artifact renderer
|
||||
try {
|
||||
if (currentChunkEl && fullResponse) {
|
||||
var _v169_codeRegex = /```(\w+)?\s*\n?([\s\S]+?)```/g;
|
||||
var _v169_match;
|
||||
var _v169_hasCode = false;
|
||||
var _v169_html = fullResponse;
|
||||
while ((_v169_match = _v169_codeRegex.exec(fullResponse)) !== null) {
|
||||
var _v169_lang = (_v169_match[1] || "text").toLowerCase();
|
||||
// Skip mermaid (autre Claude handle)
|
||||
if (_v169_lang === "mermaid") continue;
|
||||
_v169_hasCode = true;
|
||||
var _v169_code = _v169_match[2].trim();
|
||||
var _v169_escaped = _v169_code.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
var _v169_replacement = "<pre style=\"background:#1a1a2e;color:#e5e7eb;padding:14px;border-radius:8px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:12px;line-height:1.5\"><code class=\"language-" + _v169_lang + "\">" + _v169_escaped + "</code></pre>";
|
||||
_v169_html = _v169_html.replace(_v169_match[0], _v169_replacement);
|
||||
}
|
||||
if (_v169_hasCode) {
|
||||
currentChunkEl.innerHTML = _v169_html;
|
||||
// Trigger artifact renderer scan
|
||||
setTimeout(function() {
|
||||
if (typeof window.scanAndAddButtons === "function") {
|
||||
window.scanAndAddButtons();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
} catch(_v169_err) { console.warn("V169 code-artifact-preview err:", _v169_err); }
|
||||
// === END V169 code-artifact-preview ===
|
||||
// Format final response with link if present
|
||||
if (currentChunkEl && finalFileUrl) {
|
||||
var _u = finalFileUrl; var linkHtml = fullResponse.split(_u).join('<a href="'+_u+'" target="_blank" style="color:#2563eb;font-weight:600">'+finalFileUrl+'</a>');
|
||||
currentChunkEl.innerHTML = linkHtml;
|
||||
}
|
||||
// V168 mermaid-postprocess · si fullResponse contient mermaid code, rendre le SVG
|
||||
try {
|
||||
var _v168_mermaidRegex = /```mermaid\s*([\s\S]+?)```|((?:graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap)\s+[\s\S]+?)(?=\n\n|$)/i;
|
||||
var _v168_m = _v168_mermaidRegex.exec(fullResponse);
|
||||
if (_v168_m && currentChunkEl && window.mermaid) {
|
||||
var _v168_code = (_v168_m[1] || _v168_m[2] || "").trim();
|
||||
// Clean LLM wrapping (backticks, quotes)
|
||||
_v168_code = _v168_code.replace(/^["'`]+|["'`]+$/g, "").trim();
|
||||
if (_v168_code.length > 10 && /^(graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|mindmap|journey)/i.test(_v168_code)) {
|
||||
var _v168_id = "v168-mermaid-" + Date.now();
|
||||
var _v168_wrapper = document.createElement("div");
|
||||
_v168_wrapper.style.cssText = "margin-top:12px;padding:16px;background:#fff;border:1px solid #e5e7eb;border-radius:8px";
|
||||
_v168_wrapper.innerHTML = "<div class=\"mermaid\" id=\"" + _v168_id + "\">" + _v168_code + "</div>";
|
||||
currentChunkEl.parentNode.appendChild(_v168_wrapper);
|
||||
setTimeout(function() {
|
||||
try { window.mermaid.init(undefined, "#" + _v168_id); }
|
||||
catch(e) { console.warn("V168 mermaid render err:", e); }
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
} catch(_v168_err) { console.warn("V168 mermaid-postprocess err:", _v168_err); }
|
||||
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';
|
||||
|
||||