lean-ctx 3.9.15

Context Runtime for AI Agents with CCP. 71 MCP tools, 10 read modes, 95+ compression patterns, cross-session memory (CCP), persistent AI knowledge with temporal facts + contradiction detection, multi-agent context sharing, LITM-aware positioning, AAAK compact format, adaptive compression with Thompson Sampling bandits. Supports 24+ AI tools. Reduces LLM token consumption by up to 99%.
Documentation
//! Thin content-deduplication hook for the ctx_read hot path.

use crate::core::context_kernel::ctx_read_dedup::{self, ReadDedupSummary};

/// Returns an unchanged-content stub when deduplication applies and finds a match.
#[must_use]
pub fn maybe_dedup(path: &str, content: &str, mode: &str, fresh: bool) -> Option<String> {
    if !ctx_read_dedup::should_dedup(mode) {
        return None;
    }
    let stub = ctx_read_dedup::try_dedup(path, content, fresh)?;
    let original_tokens = crate::core::tokens::count_tokens(content);
    let stub_tokens = crate::core::tokens::count_tokens(&stub);
    crate::core::stats::record_reread(original_tokens.saturating_sub(stub_tokens));
    Some(stub)
}

/// Invalidates cached content for `path` after a file write.
pub fn on_write(path: &str) {
    ctx_read_dedup::on_file_write(path);
}

/// Returns current ctx_read deduplication statistics.
#[must_use]
pub fn summary() -> ReadDedupSummary {
    ctx_read_dedup::dedup_summary()
}

#[cfg(test)]
mod tests {
    use std::sync::MutexGuard;

    use super::{maybe_dedup, on_write};

    fn isolated() -> MutexGuard<'static, ()> {
        let guard = crate::core::context_kernel::kernel_config::KERNEL_TEST_LOCK
            .lock()
            .unwrap_or_else(std::sync::PoisonError::into_inner);
        crate::core::context_kernel::kernel_config::reset_features();
        crate::core::context_kernel::dedup_wiring::reset_dedup();
        guard
    }

    #[test]
    fn dedup_returns_none_for_new_content() {
        let _guard = isolated();
        assert_eq!(maybe_dedup("new.rs", "content", "full", false), None);
    }

    #[test]
    fn dedup_returns_stub_for_repeated() {
        let _guard = isolated();
        assert_eq!(maybe_dedup("repeat.rs", "content", "full", false), None);
        assert!(maybe_dedup("repeat.rs", "content", "full", false).is_some());
    }

    #[test]
    fn raw_mode_skips_dedup() {
        let _guard = isolated();
        assert_eq!(maybe_dedup("raw.rs", "content", "full", false), None);
        assert_eq!(maybe_dedup("raw.rs", "content", "raw", false), None);
    }

    #[test]
    fn write_invalidates_cache() {
        let _guard = isolated();
        assert_eq!(maybe_dedup("written.rs", "content", "full", false), None);
        assert!(maybe_dedup("written.rs", "content", "full", false).is_some());
        on_write("written.rs");
        assert_eq!(maybe_dedup("written.rs", "content", "full", false), None);
    }
}