Skip to main content

lean_ctx/core/benchmark_compare/
competitors.rs

1use std::fmt;
2
3#[derive(Debug, Clone)]
4pub struct CompetitorProfile {
5    pub name: &'static str,
6    pub version: &'static str,
7    pub compression_pct: Option<f64>,
8    pub source: &'static str,
9    pub url: &'static str,
10    pub supports_search: bool,
11    pub supports_caching: bool,
12    pub supports_multi_mode: bool,
13    pub supports_session_memory: bool,
14    pub feature_count: usize,
15}
16
17impl fmt::Display for CompetitorProfile {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        write!(f, "{} ({})", self.name, self.version)
20    }
21}
22
23pub fn all_competitors() -> Vec<CompetitorProfile> {
24    vec![
25        CompetitorProfile {
26            name: "Raw file read",
27            version: "baseline",
28            compression_pct: Some(0.0),
29            source: "Baseline — no compression applied",
30            url: "",
31            supports_search: false,
32            supports_caching: false,
33            supports_multi_mode: false,
34            supports_session_memory: false,
35            feature_count: 1,
36        },
37        CompetitorProfile {
38            name: "Repomix",
39            version: "--compress",
40            compression_pct: Some(70.0),
41            source: "Repomix docs (Tree-sitter compress mode)",
42            url: "https://github.com/yamadashy/repomix",
43            supports_search: false,
44            supports_caching: false,
45            supports_multi_mode: false,
46            supports_session_memory: false,
47            feature_count: 3,
48        },
49        CompetitorProfile {
50            name: "aider /map",
51            version: "repo-map",
52            compression_pct: Some(85.0),
53            source: "aider docs (repo-map with ctags/tree-sitter)",
54            url: "https://aider.chat/docs/repomap.html",
55            supports_search: false,
56            supports_caching: true,
57            supports_multi_mode: false,
58            supports_session_memory: false,
59            feature_count: 4,
60        },
61        CompetitorProfile {
62            name: "codebase-memory-mcp",
63            version: "graph-queries",
64            compression_pct: Some(99.2),
65            source: "arXiv paper (graph-query extraction only)",
66            url: "https://github.com/nicobailey/codebase-memory-mcp",
67            supports_search: true,
68            supports_caching: true,
69            supports_multi_mode: false,
70            supports_session_memory: true,
71            feature_count: 5,
72        },
73        CompetitorProfile {
74            name: "TokenForge",
75            version: "full-stack",
76            // Code engine is AST folding at 40-70%; we list the top of the
77            // published range to match how Repomix's "up to 70%" is reported.
78            compression_pct: Some(70.0),
79            source: "TokenForge README (tree-sitter code folding 40-70%; \
80                     full-stack: code/command/conversation/json/mcp-schema)",
81            url: "https://github.com/Manavarya09/tokenforge",
82            supports_search: false,
83            supports_caching: true,
84            supports_multi_mode: true,
85            supports_session_memory: true,
86            feature_count: 6,
87        },
88    ]
89}
90
91pub fn competitor_count() -> usize {
92    all_competitors().len()
93}
94
95#[cfg(test)]
96mod tests {
97    use super::*;
98
99    #[test]
100    fn all_competitors_non_empty() {
101        let c = all_competitors();
102        assert!(c.len() >= 3);
103    }
104
105    #[test]
106    fn baseline_is_zero_compression() {
107        let c = all_competitors();
108        let baseline = c.iter().find(|p| p.name == "Raw file read").unwrap();
109        assert_eq!(baseline.compression_pct, Some(0.0));
110    }
111
112    #[test]
113    fn display_includes_version() {
114        let c = &all_competitors()[1];
115        let s = format!("{c}");
116        assert!(s.contains(c.version));
117    }
118}