Add session persistence and browser functionality
Some checks failed
Release / Build aarch64-unknown-linux-gnu (push) Has been cancelled
Release / Build aarch64-unknown-linux-musl (push) Has been cancelled
Release / Build armv7-unknown-linux-gnueabihf (push) Has been cancelled
Release / Build armv7-unknown-linux-musleabihf (push) Has been cancelled
Release / Build x86_64-unknown-linux-gnu (push) Has been cancelled
Release / Build x86_64-unknown-linux-musl (push) Has been cancelled
Release / Build aarch64-apple-darwin (push) Has been cancelled
Release / Build x86_64-apple-darwin (push) Has been cancelled
Release / Build aarch64-pc-windows-msvc (push) Has been cancelled
Release / Build x86_64-pc-windows-msvc (push) Has been cancelled
Release / Create Release (push) Has been cancelled
Some checks failed
Release / Build aarch64-unknown-linux-gnu (push) Has been cancelled
Release / Build aarch64-unknown-linux-musl (push) Has been cancelled
Release / Build armv7-unknown-linux-gnueabihf (push) Has been cancelled
Release / Build armv7-unknown-linux-musleabihf (push) Has been cancelled
Release / Build x86_64-unknown-linux-gnu (push) Has been cancelled
Release / Build x86_64-unknown-linux-musl (push) Has been cancelled
Release / Build aarch64-apple-darwin (push) Has been cancelled
Release / Build x86_64-apple-darwin (push) Has been cancelled
Release / Build aarch64-pc-windows-msvc (push) Has been cancelled
Release / Build x86_64-pc-windows-msvc (push) Has been cancelled
Release / Create Release (push) Has been cancelled
- Implement `StorageManager` for saving, loading, and managing sessions. - Introduce platform-specific session directories for persistence. - Add session browser UI for listing, loading, and deleting saved sessions. - Enable AI-generated descriptions for session summaries. - Update configurations to support storage settings and description generation. - Extend README and tests to document and validate new functionality.
This commit is contained in:
@@ -218,4 +218,88 @@ impl SessionController {
|
||||
pub fn clear(&mut self) {
|
||||
self.conversation.clear();
|
||||
}
|
||||
|
||||
/// Generate a short AI description for the current conversation
|
||||
pub async fn generate_conversation_description(&self) -> Result<String> {
|
||||
let conv = self.conversation.active();
|
||||
|
||||
// If conversation is empty or very short, return a simple description
|
||||
if conv.messages.is_empty() {
|
||||
return Ok("Empty conversation".to_string());
|
||||
}
|
||||
|
||||
if conv.messages.len() == 1 {
|
||||
let first_msg = &conv.messages[0];
|
||||
let preview = first_msg.content.chars().take(50).collect::<String>();
|
||||
return Ok(format!("{}{}", preview, if first_msg.content.len() > 50 { "..." } else { "" }));
|
||||
}
|
||||
|
||||
// Build a summary prompt from the first few and last few messages
|
||||
let mut summary_messages = Vec::new();
|
||||
|
||||
// Add system message to guide the description
|
||||
summary_messages.push(crate::types::Message::system(
|
||||
"Summarize this conversation in 1-2 short sentences (max 100 characters). \
|
||||
Focus on the main topic or question being discussed. Be concise and descriptive.".to_string()
|
||||
));
|
||||
|
||||
// Include first message
|
||||
if let Some(first) = conv.messages.first() {
|
||||
summary_messages.push(first.clone());
|
||||
}
|
||||
|
||||
// Include a middle message if conversation is long enough
|
||||
if conv.messages.len() > 4 {
|
||||
if let Some(mid) = conv.messages.get(conv.messages.len() / 2) {
|
||||
summary_messages.push(mid.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Include last message
|
||||
if let Some(last) = conv.messages.last() {
|
||||
if conv.messages.len() > 1 {
|
||||
summary_messages.push(last.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Create a summarization request
|
||||
let request = crate::types::ChatRequest {
|
||||
model: conv.model.clone(),
|
||||
messages: summary_messages,
|
||||
parameters: crate::types::ChatParameters {
|
||||
temperature: Some(0.3), // Lower temperature for more focused summaries
|
||||
max_tokens: Some(50), // Keep it short
|
||||
stream: false,
|
||||
extra: std::collections::HashMap::new(),
|
||||
},
|
||||
};
|
||||
|
||||
// Get the summary from the provider
|
||||
match self.provider.chat(request).await {
|
||||
Ok(response) => {
|
||||
let description = response.message.content.trim().to_string();
|
||||
|
||||
// If description is empty, use fallback
|
||||
if description.is_empty() {
|
||||
let first_msg = &conv.messages[0];
|
||||
let preview = first_msg.content.chars().take(50).collect::<String>();
|
||||
return Ok(format!("{}{}", preview, if first_msg.content.len() > 50 { "..." } else { "" }));
|
||||
}
|
||||
|
||||
// Truncate if too long
|
||||
let truncated = if description.len() > 100 {
|
||||
format!("{}...", description.chars().take(97).collect::<String>())
|
||||
} else {
|
||||
description
|
||||
};
|
||||
Ok(truncated)
|
||||
}
|
||||
Err(_e) => {
|
||||
// Fallback to simple description if AI generation fails
|
||||
let first_msg = &conv.messages[0];
|
||||
let preview = first_msg.content.chars().take(50).collect::<String>();
|
||||
Ok(format!("{}{}", preview, if first_msg.content.len() > 50 { "..." } else { "" }))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user