feat(model): add rich model metadata, caching, and UI panel for inspection
Introduce `DetailedModelInfo` and `ModelInfoRetrievalError` structs for richer model data. Add `ModelDetailsCache` with TTL‑based storage and async API for get/insert/invalidate. Extend `OllamaProvider` to fetch, cache, refresh, and list detailed model info. Expose model‑detail methods in `Session` for on‑demand and bulk retrieval. Add `ModelInfoPanel` widget to display detailed info with scrolling support. Update TUI rendering to show the panel, compute viewport height, and render model selector labels with parameters, size, and context length. Adjust imports and module re‑exports accordingly.
This commit is contained in:
@@ -9,8 +9,9 @@ use crate::mcp::client::McpClient;
|
||||
use crate::mcp::factory::McpClientFactory;
|
||||
use crate::mcp::permission::PermissionLayer;
|
||||
use crate::mcp::McpToolCall;
|
||||
use crate::model::ModelManager;
|
||||
use crate::model::{DetailedModelInfo, ModelManager};
|
||||
use crate::provider::{ChatStream, Provider};
|
||||
use crate::providers::OllamaProvider;
|
||||
use crate::storage::{SessionMeta, StorageManager};
|
||||
use crate::types::{
|
||||
ChatParameters, ChatRequest, ChatResponse, Conversation, Message, ModelInfo, ToolCall,
|
||||
@@ -609,6 +610,66 @@ impl SessionController {
|
||||
.await
|
||||
}
|
||||
|
||||
fn as_ollama(&self) -> Option<&OllamaProvider> {
|
||||
self.provider
|
||||
.as_ref()
|
||||
.as_any()
|
||||
.downcast_ref::<OllamaProvider>()
|
||||
}
|
||||
|
||||
pub async fn model_details(
|
||||
&self,
|
||||
model_name: &str,
|
||||
force_refresh: bool,
|
||||
) -> Result<DetailedModelInfo> {
|
||||
if let Some(ollama) = self.as_ollama() {
|
||||
if force_refresh {
|
||||
ollama.refresh_model_info(model_name).await
|
||||
} else {
|
||||
ollama.get_model_info(model_name).await
|
||||
}
|
||||
} else {
|
||||
Err(Error::NotImplemented(format!(
|
||||
"Provider '{}' does not expose model inspection",
|
||||
self.provider.name()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn all_model_details(&self, force_refresh: bool) -> Result<Vec<DetailedModelInfo>> {
|
||||
if let Some(ollama) = self.as_ollama() {
|
||||
if force_refresh {
|
||||
ollama.clear_model_info_cache().await;
|
||||
}
|
||||
ollama.get_all_models_info().await
|
||||
} else {
|
||||
Err(Error::NotImplemented(format!(
|
||||
"Provider '{}' does not expose model inspection",
|
||||
self.provider.name()
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn cached_model_details(&self) -> Vec<DetailedModelInfo> {
|
||||
if let Some(ollama) = self.as_ollama() {
|
||||
ollama.cached_model_info().await
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn invalidate_model_details(&self, model_name: &str) {
|
||||
if let Some(ollama) = self.as_ollama() {
|
||||
ollama.invalidate_model_info(model_name).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn clear_model_details_cache(&self) {
|
||||
if let Some(ollama) = self.as_ollama() {
|
||||
ollama.clear_model_info_cache().await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn ensure_default_model(&mut self, models: &[ModelInfo]) {
|
||||
let mut config = self.config.lock().await;
|
||||
if let Some(default) = config.general.default_model.clone() {
|
||||
|
||||
Reference in New Issue
Block a user