feat(tui): deduplicate model metadata and populate model details cache from session
- Add `seen_meta` set and `push_meta` helper to avoid duplicate entries when building model metadata strings. - Extend metadata handling to include context length fallback, architecture/family information, embedding length, size formatting, and quantization details. - Introduce `populate_model_details_cache_from_session` to load model details from the controller, with a fallback to cached details. - Update `refresh_models` to use the new cache‑population method instead of manually clearing the cache.
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -2832,22 +2832,64 @@ fn build_model_selector_label(
|
||||
}
|
||||
|
||||
let mut meta_parts: Vec<String> = Vec::new();
|
||||
let mut seen_meta: HashSet<String> = 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::<Vec<_>>()
|
||||
.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() {
|
||||
|
||||
Reference in New Issue
Block a user