chore: fix formatting and clippy lints

This commit is contained in:
Riz Ashraf committed 2026-10-08 23:01:38 +01:00
1 parent 8952bd5399
commit 9d9e959744
35 files changed
+1091 -582

No files matched your search

+153 -69
View File
@@ -62,8 +62,8 @@ impl<'a> GraphQueryBuilder<'a> {
break;
}
nodes_at_current_depth -= 1;
if current_depth < self.max_depth {
if let Some(neighbors) = adj.get(current) {
if current_depth < self.max_depth
&& let Some(neighbors) = adj.get(current) {
for &(neighbor, rel_type, is_inverse) in neighbors {
if !visited.contains(neighbor) {
visited.insert(neighbor);
@@ -73,7 +73,6 @@ impl<'a> GraphQueryBuilder<'a> {
}
}
}
}
if nodes_at_current_depth == 0 {
current_depth += 1;
nodes_at_current_depth = nodes_at_next_depth;
@@ -138,7 +137,9 @@ impl McpTool for QueryGraphPathHandler {
})
})
.await
.map_err(|e| crate::error::AppError::Internal(format!("Graph traversal task failed: {}", e)))?
.map_err(|e| {
crate::error::AppError::Internal(format!("Graph traversal task failed: {}", e))
})?
}
}
@@ -169,12 +170,19 @@ impl McpTool for CreateEntitiesHandler {
}
}
});
let names: Vec<String> = inserted.iter().map(|e| format!("{} ({})", e.name, e.entity_type)).collect();
let names: Vec<String> = inserted
.iter()
.map(|e| format!("{} ({})", e.name, e.entity_type))
.collect();
if !inserted.is_empty() {
let idx = state.get_search_index().await;
let _ = idx.index_entities_batch(&inserted).await;
}
Ok(format!("Successfully created {} entity/entities: {}", names.len(), names.join(", ")))
Ok(format!(
"Successfully created {} entity/entities: {}",
names.len(),
names.join(", ")
))
}
}
@@ -236,7 +244,9 @@ impl McpTool for CreateRelationsHandler {
crate::models::Entity {
name: node_name.clone(),
entity_type: "Entity".to_string(),
observations: vec!["Auto-created stub entity for relation endpoint".to_string()],
observations: vec![
"Auto-created stub entity for relation endpoint".to_string(),
],
namespace: crate::models::default_namespace(),
git_branch: None,
..Default::default()
@@ -247,16 +257,28 @@ impl McpTool for CreateRelationsHandler {
}
for mut relation in req.relations {
if !relation.from.is_empty() && !relation.to.is_empty() {
relation.relation_type = crate::models::normalize_relation_type(&relation.relation_type);
added_relations.push(format!("{} -[{}]-> {}", relation.from, relation.relation_type, relation.to));
relation.relation_type =
crate::models::normalize_relation_type(&relation.relation_type);
added_relations.push(format!(
"{} -[{}]-> {}",
relation.from, relation.relation_type, relation.to
));
g.relations.push(relation);
}
}
});
let mut msg = format!("Successfully created {} relation(s):\n{}", added_relations.len(), added_relations.join("\n"));
let mut msg = format!(
"Successfully created {} relation(s):\n{}",
added_relations.len(),
added_relations.join("\n")
);
if !auto_created.is_empty() {
msg.push_str(&format!("\nNote: Auto-created {} missing stub entity/entities: {}", auto_created.len(), auto_created.join(", ")));
msg.push_str(&format!(
"\nNote: Auto-created {} missing stub entity/entities: {}",
auto_created.len(),
auto_created.join(", ")
));
}
Ok(msg)
}
@@ -462,7 +484,7 @@ impl McpTool for ReadGraphHandler {
let filtered_entities: Vec<(&String, &crate::models::Entity)> = full
.entities
.iter()
.filter(|(_, v)| req.namespace.as_ref().map_or(true, |ns| &v.namespace == ns))
.filter(|(_, v)| req.namespace.as_ref().is_none_or(|ns| &v.namespace == ns))
.collect();
let total_count = filtered_entities.len();
@@ -481,7 +503,7 @@ impl McpTool for ReadGraphHandler {
.relations
.iter()
.filter(|r| {
let ns_match = req.namespace.as_ref().map_or(true, |ns| &r.namespace == ns);
let ns_match = req.namespace.as_ref().is_none_or(|ns| &r.namespace == ns);
ns_match && (paged_entities.contains_key(&r.from) || paged_entities.contains_key(&r.to))
})
.collect();
@@ -499,7 +521,7 @@ impl McpTool for ReadGraphHandler {
let rel_vec: Vec<&crate::models::Relation> = full
.relations
.iter()
.filter(|r| req.namespace.as_ref().map_or(true, |ns| &r.namespace == ns))
.filter(|r| req.namespace.as_ref().is_none_or(|ns| &r.namespace == ns))
.collect();
(ent_map, rel_vec, None)
};
@@ -549,21 +571,19 @@ impl McpTool for ReadGraphHandler {
}
});
if let Some(meta) = &meta_json {
if let Some(obj) = truncated_val.as_object_mut() {
if let Some(meta) = &meta_json
&& let Some(obj) = truncated_val.as_object_mut() {
obj.insert("total_count".to_string(), meta["total_count"].clone());
obj.insert("offset".to_string(), meta["offset"].clone());
obj.insert("limit".to_string(), meta["limit"].clone());
obj.insert("has_more".to_string(), serde_json::Value::Bool(true));
}
}
if let Ok(trunc_str) = serde_json::to_string(&truncated_val) {
if trunc_str.len() <= max_chars || keep_count == 1 {
if let Ok(trunc_str) = serde_json::to_string(&truncated_val)
&& (trunc_str.len() <= max_chars || keep_count == 1) {
result_json = trunc_str;
break;
}
}
keep_count = keep_count.saturating_sub(keep_count / 3 + 1);
}
}
@@ -820,7 +840,10 @@ impl McpTool for CondenseEntityHandler {
e.observations = unique_obs;
}
});
return Ok(format!("Entity '{}' observations condensed with deduplication/AI summary.", req.entity_name));
return Ok(format!(
"Entity '{}' observations condensed with deduplication/AI summary.",
req.entity_name
));
}
state.modify_graph(|master| {
@@ -953,10 +976,9 @@ impl McpTool for GetSubgraphHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: GetSubgraphTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let root = req
.root_entity
.or(req.root_node)
.ok_or_else(|| crate::error::AppError::Internal("root_entity or root_node is required".to_string()))?;
let root = req.root_entity.or(req.root_node).ok_or_else(|| {
crate::error::AppError::Internal("root_entity or root_node is required".to_string())
})?;
let depth = req.depth.unwrap_or(2);
let format = req.format.unwrap_or(SubgraphFormat::Json);
@@ -974,15 +996,14 @@ impl McpTool for GetSubgraphHandler {
visited.insert(root.clone());
while let Some((curr, d)) = queue.pop_front() {
if d < depth {
if let Some(neighbors) = adj.get(curr) {
if d < depth
&& let Some(neighbors) = adj.get(curr) {
for &next in neighbors {
if visited.insert(next.to_string()) {
queue.push_back((next, d + 1));
}
}
}
}
}
let ent: std::collections::HashMap<String, crate::models::Entity> = visited
@@ -1011,7 +1032,10 @@ impl McpTool for GetSubgraphHandler {
markdown.push_str("\n## Relations\n");
for r in &matched_relations {
markdown.push_str(&format!("- `{}` --[{}]--> `{}`\n", r.from, r.relation_type, r.to));
markdown.push_str(&format!(
"- `{}` --[{}]--> `{}`\n",
r.from, r.relation_type, r.to
));
}
return Ok(markdown);
}
@@ -1038,7 +1062,10 @@ impl McpTool for SweepGraphHealthHandler {
}
fn schema(&self) -> Value {
crate::mcp::tool_def::<SweepGraphHealthTool>("sweep_graph_health", "Audit and sweep graph health")
crate::mcp::tool_def::<SweepGraphHealthTool>(
"sweep_graph_health",
"Audit and sweep graph health",
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
@@ -1132,26 +1159,31 @@ impl McpTool for ResolveStaleSymbolsHandler {
}
fn schema(&self) -> Value {
crate::mcp::tool_def::<ResolveStaleSymbolsTool>("resolve_stale_symbols", "Inspect Knowledge Graph entities and tech debt symbol/line references against files on disk, healing stale pointers.")
crate::mcp::tool_def::<ResolveStaleSymbolsTool>(
"resolve_stale_symbols",
"Inspect Knowledge Graph entities and tech debt symbol/line references against files on disk, healing stale pointers.",
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ResolveStaleSymbolsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let req: ResolveStaleSymbolsTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
let auto_heal = req.auto_heal.unwrap_or(true);
let mut checked = 0;
let mut stale_entities = Vec::new();
state.modify_graph(|g| {
for (name, _entity) in g.entities.iter_mut() {
if let Some(target) = &req.target {
if name != target && !name.contains(target) {
for name in g.entities.keys() {
if let Some(target) = &req.target
&& name != target && !name.contains(target) {
continue;
}
}
checked += 1;
let path = std::path::Path::new(name);
if (name.contains('/') || name.contains('\\') || name.contains('.')) && !path.exists() {
if (name.contains('/') || name.contains('\\') || name.contains('.'))
&& !path.exists()
{
stale_entities.push(name.clone());
}
}
@@ -1184,7 +1216,10 @@ impl McpTool for SummarizeSubgraphHandler {
}
fn schema(&self) -> Value {
crate::mcp::tool_def::<SummarizeSubgraphTool>("summarize_subgraph", "Generate compact, LLM-optimized Markdown topology of a graph component capped within a token budget.")
crate::mcp::tool_def::<SummarizeSubgraphTool>(
"summarize_subgraph",
"Generate compact, LLM-optimized Markdown topology of a graph component capped within a token budget.",
)
}
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
@@ -1212,8 +1247,18 @@ impl McpTool for SummarizeSubgraphHandler {
}
}
let ent: Vec<_> = g.entities.values().filter(|e| visited.contains(&e.name)).cloned().collect();
let rel: Vec<_> = g.relations.iter().filter(|r| visited.contains(&r.from) && visited.contains(&r.to)).cloned().collect();
let ent: Vec<_> = g
.entities
.values()
.filter(|e| visited.contains(&e.name))
.cloned()
.collect();
let rel: Vec<_> = g
.relations
.iter()
.filter(|r| visited.contains(&r.from) && visited.contains(&r.to))
.cloned()
.collect();
(ent, rel)
});
@@ -1228,7 +1273,10 @@ impl McpTool for SummarizeSubgraphHandler {
markdown.push_str("\n## Relations\n");
for r in &sub_relations {
markdown.push_str(&format!("- `{}` --[{}]--> `{}`\n", r.from, r.relation_type, r.to));
markdown.push_str(&format!(
"- `{}` --[{}]--> `{}`\n",
r.from, r.relation_type, r.to
));
}
let max_tokens = req.max_tokens.unwrap_or(1000);
@@ -1249,7 +1297,6 @@ mod tests {
use crate::handlers::meta::AgentSignalsHandler;
use serde_json::json;
#[tokio::test]
async fn test_create_and_read_entities() {
let state = Arc::new(MemoryState::new_in_memory());
@@ -1324,10 +1371,7 @@ mod tests {
{"source": "A", "target": "B", "relationType": "knows"}
]
});
let alias_res = handler
.execute(alias_args, state.clone())
.await
.unwrap();
let alias_res = handler.execute(alias_args, state.clone()).await.unwrap();
assert!(alias_res.contains("Successfully created 1 relation(s)"));
// Test semantic LLM schema feedback on missing fields
@@ -1499,7 +1543,10 @@ mod tests {
{"name": "Beta", "entity_type": "Node", "observations": ["Obs3"], "namespace": "global"}
]
});
create_handler.execute(args_ent, state.clone()).await.unwrap();
create_handler
.execute(args_ent, state.clone())
.await
.unwrap();
let rel_handler = CreateRelationsHandler;
let args_rel = json!({
@@ -1510,48 +1557,86 @@ mod tests {
rel_handler.execute(args_rel, state.clone()).await.unwrap();
let path_handler = QueryGraphPathHandler;
let path_res = path_handler.execute(json!({"start_node": "Alpha", "end_node": "Beta"}), state.clone()).await.unwrap();
let path_res = path_handler
.execute(
json!({"start_node": "Alpha", "end_node": "Beta"}),
state.clone(),
)
.await
.unwrap();
assert!(path_res.contains("Alpha"));
let sub_handler = GetSubgraphHandler;
let sub_res = sub_handler.execute(json!({"root_entity": "Alpha"}), state.clone()).await.unwrap();
let sub_res = sub_handler
.execute(json!({"root_entity": "Alpha"}), state.clone())
.await
.unwrap();
assert!(sub_res.contains("Alpha"));
let sum_handler = SummarizeSubgraphHandler;
let sum_res = sum_handler.execute(json!({"root_entity": "Alpha"}), state.clone()).await.unwrap();
let sum_res = sum_handler
.execute(json!({"root_entity": "Alpha"}), state.clone())
.await
.unwrap();
assert!(!sum_res.is_empty());
let sweep_handler = SweepGraphHealthHandler;
let sweep_res = sweep_handler.execute(json!({}), state.clone()).await.unwrap();
let sweep_res = sweep_handler
.execute(json!({}), state.clone())
.await
.unwrap();
assert!(!sweep_res.is_empty());
let del_obs_handler = DeleteObservationsHandler;
let del_obs_res = del_obs_handler.execute(json!({
"deletions": [{"entity_name": "Alpha", "observations": ["Obs1"]}]
}), state.clone()).await.unwrap();
let del_obs_res = del_obs_handler
.execute(
json!({
"deletions": [{"entity_name": "Alpha", "observations": ["Obs1"]}]
}),
state.clone(),
)
.await
.unwrap();
assert_eq!(del_obs_res, "Observations deleted");
let del_rel_handler = DeleteRelationsHandler;
let del_rel_res = del_rel_handler.execute(json!({
"relations": [{"from": "Alpha", "to": "Beta", "relation_type": "links_to"}]
}), state.clone()).await.unwrap();
let del_rel_res = del_rel_handler
.execute(
json!({
"relations": [{"from": "Alpha", "to": "Beta", "relation_type": "links_to"}]
}),
state.clone(),
)
.await
.unwrap();
assert_eq!(del_rel_res, "Relations deleted");
let bcast_handler = AgentSignalsHandler;
let bcast_res = bcast_handler.execute(json!({
"action": "broadcast",
"sender": "agent1",
"signal_type": "task_completed",
"payload": "fix_bug"
}), state.clone()).await.unwrap();
let bcast_res = bcast_handler
.execute(
json!({
"action": "broadcast",
"sender": "agent1",
"signal_type": "task_completed",
"payload": "fix_bug"
}),
state.clone(),
)
.await
.unwrap();
assert!(bcast_res.contains("Broadcasted signal"));
let qsignal_handler = AgentSignalsHandler;
let qsignal_res = qsignal_handler.execute(json!({
"action": "query",
"sender": "agent1"
}), state.clone()).await.unwrap();
let qsignal_res = qsignal_handler
.execute(
json!({
"action": "query",
"sender": "agent1"
}),
state.clone(),
)
.await
.unwrap();
assert!(qsignal_res.contains("task_completed"));
let read_paged_handler = ReadGraphHandler;
let paged_res = read_paged_handler
@@ -1563,4 +1648,3 @@ mod tests {
assert_eq!(parsed_paged["has_more"], true);
}
}