mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 14:39:42 +02:00
fix: exclude full terminal buffers from SSE init to prevent browser freezes
- Add getLightState() and getLightSessionsState() methods - SSE init payload reduced from ~1.9MB to ~5KB (~400x smaller) - Terminal buffers are fetched on-demand when switching tabs - Fixes UI becoming unresponsive on SSE reconnect chore: bump version to 0.1388
This commit is contained in:
+54
-1
@@ -384,7 +384,9 @@ export class WebServer extends EventEmitter {
|
||||
this.sseClients.add(reply);
|
||||
|
||||
// Send initial state
|
||||
this.sendSSE(reply, 'init', this.getFullState());
|
||||
// Use light state for SSE init to avoid sending 2MB+ terminal buffers
|
||||
// Buffers are fetched on-demand when switching tabs
|
||||
this.sendSSE(reply, 'init', this.getLightState());
|
||||
|
||||
req.raw.on('close', () => {
|
||||
this.sseClients.delete(reply);
|
||||
@@ -2797,6 +2799,27 @@ export class WebServer extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lightweight session state for SSE init - excludes full terminal buffers
|
||||
* to prevent browser freezes on SSE reconnect. Full buffers are fetched
|
||||
* on-demand when switching tabs via /api/sessions/:id/buffer
|
||||
*/
|
||||
private getLightSessionsState() {
|
||||
return Array.from(this.sessions.values()).map(s => {
|
||||
const controller = this.respawnControllers.get(s.id);
|
||||
const detailed = s.toDetailedState();
|
||||
return {
|
||||
...detailed,
|
||||
// Exclude full buffers - they're fetched on-demand
|
||||
terminalBuffer: '',
|
||||
textOutput: '',
|
||||
respawnEnabled: controller?.getConfig()?.enabled ?? false,
|
||||
respawnConfig: controller?.getConfig() ?? null,
|
||||
respawn: controller?.getStatus() ?? null,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Clean up old completed scheduled runs
|
||||
private cleanupScheduledRuns(): void {
|
||||
const now = Date.now();
|
||||
@@ -2850,6 +2873,36 @@ export class WebServer extends EventEmitter {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lightweight state for SSE init - excludes full terminal buffers
|
||||
* to prevent browser freezes. Terminal buffers are fetched on-demand.
|
||||
*/
|
||||
private getLightState() {
|
||||
const respawnStatus: Record<string, ReturnType<RespawnController['getStatus']>> = {};
|
||||
for (const [sessionId, controller] of this.respawnControllers) {
|
||||
respawnStatus[sessionId] = controller.getStatus();
|
||||
}
|
||||
|
||||
const activeSessionTokens: Record<string, { inputTokens?: number; outputTokens?: number; totalCost?: number }> = {};
|
||||
for (const [sessionId, session] of this.sessions) {
|
||||
activeSessionTokens[sessionId] = {
|
||||
inputTokens: session.inputTokens,
|
||||
outputTokens: session.outputTokens,
|
||||
totalCost: session.totalCost,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
version: APP_VERSION,
|
||||
sessions: this.getLightSessionsState(),
|
||||
scheduledRuns: Array.from(this.scheduledRuns.values()),
|
||||
respawnStatus,
|
||||
globalStats: this.store.getAggregateStats(activeSessionTokens),
|
||||
subagents: subagentWatcher.getRecentSubagents(60),
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
private sendSSE(reply: FastifyReply, event: string, data: unknown): void {
|
||||
try {
|
||||
reply.raw.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
|
||||
Reference in New Issue
Block a user