Skip to content

Study Hub AI

Study Hub AI is a first-class dockable learning workspace. It is not a generic chatbot pasted on top of course pages: Ask mode answers with bounded Study Hub context, while Tutor mode owns a persistent Probe → verified Plan → Teach one step → Check → Adapt loop.

Product contract

  • /ai is a global workspace destination. Each conversation has a stable /ai?conversation=<id> identity and can be opened in ordinary tabs or split panes.
  • /ai opens directly on a live composer. A conversation is only written to storage, and only claims its ?conversation= identity, once the learner's first turn is sent, so abandoned openings never accumulate in history. Adopting that identity never reloads an in-flight answer.
  • Opening AI from a course page carries that page into the next new conversation once. Later pane focus never mutates the conversation's reference set.
  • @ searches open referenceable course panes and canonical Study Hub course material. Add page is the explicit shortcut. Attached reference chips remain visible, removable, and persistent inside the composer so the context being sent is clear before each turn.
  • Ask and Tutor are explicit modes. Automatic model routing is the default; a configured model can be pinned per conversation.
  • The model picker and Ask/Tutor switch live in the composer. Assistant responses render safe GitHub-flavored Markdown, inline and display LaTeX through KaTeX, and fenced Mermaid diagrams in the reading column without a surrounding card; learner messages keep a compact bubble so the two roles remain easy to scan. Raw HTML remains disabled, and invalid Mermaid source falls back to a visible error with its source preserved. Fenced code uses the same block as authored course snippets: a labeled header carrying the fence language, a copy action, and shared highlighting.
  • Ask answers use provider-backed text streaming. One compact, expandable pixel-grid trace reports the current phase and elapsed time, then the answer grows from actual transport chunks. The trace records visible application work—reference retrieval, model generation, writing, and grounding—not hidden model chain-of-thought.
  • Any turn can be stopped from the composer or with Escape, which aborts the request so the server stops generating too. Text that already arrived is kept as a finished answer; a turn stopped before anything arrived records nothing and leaves Tutor session state untouched.
  • Validated citations become numbered inline source links and remain available in a compact source disclosure. Completed answers expose copy and regenerate actions and contextual follow-up prompts.
  • Tutor probes return structured choices that render as approval cards, so multiple-choice prompts never fall back to A/B/C/D prose and the learner explicitly chooses before the Tutor advances. The prompt bar supports @ sources, / commands, model and mode selection, and browser dictation when the Web Speech API is available.
  • Explicit quiz requests such as Quiz me on this, Test my understanding, or /quiz use a schema-validated quiz artifact instead of prose. The artifact supports single- and multiple-choice questions, answer checking, explanations, scoring, and retry, and remains part of local conversation history. Quiz requests also work without interrupting an active Tutor session.
  • Every topic exposes a private Visual Explainer preview. It generates a 30–60 second, source-grounded storyboard from fixed emphasis choices, validates every cited source ID, and runs a separate grounded quality review. Explicit approval queues a durable job for the isolated, trusted Manim renderer; real progress, private playback, captions, cache reuse, retries, and correction reports are documented in Visual Explainer.
  • AI-generated Mermaid is validated before rendering. Study Hub also repairs the common invalid class-note form produced by models while preserving unrecoverable source in the error state.
  • History supports search, rename, pin, archive, restore, and explicit deletion from either a history row or the conversation menu. Closing an AI pane does not delete its conversation.
  • Tutor uses one explicit primary course, keeps the learning path and evidence ledger as application state, and never treats self-report as mastery.
  • Conversation History collapses at workspace level. Tutor Path and Progress rails collapse per conversation. Mobile sheets are transient and do not overwrite those desktop preferences.

Architecture and trust boundaries

The implementation lives under src/ai:

  • conversations/ stores a compact index and separate conversation records in localStorage. This keeps multiple open conversations independent and includes migration from the interrupted single-record prototype.
  • references/ reuses the validated Course OS search index. The server resolves every submitted href, course, topic, collection, block, and revision before retrieval. Client labels are never trusted as source metadata.
  • providers/ is the only provider-SDK boundary. It routes operations through enabled models, enforces timeouts, records actual model/fallback metadata, and sends provider-neutral errors to the browser.
  • tutor/ contains the application-owned state machine, evidence updates, structured-output schemas, dependency-plan validation, and adaptive transitions. Provider output proposes a bounded result; only this code mutates Tutor state.
  • src/app/api/ai/ contains Node route handlers for model discovery, reference search, Ask, Tutor start, and Tutor turns. Mutation routes require JSON, reject cross-site requests, apply a best-effort per-process request limit, and return private no-store responses.
  • src/ai/ui/AiWorkspace.client.tsx is the dense desktop/mobile workspace surface. It uses shared primitives and normal dockable-workspace navigation instead of introducing a second tab system. Its canonical visual direction is the border-light Unhoused composition: history, the learning thread, and Tutor context remain distinct through spacing and typography; Tutor progress becomes one compact thread above the composer instead of another permanent panel.

Course source text is wrapped as untrusted data in provider prompts. Only canonical internal source IDs and hrefs can become citations. Tutor plan generation is followed by a separate bounded verification call; unsupported foundations or prerequisite claims prevent the plan from being installed. A session is also rejected when its course revision no longer matches the current published course.

Native Study Hub Ask and Tutor use the server-side providers configured below. A compatible Claude, ChatGPT, or other MCP client can instead operate the same canonical Study Hub sources and Tutor records through the remote MCP connector, using the model supplied by that client. The client's consumer plan and MCP support determine availability and limits; an MCP connection does not convert a consumer subscription into provider API credit, and Study Hub never stores the client's model-provider credentials.

Provider configuration

At least one server-side credential enables AI. Do not prefix any credential with NEXT_PUBLIC_.

Provider Credential Optional model override Default model
Groq GROQ_API_KEY GROQ_MODEL_ID, GROQ_MODEL_NAME openai/gpt-oss-120b
Google Gemini GEMINI_API_KEY (or GOOGLE_GENERATIVE_AI_API_KEY) GEMINI_MODEL_ID, GEMINI_MODEL_NAME gemini-3.7-flash
OpenRouter OPENROUTER_API_KEY OPENROUTER_MODEL_ID, OPENROUTER_MODEL_NAME openrouter/free
Mistral MISTRAL_API_KEY MISTRAL_MODEL_ID, MISTRAL_MODEL_NAME mistral-large-latest
OrcaRouter ORCAROUTER_API_KEY ORCAROUTER_BASE_URL, ORCAROUTER_MODEL_ID, ORCAROUTER_MODEL_NAME orcarouter/free
Hetzner Inference HETZNER_INFERENCE_API_KEY (or HETZNER_VLLM_API_KEY) HETZNER_INFERENCE_BASE_URL, HETZNER_INFERENCE_MODEL_ID, HETZNER_INFERENCE_MODEL_NAME Qwen3.8-27B
NVIDIA NIM NVIDIA_NIM_API_KEY NVIDIA_NIM_BASE_URL, NVIDIA_NIM_MODEL_ID, NVIDIA_NIM_MODEL_NAME nvidia/nemotron-3-super-120b-a12b

One provider credential enables its full application allowlist. Groq exposes GPT-OSS 120B, GPT-OSS 20B, Llama 3.3 70B, and Llama 4 Maverick. Gemini exposes Gemini 3.7 Flash, 3.6 Flash, 3.5 Flash, and 3.5 Flash-Lite. OpenRouter exposes its Free Router, GPT-OSS 120B, Gemini 3.7 Flash, and Claude Sonnet 4.6. Mistral exposes the configured default plus Mistral Small. OrcaRouter exposes its configured routed model, while Hetzner exposes Qwen 3.8 27B and Qwen 3.6 35B A3B. OrcaRouter, Hetzner, and NVIDIA NIM are Ask-only experimental choices and are not part of automatic fallback. The Llama choices are also Ask-only because the Tutor state machine requires structured output.

Only providers with a credential appear in GET /api/ai/models. Automatic mode tries only each provider's automatic default in allowlist order (Groq, Gemini, OpenRouter, then Mistral, so the free tiers are tried before the paid Mistral endpoint); OrcaRouter, Hetzner, NVIDIA NIM, and the additional choices are opt-in and never expand the automatic fallback chain. A pinned model does not switch to a different model unless allowFallbackWhenPinned is explicitly enabled in the conversation. The exception is an explicit quiz request while an Ask-only model is pinned: quizzes are routed automatically to a configured quiz-capable model because they require structured output. When direct Gemini 3.7 is pinned, an unavailable Google endpoint may retry the same Gemini 3.7 model through the configured OpenRouter provider; completion metadata exposes the actual provider and fallback depth. The Ask-only classification is backed by pinned streaming probes: both providers completed text requests, while schema-validated output did not pass acceptance. Settings can hide configured models from the manual picker without changing automatic server routing. This device-level visibility preference is backed up and synchronized with the existing workspace preference record; newly configured models appear by default. Provider credentials and raw provider errors are never returned by an API or persisted in browser state. Conversations live in the account-scoped local partition and are one of the synchronized personal domains, so a signed-in learner reaches the same history from another device. See Accounts and cross-device synchronization for the transport and conflict rules.

For local development, copy .env.example to .env.local, add at least one provider credential, then run npm run dev. On the VPS, add credentials to the appropriate external .env file used by the production or isolated test compose project and recreate the application container. Never commit real values.

HTTP surface

  • GET /api/ai/models — enabled, public-safe model choices.
  • GET /api/ai/references?q=... — canonical Study Hub-only reference results.
  • POST /api/ai/ask — grounded Ask turn with bounded recent history, returned as a private newline-delimited event stream (status, text_delta, schema-validated artifact, complete, or safe error).
  • POST /api/ai/tutor/start — creates an application session and the first diagnostic probe.
  • POST /api/ai/tutor/turn — revision-checked answer, hint, explanation, pause, or resume action.
  • POST /api/visual-explainers/storyboard — allowlisted, quota-limited grounded storyboard events.
  • POST /api/visual-explainers/jobs/:id/render — explicit render approval and queue transition.
  • GET /api/visual-explainers/jobs/:id/events — private durable renderer progress over SSE.
  • GET /api/visual-explainers/jobs/:id/artifact — owner-only byte-range video, captions, or poster.
  • /api/visual-explainers/worker/* — bearer-protected internal claim and lease update boundary.

All payloads are schema-versioned and reject unknown fields. Tutor records, message history, references, goals, and source bodies have explicit count and size bounds.

Verification

Run the focused AI suite while iterating:

npm exec vitest run src/ai src/app/api/ai

Before delivery, run the repository gate:

npm run check

Manual verification should cover: the no-provider banner; sending straight from a bare /ai and confirming the URL gains its conversation identity mid-turn without reloading; Ask with and without a reference; actual incremental Ask text; stopping a turn mid-stream from the button and from Escape, and stopping one before any text arrives; loading elapsed time and reduced motion; activity disclosure; inline source navigation; Mermaid, LaTeX, and fenced-code rendering with its copy action; interactive quiz generation, grading, and retry; response actions and follow-ups; approval choices; @ and / keyboard menus; dictation when supported; automatic and pinned routing; provider failure preservation; reference removal; independent conversations in split panes; all history actions; broad-to-narrow probing; verified plan display; advance, reinforce, replan, pause/resume, and completion; desktop rail persistence; and mobile History/Path/Progress sheets.