mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
24 files, -319 LoC. Behaviour preserved, 369/369 tests green. - hermes-ink caches: shared lruEvict helper for the four parallel LRU caches (stringWidth, wrapText, sliceAnsi, lineWidth); touch-on-read stays inlined per cache; tightened output.ts skip-slice fast path. - wheelAccel: trimmed provenance header, collapsed env parsing, ternary dispatch in computeWheelStep. - perfPane: folded ensureLogDir into once-flag, spread-with-overrides for fastPath/phases instead of full rebuilds. - env: extracted truthy() (used 4×). - virtualHeights: collapsed user/diff/slash height bumps; trail+todos estimate. - useInputHandlers: scrollIdleTimer cleanup on unmount, ?? undefined shorthand. - useMainApp: dropped dead liveTailVisible IIFE and liveProgress indirection. - appLayout, markdown, messageLine, entry: vertical rhythm, dropped narration comments, inlined one-shot vars. - fix: empty catch blocks → /* best-effort */ for no-empty lint.
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { evictInkCaches } from '@hermes/ink'
|
|
|
|
import { type HeapDumpResult, performHeapDump } from './memory.js'
|
|
|
|
export type MemoryLevel = 'critical' | 'high' | 'normal'
|
|
|
|
export interface MemorySnapshot {
|
|
heapUsed: number
|
|
level: MemoryLevel
|
|
rss: number
|
|
}
|
|
|
|
export interface MemoryMonitorOptions {
|
|
criticalBytes?: number
|
|
highBytes?: number
|
|
intervalMs?: number
|
|
onCritical?: (snap: MemorySnapshot, dump: HeapDumpResult | null) => void
|
|
onHigh?: (snap: MemorySnapshot, dump: HeapDumpResult | null) => void
|
|
}
|
|
|
|
const GB = 1024 ** 3
|
|
|
|
export function startMemoryMonitor({
|
|
criticalBytes = 2.5 * GB,
|
|
highBytes = 1.5 * GB,
|
|
intervalMs = 10_000,
|
|
onCritical,
|
|
onHigh
|
|
}: MemoryMonitorOptions = {}): () => void {
|
|
const dumped = new Set<Exclude<MemoryLevel, 'normal'>>()
|
|
|
|
const tick = async () => {
|
|
const { heapUsed, rss } = process.memoryUsage()
|
|
const level: MemoryLevel = heapUsed >= criticalBytes ? 'critical' : heapUsed >= highBytes ? 'high' : 'normal'
|
|
|
|
if (level === 'normal') {
|
|
return void dumped.clear()
|
|
}
|
|
|
|
if (dumped.has(level)) {
|
|
return
|
|
}
|
|
|
|
// Prune Ink content caches before dump/exit — half on 'high' (recoverable),
|
|
// full on 'critical' (post-dump RSS reduction, keeps user running).
|
|
evictInkCaches(level === 'critical' ? 'all' : 'half')
|
|
|
|
dumped.add(level)
|
|
const dump = await performHeapDump(level === 'critical' ? 'auto-critical' : 'auto-high').catch(() => null)
|
|
|
|
const snap: MemorySnapshot = { heapUsed, level, rss }
|
|
|
|
;(level === 'critical' ? onCritical : onHigh)?.(snap, dump)
|
|
}
|
|
|
|
const handle = setInterval(() => void tick(), intervalMs)
|
|
|
|
handle.unref?.()
|
|
|
|
return () => clearInterval(handle)
|
|
}
|