fix(autocomplete): cap reserved output tokens in pruneLength - #13099
Open
Hamjaster wants to merge 3 commits into
Open
fix(autocomplete): cap reserved output tokens in pruneLength#13099Hamjaster wants to merge 3 commits into
Hamjaster wants to merge 3 commits into
Conversation
When a model's contextLength (e.g. Ollama's num_ctx) is smaller than the default maxTokens (4096), pruneLength computed a negative prompt budget, causing every autocomplete request to prune the prefix/suffix to nothing, silently, with no error. compileChatMessages already caps its output reservation at MIN_RESPONSE_TOKENS for the same reason; pruneLength now does the same. Fixes continuedev#13038
Author
|
I have read the CLA Document and I hereby sign the CLA |
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
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.
Fixes #13038
What's broken
Tab autocomplete silently produces nothing, with no error and no log line, whenever the selected model's
contextLengthis smaller than the defaultmaxTokensreservation (4096). This is common with Ollama, where a Modelfile pinningPARAMETER num_ctx 4096(a common move on small-VRAM GPUs) hits it directly, since Continue reads that value straight intocontextLength.pruneLengthincore/autocomplete/templating/index.tscomputes:with
reservedTokensdefaulting to 4096 whenever the user hasn't setmaxTokensexplicitly. IfcontextLengthis anywhere near or below that,maxAllowedPromptTokensgoes negative, and the prune amount ends up larger than the entire prefix plus suffix no matter how small the actual prompt is.renderPromptWithTokenLimitthen prunes both down to nothing, sends an effectively empty prompt to the model, andpostprocessCompletiondrops the resulting blank completion. Nothing in that path surfaces an error.The fix
compileChatMessages, in the same file, already handles the equivalent chat-pruning case by capping the output reservation atMIN_RESPONSE_TOKENS(1000) instead of the fullmaxTokens:pruneLengthnever got the same treatment. This applies the identical cap:MIN_RESPONSE_TOKENSwasn't exported fromcountTokens.ts, so I added it to the export list rather than duplicating the constant.This only changes behavior when
reservedTokensis larger thanMIN_RESPONSE_TOKENS(1000), which is exactly the pathological case, smallcontextLengthwith a large defaultmaxTokens. Models wheremaxTokensis already below 1000 seeMath.minreturn the same value as before, so the existing pruning test (contextLength: 120, maxTokens: 10) is untouched.How I checked it
Reimplemented the exact arithmetic from
pruneLengthand the pruning branch in a standalone script to compare before/after against the reported repro's numbers (contextLength=4096, unsetmaxTokensdefaulting to 4096):Then applied the real fix and ran the actual suite. Added a test to
core/autocomplete/templating/__tests__/renderPrompt.vitest.ts(contextLength: 2048, defaultmaxTokens, a short prefix) asserting the prefix survives. It fails onmain(expected false to be true, the prefix gets wiped) and passes with this change. Had to addMIN_RESPONSE_TOKENSto that file's existingcountTokensmock too, since vitest's module mock doesn't auto-forward unmocked exports.Full run:
npx vitest run autocomplete/incore/, 178 passed, 1 pre-existing todo, the same asmain.tsc -p ./ --noEmitandeslintare clean on all three changed files.Type
🐛 Bug Fix