57 lines
2.1 KiB
JavaScript
57 lines
2.1 KiB
JavaScript
/* Dona Hermes CLI streaming overlay. Unobtrusive; never modifies existing cards. */
|
|
(() => {
|
|
'use strict';
|
|
if (typeof window.io !== 'function' || window.__donaHermesStreamV1) return;
|
|
window.__donaHermesStreamV1 = true;
|
|
|
|
const el = document.createElement('aside');
|
|
el.id = 'dona-hermes-live-v1';
|
|
el.setAttribute('aria-live', 'polite');
|
|
el.setAttribute('aria-label', 'Progression de la réponse de Dona');
|
|
el.hidden = true;
|
|
const label = document.createElement('div');
|
|
label.className = 'dona-hlive-title';
|
|
const body = document.createElement('div');
|
|
body.className = 'dona-hlive-text';
|
|
el.append(label, body);
|
|
document.body.appendChild(el);
|
|
let activeId = null, contents = '', closeTimer = null;
|
|
const close = (delay = 1000) => {
|
|
clearTimeout(closeTimer);
|
|
closeTimer = setTimeout(() => { el.hidden = true; activeId = null; }, delay);
|
|
};
|
|
const socket = window.io({ reconnection: true });
|
|
socket.on('dona_hermes_stream', (event) => {
|
|
if (!event || !event.type || !event.id) return;
|
|
if (event.type === 'start') {
|
|
activeId = event.id;
|
|
contents = '';
|
|
clearTimeout(closeTimer);
|
|
label.textContent = 'Dona réfléchit…';
|
|
body.textContent = '';
|
|
el.hidden = false;
|
|
return;
|
|
}
|
|
if (event.id !== activeId) return;
|
|
if (event.type === 'first_text') {
|
|
label.textContent = 'Dona répond…';
|
|
} else if (event.type === 'delta') {
|
|
// Avoid unlimited DOM growth; normal Dona cards remain the final source.
|
|
contents = (contents + String(event.text || '')).slice(-1200);
|
|
body.textContent = contents;
|
|
} else if (event.type === 'tool') {
|
|
label.textContent = 'Dona utilise un outil…';
|
|
body.textContent = String(event.name || 'Outil en cours');
|
|
contents = '';
|
|
} else if (event.type === 'tool_done') {
|
|
label.textContent = 'Dona prépare sa réponse…';
|
|
} else if (event.type === 'end') {
|
|
close(1100);
|
|
} else if (event.type === 'error') {
|
|
label.textContent = 'Traitement interrompu';
|
|
close(2300);
|
|
}
|
|
});
|
|
socket.on('disconnect', () => { el.hidden = true; activeId = null; });
|
|
})();
|