Three real sessions, start to finish.
One session for each context type: an algebra problem, a question about recursion, and a persuasive essay. The screenshots are the real app and the quotes are what it said.
Algebra Homework Help
The student opens with "Can you just tell me the answer?" Four exchanges later they have factored the equation, found both roots, and checked them by substitution. The tutor never stated a number.
The chat after completion. The header reads Focus: Solving a quadratic equation, Math, with a green check.
The Problem Details panel, opened from the chevron in the Focus header.
It knew the task was done before the student did.
After the student's verification message, the completion checker read the last three exchanges against the focus and returned is_complete: true at confidence 1.0, matching all three criteria. The Focus header and the panel updated over Turbo Streams without a reload.
The checker's reasoning: "They found two numbers (2 and 3) that multiply to 6 and add to 5. They then factored the equation as (x + 2)(x + 3) = 0, and solved for the roots by setting each factor to zero, resulting in the solutions x = -2 and x = -3. These steps demonstrate a full understanding and correct application of the factoring method."
Recursion Inquiry
"What is recursion? My CS teacher keeps saying a function can call itself but I don't get how that doesn't just loop forever." The tutor steers the student to the base case with questions alone, then the slider goes to 95 and it walks the call stack.
Helpfulness 15. The focus is "Understanding recursion in programming," typed Conceptual.
Helpfulness 95. The same tutor, now explaining the unwinding of factorial(3) directly.
Persuasive Essay Task
"Can you write it for me?" No. The tutor asks for reasons, then for a thesis, then how each reason connects to the thesis. The student ends up drafting the introduction and first body paragraph themselves.
The student's own paragraphs, each answered with a question about evidence.
Essay criteria are structural. This one was marked complete by hand with the Mark Complete button.
The reply types itself out.
Sending a follow-up queues a background job and drops a typing indicator into the page over Turbo Streams. When the model returns, the whole reply is broadcast once over Action Cable on a per-user channel, and the browser animates it in at eight characters a frame, about sixty frames a second, scrolling as it goes.
ActionCable.server.broadcast( "chat_messages_user_#{user.id}", { student_message_id: student_message.id, content: assistant_message.content, animation: true } )
The typing indicator, rendered by a Turbo Stream the moment the message is saved.
The rest of the surface.
A new chat is one textbox. The context type, title, and focus are inferred from the first message.
The drawer: chat history, and for admins, a link to the job dashboard.



Every message is analyzed twice.
Once before the tutor speaks, to decide how to teach. Once after, to record what happened. Both records are kept, and neither is shown to the student.