mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-12 04:33:29 +08:00
feat: add ecc2 graph compaction
This commit is contained in:
116
ecc2/src/main.rs
116
ecc2/src/main.rs
@@ -490,6 +490,18 @@ enum GraphCommands {
|
||||
#[arg(long)]
|
||||
json: bool,
|
||||
},
|
||||
/// Compact stored observations in the shared context graph
|
||||
Compact {
|
||||
/// Filter by source session ID or alias
|
||||
#[arg(long)]
|
||||
session_id: Option<String>,
|
||||
/// Maximum observations to retain per entity after compaction
|
||||
#[arg(long, default_value_t = 12)]
|
||||
keep_observations_per_entity: usize,
|
||||
/// Emit machine-readable JSON instead of the human summary
|
||||
#[arg(long)]
|
||||
json: bool,
|
||||
},
|
||||
/// Recall relevant context graph entities for a query
|
||||
Recall {
|
||||
/// Filter by source session ID or alias
|
||||
@@ -1314,6 +1326,32 @@ async fn main() -> Result<()> {
|
||||
println!("{}", format_graph_observations_human(&observations));
|
||||
}
|
||||
}
|
||||
GraphCommands::Compact {
|
||||
session_id,
|
||||
keep_observations_per_entity,
|
||||
json,
|
||||
} => {
|
||||
let resolved_session_id = session_id
|
||||
.as_deref()
|
||||
.map(|value| resolve_session_id(&db, value))
|
||||
.transpose()?;
|
||||
let stats = db.compact_context_graph(
|
||||
resolved_session_id.as_deref(),
|
||||
keep_observations_per_entity,
|
||||
)?;
|
||||
if json {
|
||||
println!("{}", serde_json::to_string_pretty(&stats)?);
|
||||
} else {
|
||||
println!(
|
||||
"{}",
|
||||
format_graph_compaction_stats_human(
|
||||
&stats,
|
||||
resolved_session_id.as_deref(),
|
||||
keep_observations_per_entity,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
GraphCommands::Recall {
|
||||
session_id,
|
||||
query,
|
||||
@@ -2416,6 +2454,32 @@ fn format_graph_recall_human(
|
||||
lines.join("\n")
|
||||
}
|
||||
|
||||
fn format_graph_compaction_stats_human(
|
||||
stats: &session::ContextGraphCompactionStats,
|
||||
session_id: Option<&str>,
|
||||
keep_observations_per_entity: usize,
|
||||
) -> String {
|
||||
let scope = session_id
|
||||
.map(short_session)
|
||||
.unwrap_or_else(|| "all sessions".to_string());
|
||||
[
|
||||
format!(
|
||||
"Context graph compaction complete for {scope} (keep {keep_observations_per_entity} observations per entity)"
|
||||
),
|
||||
format!("- entities scanned {}", stats.entities_scanned),
|
||||
format!(
|
||||
"- duplicate observations deleted {}",
|
||||
stats.duplicate_observations_deleted
|
||||
),
|
||||
format!(
|
||||
"- overflow observations deleted {}",
|
||||
stats.overflow_observations_deleted
|
||||
),
|
||||
format!("- observations retained {}", stats.observations_retained),
|
||||
]
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
fn format_graph_entity_detail_human(detail: &session::ContextGraphEntityDetail) -> String {
|
||||
let mut lines = vec![format_graph_entity_human(&detail.entity)];
|
||||
lines.push(String::new());
|
||||
@@ -4393,6 +4457,37 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_parses_graph_compact_command() {
|
||||
let cli = Cli::try_parse_from([
|
||||
"ecc",
|
||||
"graph",
|
||||
"compact",
|
||||
"--session-id",
|
||||
"latest",
|
||||
"--keep-observations-per-entity",
|
||||
"6",
|
||||
"--json",
|
||||
])
|
||||
.expect("graph compact should parse");
|
||||
|
||||
match cli.command {
|
||||
Some(Commands::Graph {
|
||||
command:
|
||||
GraphCommands::Compact {
|
||||
session_id,
|
||||
keep_observations_per_entity,
|
||||
json,
|
||||
},
|
||||
}) => {
|
||||
assert_eq!(session_id.as_deref(), Some("latest"));
|
||||
assert_eq!(keep_observations_per_entity, 6);
|
||||
assert!(json);
|
||||
}
|
||||
_ => panic!("expected graph compact subcommand"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_decisions_human_renders_details() {
|
||||
let text = format_decisions_human(
|
||||
@@ -4534,6 +4629,27 @@ mod tests {
|
||||
assert!(text.contains("summary Finished auth callback recovery with 2 tests"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_graph_compaction_stats_human_renders_counts() {
|
||||
let text = format_graph_compaction_stats_human(
|
||||
&session::ContextGraphCompactionStats {
|
||||
entities_scanned: 3,
|
||||
duplicate_observations_deleted: 2,
|
||||
overflow_observations_deleted: 4,
|
||||
observations_retained: 9,
|
||||
},
|
||||
Some("sess-12345678"),
|
||||
6,
|
||||
);
|
||||
|
||||
assert!(text.contains("Context graph compaction complete for sess-123"));
|
||||
assert!(text.contains("keep 6 observations per entity"));
|
||||
assert!(text.contains("- entities scanned 3"));
|
||||
assert!(text.contains("- duplicate observations deleted 2"));
|
||||
assert!(text.contains("- overflow observations deleted 4"));
|
||||
assert!(text.contains("- observations retained 9"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_graph_sync_stats_human_renders_counts() {
|
||||
let text = format_graph_sync_stats_human(
|
||||
|
||||
Reference in New Issue
Block a user