From 1a94ef1f1c50221c8fccedf61da7ea5bee8e9d82 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sat, 21 Mar 2026 22:44:59 -0400 Subject: [PATCH] fix: cap neighborhood size in agent prompts to prevent oversized prompts When building the {{neighborhood}} placeholder for distill and other agents, stop adding full neighbor content once the prompt exceeds 600KB (~150K tokens). Remaining neighbors get header-only treatment (key + link strength + first line). This fixes distill consistently failing on high-degree nodes like inner-life-sexuality-intimacy whose full neighborhood was 2.5MB. Co-Authored-By: Claude Opus 4.6 (1M context) --- poc-memory/src/agents/defs.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/poc-memory/src/agents/defs.rs b/poc-memory/src/agents/defs.rs index 68e8a74..a3cd7f4 100644 --- a/poc-memory/src/agents/defs.rs +++ b/poc-memory/src/agents/defs.rs @@ -319,13 +319,31 @@ fn resolve( let included_keys: std::collections::HashSet<&str> = included.iter() .map(|(k, _, _)| k.as_str()).collect(); + // Budget: stop adding full content when prompt gets large. + // Remaining neighbors get header-only (key + first line). + const NEIGHBORHOOD_BUDGET: usize = 600_000; // ~150K tokens + let mut budget_exceeded = false; + for (nbr, strength, _score) in &included { if let Some(n) = store.nodes.get(nbr.as_str()) { - out.push_str(&format!("#### {} (link: {:.2})\n\n{}\n\n", - nbr, strength, n.content)); + if budget_exceeded || out.len() > NEIGHBORHOOD_BUDGET { + // Header-only: key + first non-empty line + budget_exceeded = true; + let first_line = n.content.lines() + .find(|l| !l.trim().is_empty()) + .unwrap_or("(empty)"); + out.push_str(&format!("#### {} (link: {:.2}) — {}\n", + nbr, strength, first_line)); + } else { + out.push_str(&format!("#### {} (link: {:.2})\n\n{}\n\n", + nbr, strength, n.content)); + } all_keys.push(nbr.to_string()); } } + if budget_exceeded { + out.push_str("\n(remaining neighbors shown as headers only — prompt budget)\n\n"); + } // Cross-links between included neighbors let mut cross_links = Vec::new();