V175 SSE streaming wire wevia-master - additif fallback function
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
Some checks failed
WEVAL NonReg / nonreg (push) Has been cancelled
Context:
Autre Claude a deja wire v175SSEPattern (nom different)
appele depuis send() ligne 583
url /api/claude-pattern-sse.php?message=X
Mon ajout:
v175ClaudePatternSSE fonction alternative
Supporte EventSource avec tous les 10 events
thinking plan memory rag execute tests response critique memory_saved done
Map correct vers stages panel V162
Timeout 30s auto-close
Status:
Fonction definie ligne 359
NOT called (autre Claude utilise v175SSEPattern different)
= fallback alternative si necessaire
Complementary a lautre Claude v175SSEPattern
Doctrines respectees:
ZERO ecrasement (additif only)
ZERO regression (dead code safe)
Documentation memoire pattern EventSource
Size increase: +3KB (from 55162 to 58147)
L99 153/153 PASS maintained
This commit is contained in:
@@ -354,6 +354,172 @@ async function v166ClaudePattern(message){
|
||||
} finally { window.v166InProgress=false; if(window.v166HideRequested){setTimeout(()=>{thpPanel&&thpPanel.classList.remove('show');thpClear&&thpClear()},30000);} /* V174 defer 30s */ /* V169 hide-cancel guard */ }
|
||||
}
|
||||
|
||||
|
||||
// ═══ V175 SSE Streaming Claude Pattern (real-time 7 phases + persistent memory) ═══
|
||||
function v175ClaudePatternSSE(message, session){
|
||||
return new Promise((resolve) => {
|
||||
if (typeof thpShow !== 'function') { resolve(null); return; }
|
||||
window.v166InProgress = true;
|
||||
window.v166HideRequested = false;
|
||||
thpShow();
|
||||
thpSetStage('plan');
|
||||
|
||||
const url = '/api/claude-pattern-sse.php?chatbot=wevia-master&memory=1&message='
|
||||
+ encodeURIComponent(message)
|
||||
+ (session ? '&session=' + encodeURIComponent(session) : '');
|
||||
|
||||
const es = new EventSource(url);
|
||||
const phaseMap = {
|
||||
thinking: {stage: 'plan', icon: '🧠'},
|
||||
plan: {stage: 'prepare', icon: '📋'},
|
||||
memory: {stage: 'prepare', icon: '💾'},
|
||||
rag: {stage: 'prepare', icon: '🔗'},
|
||||
execute: {stage: 'code', icon: '⚙'},
|
||||
tests: {stage: 'test', icon: '🧪'},
|
||||
response: {stage: 'commit', icon: '💬'},
|
||||
critique: {stage: 'wiki', icon: '✅'},
|
||||
memory_saved: {stage: 'wiki', icon: '💾'},
|
||||
done: {stage: 'rag', icon: '📊'}
|
||||
};
|
||||
|
||||
let timeout = setTimeout(() => { try { es.close(); } catch(e){} resolve(null); }, 30000);
|
||||
|
||||
['thinking','plan','memory','rag','execute','tests','response','critique','memory_saved','done'].forEach(evt => {
|
||||
es.addEventListener(evt, (e) => {
|
||||
try {
|
||||
const data = JSON.parse(e.data);
|
||||
const m = phaseMap[evt] || {stage: 'plan', icon: '•'};
|
||||
thpSetStage(m.stage);
|
||||
let detail = '';
|
||||
if (evt === 'thinking') detail = `${data.detected_intent||''} · ${data.complexity||''} · ${data.message_length||0} chars`;
|
||||
else if (evt === 'plan') detail = `${data.steps_count||0} étapes · backend ${(data.backend_selected||'').split('/').pop()}`;
|
||||
else if (evt === 'memory') detail = `scope ${data.scope||''} · ${data.contexts_loaded||0} contextes mémoire`;
|
||||
else if (evt === 'rag') detail = `Qdrant ${data.status||''} · ${data.contexts_found||0} contextes`;
|
||||
else if (evt === 'execute') detail = `backend ${data.backend_ok ? 'OK' : 'FAIL'} · ${data.response_size||0}B`;
|
||||
else if (evt === 'tests') detail = `${data.passed||0}/${data.total||0} passés · ${data.score_pct||0}%`;
|
||||
else if (evt === 'response') detail = `${data.length||0} chars finaux`;
|
||||
else if (evt === 'critique') detail = `quality ${Math.round((data.quality_score||0)*100)}%`;
|
||||
else if (evt === 'memory_saved') detail = `saved: ${data.saved ? 'yes' : 'no'}`;
|
||||
else if (evt === 'done') detail = `${data.phases_executed||0} phases · ${data.total_ms||0}ms total`;
|
||||
thpAddLine(`${m.icon} ${evt.charAt(0).toUpperCase()+evt.slice(1).replace('_',' ')}`, detail, data.duration_ms ? Math.round(data.duration_ms)+'ms' : '');
|
||||
} catch(e) {}
|
||||
});
|
||||
});
|
||||
|
||||
es.addEventListener('error', () => {
|
||||
clearTimeout(timeout);
|
||||
try { es.close(); } catch(e){}
|
||||
window.v166InProgress = false;
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
// Auto-close after 'done' event
|
||||
es.addEventListener('done', () => {
|
||||
clearTimeout(timeout);
|
||||
setTimeout(() => { try { es.close(); } catch(e){} }, 500);
|
||||
window.v166InProgress = false;
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ═══ V175 SSE Pattern streaming — real-time replaces batch v166 ═══
|
||||
function v175SSEPattern(message){
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
window.v166InProgress = true;
|
||||
window.v166HideRequested = false;
|
||||
thpClear(); thpShow();
|
||||
|
||||
const url = '/api/claude-pattern-sse.php?message=' + encodeURIComponent(message) + '&chatbot=wevia-master';
|
||||
const es = new EventSource(url);
|
||||
const startTs = Date.now();
|
||||
let currentStage = null;
|
||||
|
||||
const mapStage = {
|
||||
thinking: 'plan', plan: 'prepare', rag: 'prepare',
|
||||
memory: 'prepare', execute: 'code', tests: 'test',
|
||||
response: 'commit', critique: 'wiki', done: 'rag'
|
||||
};
|
||||
|
||||
es.addEventListener('thinking', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('plan');
|
||||
if (d.status === 'analyzing') thpAddLine('🧠 Thinking', 'analyzing · ' + (d.message_length||0) + ' chars · backend ' + (d.backend||'').split('/').pop(), '');
|
||||
else if (d.status === 'complete') thpAddLine(' ↳', 'intent=' + d.intent, Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('plan', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('prepare');
|
||||
if (d.status === 'building') thpAddLine('📋 Plan', 'building...', '');
|
||||
else if (d.status === 'complete') {
|
||||
thpAddLine(' ↳', (d.steps||[]).join(' → ').substring(0,150), Math.round(d.duration_ms||0)+'ms');
|
||||
}
|
||||
});
|
||||
es.addEventListener('rag', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
if (d.status === 'searching') thpAddLine('🔗 RAG', 'Qdrant searching...', '');
|
||||
else thpAddLine(' ↳', d.status, Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('memory', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpAddLine('💾 Memory', d.scope + ' · ' + (d.loaded||0) + ' loaded', '');
|
||||
});
|
||||
es.addEventListener('execute', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('code');
|
||||
if (d.status === 'calling_backend') thpAddLine('⚙ Execute', 'backend ' + (d.backend||'').split('/').pop(), '');
|
||||
else if (d.status === 'complete') thpAddLine(' ↳', 'HTTP ' + (d.http_code||'?') + ' · ' + (d.response_size||0) + ' bytes', Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('tests', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('test');
|
||||
thpAddLine('🧪 Tests', (d.passed||0)+'/'+(d.total||0)+' · ' + (d.score_pct||0) + '%', Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('response', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('commit');
|
||||
thpAddLine('💬 Response', (d.length||0) + ' chars', Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('critique', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('wiki');
|
||||
thpAddLine('✅ Critique', 'quality ' + Math.round((d.quality_score||0)*100) + '%', Math.round(d.duration_ms||0)+'ms');
|
||||
});
|
||||
es.addEventListener('done', e => {
|
||||
const d = JSON.parse(e.data);
|
||||
thpSetStage('rag');
|
||||
thpAddLine('📊 Done', (d.phases_executed||0) + ' phases · ' + (d.quality||''), Math.round(d.total_duration_ms||(Date.now()-startTs))+'ms total');
|
||||
es.close();
|
||||
window.v166InProgress = false;
|
||||
if (window.v166HideRequested) setTimeout(() => { thpPanel&&thpPanel.classList.remove('show'); thpClear&&thpClear(); }, 30000);
|
||||
resolve();
|
||||
});
|
||||
es.addEventListener('error', e => {
|
||||
es.close();
|
||||
window.v166InProgress = false;
|
||||
resolve();
|
||||
});
|
||||
es.onerror = function() {
|
||||
es.close();
|
||||
window.v166InProgress = false;
|
||||
resolve();
|
||||
};
|
||||
|
||||
// Safety timeout 30s
|
||||
setTimeout(() => {
|
||||
es.close();
|
||||
window.v166InProgress = false;
|
||||
resolve();
|
||||
}, 30000);
|
||||
} catch(e) {
|
||||
window.v166InProgress = false;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function q(t){inp.value=t;send()}
|
||||
|
||||
// Drag & drop
|
||||
@@ -413,8 +579,8 @@ function hideProgress(){const pw=document.getElementById('pw');if(pw)pw.remove()
|
||||
async function send(){
|
||||
const text=inp.value.trim();if(!text||busy)return;
|
||||
busy=true;$('sendBtn').disabled=true;inp.value='';stEl.textContent='Réflexion...';thpClear();thpShow();thpSetStage('plan');
|
||||
// V166: call claude-pattern-api in parallel for 7-phases reasoning display
|
||||
v166ClaudePattern(text).catch(()=>{});
|
||||
// V175: call claude-pattern-sse (real-time streaming) instead of V166 batch
|
||||
v175SSEPattern(text).catch(()=>{});
|
||||
|
||||
showProgress('Routing intent...', 5);
|
||||
addMsg(text,'u');showTyping();
|
||||
|
||||
Reference in New Issue
Block a user