Describe the bug
In crates/goose/src/providers/litellm.rs (and potentially openai.rs), Goose fetches supported models from the proxy's API and successfully parses the max_input_tokens / context_length. However, it explicitly discards this context length when returning the list of supported models from the provider.
This causes Goose's ModelConfig to fall back to checking its internal static canonical_models.json. When it fails to find a match for a custom local model (e.g., local/unsloth/Qwen3-8B-Q4_K_M.gguf), it blindly defaults to its hardcoded DEFAULT_CONTEXT_LIMIT of 128,000.
As a result:
- Goose can feed too many tokens to local models with smaller context windows (e.g., 8k tokens for Qwen), causing them to crash or throw errors during long sessions unless the user manually overrides
GOOSE_CONTEXT_LIMIT.
- Features that depend on the percentage of context used, such as automatic context compaction, will not work correctly because the perceived context limit (128k) is drastically different from the actual limit.
To Reproduce
Steps to reproduce the behavior:
- Start a local LiteLLM proxy (or any OpenAI-compatible server) that returns custom local models where
max_input_tokens is smaller than 128k.
- Configure Goose to use the
litellm provider.
- Start Goose without setting
GOOSE_CONTEXT_LIMIT.
- Check the parsed context limit for the model (or try a long session).
- See error: Goose assumes a 128k context window and either overflows the model or fails to trigger context compaction at the correct threshold.
Expected behavior
Goose should retain and respect the context_length (or max_input_tokens) provided by the /model/info (or /v1/models) endpoint of the provider, rather than discarding it and defaulting to 128,000.
Screenshots
N/A
Please provide the following information
- OS & Arch: Ubuntu 24.04.4 x86_64
- Interface: CLI
- Version: Latest (main branch)
- Extensions enabled: Developer, Tom, Skills, Todo, Summon, Apps, Extension Manager
- Provider & Model: LiteLLM / local .gguf models
Additional context
The issue is clearly visible in the fetch_supported_models implementation.
In crates/goose/src/providers/litellm.rs (around line 111):
let context_length = model_info["max_input_tokens"].as_u64().unwrap_or(128000) as usize;
let mut model_info_obj = ModelInfo::new(model_name, context_length);
model_info_obj.supports_cache_control = supports_cache_control;
models.push(model_info_obj);
// ... Later in fetch_supported_models:
let models = self.fetch_models().await.map_err(|e| { /* ... */ })?;
// BUG: Goose correctly fetched and parsed it, but throws it away here!
Ok(models.into_iter().map(|m| m.name).collect())
Because the Provider::fetch_supported_models trait signature expects Result<Vec<String>, ProviderError>, the rich metadata (including the context limit) is lost in transit.
Describe the bug
In
crates/goose/src/providers/litellm.rs(and potentiallyopenai.rs), Goose fetches supported models from the proxy's API and successfully parses themax_input_tokens/context_length. However, it explicitly discards this context length when returning the list of supported models from the provider.This causes Goose's
ModelConfigto fall back to checking its internal staticcanonical_models.json. When it fails to find a match for a custom local model (e.g.,local/unsloth/Qwen3-8B-Q4_K_M.gguf), it blindly defaults to its hardcodedDEFAULT_CONTEXT_LIMITof 128,000.As a result:
GOOSE_CONTEXT_LIMIT.To Reproduce
Steps to reproduce the behavior:
max_input_tokensis smaller than 128k.litellmprovider.GOOSE_CONTEXT_LIMIT.Expected behavior
Goose should retain and respect the
context_length(ormax_input_tokens) provided by the/model/info(or/v1/models) endpoint of the provider, rather than discarding it and defaulting to 128,000.Screenshots
N/A
Please provide the following information
Additional context
The issue is clearly visible in the
fetch_supported_modelsimplementation.In
crates/goose/src/providers/litellm.rs(around line 111):Because the
Provider::fetch_supported_modelstrait signature expectsResult<Vec<String>, ProviderError>, the rich metadata (including the context limit) is lost in transit.