tycono 0.1.96-beta.39 → 0.1.96-beta.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.1.96-beta.39",
3
+ "version": "0.1.96-beta.40",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -83,19 +83,30 @@ class WaveMultiplexer {
83
83
 
84
84
  const sessions = this.waveSessions.get(waveId);
85
85
  if (sessions) {
86
- // Phase 1: Replay all historical events sorted by timestamp
87
- const allEvents: { event: ActivityEvent; sessionId: string }[] = [];
86
+ // Phase 1: Replay recent historical events (capped to prevent OOM)
87
+ // Only replay from recent sessions (last 5) to avoid 120-session waves killing memory
88
+ const MAX_REPLAY_SESSIONS = 5;
89
+ const MAX_REPLAY_EVENTS = 200;
90
+
91
+ const sessionList = Array.from(sessions.values());
92
+ const recentSessions = sessionList.slice(-MAX_REPLAY_SESSIONS);
88
93
 
89
- for (const [, exec] of sessions) {
94
+ const allEvents: { event: ActivityEvent; sessionId: string }[] = [];
95
+ for (const exec of recentSessions) {
90
96
  const events = ActivityStream.readFrom(exec.sessionId, 0);
91
- for (const event of events) {
97
+ // Take last N events per session
98
+ const recent = events.slice(-50);
99
+ for (const event of recent) {
92
100
  allEvents.push({ event, sessionId: exec.sessionId });
93
101
  }
94
102
  }
95
103
 
96
104
  allEvents.sort((a, b) => a.event.ts.localeCompare(b.event.ts));
97
105
 
98
- for (const item of allEvents) {
106
+ // Cap total replay events
107
+ const replayEvents = allEvents.slice(-MAX_REPLAY_EVENTS);
108
+
109
+ for (const item of replayEvents) {
99
110
  const waveSeq = client.waveSeq++;
100
111
  if (waveSeq < fromWaveSeq) continue;
101
112
 
@@ -111,8 +122,10 @@ class WaveMultiplexer {
111
122
  } as WaveStreamEnvelope);
112
123
  }
113
124
 
125
+ console.log(`[WaveMux] Replayed ${replayEvents.length} events (${sessionList.length} total sessions, ${recentSessions.length} replayed)`);
126
+
114
127
  // Phase 2: Subscribe to live events for active sessions
115
- for (const [, exec] of sessions) {
128
+ for (const [, exec] of sessionList) {
116
129
  if (exec.status === 'running' || exec.status === 'awaiting_input') {
117
130
  this.subscribeSessionToClient(waveId, client, exec, true);
118
131
  }
@@ -137,7 +150,8 @@ class WaveMultiplexer {
137
150
  });
138
151
 
139
152
  const events = ActivityStream.readFrom(execution.sessionId, 0);
140
- for (const event of events) {
153
+ const recentEvents = events.slice(-50); // Cap replay per session
154
+ for (const event of recentEvents) {
141
155
  const key = `${event.roleId}:${event.seq}`;
142
156
  if (client.sentEvents.has(key)) continue;
143
157
  client.sentEvents.add(key);