diff --git a/crates/owlen-tui/src/chat_app.rs b/crates/owlen-tui/src/chat_app.rs index cc915f3..69b9f06 100644 --- a/crates/owlen-tui/src/chat_app.rs +++ b/crates/owlen-tui/src/chat_app.rs @@ -7257,6 +7257,25 @@ impl ChatApp { Ok(()) } + async fn populate_model_details_cache_from_session(&mut self) { + self.model_details_cache.clear(); + + let mut populated = false; + if let Ok(details) = self.controller.all_model_details(false).await { + for info in details { + self.model_details_cache.insert(info.name.clone(), info); + } + populated = !self.model_details_cache.is_empty(); + } + + if !populated { + let cached = self.controller.cached_model_details().await; + for info in cached { + self.model_details_cache.insert(info.name.clone(), info); + } + } + } + async fn refresh_models(&mut self) -> Result<()> { let config_model_name = self.controller.config().general.default_model.clone(); let config_model_provider = self.controller.config().general.default_provider.clone(); @@ -7286,9 +7305,9 @@ impl ChatApp { } self.models = all_models; - self.model_details_cache.clear(); self.model_info_panel.clear(); self.set_model_info_visible(false); + self.populate_model_details_cache_from_session().await; self.recompute_available_providers(); diff --git a/crates/owlen-tui/src/ui.rs b/crates/owlen-tui/src/ui.rs index def12df..ae8f595 100644 --- a/crates/owlen-tui/src/ui.rs +++ b/crates/owlen-tui/src/ui.rs @@ -2832,22 +2832,64 @@ fn build_model_selector_label( } let mut meta_parts: Vec = Vec::new(); + let mut seen_meta: HashSet = HashSet::new(); + let mut push_meta = |value: String| { + let trimmed = value.trim(); + if trimmed.is_empty() { + return; + } + let key = trimmed.to_ascii_lowercase(); + if seen_meta.insert(key) { + meta_parts.push(trimmed.to_string()); + } + }; + if let Some(detail) = detail { + if let Some(ctx) = detail.context_length { + push_meta(format!("max tokens {}", ctx)); + } else if let Some(ctx) = model.context_window { + push_meta(format!("max tokens {}", ctx)); + } + if let Some(parameters) = detail .parameter_size .as_ref() .or(detail.parameters.as_ref()) && !parameters.trim().is_empty() { - meta_parts.push(parameters.trim().to_string()); + push_meta(parameters.trim().to_string()); + } + + if let Some(arch) = detail.architecture.as_deref() { + let trimmed = arch.trim(); + if !trimmed.is_empty() { + push_meta(format!("arch {}", trimmed)); + } + } else if let Some(family) = detail.family.as_deref() { + let trimmed = family.trim(); + if !trimmed.is_empty() { + push_meta(format!("family {}", trimmed)); + } + } else if !detail.families.is_empty() { + let families = detail + .families + .iter() + .map(|f| f.trim()) + .filter(|f| !f.is_empty()) + .take(2) + .collect::>() + .join("/"); + if !families.is_empty() { + push_meta(format!("family {}", families)); + } + } + + if let Some(embedding) = detail.embedding_length { + push_meta(format!("embedding {}", embedding)); } if let Some(size) = detail.size { - meta_parts.push(format_short_size(size)); - } - - if let Some(ctx) = detail.context_length { - meta_parts.push(format!("ctx {}", ctx)); + push_meta(format_short_size(size)); } if let Some(quant) = detail @@ -2855,8 +2897,10 @@ fn build_model_selector_label( .as_ref() .filter(|q| !q.trim().is_empty()) { - meta_parts.push(quant.trim().to_string()); + push_meta(format!("quant {}", quant.trim())); } + } else if let Some(ctx) = model.context_window { + push_meta(format!("max tokens {}", ctx)); } if let Some(desc) = model.description.as_deref() {