Update index.html
Browse files- index.html +95 -29
index.html
CHANGED
|
@@ -457,7 +457,15 @@ function loadHistory() {
|
|
| 457 |
try { return JSON.parse(localStorage.getItem(HIST_KEY)) || []; } catch (e) { return []; }
|
| 458 |
}
|
| 459 |
function saveHistory(h) {
|
| 460 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 461 |
}
|
| 462 |
function renderHistory() {
|
| 463 |
const h = loadHistory();
|
|
@@ -472,24 +480,76 @@ function renderHistory() {
|
|
| 472 |
h.forEach(item => {
|
| 473 |
const d = document.createElement('div');
|
| 474 |
d.className = 'hist-item';
|
| 475 |
-
d.title = 'Reutilizar este tema';
|
| 476 |
const t = document.createElement('div');
|
| 477 |
t.className = 'hist-topic'; t.textContent = item.topic;
|
| 478 |
const m = document.createElement('div');
|
| 479 |
m.className = 'hist-meta';
|
| 480 |
m.textContent = new Date(item.ts).toLocaleString('es-ES', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }) +
|
| 481 |
-
' \u00b7 ' + item.agents + ' agentes'
|
|
|
|
| 482 |
d.appendChild(t); d.appendChild(m);
|
| 483 |
-
d.addEventListener('click', () => {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 484 |
histListEl.appendChild(d);
|
| 485 |
});
|
| 486 |
}
|
| 487 |
function recordTopic(topicText) {
|
| 488 |
const h = loadHistory();
|
| 489 |
-
if (h[0] && h[0].topic === topicText)
|
| 490 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 491 |
saveHistory(h);
|
| 492 |
renderHistory();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
}
|
| 494 |
document.getElementById('hist-clear').addEventListener('click', () => {
|
| 495 |
if (!loadHistory().length) return;
|
|
@@ -597,6 +657,31 @@ async function fetchWebContext(query) {
|
|
| 597 |
return { sources: sources.slice(0, 6), failed: failed };
|
| 598 |
}
|
| 599 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 600 |
async function prepareWebContext(q) {
|
| 601 |
addSys(b => { b.textContent = '\u{1F50E} Buscando contexto web sobre \u00ab' + q + '\u00bb (solo se env\u00eda el tema a Tavily y Wikipedia)\u2026'; });
|
| 602 |
let res;
|
|
@@ -606,28 +691,7 @@ async function prepareWebContext(q) {
|
|
| 606 |
if (webSources.length) {
|
| 607 |
webContext = webSources.map((s, i) => '[' + (i + 1) + '] ' + s.title + ' \u2014 ' + s.url + '\n' + s.snippet).join('\n');
|
| 608 |
if (webContext.length > 1600) webContext = webContext.slice(0, 1600);
|
| 609 |
-
|
| 610 |
-
const t = document.createElement('div');
|
| 611 |
-
t.textContent = '\u{1F4DA} Fuentes para este debate (los agentes pueden citarlas como [1], [2]\u2026):';
|
| 612 |
-
b.appendChild(t);
|
| 613 |
-
const ol = document.createElement('ol');
|
| 614 |
-
ol.style.margin = '6px 0 0 18px';
|
| 615 |
-
webSources.forEach(s => {
|
| 616 |
-
const li = document.createElement('li');
|
| 617 |
-
const a = document.createElement('a');
|
| 618 |
-
if (/^https?:\/\//i.test(s.url)) { a.href = s.url; a.target = '_blank'; a.rel = 'noopener'; }
|
| 619 |
-
a.textContent = s.title;
|
| 620 |
-
li.appendChild(a);
|
| 621 |
-
ol.appendChild(li);
|
| 622 |
-
});
|
| 623 |
-
b.appendChild(ol);
|
| 624 |
-
if (res.failed.length) {
|
| 625 |
-
const f = document.createElement('div');
|
| 626 |
-
f.style.marginTop = '4px';
|
| 627 |
-
f.textContent = '\u26a0\uFE0F ' + res.failed.join(' \u00b7 ');
|
| 628 |
-
b.appendChild(f);
|
| 629 |
-
}
|
| 630 |
-
});
|
| 631 |
} else {
|
| 632 |
webContext = '';
|
| 633 |
addSys(b => { b.textContent = '\u26a0\uFE0F B\u00fasqueda web sin resultados ahora (' + (res.failed.join(' \u00b7 ') || 'error') + '). El debate contin\u00faa sin contexto web.'; });
|
|
@@ -801,6 +865,7 @@ async function runDebate() {
|
|
| 801 |
if (!stopRequested) resume = { round: 1, order: null, pos: 0 };
|
| 802 |
} finally {
|
| 803 |
running = false;
|
|
|
|
| 804 |
stopBtn.style.display = 'none';
|
| 805 |
startBtn.style.display = 'inline-block';
|
| 806 |
startBtn.textContent = 'Continuar debate';
|
|
@@ -815,6 +880,7 @@ startBtn.addEventListener('click', async () => {
|
|
| 815 |
const newTopic = topicEl.value.trim();
|
| 816 |
let freshTopic = false;
|
| 817 |
if (newTopic && newTopic !== topic) {
|
|
|
|
| 818 |
topic = newTopic;
|
| 819 |
transcript = [];
|
| 820 |
chatEl.innerHTML = '';
|
|
@@ -824,7 +890,7 @@ startBtn.addEventListener('click', async () => {
|
|
| 824 |
const m = addMsg(null, true);
|
| 825 |
m.body.textContent = newTopic;
|
| 826 |
transcript.push({ name: null, text: 'Tema propuesto: ' + newTopic });
|
| 827 |
-
recordTopic(newTopic);
|
| 828 |
freshTopic = true;
|
| 829 |
} else if (!topic) {
|
| 830 |
topic = 'Tema libre';
|
|
|
|
| 457 |
try { return JSON.parse(localStorage.getItem(HIST_KEY)) || []; } catch (e) { return []; }
|
| 458 |
}
|
| 459 |
function saveHistory(h) {
|
| 460 |
+
h = h.slice(0, 30);
|
| 461 |
+
for (let attempt = 0; attempt < 3; attempt++) {
|
| 462 |
+
try { localStorage.setItem(HIST_KEY, JSON.stringify(h)); return; } catch (e) {}
|
| 463 |
+
let trimmed = false;
|
| 464 |
+
h.forEach(it => (it.msgs || []).forEach(m => {
|
| 465 |
+
if (m.text.length > 800) { m.text = m.text.slice(0, 800); trimmed = true; }
|
| 466 |
+
}));
|
| 467 |
+
if (!trimmed) h.forEach(it => { delete it.msgs; delete it.ctx; delete it.sources; });
|
| 468 |
+
}
|
| 469 |
}
|
| 470 |
function renderHistory() {
|
| 471 |
const h = loadHistory();
|
|
|
|
| 480 |
h.forEach(item => {
|
| 481 |
const d = document.createElement('div');
|
| 482 |
d.className = 'hist-item';
|
| 483 |
+
d.title = (Array.isArray(item.msgs) && item.msgs.length) ? 'Recuperar esta conversaci\u00f3n' : 'Reutilizar este tema';
|
| 484 |
const t = document.createElement('div');
|
| 485 |
t.className = 'hist-topic'; t.textContent = item.topic;
|
| 486 |
const m = document.createElement('div');
|
| 487 |
m.className = 'hist-meta';
|
| 488 |
m.textContent = new Date(item.ts).toLocaleString('es-ES', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }) +
|
| 489 |
+
' \u00b7 ' + item.agents + ' agentes' +
|
| 490 |
+
((Array.isArray(item.msgs) && item.msgs.length) ? ' \u00b7 ' + item.msgs.filter(x => x.name).length + ' interv.' : '');
|
| 491 |
d.appendChild(t); d.appendChild(m);
|
| 492 |
+
d.addEventListener('click', () => {
|
| 493 |
+
if (running) return;
|
| 494 |
+
if (Array.isArray(item.msgs) && item.msgs.length) restoreConversation(item);
|
| 495 |
+
else { topicEl.value = item.topic; topicEl.focus(); }
|
| 496 |
+
});
|
| 497 |
histListEl.appendChild(d);
|
| 498 |
});
|
| 499 |
}
|
| 500 |
function recordTopic(topicText) {
|
| 501 |
const h = loadHistory();
|
| 502 |
+
if (h[0] && h[0].topic === topicText) {
|
| 503 |
+
h[0].ts = Date.now();
|
| 504 |
+
h[0].agents = agents.length;
|
| 505 |
+
saveHistory(h);
|
| 506 |
+
renderHistory();
|
| 507 |
+
return h[0].ts;
|
| 508 |
+
}
|
| 509 |
+
const ts = Date.now();
|
| 510 |
+
h.unshift({ topic: topicText, ts: ts, agents: agents.length });
|
| 511 |
saveHistory(h);
|
| 512 |
renderHistory();
|
| 513 |
+
return ts;
|
| 514 |
+
}
|
| 515 |
+
|
| 516 |
+
// --- Guardado y restauracion de la conversacion completa ---
|
| 517 |
+
let currentHistId = null;
|
| 518 |
+
function saveTranscriptToHistory() {
|
| 519 |
+
if (!currentHistId || !transcript.length) return;
|
| 520 |
+
const h = loadHistory();
|
| 521 |
+
const it = h.find(x => x.ts === currentHistId);
|
| 522 |
+
if (!it) return;
|
| 523 |
+
it.msgs = transcript.slice(-80).map(m => ({ name: m.name, text: String(m.text).slice(0, 4000) }));
|
| 524 |
+
it.agents = agents.length;
|
| 525 |
+
if (webContext) it.ctx = webContext; else delete it.ctx;
|
| 526 |
+
if (webSources.length) it.sources = webSources; else delete it.sources;
|
| 527 |
+
saveHistory(h);
|
| 528 |
+
}
|
| 529 |
+
window.addEventListener('beforeunload', saveTranscriptToHistory);
|
| 530 |
+
|
| 531 |
+
function restoreConversation(item) {
|
| 532 |
+
saveTranscriptToHistory();
|
| 533 |
+
topic = item.topic;
|
| 534 |
+
topicEl.value = item.topic;
|
| 535 |
+
transcript = item.msgs.map(m => ({ name: m.name, text: m.text }));
|
| 536 |
+
chatEl.innerHTML = '';
|
| 537 |
+
resume = { round: 1, order: null, pos: 0 };
|
| 538 |
+
currentHistId = item.ts;
|
| 539 |
+
webContext = item.ctx || '';
|
| 540 |
+
webSources = Array.isArray(item.sources) ? item.sources : [];
|
| 541 |
+
const um = addMsg(null, true);
|
| 542 |
+
um.body.textContent = item.topic;
|
| 543 |
+
let n = 0;
|
| 544 |
+
transcript.forEach(m => {
|
| 545 |
+
if (!m.name) return;
|
| 546 |
+
n++;
|
| 547 |
+
const a = agents.find(x => x.name === m.name) || { name: m.name, emoji: '\u{1F916}', color: '#8b949e' };
|
| 548 |
+
const r = addMsg(a);
|
| 549 |
+
r.body.innerHTML = (typeof marked !== 'undefined') ? marked.parse(m.text) : esc(m.text).replace(/\n/g, '<br>');
|
| 550 |
+
});
|
| 551 |
+
if (webSources.length) renderSourcesMsg(webSources, []);
|
| 552 |
+
setStatus('Conversaci\u00f3n recuperada (' + n + ' intervenciones). Puedes continuar el debate.');
|
| 553 |
}
|
| 554 |
document.getElementById('hist-clear').addEventListener('click', () => {
|
| 555 |
if (!loadHistory().length) return;
|
|
|
|
| 657 |
return { sources: sources.slice(0, 6), failed: failed };
|
| 658 |
}
|
| 659 |
|
| 660 |
+
function renderSourcesMsg(sources, failed) {
|
| 661 |
+
addSys(b => {
|
| 662 |
+
const t = document.createElement('div');
|
| 663 |
+
t.textContent = '\u{1F4DA} Fuentes de este debate (los agentes pueden citarlas como [1], [2]\u2026):';
|
| 664 |
+
b.appendChild(t);
|
| 665 |
+
const ol = document.createElement('ol');
|
| 666 |
+
ol.style.margin = '6px 0 0 18px';
|
| 667 |
+
sources.forEach(s => {
|
| 668 |
+
const li = document.createElement('li');
|
| 669 |
+
const a = document.createElement('a');
|
| 670 |
+
if (/^https?:\/\//i.test(s.url)) { a.href = s.url; a.target = '_blank'; a.rel = 'noopener'; }
|
| 671 |
+
a.textContent = s.title;
|
| 672 |
+
li.appendChild(a);
|
| 673 |
+
ol.appendChild(li);
|
| 674 |
+
});
|
| 675 |
+
b.appendChild(ol);
|
| 676 |
+
if (failed && failed.length) {
|
| 677 |
+
const f = document.createElement('div');
|
| 678 |
+
f.style.marginTop = '4px';
|
| 679 |
+
f.textContent = '\u26a0\uFE0F ' + failed.join(' \u00b7 ');
|
| 680 |
+
b.appendChild(f);
|
| 681 |
+
}
|
| 682 |
+
});
|
| 683 |
+
}
|
| 684 |
+
|
| 685 |
async function prepareWebContext(q) {
|
| 686 |
addSys(b => { b.textContent = '\u{1F50E} Buscando contexto web sobre \u00ab' + q + '\u00bb (solo se env\u00eda el tema a Tavily y Wikipedia)\u2026'; });
|
| 687 |
let res;
|
|
|
|
| 691 |
if (webSources.length) {
|
| 692 |
webContext = webSources.map((s, i) => '[' + (i + 1) + '] ' + s.title + ' \u2014 ' + s.url + '\n' + s.snippet).join('\n');
|
| 693 |
if (webContext.length > 1600) webContext = webContext.slice(0, 1600);
|
| 694 |
+
renderSourcesMsg(webSources, res.failed);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 695 |
} else {
|
| 696 |
webContext = '';
|
| 697 |
addSys(b => { b.textContent = '\u26a0\uFE0F B\u00fasqueda web sin resultados ahora (' + (res.failed.join(' \u00b7 ') || 'error') + '). El debate contin\u00faa sin contexto web.'; });
|
|
|
|
| 865 |
if (!stopRequested) resume = { round: 1, order: null, pos: 0 };
|
| 866 |
} finally {
|
| 867 |
running = false;
|
| 868 |
+
saveTranscriptToHistory();
|
| 869 |
stopBtn.style.display = 'none';
|
| 870 |
startBtn.style.display = 'inline-block';
|
| 871 |
startBtn.textContent = 'Continuar debate';
|
|
|
|
| 880 |
const newTopic = topicEl.value.trim();
|
| 881 |
let freshTopic = false;
|
| 882 |
if (newTopic && newTopic !== topic) {
|
| 883 |
+
saveTranscriptToHistory();
|
| 884 |
topic = newTopic;
|
| 885 |
transcript = [];
|
| 886 |
chatEl.innerHTML = '';
|
|
|
|
| 890 |
const m = addMsg(null, true);
|
| 891 |
m.body.textContent = newTopic;
|
| 892 |
transcript.push({ name: null, text: 'Tema propuesto: ' + newTopic });
|
| 893 |
+
currentHistId = recordTopic(newTopic);
|
| 894 |
freshTopic = true;
|
| 895 |
} else if (!topic) {
|
| 896 |
topic = 'Tema libre';
|