fix(context): honour an explicit context_size of 512 - #29
Merged
Conversation
llm_context_create*() decided whether the caller had asked for a context size
by comparing the parsed value against llama_context_default_params().n_ctx:
struct llama_context_params defaults = llama_context_default_params();
if (ai->model && ctx_params.n_ctx == defaults.n_ctx) {
ctx_params.n_ctx = 0; // 0 = use the model's training window
}
That default is 512 (llama-context.cpp:2772), a value a caller can perfectly
well pass, so an explicit context_size=512 was indistinguishable from unset and
was silently replaced by the model's full training window:
context_size=64 -> n_ctx=256
context_size=512 -> n_ctx=32768 <-- asked for 512, got 64x that
context_size=513 -> n_ctx=768
n_ctx=512 hit it too, since the check looked at the resolved value rather than
at which key was written.
The intent was right, only the detection was wrong. llama.cpp already defines
n_ctx = 0 as "use the training window", so start from that sentinel instead of
inferring it after the fact: the caller's value now always survives, and 0 keeps
its documented meaning. Also stops context_size=0 driving n_batch to 0, which
llama will not accept.
Behaviour change, and a quiet one: anyone passing context_size=512 or n_ctx=512
was getting the model's whole window and now gets 512. Nothing errors - the
context simply becomes what was asked for, so a conversation that used to fit
may now reach the limit. That is the point: silently ignoring the configuration
is the bug. It does make #28 easier to hit, where a full context errors and
leaves the chat unusable.
API.md said llm_context_create_chat() and llm_context_create_textgen() were
equivalent to context_size=4096. Their presets are empty, so both inherit the
model's training window; documented as such, along with 0 on context_size/n_ctx.
test_context_size_is_honoured covers 256/512/1024 exactly (llama pads n_ctx to a
multiple of 256), both spellings, and that omitting the key - or passing 0 -
still auto-sizes. Verified to fail against the pre-fix build with
"context_size=512 produced n_ctx=32768".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012KRojTrn4Q4SaZQpqcwpAt
andinux
added a commit
that referenced
this pull request
Aug 25, 2026
…on" typo
The remaining API.md errors recorded in notes/DEMO-FINDINGS.md, each re-verified
against the current build rather than taken on trust - that note was written
against 0.7.58.
embedding_type was documented as accepting BFLOAT16. It does not:
embedding_name_to_type() spells it FLOATB16, and anything unrecognised returns 0,
which surfaces as the "must be specified" error rather than as a bad-value one.
So a caller following the documentation got told they had omitted an option they
had in fact passed:
embedding_type=BFLOAT16 -> Embedding type (embedding_type) must be specified
embedding_type=FLOATB16 -> 768 bytes
The entry now carries the right spelling, calls out that it is not BFLOAT16, and
quotes the error so the misleading message is at least searchable. All five
documented names verified against a 384-dimension model: 1536, 768, 768, 384, 384
bytes - exactly 4, 2, 2, 1 and 1 bytes per element.
json_output=1 was documented as returning "a JSON object". It returns a JSON
array: json_type() reports 'array' and the text begins '[-0.0355376,...'. Also
notes that the plain BLOB is what belongs in a sqlite-vector column, since
wrapping it is the mistake the JSON form invites.
The error message itself said "funtion". Fixed - nothing asserts on the string,
and the docs now quote it, so the two agreeing matters.
Two other items from that note are already handled: llm_context_create_chat()'s
phantom context_size=4096 preset went with #29, and llm_chat_restore()'s return
type earlier in this PR.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012KRojTrn4Q4SaZQpqcwpAt
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 the "
context_size=512is silently ignored" part of #28.The bug
llm_context_create_with_options()decided whether the caller had asked for a context size by comparing the parsed value against llama's default:That default is 512 (
llama-context.cpp:2772) — a value a caller can perfectly well pass. So an explicitcontext_size=512was indistinguishable from unset:llm_context_size()n_ctx=512hit it too, since the check looked at the resolved value rather than at which key was written.The fix
The intent was right; only the detection was wrong.
llama.cppalready definesn_ctx = 0as "use the training window", so start from that sentinel rather than inferring it after the fact:and delete the comparison block. The caller's value now always survives, and
0keeps its documented meaning. Net +1/−4 lines — no new struct, no signature changes, and no churn through the fourllm_context_options_callbackcall sites (two of which passxdata = NULL).Also stops
context_size=0drivingn_batchto 0, which llama will not accept.Verified against the built extension:
context_size=256context_size=512context_size=1024n_ctx=512context_size=0Behaviour change
Anyone passing
context_size=512orn_ctx=512was getting the model's whole window and now gets 512. Nothing errors — the context simply becomes what was asked for, so a conversation that used to fit may now reach the limit.That is the intended outcome: silently ignoring the configuration is the bug. It does make the other half of #28 easier to hit, where a full context returns an error and leaves the chat unusable for every subsequent turn. That issue stays open.
Patch version bump,
1.0.5→1.0.6.Docs
API.mdclaimedllm_context_create_chat()andllm_context_create_textgen()were "equivalent toSELECT llm_context_create('context_size=4096')". Their presets are empty strings, so both inherit the model's training window. Corrected, and0is now documented oncontext_sizeandn_ctx.Testing
test_context_size_is_honouredcovers 256/512/1024 exactly — llama padsn_ctxup to a multiple of 256, so only exact multiples compare equal — plus both spellings, and that omitting the key or passing0still auto-sizes. It asserts the model trains above 1024 first, so it can actually tell an honoured size from an auto-sized one.Verified to fail against a pre-fix build:
make test: 44/44 pass.🤖 Generated with Claude Code
https://claude.ai/code/session_012KRojTrn4Q4SaZQpqcwpAt