-
Notifications
You must be signed in to change notification settings - Fork 6.3k
fix(litellm): use context limit from /model/info for custom models #9303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,8 @@ pub struct LiteLLMProvider { | |
| model: ModelConfig, | ||
| #[serde(skip)] | ||
| name: String, | ||
| #[serde(skip)] | ||
| cached_model_info: tokio::sync::OnceCell<Vec<ModelInfo>>, | ||
| } | ||
|
|
||
| impl LiteLLMProvider { | ||
|
|
@@ -77,10 +79,18 @@ impl LiteLLMProvider { | |
| base_path, | ||
| model, | ||
| name: LITELLM_PROVIDER_NAME.to_string(), | ||
| cached_model_info: tokio::sync::OnceCell::new(), | ||
| }) | ||
| } | ||
|
|
||
| async fn fetch_models(&self) -> Result<Vec<ModelInfo>, ProviderError> { | ||
| async fn get_or_fetch_models(&self) -> Result<&[ModelInfo], ProviderError> { | ||
| self.cached_model_info | ||
| .get_or_try_init(|| self.fetch_models_from_api()) | ||
| .await | ||
| .map(|v| v.as_slice()) | ||
| } | ||
|
|
||
| async fn fetch_models_from_api(&self) -> Result<Vec<ModelInfo>, ProviderError> { | ||
| let response = self | ||
| .api_client | ||
| .request(None, "model/info") | ||
|
|
@@ -184,7 +194,22 @@ impl Provider for LiteLLMProvider { | |
| } | ||
|
|
||
| fn get_model_config(&self) -> ModelConfig { | ||
| self.model.clone() | ||
| let mut config = self.model.clone(); | ||
| // The cache is populated lazily by the first stream() call (via | ||
| // supports_cache_control). On turn 1 this will be None and we fall | ||
| // back to DEFAULT_CONTEXT_LIMIT, which is fine — the conversation is | ||
| // too small to trigger compaction. From turn 2 onward the real limit | ||
| // from /model/info is used. | ||
| 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) { | ||
| if info.context_limit > 0 { | ||
| config.context_limit = Some(info.context_limit); | ||
| } | ||
| } | ||
|
Comment on lines
+205
to
+209
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This assignment accepts Useful? React with 👍 / 👎. |
||
| } | ||
| } | ||
| config | ||
| } | ||
|
|
||
| async fn stream( | ||
|
|
@@ -237,7 +262,7 @@ impl Provider for LiteLLMProvider { | |
| } | ||
|
|
||
| async fn supports_cache_control(&self) -> bool { | ||
| if let Ok(models) = self.fetch_models().await { | ||
| if let Ok(models) = self.get_or_fetch_models().await { | ||
| if let Some(model_info) = models.iter().find(|m| m.name == self.model.model_name) { | ||
| return model_info.supports_cache_control.unwrap_or(false); | ||
| } | ||
|
|
@@ -247,10 +272,8 @@ impl Provider for LiteLLMProvider { | |
| } | ||
|
|
||
| async fn fetch_supported_models(&self) -> Result<Vec<String>, ProviderError> { | ||
| let models = self.fetch_models().await.map_err(|e| { | ||
| ProviderError::RequestFailed(format!("Failed to fetch models from LiteLLM: {}", e)) | ||
| })?; | ||
| Ok(models.into_iter().map(|m| m.name).collect()) | ||
| let models = self.get_or_fetch_models().await?; | ||
| Ok(models.iter().map(|m| m.name.clone()).collect()) | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_model_config()now only readscached_model_infoand never initiates a fetch whencontext_limitisNone, 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 beforesupports_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 👍 / 👎.