github HKUDS/DeepTutor v1.1.1
DeepTutor-v1.1.1

12 hours ago

DeepTutor v1.1.1 Release Notes

Release Date: 2026.04.17

Highlights

Universal "Answer Now" Escape Hatch — Per-Capability Fast Paths

Promoted "Answer now" from a chat-only affordance to a universal interrupt that respects each capability's output shape. A new shared helper deeptutor/capabilities/_answer_now.py provides the gate (extract_answer_now_context) and the prompt-friendly trace summary, and every built-in capability now owns its own fast-path branch at the top of run():

  • chat — synthesize the final markdown answer from the partial trace (existing behavior).
  • deep_solve — skip planning + reasoning, jump straight into the writer.
  • deep_question — skip ideation/templates, emit the full quiz JSON in one structured call (still rendered by QuizViewer).
  • deep_research — skip rephrase/decompose/research, write the report directly from accumulated evidence.
  • math_animator — skip analysis + design + summary but keep code generation + render, so the user still gets a real animation.
  • visualize — skip analysis + review, emit the final renderable code in one structured call.

Each fast-path preserves the same result envelope as the normal pipeline (so the Quiz / MathAnimator / Visualization viewers render unchanged) and prepends a > ⚡ Skipped X stage(s) notice so users know it was a best-effort early exit. The orchestrator no longer re-routes answer_now to chat; it now keeps active_capability and only falls back to chat if the originally selected capability has been removed from the registry. The frontend matches: handleAnswerNow no longer overrides the snapshot's capability, and a single-shot guarded AnswerNowRow component renders the action inline below the streaming trace panel.

Co-Writer — Resizable Split & Line-Anchored Scroll Sync

The Co-Writer page picked up a draggable splitter between the editor and preview panes (with a persisted ratio in localStorage) and a true bidirectional scroll-sync that survives soft-wrapped lines. Each preview block now carries a data-source-line attribute pointing back at its starting line in the markdown source (provided by remark's AST positions); on the editor side a hidden mirror element mimics the textarea's wrap geometry so we can read the real pixel-y of every source line. With both sides expressed as pixel coordinates the sync becomes a single piecewise-linear interpolation in either direction, with a per-source-line cache that invalidates only when the content or wrap width changes.

Save-to-Notebook — Message Selection Mode

SaveToNotebookModal now accepts an optional messages prop that flips the modal into "selection mode": the user picks exactly which user/assistant turns to include, and the transcript + userQuery shipped to the backend are rebuilt from the selected subset. Quick presets ("Select all", "Last turn", "Last 3 turns") and an auto-derived title that tracks the first selected user message keep the flow fast for the common cases. The modal also now uses Check / MessageSquare / User icons to distinguish roles at a glance, and reports loading state for the notebook list separately from the save spinner.

Real Notebook System Adoption Across the Stack

Migrated every remaining Notebook surface off the legacy quiz-category API onto the real /api/v1/notebook/* endpoints. A new web/lib/notebook-api.ts block exports typed helpers — listNotebooks, getNotebook, createNotebook, updateNotebook, deleteNotebook, deleteNotebookRecord — alongside the preserved quiz-only helpers. The Knowledge → Notebooks tab, the Guide page's notebook reference picker (useNotebookSelection), and the Save-to-Notebook modal all now resolve UUIDs end-to-end, so records saved from Co-Writer, Chat, or Guided Learning are immediately discoverable as references everywhere.

Unified Collapsible Settings Panel

Extracted the collapsible "Settings" section that previously only existed in ResearchConfigPanel into a shared CollapsibleConfigSection component. The Quiz, Math Animator, and Visualize panels now share the exact same chevron + summary header, and each form ships a summarizeXxxConfig helper so the collapsed state shows a meaningful one-liner (e.g. Custom · 5q · Hard · MCQ or Mimic · paper.pdf · max 10). The chat page now keeps a single panelCollapsed state for whichever capability is active, auto-expands on capability switch, and auto-collapses after sending a message so the composer stays compact during conversation.

Streaming Stop Button & Composer Polish

Replaced the spinner-inside-the-Send-button with a dedicated Stop button that appears in place of Send while a turn is streaming. A faint ring slowly rotates around the rim to signal "still working — click to cancel", with a white square front-and-center as the click target. The header above the messages (capability label + Save / New chat buttons) is now always rendered, and the messages container picks up a soft mask gradient at the top and bottom so streaming content fades in/out instead of clipping at the scroll edge. In Deep Research mode, sources moved into a dropdown with a compact summary line of the active picks, matching the pattern used by the tool selector.

TutorBot Config Manager Refactor

Rewrote TutorBotManager's config persistence into a small public API (load_bot_config, save_bot_config, merge_bot_config) with three meaningful improvements: writes are now atomic (write-temp + Path.replace) so a killed process never leaves a half-written config.yaml; merges have explicit-clear semanticsNone means "leave as-is", an empty string or empty dict is an intentional clear — so clients can deliberately wipe a description or channels list; and the API endpoint forwards only model_dump(exclude_unset=True) so omitted fields fall through to the on-disk value. New regression tests cover the atomic-write contract, the corrupt-yaml fallback, and the four merge-semantics cases.

Markdown Renderer Refinements

The MarkdownRenderer family gained a trackSourceLines prop that propagates data-source-line attributes through every block element (headings, lists, paragraphs, etc.) and bypasses the line-shifting normalization passes (processMarkdownContent, normalizeMarkdownForDisplay) so AST positions stay faithful for editor/preview sync consumers. RichCodeBlock now skips react-syntax-highlighter entirely for unlabeled / text / plaintext fences (eliminating Prism "unknown language" warnings) and renders them as a tidy plain-monospace block. Mermaid detection was also extended to recognize editor.md style ```flow, ```seq, and ```sequence fences that get rewritten to mermaid by the preprocessor.

Theme & Guide UI Refresh

Tightened the default light and Snow themes with deeper foregrounds, warmer borders, and a slightly more saturated --primary (#B0501E) for better legibility against the new card surfaces. The Guided Learning page (/guide) was migrated off hardcoded slate-* / indigo-* palettes onto the design tokens (var(--card), var(--primary), var(--muted-foreground), etc.) so it now respects the theme switcher. HistorySessionPicker got the same treatment, plus a fix for session timestamps that were being treated as milliseconds instead of seconds (which produced 1970 dates).

System Message Rendering Fix

Backend system messages (e.g. quiz follow-up grounding context written by the turn runtime) are now filtered out at the UnifiedChatContext.hydrateMessages boundary and again defensively in ChatMessageList, so they never surface as ghost chat bubbles in the UI while still flowing into the LLM context as intended.

Bug Fixes

  • TutorBot channel config wiped on every server restart (#332)create_and_start_bot was constructing a fresh BotConfig with empty defaults on every call, which _save_bot_config then persisted over the existing config.yaml, wiping user-configured channels (e.g. Telegram). The endpoint now loads the existing config first and overlays only client-supplied fields.
  • selective_access_log middleware crash on every non-200 response (#334 / #335) — the middleware passed four args to uvicorn's AccessFormatter which expects five (omitting http_version), raising ValueError: not enough values to unpack on every error response. Now reads http_version from the ASGI scope with a 1.1 fallback.
  • 15 npm security vulnerabilities (#330) — bumped jspdf 4.0.0 → 4.2.0 (9 CVEs incl. critical PDF injection), next 16.1.1 → 16.2.3 (8 CVEs incl. HTTP smuggling, CSRF bypass), mermaid 11.12.2 → 11.14.0, and the matching eslint-config-next. npm audit fix swept up the indirect chain (flatted, lodash-es, minimatch, picomatch, dompurify, ajv, brace-expansion). End state: 0 vulnerabilities, no breaking changes.
  • .env.example_CN — removed an accidental // README suffix on the provider-list comment.

Test Suite Expansion

Added a new tests/services/tutorbot/test_manager_config.py module covering load/save round-trips, the corrupt-yaml fallback, atomic temp-file writes, failure-recovery after a mid-write OSError, and all four merge_bot_config semantics (no existing config, omitted-field passthrough, None-as-not-provided, and empty-value-as-explicit-clear). Extended tests/api/test_tutorbot_router.py with the explicit-clear test class. Rewrote the orchestrator answer-now routing tests to pin the new contract — active_capability is preserved when answer_now_context is set, the orchestrator falls back to chat only when the original capability is missing, and emits a clear error when neither is registered. Added a new tests/capabilities/test_answer_now.py module with 28 cases covering the shared helpers (extract_answer_now_context, format_trace_summary truncation/i18n, make_skip_notice, labeled_block, join_chunks) and every per-capability fast-path: chat, deep_solve, deep_question (including the unparseable-JSON fallback), deep_research, visualize (including code-fence stripping and invalid render_type recovery), and math_animator (verifying that run_analysis/run_design/run_summary are not invoked while run_code_generation/run_render are). A reverse test confirms that capabilities still take their normal pipeline when no answer_now_context is present.

What's Changed

  • Fix: TutorBot channel config wiped on every server restart by @srinivasrk in #332
  • fix(api): add missing http_version arg in selective_access_log middleware by @kagura-agent in #335
  • fix(web): resolve 15 npm security vulnerabilities by @srinivasrk in #330

Community Contributions

Full Changelog: v1.1.0...v1.1.1

Don't miss a new DeepTutor release

NewReleases is sending notifications on new releases.