Merge pull request #2 from leachy14/codex/introduce-cached-config-in-session.rs

Cache session configuration
This commit is contained in:
Christopher 2025-08-25 00:54:42 -04:00 committed by GitHub
commit 3f1b88ece0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 6 deletions

1
Cargo.lock generated
View File

@ -590,6 +590,7 @@ dependencies = [
"futures",
"indicatif",
"mockall",
"once_cell",
"regex",
"reqwest",
"rustyline",

View File

@ -23,6 +23,8 @@ syntect = "5.1"
regex = "1.0"
futures = "0.3"
tokio-stream = "0.1"
once_cell = "1.21"
[dev-dependencies]
tempfile = "3.0"

View File

@ -1,5 +1,6 @@
use anyhow::{Context, Result};
use chrono::{DateTime, Utc};
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
@ -12,6 +13,12 @@ ASCII art or concise bullet lists over heavy markup, and wrap code \
snippets in fenced blocks when helpful. Do not emit trailing spaces or \
control characters.";
static CONFIG: OnceCell<Config> = OnceCell::new();
fn get_config() -> &'static Config {
CONFIG.get_or_init(|| Config::load().unwrap_or_default())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub role: String,
@ -98,7 +105,7 @@ impl Session {
}
pub fn sessions_dir() -> Result<PathBuf> {
let config = Config::load().unwrap_or_default();
let config = get_config();
let home = dirs::home_dir().context("Could not find home directory")?;
let sessions_dir = home.join(&config.session.sessions_dir_name);
@ -111,11 +118,12 @@ impl Session {
}
pub fn session_path(name: &str) -> Result<PathBuf> {
let config = Config::load().unwrap_or_default();
let config = get_config();
Ok(Self::sessions_dir()?.join(format!("{}.{}", name, config.session.file_extension)))
}
pub fn save(&self) -> Result<()> {
let _config = get_config();
let data = SessionData {
model: self.model.clone(),
messages: self.messages.clone(),
@ -143,6 +151,7 @@ impl Session {
}
pub fn load(name: &str) -> Result<Self> {
let _config = get_config();
let path = Self::session_path(name)?;
if !path.exists() {
@ -195,7 +204,7 @@ impl Session {
/// Truncates conversation history to stay within configured limits
fn truncate_history_if_needed(&mut self) {
let config = Config::load().unwrap_or_default();
let config = get_config();
let max_history = config.limits.max_conversation_history;
// Always preserve the system prompt (first message)
@ -252,13 +261,14 @@ impl Session {
}
pub fn list_sessions() -> Result<Vec<(String, DateTime<Utc>)>> {
let _config = get_config();
let sessions = Self::list_sessions_lazy(false)?;
Ok(sessions.into_iter().map(|s| (s.name, s.last_modified)).collect())
}
/// Lists sessions with lazy loading - only loads full data if detailed=true
pub fn list_sessions_lazy(detailed: bool) -> Result<Vec<SessionInfo>> {
let config = Config::load().unwrap_or_default();
let config = get_config();
let sessions_dir = Self::sessions_dir()?;
if !sessions_dir.exists() {
@ -351,7 +361,7 @@ impl Session {
/// Checks if session needs cleanup based on size and age
pub fn needs_cleanup(&self) -> bool {
let stats = self.get_stats();
let config = Config::load().unwrap_or_default();
let config = get_config();
// Check if conversation is too long
if stats.total_messages > config.limits.max_conversation_history * 2 {
@ -368,7 +378,7 @@ impl Session {
/// Performs aggressive cleanup for memory optimization
pub fn cleanup_for_memory(&mut self) {
let config = Config::load().unwrap_or_default();
let config = get_config();
let target_messages = config.limits.max_conversation_history / 2;
if self.messages.len() > target_messages + 1 {