(ctx context.Context)
| 104 | } |
| 105 | |
| 106 | func (mw *memoryWorker) loop(ctx context.Context) { |
| 107 | extractTicker := time.NewTicker(3 * time.Minute) |
| 108 | compactTicker := time.NewTicker(compactionCheckInterval) |
| 109 | cleanupTicker := time.NewTicker(dailyCleanupInterval) |
| 110 | // Rollups must not wait for the 24h cleanup tick — short sessions would |
| 111 | // never consolidate. One early pass shortly after start, then periodic. |
| 112 | rollupTimer := time.NewTimer(2 * time.Minute) |
| 113 | rollupTicker := time.NewTicker(rollupCheckInterval) |
| 114 | defer extractTicker.Stop() |
| 115 | defer compactTicker.Stop() |
| 116 | defer cleanupTicker.Stop() |
| 117 | defer rollupTimer.Stop() |
| 118 | defer rollupTicker.Stop() |
| 119 | |
| 120 | for { |
| 121 | select { |
| 122 | case <-mw.stopCh: |
| 123 | return |
| 124 | case <-extractTicker.C: |
| 125 | mw.maybeExtract(ctx) |
| 126 | case <-compactTicker.C: |
| 127 | mw.maybeCompact(ctx) |
| 128 | case <-cleanupTicker.C: |
| 129 | mw.cleanupDailyNotes() |
| 130 | case <-rollupTimer.C: |
| 131 | mw.runRollups(ctx) |
| 132 | case <-rollupTicker.C: |
| 133 | mw.runRollups(ctx) |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // runRollups consolidates elapsed weeks/months into digests. Rollup passes |
| 139 | // are idempotent and cheap when nothing is pending; the LLM is only invoked |
no test coverage detected