( data: ContextData, suggestions: ContextSuggestion[], )
| 185 | } |
| 186 | |
| 187 | function checkMemoryBloat( |
| 188 | data: ContextData, |
| 189 | suggestions: ContextSuggestion[], |
| 190 | ): void { |
| 191 | const totalMemoryTokens = data.memoryFiles.reduce( |
| 192 | (sum, f) => sum + f.tokens, |
| 193 | 0, |
| 194 | ) |
| 195 | const memoryPercent = (totalMemoryTokens / data.rawMaxTokens) * 100 |
| 196 | |
| 197 | if ( |
| 198 | memoryPercent >= MEMORY_HIGH_PERCENT && |
| 199 | totalMemoryTokens >= MEMORY_HIGH_TOKENS |
| 200 | ) { |
| 201 | const largestFiles = [...data.memoryFiles] |
| 202 | .sort((a, b) => b.tokens - a.tokens) |
| 203 | .slice(0, 3) |
| 204 | .map(f => { |
| 205 | const name = getDisplayPath(f.path) |
| 206 | return `${name} (${formatTokens(f.tokens)})` |
| 207 | }) |
| 208 | .join(', ') |
| 209 | |
| 210 | suggestions.push({ |
| 211 | severity: 'info', |
| 212 | title: `Memory files using ${formatTokens(totalMemoryTokens)} tokens (${memoryPercent.toFixed(0)}%)`, |
| 213 | detail: `Largest: ${largestFiles}. Use /memory to review and prune stale entries.`, |
| 214 | savingsTokens: Math.floor(totalMemoryTokens * 0.3), |
| 215 | }) |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | function checkAutoCompactDisabled( |
| 220 | data: ContextData, |
no test coverage detected