The exam covers chapter 3. You have read it once and highlighted half of it. What you need now is someone to ask you questions about it, tell you when you are wrong, and explain the part you missed, without drifting into things the chapter never said.
A general chatbot can do that if you paste the chapter in, explain the rules, and do it again in every new conversation. This flow is an AI study buddy that already has the chapter and the rules. Control-Option-S opens a chat window on your Mac. Ask it to explain something and it answers from the PDF, quoting the line it used. Say "quiz me" and it asks one question at a time, grades each answer, and keeps a running score until you say stop.
It is four nodes: a hotkey, a Chat node, Extract Text (PDF) and an AI Prompt. The model is whichever provider you set as the default in Watchflows, so it can be a local model through Ollama that never sends your notes anywhere.
The flow
Open the window with Control-Option-S
Keyboard Shortcut is set to ctrl+option+s with Consume Key on. It needs Accessibility permission the first time. All it does is fire into the Chat node's Input, and that opens the window. Opening runs nothing else: the chapter is not read and no model is called until you send something.
The window is an ordinary Mac window with the flow's chat in it. It comes forward on the hotkey, moves to the Space you are on, and closing it only hides it.
Every message is one lap around a loop
This is the part that makes a chat window out of a flow. The Chat node has one inlet for opening (Input), one outlet (Call) and a second inlet called Response. Each message you send starts its own run at Call, carrying:
{{message}}, what you just typed{{historyText}}, the earlier conversation as plain lines (User: …andAssistant: …){{history}}, the same turns as a real array, for a flow that needs to act on them
Whatever the flow sends into Response becomes the reply bubble. So the last node's outlet is wired back into the node that started the run. The canvas refuses a wire that makes a loop anywhere else; this inlet is the one exception, and the run ends when the answer lands. On the canvas it reads as a figure 8: out through Call, down through the lap, and back up into Response.
Four settings matter here:
- History turns sent to the flow is
40, up from the default 20. A turn is one message, so this is the last 20 questions and answers. - Conversation is Fresh each time it opens. Every study session starts at zero. It never clears a window that is already up, so pressing the hotkey again mid-quiz does not wipe your score.
- Response shows stays at
{{result}}, which is where AI Prompt leaves its answer. - Web Search and Web Fetch are switched off in the Chat node's Tools section. A new Chat node lends both to the model behind it, and a tutor that answers from the web is not answering from your chapter.
Read the chapter on every message
Read chapter 3 is Extract Text (PDF) with PDF Path set to /Users/Shared/Study/chapter-3.pdf and Output Key set to chapter, so the text arrives as {{chapter}}. It merges onto the payload rather than replacing it, so {{message}} and {{historyText}} are still there for the next node.
It runs on every message, which sounds wasteful but costs little: reading a text PDF takes a moment, and it means replacing the file with next week's chapter needs no edit to the flow. A scanned handout works too. Pages with no text layer go through on-device OCR.
The tutor
Tutor is an AI Prompt with Provider and Model left blank, so it uses your default. Temperature is 0.4, low enough that grading stays consistent. The Prompt puts the three pieces together:
Chapter:
{{chapter}}
Conversation so far:
{{historyText}}
User: {{message}}
The System Prompt holds the rules:
You are a study partner for one chapter. The chapter's text is in the prompt. Answer only from it, and if something is not in the chapter, say so.
Work in one of two modes, chosen by what the student writes.
Explain: when they ask a question or ask you to explain something, answer in plain words in a short paragraph, then quote the sentence from the chapter you relied on.
Quiz: when they say "quiz me", ask one question about the chapter and stop. When they answer, start with Correct, Partly or Wrong, say in one or two sentences what the chapter says, then write the running score on its own line as "Score: X/Y", then ask the next question. Take the score from the last "Score:" line in the conversation. Stay in quiz mode until they say "stop", then give the final score and list the topics they missed.
Never ask more than one question in a reply.
Its Result outlet is the wire back into Response. Failure is left unwired, so a model error shows in the window as a red card with a Retry button.
Paste this into the Flow Builder to get the same flow:
On Control-Option-S, open a chat window called Study Buddy that starts fresh each time it opens, sends the last 40 turns of history, and has web search and web fetch turned off. For every message, extract the text of /Users/Shared/Study/chapter-3.pdf into a key called chapter, then have an AI prompt answer using the chapter, the conversation so far and my message. The system prompt: answer only from the chapter; explain what I ask about and quote the line used; when I say "quiz me", ask one question at a time, grade each answer as Correct, Partly or Wrong, keep a running "Score: X/Y" line, and when I say "stop", give the final score and the topics I missed. Send the answer back into the chat.
Explain and quiz in one window
There is no Condition deciding which mode you are in, and that is on purpose. "Quiz me" could be matched with a Condition, but the answer you type two messages later ("because food is limited") carries no command at all. What says a quiz is running is the conversation itself, and that is already in {{historyText}}. So the mode lives in the history and the rules live in the system prompt, and you can break off mid-quiz to ask "wait, what does checks mean here?" and then go back to the questions.
The score works the same way. Every graded reply ends with a Score: X/Y line, the next lap sees that line in the history, and the model adds one to it. Nothing is stored anywhere else, which is why the score resets when a fresh window opens.
How it behaves
Your notes go where your default provider is. Set Ollama as the default and the chapter, your answers and the grading stay on this Mac. A cloud provider receives the whole chapter with every message. The model pill in the chat window's header lists the Tutor, and picking a provider there writes it onto the node, the same as the inspector.
The chapter is sent again with every message. A 20 page chapter is on the order of 13,000 tokens, so on a paid API a 30 message session is a few hundred thousand input tokens. Use Page Range on Read chapter 3 (12-24) to send only tonight's pages.
Small context windows do not fit a chapter. Apple Intelligence has room for a few pages at most; a longer prompt fails with contextWindowExceeded and the window shows the failure card. Ollama is given a context window sized to the request, up to 32,768 tokens. Past that, roughly 70,000 characters of chapter plus history, Ollama drops the start of the prompt without saying so, which means the start of the chapter.
Answers arrive whole. The reply is not typed out as the model writes. A thinking line shows while the lap runs, and the answer lands block by block once it is complete.
Typing again before the answer lands asks both at once. The lap in flight is cancelled and your two messages go as one {{message}}.
The grading is only as good as the model. A small local model is lenient and sometimes counts wrong. If the score drifts, a larger model fixes more than a longer prompt does.
Setting it up
- Put the chapter at
/Users/Shared/Study/chapter-3.pdf, or change PDF Path to your own file. Type the full path:~is not expanded here, so~/Documents/...reads as a file that does not exist. - Set a default provider in Settings ▸ AI Providers if you have not.
- Switch the flow on and grant Accessibility when macOS asks.
To open the window without the hotkey, use Open Chat… in the Chat node's inspector, or the same item in the flow's menu on Home. Each message is a row in the flow's Execution History with a Chat chip, so you can see exactly what the Tutor was sent.
Variations
- A folder of notes instead of one PDF. Replace the two lap nodes with an Agent, set its File Access Scope to the folder, and switch on Read File and List Directory. It can then open whichever note the question is about. Read File reads text, so this suits Markdown or plain-text notes; a PDF still needs Extract Text.
- One hotkey per class. Duplicate the flow, change the title, the PDF path and the shortcut. Each Chat node is its own window with its own history.
- Pick up where you left off. Set Conversation to Kept across openings and the quiz, score included, is still there tomorrow, even after a restart.
- Flashcards instead of a quiz. Change the quiz rule to "show a term, wait, then give the definition" and nothing else in the flow changes.