Skip to content

fix(litellm): use context limit from /model/info for custom models - #9303

Merged
jamadeo merged 1 commit into
mainfrom
fix/8835-litellm-context-limit
May 22, 2026
Merged

fix(litellm): use context limit from /model/info for custom models#9303
jamadeo merged 1 commit into
mainfrom
fix/8835-litellm-context-limit

Conversation

@DOsinga

@DOsinga DOsinga commented May 18, 2026

Copy link
Copy Markdown
Collaborator

When a model isn't in the canonical database (e.g. local/custom models behind a LiteLLM proxy), context_limit was left as None and silently defaulted to 128k. This caused context overflow on smaller models and broke context compaction.

Cache the /model/info response in a OnceCell, populated lazily on first use (supports_cache_control during stream(), or fetch_supported_models). get_model_config() reads the cache synchronously — no blocking at init, no extra HTTP calls, and the context limit is available before any compaction decision since the first stream() call populates the cache.

Also fixes the pre-existing issue where supports_cache_control and fetch_supported_models each made separate HTTP calls to /model/info on every invocation.

Fixes #8835

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 17424a49bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/goose/src/providers/litellm.rs Outdated
// from the LiteLLM /model/info endpoint so custom/local models get the
// correct limit instead of silently defaulting to 128k.
if provider.model.context_limit.is_none() {
if let Ok(models) = provider.fetch_models().await {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Avoid blocking provider init on /model/info timeout

This new eager call to fetch_models().await runs during provider construction whenever context_limit is unset, so environments where /model/info is slow, disabled, or permission-blocked will stall initialization until the full request timeout elapses (default is 600 seconds via LITELLM_TIMEOUT). Because the error is ignored after awaiting, startup can hang for minutes and then silently continue, which is a user-visible regression for custom LiteLLM deployments where chat completions work but model metadata does not.

Useful? React with 👍 / 👎.

@DOsinga
DOsinga force-pushed the fix/8835-litellm-context-limit branch 2 times, most recently from 3e05628 to 727f257 Compare May 18, 2026 15:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 727f257742

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +198 to +200
if config.context_limit.is_none() {
if let Some(models) = self.cached_model_info.get() {
if let Some(info) = models.iter().find(|m| m.name == config.model_name) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Trigger /model/info lookup when context_limit is missing

get_model_config() now only reads cached_model_info and never initiates a fetch when context_limit is None, so on a fresh provider instance the first request still uses the 128k default until some other path warms the cache. In the normal chat flow, provider.get_model_config() is consumed before supports_cache_control() performs any fetch, so custom LiteLLM models with smaller windows can still hit context-overflow errors on initial turns instead of compacting to the real limit.

Useful? React with 👍 / 👎.

Comment on lines +200 to +202
if let Some(info) = models.iter().find(|m| m.name == config.model_name) {
config.context_limit = Some(info.context_limit);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Skip non-positive context limits from model metadata

This assignment accepts info.context_limit verbatim, including 0, which can happen when upstream metadata is unset/sentinel-valued; once stored, downstream context_limit() calls treat it as authoritative and can break compaction math or force pathological behavior. The provider should ignore non-positive limits here (consistent with other model-limit normalization paths) and keep the fallback/default instead.

Useful? React with 👍 / 👎.

When a model isn't in the canonical database (e.g. local/custom models
behind a LiteLLM proxy), context_limit was left as None and silently
defaulted to 128k. This caused context overflow on smaller models and
broke context compaction.

Cache the /model/info response in a OnceCell, populated lazily on first
use (supports_cache_control during stream, or fetch_supported_models).
get_model_config() reads the cache synchronously — no blocking at init,
no extra HTTP calls, and the context limit is available before any
compaction decision since the first stream() call populates the cache.
Zero-value context limits from upstream metadata are ignored.

Also fixes the pre-existing issue where supports_cache_control and
fetch_supported_models each made separate HTTP calls to /model/info
on every invocation.

Fixes #8835

Signed-off-by: Douwe Osinga <douwe@squareup.com>
@DOsinga
DOsinga force-pushed the fix/8835-litellm-context-limit branch from 727f257 to 346b7f6 Compare May 18, 2026 15:21
@DOsinga

DOsinga commented May 18, 2026

Copy link
Copy Markdown
Collaborator Author

Addressing Codex review feedback:

P1 (blocking init): Already addressed in the previous push — replaced the eager fetch_models().await with a lazy OnceCell that populates on first use during stream(). Zero blocking at init.

P1 (get_model_config not triggering fetch): By design — get_model_config() is a sync trait method so it can't initiate an async fetch. The cache is populated by supports_cache_control() during the first stream() call on turn 1. On that first turn the conversation is too small to trigger compaction, so the 128k default is harmless. From turn 2 onward the real limit is available. Added a code comment explaining this.

P2 (zero context limits): Fixed — now skips non-positive context limits from upstream metadata.

@jamadeo
jamadeo added this pull request to the merge queue May 22, 2026
Merged via the queue into main with commit 612cd89 May 22, 2026
23 checks passed
@jamadeo
jamadeo deleted the fix/8835-litellm-context-limit branch May 22, 2026 18:21
shafqatevo pushed a commit to shafqatevo/goose that referenced this pull request Aug 7, 2026
…aif-goose#9303)

Signed-off-by: Douwe Osinga <douwe@squareup.com>
Co-authored-by: Douwe Osinga <douwe@squareup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Context limit from Provider API is discarded, causing fallback to 128k for local models

3 participants