Skip to content

Commit 6efe4c2

Browse files
committed
fix(provider_registry): case-insensitive model name lookup for context_limit
Custom provider model names with case mismatches (e.g. 'GLM-5.1' in config vs 'glm-5.1' in GOOSE_MODEL) silently failed the known_models context_limit lookup and fell back to the default 128k. Use eq_ignore_ascii_case instead of strict equality in normalize_model_config so the lookup works regardless of case. Fixes #8752 Signed-off-by: Bright Zheng <bzqzheng@gmail.com>
1 parent 503ad20 commit 6efe4c2

1 file changed

Lines changed: 64 additions & 1 deletion

File tree

crates/goose/src/providers/provider_registry.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl ProviderEntry {
6060
.metadata
6161
.known_models
6262
.iter()
63-
.find(|m| m.name == model.model_name && m.context_limit > 0)
63+
.find(|m| m.name.eq_ignore_ascii_case(&model.model_name) && m.context_limit > 0)
6464
{
6565
model.context_limit = Some(info.context_limit);
6666
}
@@ -280,3 +280,66 @@ impl ProviderRegistry {
280280
self.entries.retain(|name, _| !name.starts_with("custom_"));
281281
}
282282
}
283+
284+
#[cfg(test)]
285+
mod tests {
286+
use super::*;
287+
use crate::providers::inventory::InventoryIdentityInput;
288+
289+
fn make_test_entry(known_models: Vec<ModelInfo>) -> ProviderEntry {
290+
let metadata = ProviderMetadata {
291+
name: "test_provider".to_string(),
292+
display_name: "Test Provider".to_string(),
293+
description: "Test".to_string(),
294+
default_model: "test-model".to_string(),
295+
known_models,
296+
model_doc_link: "https://example.com".to_string(),
297+
config_keys: vec![],
298+
setup_steps: vec![],
299+
model_selection_hint: None,
300+
};
301+
302+
ProviderEntry {
303+
metadata,
304+
constructor: Arc::new(|_, _| Box::pin(async { unimplemented!() })),
305+
inventory_identity: Arc::new(|| Ok(InventoryIdentityInput::default())),
306+
inventory_configured: Arc::new(|| true),
307+
cleanup: None,
308+
provider_type: ProviderType::Builtin,
309+
supports_inventory_refresh: false,
310+
}
311+
}
312+
313+
#[test]
314+
fn test_normalize_model_config_case_mismatch() {
315+
// Registry has uppercase model name; GOOSE_MODEL is lowercase.
316+
let entry = make_test_entry(vec![ModelInfo::new("GLM-5.1", 32_000)]);
317+
let model = ModelConfig::new_or_fail("glm-5.1");
318+
assert!(model.context_limit.is_none());
319+
320+
let normalized = entry.normalize_model_config(model);
321+
assert_eq!(normalized.context_limit, Some(32_000));
322+
}
323+
324+
#[test]
325+
fn test_normalize_model_config_exact_case_match() {
326+
// Exact case match should continue to work (no regression).
327+
let entry = make_test_entry(vec![ModelInfo::new("gpt-4o", 128_000)]);
328+
let model = ModelConfig::new_or_fail("gpt-4o");
329+
assert!(model.context_limit.is_none());
330+
331+
let normalized = entry.normalize_model_config(model);
332+
assert_eq!(normalized.context_limit, Some(128_000));
333+
}
334+
335+
#[test]
336+
fn test_normalize_model_config_no_match_falls_back() {
337+
// Unknown model should not get a context_limit from known_models.
338+
let entry = make_test_entry(vec![ModelInfo::new("GLM-5.1", 32_000)]);
339+
let model = ModelConfig::new_or_fail("unknown-model");
340+
assert!(model.context_limit.is_none());
341+
342+
let normalized = entry.normalize_model_config(model);
343+
assert!(normalized.context_limit.is_none());
344+
}
345+
}

0 commit comments

Comments
 (0)