Repository navigation
feat(decision-model): count the request ceiling and recall's caps in the model's own vocabulary - #6115
Merged
Conversation
…the model's own vocabulary The decision model's request ceiling and the reranker's per-memory and query caps were counted in HINDSIGHT_API_TOKENIZER_ENCODING (o200k_base by default), while the endpoint counts its window with the served model's tokenizer. On mixed-script text the two diverge widely, so a request sized to fit could still overflow, and a capped memory could still run past its cap. HINDSIGHT_API_DECISION_MODEL_TOKENIZER names the vocabulary. It defaults to 'jev' for the typesafe provider (toktok's estimate of Jev's count) and to the configured encoding for the others; set it when an endpoint serves another model (e.g. qwen3.5). token_encoding gains an encoding argument on truncate_to_tokens and accepts 'jev', which has no ids and so only goes through toktok's batch count / truncate.
…'s own vocabulary
- overflowed_window: the window can now be estimated ('jev'), not 'no client can count'
- default request ceiling: the 14% gap was measured against o200k_base
- BUNDLED_ENCODINGS: also validates HINDSIGHT_API_DECISION_MODEL_TOKENIZER and bounds the cache
- docs/.env.example: the setting covers recall's query and shared-context caps too
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The decision model's request ceiling (
HINDSIGHT_API_DECISION_MODEL_MAX_REQUEST_TOKENS) and the decision reranker's caps (2k-token query, 4k shared context, 4k per memory) were counted inHINDSIGHT_API_TOKENIZER_ENCODING, which iso200k_baseby default. The endpoint counts its window with the served model's own tokenizer, and on mixed-script text the two drift apart a lot. Example:東京 café naïve 🎉repeated is ~1.6× more tokens by Jev's count. So a request sized to fit could still overflow the window (the halving in #5794 catches that, at the cost of extra round trips), and a memory "capped at 4k" could still be well over 4k for the model.What
HINDSIGHT_API_DECISION_MODEL_TOKENIZER: the vocabulary both the ceiling and the reranker's caps are counted in.typesafe:jev, toktok's estimate of Jev's count.HINDSIGHT_API_TOKENIZER_ENCODING, so nothing changes for them.qwen3.5.token_encoding:truncate_to_tokenstakes an optionalencoding, likecount_tokensandtruncate_many_to_tokensalready do.jevis accepted as a named encoding. It has no ids, so it only goes through toktok'sbatch_count/truncate, never a loaded tokenizer, and it can't be the global encoding.qwen3.5is added toBUNDLED_ENCODINGS; the installed toktok ships it.DecisionModel._splitand the decision reranker's caps count with the configured vocabulary.A standalone file for the decision-rerank questions
New
hindsight_api/engine/decision_rerank_interface.py. It holds everything that decides what the decision reranker sends and how it reads the answers:It is meant to be used outside
hindsight-apitoo. A service that reranks over the System One API can load this one file by path and send exactly what recall sends. To make that work:hindsight_api;countandtruncatefunctions;DecisionModelRerankerandDecisionModel._splitnow call it, so there is one copy of this logic. Behaviour is unchanged; the existing reranker and splitting tests pass untouched apart from where the constants are imported from. The module docstring says to treat its names and signatures as an API.Behaviour change
typesafeusers now count in Jev's vocabulary instead ofo200k_base. On English text the counts are close. On mixed-script text Jev counts higher, so:No change for
openaiorcloudflare, or when the setting is unset for them.Tests
test_token_encoding.py: every named encoding,jevincluded, counts and truncates, and the batched cut matches the single one. An unknown name lists what would work.test_decision_model_config.py:typesafedefaults tojev, and the setting overrides it.o200k_basesplits underjev, and every part fits by Jev's count.test_decision_reranker.py: the per-memory cap is counted in the client's vocabulary.test_decision_rerank_interface.py: the file loads by path in a freshpython -I, with nohindsight_api,toktokorpydanticimported; the caller's tokenizer sets the caps.Full
hindsight-api-slimsuite run locally: the same set of tests fails before and after this change. All of them need LLM keys or local ML models that aren't set up locally, and none of them involve this code.