fix(graph): implement fuzzy substring matching for DeleteObservationsTool to improve LLM UX
This commit is contained in:
1 parent
7c9e901c12
commit
cfcd42f41e
1 file changed
+36
-18
@@ -409,30 +409,48 @@ impl McpTool for DeleteObservationsHandler {
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
|
||||
let req: DeleteObservationsTool =
|
||||
serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut missing = Vec::new();
|
||||
state.read_graph(|g| {
|
||||
for d in &req.deletions {
|
||||
if !g.entities.contains_key(&d.entity_name) {
|
||||
missing.push(d.entity_name.clone());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if !missing.is_empty() {
|
||||
return Err(crate::error::AppError::Internal(format!(
|
||||
"Error: Entities not found: {}. Please use the search_nodes or read_graph tools to verify the exact entity names.",
|
||||
missing.join(", ")
|
||||
)));
|
||||
}
|
||||
|
||||
|
||||
let mut missing_entities = Vec::new();
|
||||
let mut missing_observations = Vec::new();
|
||||
|
||||
state.modify_graph(|master| {
|
||||
for d in req.deletions {
|
||||
if let Some(e) = master.entities.get_mut(&d.entity_name) {
|
||||
let to_rem: HashSet<_> = d.observations.into_iter().collect();
|
||||
e.observations.retain(|o| !to_rem.contains(o));
|
||||
for target in d.observations {
|
||||
let target_clean = target.trim();
|
||||
if target_clean.is_empty() { continue; }
|
||||
|
||||
let initial_len = e.observations.len();
|
||||
e.observations.retain(|o| {
|
||||
let o_clean = o.trim();
|
||||
// Exact match OR substantial substring match (to forgive LLM whitespace/newline errors)
|
||||
!(o_clean == target_clean || (target_clean.len() >= 10 && o_clean.contains(target_clean)))
|
||||
});
|
||||
|
||||
if e.observations.len() == initial_len {
|
||||
missing_observations.push(target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
missing_entities.push(d.entity_name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if !missing_entities.is_empty() {
|
||||
return Err(crate::error::AppError::Internal(format!(
|
||||
"Error: Entities not found: {}. Please use search_nodes to verify the exact entity names.",
|
||||
missing_entities.join(", ")
|
||||
)));
|
||||
}
|
||||
|
||||
if !missing_observations.is_empty() {
|
||||
return Err(crate::error::AppError::Internal(format!(
|
||||
"Error: Failed to find {} observation(s) to delete. Make sure you provide a sufficiently long exact substring match.",
|
||||
missing_observations.len()
|
||||
)));
|
||||
}
|
||||
|
||||
Ok("Observations deleted".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user