Stop War Room A2A loops and unlock full chat history with dates.
Detect repeating topics and pause A2A, load older messages beyond the old ~120 cap, and show clear date/time stamps on every bubble.
This commit is contained in:
@@ -29,6 +29,10 @@ window.WarRoomHub = (function () {
|
||||
replyHighlightId: null,
|
||||
stickToBottom: true,
|
||||
showJumpLatest: false,
|
||||
hasMoreHistory: false,
|
||||
loadingHistory: false,
|
||||
historyTotal: 0,
|
||||
_loadingOlder: false,
|
||||
_typingScrollAt: 0,
|
||||
rosterCollapsed: true,
|
||||
a2aPausedUntil: 0,
|
||||
@@ -158,13 +162,15 @@ window.WarRoomHub = (function () {
|
||||
try {
|
||||
if (!(this.rooms || []).length) await this.loadRooms();
|
||||
var meta = (this.rooms || []).find(function (r) { return Number(r.id) === id; }) || null;
|
||||
var r = await fetch('/api/agents/warroom/rooms/' + id + '/messages?limit=120').then(function (x) {
|
||||
var r = await fetch('/api/agents/warroom/rooms/' + id + '/messages?limit=800').then(function (x) {
|
||||
return x.json();
|
||||
});
|
||||
// messages API returns {items}, NOT {room} — keep room from rooms list
|
||||
this.room = meta || r.room || { id: id, kind: 'warroom', title: 'War Room' };
|
||||
this.messages = this.normalizeList(r.items || []);
|
||||
this.lastId = this.maxId(this.messages);
|
||||
this.historyTotal = r.total || this.messages.length;
|
||||
this.hasMoreHistory = !!r.has_more;
|
||||
this.stickToBottom = true;
|
||||
this.showJumpLatest = false;
|
||||
this.$nextTick(function () {
|
||||
@@ -174,7 +180,7 @@ window.WarRoomHub = (function () {
|
||||
}.bind(this));
|
||||
var last = (this.messages || [])[(this.messages || []).length - 1];
|
||||
if (last && last.sender_type === 'agent' && this.room && this.room.kind === 'warroom') {
|
||||
if (this.autoDebate) this.scheduleContinue(60000);
|
||||
if (this.autoDebate) this.scheduleContinue(120000);
|
||||
}
|
||||
} catch (e) {
|
||||
this.status = e.message || 'Laden mislukt';
|
||||
@@ -246,6 +252,58 @@ window.WarRoomHub = (function () {
|
||||
var near = this.isNearBottom(el, 100);
|
||||
this.stickToBottom = near;
|
||||
this.showJumpLatest = !near;
|
||||
// bovenaan: oudere geschiedenis laden
|
||||
if (el.scrollTop < 80) this.loadOlderMessages();
|
||||
},
|
||||
|
||||
minId(items) {
|
||||
var n = null;
|
||||
(items || []).forEach(function (m) {
|
||||
var id = Number(m && m.id);
|
||||
if (!isNaN(id) && (n === null || id < n)) n = id;
|
||||
});
|
||||
return n;
|
||||
},
|
||||
|
||||
async loadOlderMessages() {
|
||||
if (!this.room || !this.room.id) return;
|
||||
if (this.loadingHistory || this._loadingOlder || !this.hasMoreHistory) return;
|
||||
if (!(this.messages || []).length) return;
|
||||
this._loadingOlder = true;
|
||||
this.loadingHistory = true;
|
||||
var el = this.$refs && this.$refs.wrLog;
|
||||
var prevHeight = el ? el.scrollHeight : 0;
|
||||
var prevTop = el ? el.scrollTop : 0;
|
||||
try {
|
||||
var before = this.minId(this.messages);
|
||||
var r = await fetch(
|
||||
'/api/agents/warroom/rooms/' + this.room.id +
|
||||
'/messages?limit=400&before_id=' + before,
|
||||
{ credentials: 'same-origin' }
|
||||
).then(function (x) { return x.json(); });
|
||||
var older = this.normalizeList(r.items || []);
|
||||
if (older.length) {
|
||||
var existing = {};
|
||||
(this.messages || []).forEach(function (m) { existing[String(m.id)] = true; });
|
||||
var merged = older.filter(function (m) { return !existing[String(m.id)]; })
|
||||
.concat(this.messages || []);
|
||||
this.messages = merged;
|
||||
this.historyTotal = r.total || this.historyTotal;
|
||||
this.hasMoreHistory = !!r.has_more;
|
||||
var self = this;
|
||||
this.$nextTick(function () {
|
||||
self.paintAvatars();
|
||||
if (el) {
|
||||
// scrollpositie behouden na prepend
|
||||
el.scrollTop = el.scrollHeight - prevHeight + prevTop;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.hasMoreHistory = false;
|
||||
}
|
||||
} catch (e) { /* quiet */ }
|
||||
this.loadingHistory = false;
|
||||
this._loadingOlder = false;
|
||||
},
|
||||
|
||||
scrollLog(force) {
|
||||
@@ -538,7 +596,7 @@ window.WarRoomHub = (function () {
|
||||
setTimeout(function () { self.replyHighlightId = null; }, 4000);
|
||||
});
|
||||
}
|
||||
if (this.autoDebate) this.scheduleContinue(60000);
|
||||
if (this.autoDebate) this.scheduleContinue(120000);
|
||||
} catch (e) {
|
||||
// Keep optimistic message; restore draft only on hard fail
|
||||
this.status = e.message || 'Verzenden mislukt';
|
||||
@@ -642,6 +700,10 @@ window.WarRoomHub = (function () {
|
||||
if (window.Cockpit) Cockpit.toast(this.status, 'error');
|
||||
} else if (type === 'done') {
|
||||
this.typing = null;
|
||||
if (ev.loop_break) {
|
||||
this.pauseA2A(180000);
|
||||
this.status = 'A2A pauze — onderwerp herhaalde zich';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -733,13 +795,15 @@ window.WarRoomHub = (function () {
|
||||
opts = opts || {};
|
||||
if (!this.room || !this.room.id) return;
|
||||
try {
|
||||
var r = await fetch('/api/agents/warroom/rooms/' + this.room.id + '/messages?limit=200', {
|
||||
var r = await fetch('/api/agents/warroom/rooms/' + this.room.id + '/messages?limit=800', {
|
||||
credentials: 'same-origin',
|
||||
}).then(function (x) { return x.json(); });
|
||||
var items = this.normalizeList(r.items || []);
|
||||
if (items.length) {
|
||||
this.messages = items;
|
||||
this.lastId = this.maxId(items);
|
||||
this.historyTotal = r.total || items.length;
|
||||
this.hasMoreHistory = !!r.has_more;
|
||||
}
|
||||
if (!opts.silent) {
|
||||
this.$nextTick(function () {
|
||||
@@ -793,11 +857,11 @@ window.WarRoomHub = (function () {
|
||||
this.busy = false;
|
||||
this.status = 'A2A live';
|
||||
// keep conversation alive
|
||||
this.scheduleContinue(55000);
|
||||
this.scheduleContinue(90000);
|
||||
} catch (e) {
|
||||
this.busy = false;
|
||||
this.status = 'A2A hervatten…';
|
||||
this.scheduleContinue(45000);
|
||||
this.scheduleContinue(75000);
|
||||
}
|
||||
this._continueBusy = false;
|
||||
},
|
||||
@@ -871,6 +935,21 @@ window.WarRoomHub = (function () {
|
||||
return d.toLocaleDateString('nl-NL', { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric' });
|
||||
},
|
||||
|
||||
/** Compact stamp on each bubble: 16 aug · 00:53 */
|
||||
formatMsgStamp(m) {
|
||||
var raw = (m && (m.created_at || m.createdAt || m.ts)) || '';
|
||||
if (!raw) return '';
|
||||
var d = new Date(raw);
|
||||
if (isNaN(d.getTime())) return '';
|
||||
var today = new Date();
|
||||
var sameDay = d.getFullYear() === today.getFullYear() && d.getMonth() === today.getMonth() && d.getDate() === today.getDate();
|
||||
var time = d.toLocaleTimeString('nl-NL', { hour: '2-digit', minute: '2-digit' });
|
||||
if (sameDay) return time;
|
||||
var date = d.toLocaleDateString('nl-NL', { day: 'numeric', month: 'short', year: d.getFullYear() !== today.getFullYear() ? 'numeric' : undefined });
|
||||
return date + ' · ' + time;
|
||||
},
|
||||
|
||||
|
||||
dayKey(m) {
|
||||
var raw = (m && (m.created_at || m.createdAt || m.ts)) || '';
|
||||
if (!raw) return '';
|
||||
|
||||
Reference in New Issue
Block a user