Skip to content

fix(autocomplete): cap reserved output tokens in pruneLength - #13099

Open
Hamjaster wants to merge 3 commits into
continuedev:mainfrom
Hamjaster:fix-autocomplete-prune-length-min-response-tokens
Open

fix(autocomplete): cap reserved output tokens in pruneLength#13099
Hamjaster wants to merge 3 commits into
continuedev:mainfrom
Hamjaster:fix-autocomplete-prune-length-min-response-tokens

Conversation

@Hamjaster

Copy link
Copy Markdown

Fixes #13038

What's broken

Tab autocomplete silently produces nothing, with no error and no log line, whenever the selected model's contextLength is smaller than the default maxTokens reservation (4096). This is common with Ollama, where a Modelfile pinning PARAMETER num_ctx 4096 (a common move on small-VRAM GPUs) hits it directly, since Continue reads that value straight into contextLength.

pruneLength in core/autocomplete/templating/index.ts computes:

const maxAllowedPromptTokens = contextLength - reservedTokens - safetyBuffer;

with reservedTokens defaulting to 4096 whenever the user hasn't set maxTokens explicitly. If contextLength is anywhere near or below that, maxAllowedPromptTokens goes negative, and the prune amount ends up larger than the entire prefix plus suffix no matter how small the actual prompt is. renderPromptWithTokenLimit then prunes both down to nothing, sends an effectively empty prompt to the model, and postprocessCompletion drops 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 at MIN_RESPONSE_TOKENS (1000) instead of the full maxTokens:

const minOutputTokens = Math.min(MIN_RESPONSE_TOKENS, maxTokens);

pruneLength never got the same treatment. This applies the identical cap:

const minOutputTokens = Math.min(MIN_RESPONSE_TOKENS, reservedTokens);
const maxAllowedPromptTokens = contextLength - minOutputTokens - safetyBuffer;

MIN_RESPONSE_TOKENS wasn't exported from countTokens.ts, so I added it to the export list rather than duplicating the constant.

This only changes behavior when reservedTokens is larger than MIN_RESPONSE_TOKENS (1000), which is exactly the pathological case, small contextLength with a large default maxTokens. Models where maxTokens is already below 1000 see Math.min return 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 pruneLength and the pruning branch in a standalone script to compare before/after against the reported repro's numbers (contextLength=4096, unset maxTokens defaulting to 4096):

before: pruned=true,  prefix='', suffix=''
after:  pruned=false, prefix='AAAAAAAAAAAAAAAAAAAA', suffix=''

Then applied the real fix and ran the actual suite. Added a test to core/autocomplete/templating/__tests__/renderPrompt.vitest.ts (contextLength: 2048, default maxTokens, a short prefix) asserting the prefix survives. It fails on main (expected false to be true, the prefix gets wiped) and passes with this change. Had to add MIN_RESPONSE_TOKENS to that file's existing countTokens mock too, since vitest's module mock doesn't auto-forward unmocked exports.

Full run: npx vitest run autocomplete/ in core/, 178 passed, 1 pre-existing todo, the same as main. tsc -p ./ --noEmit and eslint are clean on all three changed files.

Type

🐛 Bug Fix

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
@Hamjaster
Hamjaster requested a review from a team as a code owner August 7, 2026 09:35
@Hamjaster
Hamjaster requested review from sestinj and removed request for a team August 7, 2026 09:35
@Hamjaster

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant