#![allow(dead_code)]
use std::path::PathBuf;
use crate::ollama::Message;
pub fn ctx_path() -> PathBuf {
std::env::current_dir()
.unwrap_or_else(|_| PathBuf::from("."))
.join(".offcode.ctx")
}
pub fn load(system_msg: &Message) -> Vec<Message> {
let mut messages = vec![system_msg.clone()];
let path = ctx_path();
if path.exists() {
if let Ok(data) = std::fs::read_to_string(&path) {
if let Ok(history) = serde_json::from_str::<Vec<Message>>(&data) {
if !history.is_empty() {
messages.extend(history);
}
}
}
}
messages
}
pub fn save(messages: &[Message]) {
let path = ctx_path();
if messages.len() <= 1 {
let _ = std::fs::remove_file(&path);
return;
}
let data = match serde_json::to_string(&messages[1..]) {
Ok(d) => d,
Err(e) => { eprintln!("offcode: context serialize error: {e}"); return; }
};
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
if let Err(e) = std::fs::write(&path, &data) {
eprintln!("offcode: context save error ({}): {e}", path.display());
}
}
pub fn clear() {
let _ = std::fs::remove_file(ctx_path());
}
pub fn trim(messages: &mut Vec<Message>, num_ctx: u32) {
const KEEP_TAIL: usize = 6;
let limit = (num_ctx as usize * 85) / 100;
loop {
if messages.len() <= KEEP_TAIL + 1 {
break;
}
let estimated: usize = messages.iter().map(|m| m.content.len() / 4).sum();
if estimated <= limit {
break;
}
messages.remove(1);
}
}