From d237f5c5add9232cb3ca2b785584be4215a7a253 Mon Sep 17 00:00:00 2001 From: Riz Ashraf Date: Mon, 21 Sep 2026 09:48:36 +0100 Subject: [PATCH] perf: remove redundant clone of json args in every tool handler --- server/src/handlers.rs | 116 ++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/server/src/handlers.rs b/server/src/handlers.rs index 1c0ba5a..d9a6541 100644 --- a/server/src/handlers.rs +++ b/server/src/handlers.rs @@ -370,7 +370,7 @@ impl MemoryHandler { let result: Result = match name { "query_graph_path" => { - let req = parse_tool!(args.clone(), id, crate::tools::QueryGraphPathTool); + let req = parse_tool!(args, id, crate::tools::QueryGraphPathTool); self.state.read_graph(|graph| { let max_depth = req.max_depth.unwrap_or(5); let mut queue = std::collections::VecDeque::new(); @@ -439,7 +439,7 @@ impl MemoryHandler { }) } "create_entities" => { - let req = parse_tool!(args.clone(), id, CreateEntitiesTool); + let req = parse_tool!(args, id, CreateEntitiesTool); self.state.modify_graph(|g| { for entity in req.entities { if !entity.name.is_empty() { @@ -453,7 +453,7 @@ impl MemoryHandler { Ok("Entities created".to_string()) } "create_relations" => { - let req = parse_tool!(args.clone(), id, CreateRelationsTool); + let req = parse_tool!(args, id, CreateRelationsTool); self.state.modify_graph(|g| { for relation in req.relations { if !relation.from.is_empty() && !relation.to.is_empty() { @@ -464,7 +464,7 @@ impl MemoryHandler { Ok("Relations created".to_string()) } "add_observations" => { - let req = parse_tool!(args.clone(), id, AddObservationsTool); + let req = parse_tool!(args, id, AddObservationsTool); self.state.modify_graph(|g| { for o in req.observations { if let Some(e) = g.entities.get_mut(&o.entity_name) { @@ -475,7 +475,7 @@ impl MemoryHandler { Ok("Observations added".to_string()) } "delete_entities" => { - let req = parse_tool!(args.clone(), id, DeleteEntitiesTool); + let req = parse_tool!(args, id, DeleteEntitiesTool); let to_delete: HashSet<_> = req.entity_names.into_iter().collect(); self.state.modify_graph(|master| { for name in &to_delete { @@ -488,7 +488,7 @@ impl MemoryHandler { Ok("Entities deleted".to_string()) } "delete_observations" => { - let req = parse_tool!(args.clone(), id, DeleteObservationsTool); + let req = parse_tool!(args, id, DeleteObservationsTool); self.state.modify_graph(|master| { for d in req.deletions { if let Some(e) = master.entities.get_mut(&d.entity_name) { @@ -500,7 +500,7 @@ impl MemoryHandler { Ok("Observations deleted".to_string()) } "delete_relations" => { - let req = parse_tool!(args.clone(), id, DeleteRelationsTool); + let req = parse_tool!(args, id, DeleteRelationsTool); self.state.modify_graph(|master| { let to_rem: HashSet<_> = req.relations.into_iter().collect(); master.relations.retain(|r| !to_rem.contains(r)); @@ -508,7 +508,7 @@ impl MemoryHandler { Ok("Relations deleted".to_string()) } "read_graph" => { - let req = parse_tool!(args.clone(), id, ReadGraphTool); + let req = parse_tool!(args, id, ReadGraphTool); let data = self.state.read_graph(|full| { if let Some(ns) = req.namespace { let mut filtered = KnowledgeGraph::default(); @@ -530,7 +530,7 @@ impl MemoryHandler { Ok(data) } "search_nodes" => { - let req = parse_tool!(args.clone(), id, SearchNodesTool); + let req = parse_tool!(args, id, SearchNodesTool); let matches = if let Ok(idx) = self.state.search_index.read() { idx.search(&req.query, req.namespace.as_deref()) .unwrap_or_default() @@ -552,7 +552,7 @@ impl MemoryHandler { Ok(data.to_string()) } "open_nodes" => { - let req = parse_tool!(args.clone(), id, OpenNodesTool); + let req = parse_tool!(args, id, OpenNodesTool); let targets: HashSet<_> = req.names.into_iter().collect(); let mut result = KnowledgeGraph::default(); let mut connected = HashSet::new(); @@ -576,7 +576,7 @@ impl MemoryHandler { Ok(data.to_string()) } "log_code_change" => { - let req = parse_tool!(args.clone(), id, LogCodeChangeTool); + let req = parse_tool!(args, id, LogCodeChangeTool); self.state.ledger.modify(|ledger| { ledger.push(CodeChange { timestamp: SystemTime::now() @@ -597,7 +597,7 @@ impl MemoryHandler { Ok(data.to_string()) } "visualize_graph" => { - let req = parse_tool!(args.clone(), id, VisualizeGraphTool); + let req = parse_tool!(args, id, VisualizeGraphTool); let query = req.query.unwrap_or_default().to_lowercase(); let mut included = HashSet::new(); let mut to_draw = Vec::new(); @@ -674,7 +674,7 @@ impl MemoryHandler { Ok(output.to_string()) } "add_sticky_note" => { - let req = parse_tool!(args.clone(), id, AddStickyNoteTool); + let req = parse_tool!(args, id, AddStickyNoteTool); self.state.sticky.modify(|notes| { notes.push(StickyNote { timestamp: SystemTime::now() @@ -692,7 +692,7 @@ impl MemoryHandler { Ok(data.to_string()) } "delete_sticky_note" => { - let req = parse_tool!(args.clone(), id, DeleteStickyNoteTool); + let req = parse_tool!(args, id, DeleteStickyNoteTool); let mut success = false; self.state.sticky.modify(|notes| { if req.index > 0 && req.index <= notes.len() { @@ -713,7 +713,7 @@ impl MemoryHandler { Ok("All sticky notes cleared.".to_string()) } "condense_entity" => { - let req = parse_tool!(args.clone(), id, CondenseEntityTool); + let req = parse_tool!(args, id, CondenseEntityTool); self.state.modify_graph(|master| { if let Some(e) = master.entities.get_mut(&req.entity_name) { e.observations = req.summarized_observations; @@ -722,7 +722,7 @@ impl MemoryHandler { Ok("Entity condensed".to_string()) } "add_task" => { - let req = parse_tool!(args.clone(), id, AddTaskTool); + let req = parse_tool!(args, id, AddTaskTool); let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() @@ -753,7 +753,7 @@ impl MemoryHandler { Ok(format!("Task added with ID: {}", task_id).to_string()) } "delete_task" => { - let req = parse_tool!(args.clone(), id, DeleteTaskTool); + let req = parse_tool!(args, id, DeleteTaskTool); let mut deleted_count = 0; self.state.tasks.modify(|tasks| { let initial_len = tasks.len(); @@ -788,7 +788,7 @@ impl MemoryHandler { } } "update_task_status" => { - let req = parse_tool!(args.clone(), id, UpdateTaskStatusTool); + let req = parse_tool!(args, id, UpdateTaskStatusTool); let mut found = false; let mut blocked = false; let mut blocker_details = String::new(); @@ -906,7 +906,7 @@ impl MemoryHandler { } } "list_active_tasks" => { - let req = parse_tool!(args.clone(), id, ListActiveTasksTool); + let req = parse_tool!(args, id, ListActiveTasksTool); let mut tasks = self.state.tasks.read(); tasks.retain(|t| t.status != "done"); if let Some(branch) = req.git_branch { @@ -919,7 +919,7 @@ impl MemoryHandler { Ok(data.to_string()) } "set_acceptance_criteria" => { - let req = parse_tool!(args.clone(), id, SetAcceptanceCriteriaTool); + let req = parse_tool!(args, id, SetAcceptanceCriteriaTool); let mut success = false; self.state.tasks.modify(|tasks| { if let Some(task) = @@ -951,7 +951,7 @@ impl MemoryHandler { } } "verify_acceptance_criteria" => { - let req = parse_tool!(args.clone(), id, VerifyAcceptanceCriteriaTool); + let req = parse_tool!(args, id, VerifyAcceptanceCriteriaTool); let mut success = false; let mut already_met = false; self.state.tasks.modify(|tasks| { @@ -989,7 +989,7 @@ impl MemoryHandler { } } "store_snippet" => { - let req = parse_tool!(args.clone(), id, StoreSnippetTool); + let req = parse_tool!(args, id, StoreSnippetTool); let snippet = Snippet { name: req.name.clone(), language: req.language, @@ -1014,7 +1014,7 @@ impl MemoryHandler { Ok(format!("Snippet '{}' stored.", req.name).to_string()) } "search_snippets" => { - let req = parse_tool!(args.clone(), id, SearchSnippetsTool); + let req = parse_tool!(args, id, SearchSnippetsTool); let query = req.query.to_lowercase(); let snippets = self.state.snippets.read(); let mut results = Vec::new(); @@ -1030,7 +1030,7 @@ impl MemoryHandler { Ok(data.to_string()) } "delete_snippet" => { - let req = parse_tool!(args.clone(), id, DeleteSnippetTool); + let req = parse_tool!(args, id, DeleteSnippetTool); let mut deleted = false; self.state.snippets.modify(|snippets| { let orig = snippets.len(); @@ -1044,7 +1044,7 @@ impl MemoryHandler { } } "log_decision" => { - let req = parse_tool!(args.clone(), id, LogDecisionTool); + let req = parse_tool!(args, id, LogDecisionTool); let mut adr_id = String::new(); let mut new_adr = None; @@ -1073,7 +1073,7 @@ impl MemoryHandler { Ok(format!("Decision logged as {}", adr_id).to_string()) } "query_decisions" => { - let req = parse_tool!(args.clone(), id, QueryDecisionsTool); + let req = parse_tool!(args, id, QueryDecisionsTool); let mut adrs = self.state.adrs.read(); if let Some(q) = req.query { let q = q.to_lowercase(); @@ -1087,7 +1087,7 @@ impl MemoryHandler { Ok(data.to_string()) } "merge_entities" => { - let req = parse_tool!(args.clone(), id, MergeEntitiesTool); + let req = parse_tool!(args, id, MergeEntitiesTool); self.state.modify_graph(|master| { if let Some(src) = master.entities.remove(&req.source_entity) { if let Some(tgt) = master.entities.get_mut(&req.target_entity) { @@ -1128,7 +1128,7 @@ impl MemoryHandler { Ok(data.to_string()) } "learn_preference" => { - let req = parse_tool!(args.clone(), id, LearnPreferenceTool); + let req = parse_tool!(args, id, LearnPreferenceTool); self.state.prefs.modify(|prefs| { prefs.insert( req.key.clone(), @@ -1150,7 +1150,7 @@ impl MemoryHandler { Ok(data.to_string()) } "log_error_fix" => { - let req = parse_tool!(args.clone(), id, LogErrorFixTool); + let req = parse_tool!(args, id, LogErrorFixTool); self.state.error_fixes.modify(|fixes| { fixes.push(crate::models::ErrorFix { signature: req.signature, @@ -1166,7 +1166,7 @@ impl MemoryHandler { Ok("Error fix logged".to_string()) } "search_error_fixes" => { - let req = parse_tool!(args.clone(), id, SearchErrorFixesTool); + let req = parse_tool!(args, id, SearchErrorFixesTool); let q = req.query.to_lowercase(); let mut fixes = self.state.error_fixes.read(); fixes.retain(|f| { @@ -1177,7 +1177,7 @@ impl MemoryHandler { Ok(data.to_string()) } "pin_file" => { - let req = parse_tool!(args.clone(), id, PinFileTool); + let req = parse_tool!(args, id, PinFileTool); self.state.pinned_files.modify(|pinned| { pinned.retain(|p| { !(p.namespace == req.namespace && p.file_path == req.file_path) @@ -1195,7 +1195,7 @@ impl MemoryHandler { Ok("File pinned".to_string()) } "unpin_file" => { - let req = parse_tool!(args.clone(), id, UnpinFileTool); + let req = parse_tool!(args, id, UnpinFileTool); self.state.pinned_files.modify(|pinned| { pinned.retain(|p| { !(p.namespace == req.namespace && p.file_path == req.file_path) @@ -1204,7 +1204,7 @@ impl MemoryHandler { Ok("File unpinned".to_string()) } "list_pinned_files" => { - let req = parse_tool!(args.clone(), id, ListPinnedFilesTool); + let req = parse_tool!(args, id, ListPinnedFilesTool); let mut pinned = self.state.pinned_files.read(); if let Some(ns) = req.namespace { pinned.retain(|p| p.namespace == ns); @@ -1219,7 +1219,7 @@ impl MemoryHandler { Ok(data.to_string()) } "add_session_summary" => { - let req = parse_tool!(args.clone(), id, AddSessionSummaryTool); + let req = parse_tool!(args, id, AddSessionSummaryTool); self.state.session_summaries.modify(|summaries| { summaries.push(crate::models::SessionSummary { summary: req.summary, @@ -1233,7 +1233,7 @@ impl MemoryHandler { Ok("Session summary added".to_string()) } "get_project_timeline" => { - let req = parse_tool!(args.clone(), id, GetProjectTimelineTool); + let req = parse_tool!(args, id, GetProjectTimelineTool); let mut summaries = self.state.session_summaries.read(); if let Some(ns) = req.namespace { summaries.retain(|s| s.namespace == ns); @@ -1243,7 +1243,7 @@ impl MemoryHandler { Ok(data.to_string()) } "leave_handoff_memo" => { - let req = parse_tool!(args.clone(), id, LeaveHandoffMemoTool); + let req = parse_tool!(args, id, LeaveHandoffMemoTool); self.state.handoff_memos.modify(|memos| { memos.push(crate::models::HandoffMemo { id: uuid::Uuid::new_v4().to_string(), @@ -1259,7 +1259,7 @@ impl MemoryHandler { Ok("Handoff memo left".to_string()) } "read_handoff_memos" => { - let req = parse_tool!(args.clone(), id, ReadHandoffMemosTool); + let req = parse_tool!(args, id, ReadHandoffMemosTool); let mut memos = self.state.handoff_memos.read(); if let Some(ns) = req.namespace { memos.retain(|m| m.namespace == ns); @@ -1268,7 +1268,7 @@ impl MemoryHandler { Ok(data.to_string()) } "clear_handoff_memos" => { - let req = parse_tool!(args.clone(), id, ClearHandoffMemosTool); + let req = parse_tool!(args, id, ClearHandoffMemosTool); let ids: HashSet<_> = req.ids.into_iter().collect(); self.state .handoff_memos @@ -1276,7 +1276,7 @@ impl MemoryHandler { Ok("Handoff memos cleared".to_string()) } "update_env_fingerprint" => { - let req = parse_tool!(args.clone(), id, UpdateEnvFingerprintTool); + let req = parse_tool!(args, id, UpdateEnvFingerprintTool); self.state.env_fingerprints.modify(|fps| { fps.insert( req.namespace.clone(), @@ -1296,7 +1296,7 @@ impl MemoryHandler { Ok("Env fingerprint updated".to_string()) } "read_env_fingerprint" => { - let req = parse_tool!(args.clone(), id, ReadEnvFingerprintTool); + let req = parse_tool!(args, id, ReadEnvFingerprintTool); let fps = self.state.env_fingerprints.read(); if let Some(fp) = fps.get(&req.namespace) { let data = serde_json::to_string(fp).unwrap_or_default(); @@ -1306,7 +1306,7 @@ impl MemoryHandler { } } "log_env_requirement" => { - let req = parse_tool!(args.clone(), id, LogEnvRequirementTool); + let req = parse_tool!(args, id, LogEnvRequirementTool); self.state.env_requirements.modify(|reqs| { reqs.retain(|r| !(r.namespace == req.namespace && r.key == req.key)); reqs.push(crate::models::EnvRequirement { @@ -1319,7 +1319,7 @@ impl MemoryHandler { Ok("Env requirement logged".to_string()) } "add_milestone" => { - let req = parse_tool!(args.clone(), id, AddMilestoneTool); + let req = parse_tool!(args, id, AddMilestoneTool); self.state.milestones.modify(|ms| { ms.push(crate::models::Milestone { id: uuid::Uuid::new_v4().to_string(), @@ -1332,7 +1332,7 @@ impl MemoryHandler { Ok("Milestone added".to_string()) } "update_milestone" => { - let req = parse_tool!(args.clone(), id, UpdateMilestoneTool); + let req = parse_tool!(args, id, UpdateMilestoneTool); let mut found = false; self.state.milestones.modify(|ms| { for m in ms.iter_mut() { @@ -1350,7 +1350,7 @@ impl MemoryHandler { } } "list_milestones" => { - let req = parse_tool!(args.clone(), id, ListMilestonesTool); + let req = parse_tool!(args, id, ListMilestonesTool); let mut ms = self.state.milestones.read(); if let Some(ns) = req.namespace { ms.retain(|m| m.namespace == ns); @@ -1359,7 +1359,7 @@ impl MemoryHandler { Ok(data.to_string()) } "generate_standup_report" => { - let req = parse_tool!(args.clone(), id, GenerateStandupReportTool); + let req = parse_tool!(args, id, GenerateStandupReportTool); let cutoff = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() @@ -1390,7 +1390,7 @@ impl MemoryHandler { Ok(report.to_string()) } "register_environment" => { - let req = parse_tool!(args.clone(), id, RegisterEnvironmentTool); + let req = parse_tool!(args, id, RegisterEnvironmentTool); self.state.environments.modify(|envs| { envs.retain(|e| !(e.namespace == req.namespace && e.name == req.name)); envs.push(crate::models::EnvironmentDetail { @@ -1408,14 +1408,14 @@ impl MemoryHandler { Ok("Environment registered".to_string()) } "get_environment_details" => { - let req = parse_tool!(args.clone(), id, GetEnvironmentDetailsTool); + let req = parse_tool!(args, id, GetEnvironmentDetailsTool); let mut envs = self.state.environments.read(); envs.retain(|e| e.namespace == req.namespace); let data = serde_json::to_string(&envs).unwrap_or_default(); Ok(data.to_string()) } "add_pr_checklist_item" => { - let req = parse_tool!(args.clone(), id, AddPrChecklistItemTool); + let req = parse_tool!(args, id, AddPrChecklistItemTool); self.state.pr_checklists.modify(|items| { items.push(crate::models::PrChecklistItem { namespace: req.namespace, @@ -1426,21 +1426,21 @@ impl MemoryHandler { Ok("PR checklist item added".to_string()) } "get_pr_checklist" => { - let req = parse_tool!(args.clone(), id, GetPrChecklistTool); + let req = parse_tool!(args, id, GetPrChecklistTool); let mut items = self.state.pr_checklists.read(); items.retain(|i| i.namespace == req.namespace); let data = serde_json::to_string(&items).unwrap_or_default(); Ok(data.to_string()) } "clear_pr_checklist" => { - let req = parse_tool!(args.clone(), id, ClearPrChecklistTool); + let req = parse_tool!(args, id, ClearPrChecklistTool); self.state .pr_checklists .modify(|items| items.retain(|i| i.namespace != req.namespace)); Ok("PR checklist cleared".to_string()) } "log_tech_debt" => { - let req = parse_tool!(args.clone(), id, LogTechDebtTool); + let req = parse_tool!(args, id, LogTechDebtTool); self.state.tech_debts.modify(|debts| { debts.push(crate::models::TechDebt { id: uuid::Uuid::new_v4().to_string(), @@ -1459,7 +1459,7 @@ impl MemoryHandler { Ok("Tech debt logged".to_string()) } "resolve_tech_debt" => { - let req = parse_tool!(args.clone(), id, ResolveTechDebtTool); + let req = parse_tool!(args, id, ResolveTechDebtTool); let mut found = false; self.state.tech_debts.modify(|debts| { for d in debts.iter_mut() { @@ -1477,7 +1477,7 @@ impl MemoryHandler { } } "list_tech_debt" => { - let req = parse_tool!(args.clone(), id, ListTechDebtTool); + let req = parse_tool!(args, id, ListTechDebtTool); let mut debts = self.state.tech_debts.read(); debts.retain(|d| { d.namespace == req.namespace && (req.include_resolved || !d.is_resolved) @@ -1486,7 +1486,7 @@ impl MemoryHandler { Ok(data.to_string()) } "save_context_workspace" => { - let req = parse_tool!(args.clone(), id, SaveContextWorkspaceTool); + let req = parse_tool!(args, id, SaveContextWorkspaceTool); self.state.context_workspaces.modify(|ws| { ws.retain(|w| !(w.namespace == req.namespace && w.name == req.name)); ws.push(crate::models::ContextWorkspace { @@ -1503,21 +1503,21 @@ impl MemoryHandler { Ok("Context workspace saved".to_string()) } "load_context_workspace" => { - let req = parse_tool!(args.clone(), id, LoadContextWorkspaceTool); + let req = parse_tool!(args, id, LoadContextWorkspaceTool); let mut ws = self.state.context_workspaces.read(); ws.retain(|w| w.namespace == req.namespace && w.name == req.name); let data = serde_json::to_string(&ws.first()).unwrap_or_default(); Ok(data.to_string()) } "list_context_workspaces" => { - let req = parse_tool!(args.clone(), id, ListContextWorkspacesTool); + let req = parse_tool!(args, id, ListContextWorkspacesTool); let mut ws = self.state.context_workspaces.read(); ws.retain(|w| w.namespace == req.namespace); let data = serde_json::to_string(&ws).unwrap_or_default(); Ok(data.to_string()) } "omni_search" => { - let req = parse_tool!(args.clone(), id, OmniSearchTool); + let req = parse_tool!(args, id, OmniSearchTool); let matches = if let Ok(idx) = self.state.search_index.read() { idx.search(&req.query, req.namespace.as_deref()) .unwrap_or_default() @@ -1605,7 +1605,7 @@ impl MemoryHandler { Ok(report.to_string()) } "get_project_health" => { - let req = parse_tool!(args.clone(), id, GetProjectHealthTool); + let req = parse_tool!(args, id, GetProjectHealthTool); let active_tasks = self .state .tasks