fix(server): free finalized message text in TimelineAssembler

TimelineAssembler.messages map retained full assistantText and
reasoningText for every message for the lifetime of the session.
Replace with a lightweight finalizedMessageIds set that prevents
duplicate emission during history replay without holding the text.
This commit is contained in:
Mohamed Boudra
2026-03-23 12:29:23 +07:00
parent ed3ed78ec3
commit c9ca1697e5
@@ -770,6 +770,7 @@ type TimelineMessageState = {
class TimelineAssembler {
private readonly messages = new Map<string, TimelineMessageState>();
private readonly finalizedMessageIds = new Set<string>();
private readonly activeMessageByRun = new Map<string, string>();
private syntheticMessageCounter = 0;
@@ -799,6 +800,9 @@ class TimelineAssembler {
if (!messageId) {
return [];
}
if (this.finalizedMessageIds.has(messageId)) {
return [];
}
const state = this.ensureMessageState(messageId, runId);
const fragments = this.extractFragments(message.message?.content);
return this.applyAbsoluteFragments(state, fragments);
@@ -922,6 +926,8 @@ class TimelineAssembler {
if (runId && this.activeMessageByRun.get(runId) === messageId) {
this.activeMessageByRun.delete(runId);
}
this.finalizedMessageIds.add(messageId);
this.messages.delete(messageId);
return items;
}