From 52523403c508dca303ae160328942159c245f758 Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Sun, 8 Mar 2026 21:13:02 -0400 Subject: [PATCH] extract truncation helpers, fix clippy warnings, dedup batching loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add util::truncate() and util::first_n_chars() to replace 16 call sites doing the same floor_char_boundary or chars().take().collect() patterns. Deduplicate the batching loop in consolidate.rs (4 copies → 1 loop over an array). Fix all clippy warnings: redundant closures, needless borrows, collapsible if, unnecessary cast, manual strip_prefix. Net: -44 lines across 16 files. --- poc-memory/src/consolidate.rs | 44 ++++++------------------ poc-memory/src/daemon.rs | 10 +++--- poc-memory/src/digest.rs | 1 + poc-memory/src/enrich.rs | 15 ++------- poc-memory/src/fact_mine.rs | 11 ++---- poc-memory/src/knowledge.rs | 4 +-- poc-memory/src/llm.rs | 4 +-- poc-memory/src/main.rs | 60 ++++++++++++++------------------- poc-memory/src/neuro/prompts.rs | 20 +++-------- poc-memory/src/neuro/rewrite.rs | 9 ++--- poc-memory/src/neuro/scoring.rs | 2 +- poc-memory/src/query.rs | 8 ++--- poc-memory/src/search.rs | 7 +--- poc-memory/src/store/types.rs | 1 + poc-memory/src/store/view.rs | 2 +- poc-memory/src/util.rs | 16 +++++++++ 16 files changed, 85 insertions(+), 129 deletions(-) diff --git a/poc-memory/src/consolidate.rs b/poc-memory/src/consolidate.rs index 0f5aea7..2f9f7d7 100644 --- a/poc-memory/src/consolidate.rs +++ b/poc-memory/src/consolidate.rs @@ -66,40 +66,18 @@ pub fn consolidate_full_with_progress( if plan.run_health { runs.push(("health", 0)); } - if plan.replay_count > 0 { - let batch = 5; - let mut remaining = plan.replay_count; + let batch_size = 5; + for (name, count) in [ + ("replay", plan.replay_count), + ("linker", plan.linker_count), + ("separator", plan.separator_count), + ("transfer", plan.transfer_count), + ] { + let mut remaining = count; while remaining > 0 { - let this_batch = remaining.min(batch); - runs.push(("replay", this_batch)); - remaining -= this_batch; - } - } - if plan.linker_count > 0 { - let batch = 5; - let mut remaining = plan.linker_count; - while remaining > 0 { - let this_batch = remaining.min(batch); - runs.push(("linker", this_batch)); - remaining -= this_batch; - } - } - if plan.separator_count > 0 { - let batch = 5; - let mut remaining = plan.separator_count; - while remaining > 0 { - let this_batch = remaining.min(batch); - runs.push(("separator", this_batch)); - remaining -= this_batch; - } - } - if plan.transfer_count > 0 { - let batch = 5; - let mut remaining = plan.transfer_count; - while remaining > 0 { - let this_batch = remaining.min(batch); - runs.push(("transfer", this_batch)); - remaining -= this_batch; + let batch = remaining.min(batch_size); + runs.push((name, batch)); + remaining -= batch; } } diff --git a/poc-memory/src/daemon.rs b/poc-memory/src/daemon.rs index f9a845e..25f3256 100644 --- a/poc-memory/src/daemon.rs +++ b/poc-memory/src/daemon.rs @@ -104,7 +104,7 @@ fn job_experience_mine(ctx: &ExecutionContext, path: &str, segment: Option Result<(), TaskError> { let p = std::path::Path::new(&path); let progress = |msg: &str| { ctx.set_progress(msg); }; let count = crate::fact_mine::mine_and_store(p, Some(&progress))?; - ctx.log_line(&format!("{} facts stored", count)); + ctx.log_line(format!("{count} facts stored")); Ok(()) }) } @@ -140,7 +140,7 @@ fn job_knowledge_loop(ctx: &ExecutionContext) -> Result<(), TaskError> { }; ctx.log_line("running agents"); let results = crate::knowledge::run_knowledge_loop(&config)?; - ctx.log_line(&format!("{} cycles, {} actions", + ctx.log_line(format!("{} cycles, {} actions", results.len(), results.iter().map(|r| r.total_applied).sum::())); Ok(()) @@ -505,7 +505,7 @@ pub fn run_daemon() -> Result<(), String> { if extract_pending > 0 { parts.push(format!("{} extract", extract_pending)); } if fact_pending > 0 { parts.push(format!("{} fact", fact_pending)); } if still_open > 0 { parts.push(format!("{} open", still_open)); } - ctx.set_progress(&parts.join(", ")); + ctx.set_progress(parts.join(", ")); } else { ctx.set_progress("idle"); } @@ -575,7 +575,7 @@ pub fn run_daemon() -> Result<(), String> { digest.depend_on(&knowledge); *last_daily_sched.lock().unwrap() = Some(today); - ctx.set_progress(&format!("daily pipeline triggered ({})", today)); + ctx.set_progress(format!("daily pipeline triggered ({today})")); } // Prune finished tasks from registry diff --git a/poc-memory/src/digest.rs b/poc-memory/src/digest.rs index aa8b638..5509a1f 100644 --- a/poc-memory/src/digest.rs +++ b/poc-memory/src/digest.rs @@ -15,6 +15,7 @@ use std::collections::BTreeSet; // --- Digest level descriptors --- +#[allow(clippy::type_complexity)] struct DigestLevel { name: &'static str, title: &'static str, diff --git a/poc-memory/src/enrich.rs b/poc-memory/src/enrich.rs index 4a4e240..e36c48c 100644 --- a/poc-memory/src/enrich.rs +++ b/poc-memory/src/enrich.rs @@ -165,11 +165,7 @@ pub fn split_on_compaction(messages: Vec<(usize, String, String, String)>) -> Ve fn format_conversation(messages: &[(usize, String, String, String)]) -> String { messages.iter() .map(|(line, role, text, ts)| { - let text = if text.len() > 2000 { - format!("{}...[truncated]", &text[..text.floor_char_boundary(1800)]) - } else { - text.clone() - }; + let text = crate::util::truncate(text, 1800, "...[truncated]"); if ts.is_empty() { format!("L{} [{}]: {}", line, role, text) } else { @@ -424,13 +420,8 @@ pub fn experience_mine( let _ = store.upsert_node(node); count += 1; - let preview = if content.len() > 80 { - let end = content.floor_char_boundary(77); - &content[..end] - } else { - content - }; - println!(" + [{}] {}...", ts, preview); + let preview = crate::util::truncate(content, 77, "..."); + println!(" + [{}] {}", ts, preview); } // Record this transcript/segment as mined (even if count == 0, to prevent re-runs) diff --git a/poc-memory/src/fact_mine.rs b/poc-memory/src/fact_mine.rs index 6cad86f..dfadcd6 100644 --- a/poc-memory/src/fact_mine.rs +++ b/poc-memory/src/fact_mine.rs @@ -144,13 +144,7 @@ fn extract_conversation(path: &Path) -> Vec { fn format_for_extraction(messages: &[Message]) -> String { messages.iter() .map(|msg| { - let text = if msg.text.len() > 3000 { - // Find a char boundary near 2800 - let trunc = msg.text.floor_char_boundary(2800); - format!("{}\n[...truncated...]", &msg.text[..trunc]) - } else { - msg.text.clone() - }; + let text = crate::util::truncate(&msg.text, 2800, "\n[...truncated...]"); let ts = if msg.timestamp.len() >= 19 { &msg.timestamp[..19] } else { "" }; if ts.is_empty() { format!("[{}] {}", msg.role, text) @@ -244,8 +238,7 @@ pub fn mine_transcript( if dry_run { for (i, (offset, chunk)) in chunks.iter().enumerate() { eprintln!("\n--- Chunk {} (offset {}, {} chars) ---", i + 1, offset, chunk.len()); - let preview = if chunk.len() > 500 { &chunk[..chunk.floor_char_boundary(500)] } else { chunk }; - eprintln!("{}", preview); + eprintln!("{}", crate::util::truncate(chunk, 500, "")); if chunk.len() > 500 { eprintln!(" ... ({} more chars)", chunk.len() - 500); } diff --git a/poc-memory/src/knowledge.rs b/poc-memory/src/knowledge.rs index 867e13e..9987c97 100644 --- a/poc-memory/src/knowledge.rs +++ b/poc-memory/src/knowledge.rs @@ -631,8 +631,8 @@ pub fn run_challenger(store: &Store, graph: &Graph, batch_size: usize) -> Result let template = load_prompt("challenger")?; let topology = get_graph_topology(store, graph); - let mut candidates: Vec<(&String, usize)> = store.nodes.iter() - .map(|(k, _)| (k, graph.degree(k))) + let mut candidates: Vec<(&String, usize)> = store.nodes.keys() + .map(|k| (k, graph.degree(k))) .collect(); candidates.sort_by(|a, b| b.1.cmp(&a.1)); diff --git a/poc-memory/src/llm.rs b/poc-memory/src/llm.rs index 2ed31e9..8e0f41a 100644 --- a/poc-memory/src/llm.rs +++ b/poc-memory/src/llm.rs @@ -83,7 +83,7 @@ fn call_model(agent: &str, model: &str, prompt: &str) -> Result Ok(response) } else { let stderr = String::from_utf8_lossy(&output.stderr); - let preview: String = stderr.chars().take(500).collect(); + let preview = crate::util::first_n_chars(&stderr, 500); log_usage(agent, model, prompt, &preview, elapsed, false); Err(format!("claude exited {}: {}", output.status, preview.trim())) } @@ -129,7 +129,7 @@ pub(crate) fn parse_json_response(response: &str) -> Result Result<(), String> { let weight = view.node_weight(k); println!(" ~ [{:.2}] {}", weight, k); if let Some(content) = view.node_content(k) { - let snippet: String = content.lines() - .find(|l| !l.trim().is_empty() && !l.starts_with('#')) - .unwrap_or("") - .chars().take(100).collect(); + let snippet = util::first_n_chars( + content.lines() + .find(|l| !l.trim().is_empty() && !l.starts_with('#')) + .unwrap_or(""), + 100); if !snippet.is_empty() { println!(" {}", snippet); } @@ -671,13 +672,11 @@ fn cmd_init() -> Result<(), String> { let mut store = store::Store::load()?; let count = store.init_from_markdown()?; for key in &cfg.core_nodes { - if !store.nodes.contains_key(key.as_str()) { - if key == "identity" { - let default = include_str!("../defaults/identity.md"); - store.upsert(key, default) - .map_err(|e| format!("seed {}: {}", key, e))?; - println!("Seeded {} in store", key); - } + if !store.nodes.contains_key(key) && key == "identity" { + let default = include_str!("../defaults/identity.md"); + store.upsert(key, default) + .map_err(|e| format!("seed {}: {}", key, e))?; + println!("Seeded {} in store", key); } } store.save()?; @@ -1319,12 +1318,7 @@ fn cmd_trace(key: &[String]) -> Result<(), String> { } // Show content preview - let preview = if node.content.len() > 200 { - let end = node.content.floor_char_boundary(200); - format!("{}...", &node.content[..end]) - } else { - node.content.clone() - }; + let preview = util::truncate(&node.content, 200, "..."); println!("\n{}\n", preview); // Walk neighbors, grouped by node type @@ -1354,7 +1348,7 @@ fn cmd_trace(key: &[String]) -> Result<(), String> { if !episodic_weekly.is_empty() { println!("Weekly digests:"); for (k, s, n) in &episodic_weekly { - let preview = n.content.lines().next().unwrap_or("").chars().take(80).collect::(); + let preview = util::first_n_chars(n.content.lines().next().unwrap_or(""), 80); println!(" [{:.2}] {} — {}", s, k, preview); } } @@ -1362,7 +1356,7 @@ fn cmd_trace(key: &[String]) -> Result<(), String> { if !episodic_daily.is_empty() { println!("Daily digests:"); for (k, s, n) in &episodic_daily { - let preview = n.content.lines().next().unwrap_or("").chars().take(80).collect::(); + let preview = util::first_n_chars(n.content.lines().next().unwrap_or(""), 80); println!(" [{:.2}] {} — {}", s, k, preview); } } @@ -1370,9 +1364,11 @@ fn cmd_trace(key: &[String]) -> Result<(), String> { if !episodic_session.is_empty() { println!("Session entries:"); for (k, s, n) in &episodic_session { - let preview = n.content.lines() - .find(|l| !l.is_empty() && !l.starts_with("