← All posts

Inside the Advisor's New Reasoning Layer

A technical deep dive into the Advisor's Chintan-phase rework: a two-stage routing pipeline that picks only the data each question needs, a free hosted thinking layer on Cloudflare Workers with Firebase-verified auth, automatic API key rotation, revision-flagged realtime sync, and the token economics behind all of it.

The Advisor's architecture has always been unusual on purpose: everything runs client-side against the student's own free Gemini key, and the app's job is to build one system prompt, the context, that carries the student's data into every request. That design is cheap and private, but it had grown a real problem. The context had become a monolith. Every message shipped the app knowledge, the behavioral instructions, the stat summaries, the advisor books, and up to twelve turns of history, whether the question needed them or not. Saying "hi" cost the same twelve-thousand-odd tokens as asking for a full study audit.

Worse, the failure mode of trimming it by hand was hallucination. Our context limiter lets students toggle data categories off, and we found a case where a category's label promised data its block did not actually contain. The model, told it had the data and forbidden from requesting it, invented numbers instead. The lesson generalized: what the model is told it has, what it actually has, and what the question needs must be reconciled per message, by machinery, not by hope.

The Chintan phase rebuilt this around a reasoning layer, and together with the dashboard rework it forms the first release of Chintan v1. Here is the whole design.

Two stages: a router that never answers

With reasoning mode on, every message goes through two model calls with strictly separated jobs.

Stage one, triage. A small, cheap call receives the question, a few truncated turns of recent history, a counts-only pulse of what data exists (how many logged questions, mocks, chapters, and so on), and a catalog of every data category with a one-line description. It never sees the data itself. It returns a single JSON object: a weight class for the message (smalltalk, general, or data), the minimal set of category ids the answer needs, an optional subject scope, optional book chapter ids, and a short step plan for the answering model. It is forbidden from writing the reply.

Stage two, the answer. The context builder assembles a system prompt containing only what the router picked, injects the plan, and appends two standing constraints: the data was auto-selected, so say plainly what is missing rather than guessing, and verify every stated number against a figure actually present in the context. The answer model then responds normally.

The router's output is never trusted raw. Every field is sanitized against reality before use: unknown category ids are dropped, subject names are matched case-insensitively against the student's actual subjects and discarded if absent, and book chapter ids are validated against the library. A hallucinating router degrades into a slightly-too-narrow context, never into a crash or a data leak.

Granularity: three axes of scoping

Categories alone were not enough, so the router controls three independent dimensions.

Categories select which summary blocks ride along, from aggregate accuracy down to raw log windows paginated by recency, so a question about last week never ships a year of history.

Subjects filter inside the blocks. If the question is clearly about one subject, every log-derived computation, chapter stats, study time, lecture hours, raw entries, runs against a filtered view, and the prompt carries an explicit note that other subjects exist but were excluded, so the model cannot misread scoped totals as overall totals.

Book chapters are addressed individually. Student-authored Advisor Books already carried per-chapter syntheses; the router sees those syntheses with stable ids and pulls in exactly the chapters whose synopsis matches the question. Unpicked books are omitted wholesale, which turned out to be one of the largest remaining sources of prompt fat.

Where the tokens actually went

The first version of the pipeline embarrassed us: a bare greeting still cost around twelve thousand tokens. Profiling the prompt showed the narrowing had only removed data blocks while three fixed costs rode along on every message. The behavioral instruction blocks (the formats the app parses for target-setting and reminders) are several thousand tokens and are now included only for data-weight messages, with the router explicitly taught to classify reminder and target requests as data so those flows keep working. The context-settings block, about seven hundred tokens explaining a limiter that reasoning mode bypasses anyway, is replaced by a one-line note. And chat history, up to twenty-four thousand characters of it, is cut to four turns and a quarter of the budget for non-data messages, because a greeting does not need the model to reread a week of analysis.

The triage prompt itself is kept lean and is ordered static-first, dynamic-last: role, catalog, and rules form a byte-identical prefix across messages, with the pulse, history, and question at the end, so Gemini's implicit prefix caching can reuse the fixed head. Obvious chitchat never reaches an API at all: a small regex answers the routing question locally for zero tokens, and anything containing digits, question marks, or real length falls through to the actual router.

The routing ladder, and a free thinking layer

Routing runs down a four-rung ladder, cheapest first, and any rung's failure falls through silently to the next.

  1. Local heuristics. A curated set of keyword rules maps unmistakably-shaped stats questions straight to their categories, with subject scoping by name match. Ambiguity, length, or the mere possibility that a book chapter is relevant defers to a real model.
  2. The hosted thinking layer. A Cloudflare Worker we run, so routing costs the student nothing and requires no personal API key.
  3. The student's own reasoner key. The same triage prompt against Gemini's small model, on a key the student can dedicate to routing so triage traffic never eats the answer key's rate limit.
  4. Full context. If all routing fails, the message goes out the classic single-pass way. Reasoning mode is never allowed to be less reliable than what it replaced.

The hosted rung deserves detail, because putting a free LLM behind a static site is mostly a security problem. The Worker exposes one inference endpoint plus a title endpoint, and both sit behind four gates checked in order. CORS restricts callers to our origins. The caller's Firebase ID token is verified in the Worker itself, signature against Google's rotating JWKs, algorithm pinned to RS256, audience, issuer, and expiry all checked, so only signed-in LairsFlow accounts get inference. The prompt must begin with the exact routing-prompt preamble and stay under a size cap, which stops the endpoint from being repurposed as a general free LLM proxy. And a per-user daily quota in Workers KV keeps any one account from draining the free inference allocation for everyone. Inference itself runs on a small quantized Llama on Workers AI, temperature zero, output capped, with the response parsed leniently and then re-sanitized client-side like every other routing source. Because the client degrades gracefully on any failure, the Worker gets to be strict.

Reliability plumbing

Two smaller mechanisms round out the pipeline. The answer call already fell back across Gemini models on quota errors; now the keys themselves rotate too. If a reply fails and the student has multiple keys saved, the app announces the switch, waits ten seconds, moves the active key to the next untried one, and re-sends, with each key getting at most one attempt per message before the real error surfaces. Errors no key can fix, offline and safety blocks, skip rotation entirely.

Token accounting stayed honest through all of this. Real usage numbers from the API are preferred over estimates, every message's spend is attributed to the key that paid it, and the thinking layer's tokens are tracked separately so hosted routing, which costs the student nothing, is never billed against their key's meter. The meter itself fills against the only daily cap Google actually enforces on the free tier, requests per day, since the free tier has no daily token cap at all.

Sync got an update flag

The last piece is cross-device correctness, because a reasoning layer that reads stale data reasons about the wrong student. Every push to Firestore now stamps the account's meta document with a monotonic revision and the writing device's id. Every signed-in device holds a realtime listener on that document: a revision it has not seen, written by a different device, triggers an immediate pull that refreshes local storage and re-renders, no reload involved. Own-write echoes and already-seen revisions are ignored, so the listener cannot loop.

The pull merge also got stricter. Conversation titles and pin state now propagate by fresher-copy-wins, with every mutation bumping the conversation's timestamp so "fresher" means something. And conversations themselves changed lifecycle: one is created only at the moment its first message needs storing, never before, so empty chat husks can no longer accumulate locally or in the cloud, and a boot-time purge cleans out any that already had.

What it adds up to

Reasoning mode turns the Advisor from an app that sends everything and hopes, into a pipeline that decides, per message, what a question deserves: a greeting costs a few hundred tokens on one call, a scoped subject question ships only that subject's numbers with a plan for using them, and a question the router cannot confidently handle falls back to the old behavior instead of failing. The thinking half of that pipeline now runs free for every signed-in student, on infrastructure we control, behind auth we verify ourselves.

There is more Chintan work coming for the Advisor, routing quality on the hosted model is the current tuning target, but the architecture this phase leaves behind is the one the product needed: grounded answers, metered honestly, on the smallest context that can support them.

Built to match your drive.

Free to start. Bring your own Gemini key when you are ready for the Advisor.

Start free