v0.12.10 — doctor tells the truth
The bug
doctor's token-counting check branched on the configured provider_type and ran its own per-runtime probe. TokenCounter treats that same field as a hint — it probes both exact shapes and self-heals when the config has drifted from the running server. doctor did not.
So on a box whose config said llamacpp while the server actually spoke vLLM, doctor sent a llama.cpp-shaped body, got a rejection, and reported:
✗ /tokenize returned 404 — token accounting falls back to tiktoken cl100k
That was false. Counting was exact the whole time. The tool you run for reassurance was the one that was wrong — the worst place for a bug to live.
The fix
Two independent sources of truth about one fact, quietly disagreeing. Fixed by deleting the duplicate rather than repairing it: doctor now constructs the same counter the runtime uses and reports its resolved mode, via a new public TokenCounter.mode. They can no longer disagree.
- A stale
provider_typeis surfaced as an INFO naming the drift, not a failure — counting already adapted, but anything else reading that config will be wrong, so it still gets said. - Message-level checks (vLLM
/tokenizemessages-mode, llama.cpp/apply-template) are kept, now gated on the resolved mode. - Whether approximate counting is a fault or expected also comes from the endpoint resolver rather than stored config: Ollama/LM Studio still report INFO; a vLLM or llama.cpp server that should serve
/tokenizebut doesn't still fails. - No more cascading: the tokenizer probe reuses
default_model, so a stale model name failed it for the same reason and invented a second issue. Dependent checks are now skipped and labelled — one root cause reports as one problem. - The approximate warning quantifies itself. Measured against a real Qwen tokenizer: ~0% off on English and JSON, ~4% on code, >100% on CJK. The error is content-shaped, so "approximate" alone was not actionable.
Why this one matters beyond the fix
It's the second bug in three releases of exactly one shape: a number or verdict derived from a proxy, while a second component already knew better. v0.12.9 was the tok/s meter counting SSE deltas as tokens. This is doctor trusting config over the server.
Both were in covered code with passing tests — the tests encoded the same wrong belief. Coverage cannot catch that; only an external oracle can.
2719 tests passing. Pre-1.0: interfaces and config schema may still change.