github HKUDS/DeepTutor v1.5.11

3 hours ago

DeepTutor v1.5.11 Release Notes

Release Date: 2026.08.10

v1.5.10 was about the paths underneath a request holding up; this one is about what happens while the answer is still being written. Prose that shared a round with a tool call used to vanish into the trace, a truncated generation was read as the model deciding it had finished, and local indexing sat on the event loop everything else needed. The settings strip also stops restating what the Models page already tells you and starts showing the one number nothing else did: what DeepTutor is actually costing in memory. Drop-in — no migrations, nothing to re-index.

What's New

Text around a tool call is no longer lost

DeepSeek's Anthropic-compatible endpoint interleaves user-facing prose and DSML tool-call markup in a single content stream. The old handling was all-or-nothing: once a round's content channel showed DSML markup, the rest of that round was diverted to the thinking channel, so any explanation the model wrote around its call disappeared from the answer. A streaming filter now removes only the DSML envelope and the invoke blocks, incrementally — text before, between, and after a call streams and persists as part of the reply. An incomplete call is released verbatim on flush rather than swallowed, and a 512-character ceiling means a stray < in ordinary prose cannot make the live stream wait forever for a closing bracket.

DSML array and object arguments decode correctly

DeepSeek marks essentially every DSML parameter string="true", JSON arrays and objects included, so a container argument arrived at the tool as a string of JSON. Parameter decoding now consults the declared tool schema: a parameter the schema types as array or object is parsed when the payload actually matches, and the provider's string contract still wins everywhere else. The schema catalog is kept even when a provider rejects native tools and the loop falls back to DSML, which is exactly when the parser needs it.

A truncated generation asks for a continuation

A length finish is an incomplete generation, not the model choosing to stop — but it was treated as a finish, so the reply ended mid-sentence. The loop now keeps the visible prefix and asks for a continuation, and the assembled answer carries the prefix through to persistence and the SDK. The round budget was restructured to make this safe: exploration rounds, then a small bounded settlement window, then a single tool-less hard finish, so repeated truncation and malformed tool cycles share one absolute upper bound of exploration + 4.

Live memory usage in Settings

The settings status strip carried Backend, LLM, Embedding, and Search — three of which restated what the Models and Chat pages already own. It now carries the two runtime facts no settings page shows: whether the backend is up, and resident memory across the whole DeepTutor process tree — backend, the Next.js server, and whatever sandboxes and subagent CLIs are alive — with a per-process split inline and a pressure dot that turns amber past two thirds of the limit. It is served by a new GET /api/v1/system/memory; psutil reads the tree and is imported lazily with a /proc fallback, so a missing wheel costs the strip and not the app. Non-admins and platforms where the tree cannot be read get {available: false} and no strip.

Local LightRAG indexing stops stalling everything else

RAG-Anything's local storage backends do synchronous graph merging and JSON serialization from inside async methods, so indexing a document on the service event loop froze unrelated API and LLM work for its duration. Indexing now runs on a worker thread's own event loop, with a narrow bridge that forwards LLM, vision, and embedding calls back to the request's loop, carrying a copy of the caller's context so request-local model and user configuration stays visible. Remote LightRAG servers are unaffected.

Mastery works from the persisted question, not the model's retelling

A posed question now projects into a small public contract — prompt, type, and the option label/body map — shared by registration, presentation, and grading, with the expected answer staying server-side. ask_user renders that persisted state instead of display data the model re-authored, so the choices a learner sees are the choices that will be graded. Registration validates the quiz shape rather than silently accepting a contradictory one: a missing type is inferred from the payload, short/open questions reject options, and a choice question must carry real option bodies instead of bare A/B/C labels.

Assorted

  • Connected knowledge bases answer honestly about local files. A linked external resource has no DeepTutor-managed raw/ directory; listing its files returns an empty collection instead of inventing one, and endpoints that require a local file return an explicit 409.
  • Generated output artifacts are served request-scoped. A new /api/outputs endpoint resolves and authorizes a path in one operation and fails closed with a 404 when there is no request user, so an auth-context regression cannot hand an administrator's artifact to an ordinary request.
  • Visualize iframes shrink as well as grow — the height bridge measures body content instead of a root height the host had already stretched, and coalesces reports into one animation frame.
  • The chat page's model list is fetched once. Option loading moved into a hook with single-flight de-duplication, so concurrent mounts and a tab-focus refresh no longer stack up identical requests.

Upgrade Notes

pip install -U deeptutor; Docker users pull ghcr.io/hkuds/deeptutor:latest. No schema changes, no re-index, no migration.

  • psutil is a new dependency and installs with the upgrade. It is imported lazily behind a /proc fallback — if your environment cannot provide it, the memory strip stays hidden and nothing else changes.

Full Changelog: v1.5.10...v1.5.11

Don't miss a new DeepTutor release

NewReleases is sending notifications on new releases.