mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-16 09:31:37 +00:00
A heavy --tui session (browser snapshots, large tool outputs) silently OOM-killed the Node parent within minutes — closing the gateway child's stdin, which the user saw only as a bare "gateway exited" / stdin EOF. CLI was immune. Root cause: each completed tool's verbose trail line embedded up to 16KB of result_text, persisted in transcript Msg.tools[] for the whole session and rendered EXPANDED by default, so an Ink render-node tree was built for every one of up to 800 messages at once. That tree blew past Node's heap at a few hundred MB — far below the 2.5GB memory-monitor exit threshold, so the death was never even attributed. - text.ts: persisted verbose tool-trail blocks now cap to a small preview (VERBOSE_TRAIL_MAX_CHARS=800/12 lines), not the 16KB live-render budget. Retained trail strings drop ~17x (12.2MB -> 0.7MB at 800 msgs); the live streaming tail still uses the larger LIVE_RENDER budget. - tui_gateway/server.py: lower the gateway-side verbose text cap to match (1KB/16 lines) so we stop shipping output the TUI no longer renders. - memoryMonitor.ts: derive critical/high thresholds from the real V8 heap ceiling (~88%/70%) instead of the hardcoded 2.5GB that killed the process at 31% of an 8GB ceiling; add a one-shot onWarn early-warning on fast sub-threshold heap growth so the next such death is diagnosable, not silent. - entry.tsx: wire onWarn to a crash-log breadcrumb + stderr line. Full tool output is unchanged in the agent context and SQLite session — this is display/transport only, no behavior or context change. Fixes #34095. Related #27282. Tests: ui-tui text + new memoryMonitor suites (33 pass), python verbose-cap guard (5 pass); full ui-tui suite shows no new failures vs pristine main. E2E repro confirms the retention drop.
26 lines
1.3 KiB
TypeScript
26 lines
1.3 KiB
TypeScript
export const LARGE_PASTE = { lines: 5 }
|
|
|
|
export const LIVE_RENDER_MAX_CHARS = 16_000
|
|
export const LIVE_RENDER_MAX_LINES = 240
|
|
|
|
// Persisted verbose tool-trail blocks (Args/Result embedded in a completed
|
|
// tool line) are kept for the WHOLE session in transcript Msg.tools[] and
|
|
// rendered expanded by default, so a render-node tree is built for every one
|
|
// of up to MAX_HISTORY messages at once. Capping these to the live-render
|
|
// budget (16KB) let a heavy browser/large-output session retain ~12MB of
|
|
// strings that exploded into a few hundred MB of Ink nodes and silently OOM-
|
|
// killed the Node parent (→ stdin EOF, gateway death; issue #34095). The live
|
|
// streaming tail still uses the larger LIVE_RENDER budget — only the persisted
|
|
// per-call block shrinks to a readable preview here. Full output remains in the
|
|
// agent context and the SQLite session; the trail is a glance, not a log.
|
|
export const VERBOSE_TRAIL_MAX_CHARS = 800
|
|
export const VERBOSE_TRAIL_MAX_LINES = 12
|
|
|
|
export const LONG_MSG = 300
|
|
export const MAX_HISTORY = 800
|
|
export const THINKING_COT_MAX = 160
|
|
|
|
// Rows per wheel event (pre-accel). 1 keeps Ink's DECSTBM fast path live
|
|
// (each scroll < viewport-1) and produces smooth motion. wheelAccel.ts
|
|
// ramps this on sustained scrolls.
|
|
export const WHEEL_SCROLL_STEP = 1
|