github HKUDS/DeepTutor v1.5.8

3 hours ago

DeepTutor v1.5.8 Release Notes

Release Date: 2026.08.02

A maintenance release with one target: memory that stays put instead of climbing. A v1.5.7 source deployment grew past 14 GB before V8 gave up mid-session, and the causes turned out to be independent — a frontend dev server whose heap ceiling never reached the process holding the memory, unbounded in-process caches, and a fresh HTTP client built for every turn. Drop-in — no migrations, but a source checkout now starts differently.

What's New

The dev server was never actually capped

next dev renders in a worker it spawns itself, and V8 flags in argv are not inherited by child processes — so the long-standing node --max-old-space-size=4096 …/next dev never reached the process that holds the memory. Finding no ceiling in NODE_OPTIONS, Next substituted 50% of total RAM: a 12 GB heap on a 24 GB machine, which V8 genuinely tried to fill before dying in Ineffective mark-compacts near heap limit after 63 seconds inside a single mark-compact. web/scripts/dev.mjs now passes the ceiling through NODE_OPTIONS, which the worker does inherit and Next honors — clamped to 4 GB, and sized against the cgroup limit inside a container rather than the host's RAM.

Source installs serve a production build

deeptutor start from a checkout now builds the frontend once into .next-deeptutor and serves the standalone output, reusing that build until an input actually changes (a fingerprint over the web/ tree, the version file, and the build-time public settings). Hot reload moves to deeptutor start --dev, which keeps using .next — separate directories, so neither mode invalidates the other's output while it is running. A long-running deployment no longer pays for a dev compiler's caches.

Bounded LLM clients instead of one per turn

The chat, research and question pipelines each built a fresh OpenAI-compatible client — and with it a new HTTP connection pool — on every turn. Both the agentic client and the services-layer provider now come from a small event-loop-local LRU pool of 2, keyed on binding, model, credentials and base URL, closed on shutdown and retired when settings change. Only the selected backend's SDK is imported.

Caches with a ceiling

Knowledge-task log streams now cap events and bytes per task, expire an hour after a task ends, and leave a small completion tombstone so a late subscriber still learns the task finished. The completed-task table keeps 256 entries. The LlamaIndex index cache drops from 8 entries to 2 and evicts anything idle for 10 minutes. A book runtime is released once its queue drains instead of living for the process.

Reclaiming what was already freed

After a turn, a finished book job, or a completed knowledge-base task, DeepTutor collects cycles and — on Linux — calls malloc_trim so glibc hands free heap pages back instead of holding arenas that make RSS look permanently pinned. Containers and deeptutor start also set MALLOC_ARENA_MAX=2 and a lower trim threshold, both overridable by an operator who has tuned their own.

A keep-alive race that surfaced as 500s

web/proxy.ts forwards to the backend over Node's http.globalAgent, which reaps idle sockets on a 5s timer — identical to uvicorn's default. Both ends armed the same timer on the same socket and raced to close it; when the server's FIN landed on a socket the pool was simultaneously handing to a new request, that request died with ECONNRESET and reached the UI as "Failed to load sessions". Every uvicorn launch now sets --timeout-keep-alive 300, leaving the client as the only side that retires an idle connection.

Assorted

  • deeptutor.agents, deeptutor.core.agentic, the provider-core package, the document extractor's parser libraries (PyMuPDF, pypdf, python-docx, openpyxl, python-pptx) and the LLM error-mapping rules all resolve on first use rather than at import time.
  • python -m deeptutor.api.run_server no longer starts with --reload; export DEEPTUTOR_DEV_RELOAD=1 for it. Reload runs a supervisor plus a worker and retains file-watcher state, which is development machinery. deeptutor serve --reload is unchanged.

Upgrade Notes

Drop-in from v1.5.7: pip install -U deeptutor; Docker users pull ghcr.io/hkuds/deeptutor:latest. No schema or config changes.

  • Source checkouts build before they serve. The first deeptutor start after upgrading runs npm run build and takes correspondingly longer; later launches reuse it until the source changes. Use deeptutor start --dev for the previous hot-reload loop. The new web/.next-deeptutor/ build directory is git-ignored.
  • python -m deeptutor.api.run_server no longer reloads by default. Export DEEPTUTOR_DEV_RELOAD=1 to restore it.

Full Changelog: v1.5.7...v1.5.8

Don't miss a new DeepTutor release

NewReleases is sending notifications on new releases.