# Finding: classifier input scope (LLMRouter "query modes" check) Status: done -- classifier.max_input_chars **Origin.** LLMRouter's chat interface offers three query modes — `current_only`, `full_context` (all history), `retrieval` (top-k similar past queries). Before considering porting any of that, the actual question was narrower and answerable by reading the code: does this project's classifier already read the whole conversation, or only the tail? If only the tail, a long session that drifts category (chat → debugging) could be mis-tiered from a stale early read. This is a verification finding, not a design proposal — no code changes proposed here. --- ## What the code actually does `chat_completions` (`dispatcher.py`) builds the classifier's input from two helpers, both scoped narrowly on purpose: - `_last_user_text(messages)` (`dispatcher.py:1734`) — the text of the **last** `user`-role message only. Walks backwards and returns on the first match; never touches earlier turns. - `_previous_context(messages)` (`dispatcher.py:1749`) — the text of the **nearest preceding `assistant` message**, truncated to 200 characters. Explicitly skips `system`, `user`, and `tool` roles "so that tool output or the system prompt never contaminates the framing signal" (its own docstring). Not the whole history — one turn of lookback, by design. Both are recomputed **fresh on every request** — there is no session-level memoization of the classification input today (that's exactly the gap [`session-classification-cache-ttl.md`](session-classification-cache-ttl.md) proposes closing, but for the *output* — the category/tier decision — not the input). ## What this means for category drift This is already, incidentally, LLMRouter's `current_only` mode plus a one-turn lookback — and it's the reason category drift within a long session is *not* currently a problem: every message gets classified from near-term signal (the current message and the immediately preceding reply), so a session moving from `general_chat` to `debugging` over 40 turns tracks that drift on the very next message, for free. `full_context` (feeding the whole conversation) would not improve this — it would make classification slower (more tokens through `max_input_chars` clamping) and arguably noisier (early, no-longer-relevant turns diluting the signal), for no accuracy benefit given the categories this project tracks are about the *current* task, not the session's history as a whole. ## The one place this now matters: the session cache The classifier-input-scope property described here is what `session-classification-cache-ttl.md` explicitly trades away, on purpose, for latency. Once that cache ships, a "cached" decision no longer re-derives category from the current message at all — it reuses whatever was true up to `staleness_minutes` ago. That's a deliberate, bounded trade, not a regression introduced silently; flagging it here so the connection is on record in both documents. ## Recommendation No action needed on classifier input scope itself — it already does the right thing, and LLMRouter's `full_context`/`retrieval` modes don't apply here (this project's categories are per-current-task, not per-conversation-history, and there's no embedding/retrieval infrastructure to reuse for `retrieval` mode even if it were wanted). Retire this as "checked, no gap found" rather than carrying it forward as an open question.