RTerm v3.8.9
RTerm v3.8.9 — AI-Native Terminal App by Hyperspace Technologies
v3.8.9 (2026-09-18)
Four fixes for the extended-chat freeze family and session durability — all
found by reading the actual code paths, three of them live-observed.
The MemorySaver checkpoint leak — the real extended-chat freeze root cause
LangGraph's MemorySaver keeps every checkpoint of every graph step,
forever: storage[threadId][ns][checkpoint.id] holds a serialized copy of
the full conversation state per step. A 100-step multi-tool run retains
~100 copies in RAM — unbounded growth, GC thrash, and the "app freezes in
extended chats until force-quit" behavior. The earlier pruning work (v3.8.3)
shrank each blob but never evicted old blobs; the count kept climbing.
SafeMemorySaver now evicts: after each put it keeps only the newest
8 checkpoints per (thread, ns), enforced on all three put paths (normal,
OOM-retry, skip-persist). Insertion order is tracked per (thread, ns) since
MemorySaver exposes no timestamps; untracked ids (from before this process)
are kept rather than risk dropping the resume point. Safe because LangGraph
resumes from the latest checkpoint and parent-chain walking touches only
recent entries.
Interruption marker — force-quit recovery for chat sessions
A force quit mid-run leaves the session's last AI message partial, but
stored looking exactly like a completed turn. After restart the model reads
it as complete and treats the next message as a fresh topic — the
interrupted task is silently abandoned.
Now a run marker (in the history_meta table, survives restart) is set
just before graph.invoke and cleared in the run's finally block. Only a
hard kill skips finally, so a leftover marker means the run was
interrupted; the next run detects it, injects a system notice telling the
model the prior response may be partial (with the interrupted task's input
preview), and offers to continue rather than start from scratch.
Ordering bug caught in review before release: the marker was initially
set before the detection block — every run found its own marker, injected
a false notice, and consumed the real one, so a genuine force-quit left
nothing behind. The feature was inverted. The set now happens after the
restore path has consumed any leftover marker.
Rename race — renames reverted by the run-end save
Renaming a chat session during a running agent task silently reverted when
the task finished: the agent's in-memory session object carried the old
title from run start, and the store's upsert (title = excluded.title)
wrote it back over the rename at run end. ChatHistoryService.saveSession
now treats the stored title as authoritative for an existing session —
the in-memory title only names a brand-new session. Same discipline the
store already applied to created_at, which is why creation dates never
had this bug.
Also
- Dead code documented:
lastCheckpointOffsetis written on every run but
has no reader — the v3.2.5 "recovery can resume from this offset"
promise was never built. Left in place (harmless) pending a real consumer. GatewayService.resumeTaskremains an empty stub.
Tests
safeMemorySaverEviction.extreme.spec.ts(6) — retention window, per-thread
isolation, getTuple resolves newest after eviction, deleteThread, and the
control: vanilla MemorySaver retains all 50 (the leak), SafeMemorySaver caps.runMarker.extreme.spec.ts(7) — marker survives store close+reopen (the
force-quit case), per-session isolation, corrupt marker reads as absent,
consume-once semantics.renameRace.extreme.spec.ts(4) — the exact live race: load → rename
mid-run → save the stale object → the rename survives.- All wired into
test:backend-unit-extreme.
Downloads
| Platform | File |
|---|---|
| macOS ARM64 | RTerm-3.8.9-arm64.dmg |
| Windows x64 (Portable) | RTerm.Portable.3.8.9-x64.exe |
| Windows x64 (Setup) | RTerm.Setup.3.8.9-x64.exe |
| Linux x64 (AppImage) | RTerm-3.8.9-x64.AppImage |
| Linux x64 (deb) | RTerm-3.8.9-x64.deb |
| Linux x64 (pacman) | RTerm-3.8.9-x64.pacman |
| Linux x64 (rpm) | RTerm-3.8.9-x64.rpm |
| Linux ARM64 (AppImage) | RTerm-3.8.9-arm64.AppImage |
| Linux ARM64 (deb) | RTerm-3.8.9-arm64.deb |
| Linux ARM64 (rpm) | RTerm-3.8.9-arm64.rpm |
Install
macOS: After installing, run xattr -cr /Applications/RTerm.app to remove quarantine.
Linux AppImage: chmod +x RTerm-*.AppImage && ./RTerm-*.AppImage
Linux deb: sudo dpkg -i RTerm-*.deb
Linux rpm: sudo rpm -i RTerm-*.rpm
Contact: rterm@hyperspace.ng