pub const DEFAULT_COMPACTION_MODEL: &str = "deepseek-chat";
pub const MINIMUM_AUTO_COMPACTION_TOKENS: usize = 500_000;
#[derive(Debug, Clone, PartialEq)]
pub struct CompactionConfig {
pub enabled: bool,
pub token_threshold: usize,
pub model: String,
pub cache_summary: bool,
pub auto_floor_tokens: usize,
}
impl Default for CompactionConfig {
fn default() -> Self {
Self {
enabled: true,
token_threshold: 800_000,
model: DEFAULT_COMPACTION_MODEL.to_string(),
cache_summary: true,
auto_floor_tokens: MINIMUM_AUTO_COMPACTION_TOKENS,
}
}
}
pub type ArtifactId = String;
#[derive(Debug, Clone)]
pub struct CompactionArtifact {
pub id: ArtifactId,
pub session_id: String,
pub created_at_ms: i64,
pub replaced_start: usize,
pub replaced_end: usize,
pub replaced_messages_json: String,
pub summary: String,
pub original_tokens: u32,
pub summary_tokens: u32,
}
impl CompactionArtifact {
#[must_use]
pub fn replaced_count(&self) -> usize {
self.replaced_end.saturating_sub(self.replaced_start)
}
#[must_use]
pub fn covers_index(&self, idx: usize) -> bool {
idx >= self.replaced_start && idx < self.replaced_end
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compaction_artifact_covers_index() {
let art = CompactionArtifact {
id: "test-id".to_string(),
session_id: "sess".to_string(),
created_at_ms: 0,
replaced_start: 2,
replaced_end: 5,
replaced_messages_json: "[]".to_string(),
summary: "summary".to_string(),
original_tokens: 100,
summary_tokens: 20,
};
assert!(!art.covers_index(1));
assert!(art.covers_index(2));
assert!(art.covers_index(4));
assert!(!art.covers_index(5));
assert_eq!(art.replaced_count(), 3);
}
}