Compare commits

...
2 Commits
+70 -74
View File
@@ -23,6 +23,18 @@ macro_rules! parse_tool {
}; };
} }
macro_rules! handle_list_with_namespace {
($self:expr, $store:ident, $tool_type:ty, $args:expr, $id:expr) => {{
let req = parse_tool!($args, $id, $tool_type);
let mut items = $self.state.$store.read();
if let Some(ns) = req.namespace {
items.retain(|i| i.namespace == ns);
}
let data = serde_json::to_string(&items).unwrap_or_default();
Ok(data.to_string())
}};
}
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
@@ -370,7 +382,7 @@ impl MemoryHandler {
let result: Result<String, String> = match name { let result: Result<String, String> = match name {
"query_graph_path" => { "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| { self.state.read_graph(|graph| {
let max_depth = req.max_depth.unwrap_or(5); let max_depth = req.max_depth.unwrap_or(5);
let mut queue = std::collections::VecDeque::new(); let mut queue = std::collections::VecDeque::new();
@@ -439,7 +451,7 @@ impl MemoryHandler {
}) })
} }
"create_entities" => { "create_entities" => {
let req = parse_tool!(args.clone(), id, CreateEntitiesTool); let req = parse_tool!(args, id, CreateEntitiesTool);
self.state.modify_graph(|g| { self.state.modify_graph(|g| {
for entity in req.entities { for entity in req.entities {
if !entity.name.is_empty() { if !entity.name.is_empty() {
@@ -453,7 +465,7 @@ impl MemoryHandler {
Ok("Entities created".to_string()) Ok("Entities created".to_string())
} }
"create_relations" => { "create_relations" => {
let req = parse_tool!(args.clone(), id, CreateRelationsTool); let req = parse_tool!(args, id, CreateRelationsTool);
self.state.modify_graph(|g| { self.state.modify_graph(|g| {
for relation in req.relations { for relation in req.relations {
if !relation.from.is_empty() && !relation.to.is_empty() { if !relation.from.is_empty() && !relation.to.is_empty() {
@@ -464,7 +476,7 @@ impl MemoryHandler {
Ok("Relations created".to_string()) Ok("Relations created".to_string())
} }
"add_observations" => { "add_observations" => {
let req = parse_tool!(args.clone(), id, AddObservationsTool); let req = parse_tool!(args, id, AddObservationsTool);
self.state.modify_graph(|g| { self.state.modify_graph(|g| {
for o in req.observations { for o in req.observations {
if let Some(e) = g.entities.get_mut(&o.entity_name) { if let Some(e) = g.entities.get_mut(&o.entity_name) {
@@ -475,7 +487,7 @@ impl MemoryHandler {
Ok("Observations added".to_string()) Ok("Observations added".to_string())
} }
"delete_entities" => { "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(); let to_delete: HashSet<_> = req.entity_names.into_iter().collect();
self.state.modify_graph(|master| { self.state.modify_graph(|master| {
for name in &to_delete { for name in &to_delete {
@@ -488,7 +500,7 @@ impl MemoryHandler {
Ok("Entities deleted".to_string()) Ok("Entities deleted".to_string())
} }
"delete_observations" => { "delete_observations" => {
let req = parse_tool!(args.clone(), id, DeleteObservationsTool); let req = parse_tool!(args, id, DeleteObservationsTool);
self.state.modify_graph(|master| { self.state.modify_graph(|master| {
for d in req.deletions { for d in req.deletions {
if let Some(e) = master.entities.get_mut(&d.entity_name) { if let Some(e) = master.entities.get_mut(&d.entity_name) {
@@ -500,7 +512,7 @@ impl MemoryHandler {
Ok("Observations deleted".to_string()) Ok("Observations deleted".to_string())
} }
"delete_relations" => { "delete_relations" => {
let req = parse_tool!(args.clone(), id, DeleteRelationsTool); let req = parse_tool!(args, id, DeleteRelationsTool);
self.state.modify_graph(|master| { self.state.modify_graph(|master| {
let to_rem: HashSet<_> = req.relations.into_iter().collect(); let to_rem: HashSet<_> = req.relations.into_iter().collect();
master.relations.retain(|r| !to_rem.contains(r)); master.relations.retain(|r| !to_rem.contains(r));
@@ -508,7 +520,7 @@ impl MemoryHandler {
Ok("Relations deleted".to_string()) Ok("Relations deleted".to_string())
} }
"read_graph" => { "read_graph" => {
let req = parse_tool!(args.clone(), id, ReadGraphTool); let req = parse_tool!(args, id, ReadGraphTool);
let data = self.state.read_graph(|full| { let data = self.state.read_graph(|full| {
if let Some(ns) = req.namespace { if let Some(ns) = req.namespace {
let mut filtered = KnowledgeGraph::default(); let mut filtered = KnowledgeGraph::default();
@@ -530,7 +542,7 @@ impl MemoryHandler {
Ok(data) Ok(data)
} }
"search_nodes" => { "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() { let matches = if let Ok(idx) = self.state.search_index.read() {
idx.search(&req.query, req.namespace.as_deref()) idx.search(&req.query, req.namespace.as_deref())
.unwrap_or_default() .unwrap_or_default()
@@ -552,7 +564,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"open_nodes" => { "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 targets: HashSet<_> = req.names.into_iter().collect();
let mut result = KnowledgeGraph::default(); let mut result = KnowledgeGraph::default();
let mut connected = HashSet::new(); let mut connected = HashSet::new();
@@ -576,7 +588,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"log_code_change" => { "log_code_change" => {
let req = parse_tool!(args.clone(), id, LogCodeChangeTool); let req = parse_tool!(args, id, LogCodeChangeTool);
self.state.ledger.modify(|ledger| { self.state.ledger.modify(|ledger| {
ledger.push(CodeChange { ledger.push(CodeChange {
timestamp: SystemTime::now() timestamp: SystemTime::now()
@@ -597,7 +609,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"visualize_graph" => { "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 query = req.query.unwrap_or_default().to_lowercase();
let mut included = HashSet::new(); let mut included = HashSet::new();
let mut to_draw = Vec::new(); let mut to_draw = Vec::new();
@@ -674,7 +686,7 @@ impl MemoryHandler {
Ok(output.to_string()) Ok(output.to_string())
} }
"add_sticky_note" => { "add_sticky_note" => {
let req = parse_tool!(args.clone(), id, AddStickyNoteTool); let req = parse_tool!(args, id, AddStickyNoteTool);
self.state.sticky.modify(|notes| { self.state.sticky.modify(|notes| {
notes.push(StickyNote { notes.push(StickyNote {
timestamp: SystemTime::now() timestamp: SystemTime::now()
@@ -692,7 +704,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"delete_sticky_note" => { "delete_sticky_note" => {
let req = parse_tool!(args.clone(), id, DeleteStickyNoteTool); let req = parse_tool!(args, id, DeleteStickyNoteTool);
let mut success = false; let mut success = false;
self.state.sticky.modify(|notes| { self.state.sticky.modify(|notes| {
if req.index > 0 && req.index <= notes.len() { if req.index > 0 && req.index <= notes.len() {
@@ -713,7 +725,7 @@ impl MemoryHandler {
Ok("All sticky notes cleared.".to_string()) Ok("All sticky notes cleared.".to_string())
} }
"condense_entity" => { "condense_entity" => {
let req = parse_tool!(args.clone(), id, CondenseEntityTool); let req = parse_tool!(args, id, CondenseEntityTool);
self.state.modify_graph(|master| { self.state.modify_graph(|master| {
if let Some(e) = master.entities.get_mut(&req.entity_name) { if let Some(e) = master.entities.get_mut(&req.entity_name) {
e.observations = req.summarized_observations; e.observations = req.summarized_observations;
@@ -722,7 +734,7 @@ impl MemoryHandler {
Ok("Entity condensed".to_string()) Ok("Entity condensed".to_string())
} }
"add_task" => { "add_task" => {
let req = parse_tool!(args.clone(), id, AddTaskTool); let req = parse_tool!(args, id, AddTaskTool);
let now = SystemTime::now() let now = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap() .unwrap()
@@ -753,7 +765,7 @@ impl MemoryHandler {
Ok(format!("Task added with ID: {}", task_id).to_string()) Ok(format!("Task added with ID: {}", task_id).to_string())
} }
"delete_task" => { "delete_task" => {
let req = parse_tool!(args.clone(), id, DeleteTaskTool); let req = parse_tool!(args, id, DeleteTaskTool);
let mut deleted_count = 0; let mut deleted_count = 0;
self.state.tasks.modify(|tasks| { self.state.tasks.modify(|tasks| {
let initial_len = tasks.len(); let initial_len = tasks.len();
@@ -788,7 +800,7 @@ impl MemoryHandler {
} }
} }
"update_task_status" => { "update_task_status" => {
let req = parse_tool!(args.clone(), id, UpdateTaskStatusTool); let req = parse_tool!(args, id, UpdateTaskStatusTool);
let mut found = false; let mut found = false;
let mut blocked = false; let mut blocked = false;
let mut blocker_details = String::new(); let mut blocker_details = String::new();
@@ -906,7 +918,7 @@ impl MemoryHandler {
} }
} }
"list_active_tasks" => { "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(); let mut tasks = self.state.tasks.read();
tasks.retain(|t| t.status != "done"); tasks.retain(|t| t.status != "done");
if let Some(branch) = req.git_branch { if let Some(branch) = req.git_branch {
@@ -919,7 +931,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"set_acceptance_criteria" => { "set_acceptance_criteria" => {
let req = parse_tool!(args.clone(), id, SetAcceptanceCriteriaTool); let req = parse_tool!(args, id, SetAcceptanceCriteriaTool);
let mut success = false; let mut success = false;
self.state.tasks.modify(|tasks| { self.state.tasks.modify(|tasks| {
if let Some(task) = if let Some(task) =
@@ -951,7 +963,7 @@ impl MemoryHandler {
} }
} }
"verify_acceptance_criteria" => { "verify_acceptance_criteria" => {
let req = parse_tool!(args.clone(), id, VerifyAcceptanceCriteriaTool); let req = parse_tool!(args, id, VerifyAcceptanceCriteriaTool);
let mut success = false; let mut success = false;
let mut already_met = false; let mut already_met = false;
self.state.tasks.modify(|tasks| { self.state.tasks.modify(|tasks| {
@@ -989,7 +1001,7 @@ impl MemoryHandler {
} }
} }
"store_snippet" => { "store_snippet" => {
let req = parse_tool!(args.clone(), id, StoreSnippetTool); let req = parse_tool!(args, id, StoreSnippetTool);
let snippet = Snippet { let snippet = Snippet {
name: req.name.clone(), name: req.name.clone(),
language: req.language, language: req.language,
@@ -1014,7 +1026,7 @@ impl MemoryHandler {
Ok(format!("Snippet '{}' stored.", req.name).to_string()) Ok(format!("Snippet '{}' stored.", req.name).to_string())
} }
"search_snippets" => { "search_snippets" => {
let req = parse_tool!(args.clone(), id, SearchSnippetsTool); let req = parse_tool!(args, id, SearchSnippetsTool);
let query = req.query.to_lowercase(); let query = req.query.to_lowercase();
let snippets = self.state.snippets.read(); let snippets = self.state.snippets.read();
let mut results = Vec::new(); let mut results = Vec::new();
@@ -1030,7 +1042,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"delete_snippet" => { "delete_snippet" => {
let req = parse_tool!(args.clone(), id, DeleteSnippetTool); let req = parse_tool!(args, id, DeleteSnippetTool);
let mut deleted = false; let mut deleted = false;
self.state.snippets.modify(|snippets| { self.state.snippets.modify(|snippets| {
let orig = snippets.len(); let orig = snippets.len();
@@ -1044,7 +1056,7 @@ impl MemoryHandler {
} }
} }
"log_decision" => { "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 adr_id = String::new();
let mut new_adr = None; let mut new_adr = None;
@@ -1073,7 +1085,7 @@ impl MemoryHandler {
Ok(format!("Decision logged as {}", adr_id).to_string()) Ok(format!("Decision logged as {}", adr_id).to_string())
} }
"query_decisions" => { "query_decisions" => {
let req = parse_tool!(args.clone(), id, QueryDecisionsTool); let req = parse_tool!(args, id, QueryDecisionsTool);
let mut adrs = self.state.adrs.read(); let mut adrs = self.state.adrs.read();
if let Some(q) = req.query { if let Some(q) = req.query {
let q = q.to_lowercase(); let q = q.to_lowercase();
@@ -1087,7 +1099,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"merge_entities" => { "merge_entities" => {
let req = parse_tool!(args.clone(), id, MergeEntitiesTool); let req = parse_tool!(args, id, MergeEntitiesTool);
self.state.modify_graph(|master| { self.state.modify_graph(|master| {
if let Some(src) = master.entities.remove(&req.source_entity) { if let Some(src) = master.entities.remove(&req.source_entity) {
if let Some(tgt) = master.entities.get_mut(&req.target_entity) { if let Some(tgt) = master.entities.get_mut(&req.target_entity) {
@@ -1128,7 +1140,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"learn_preference" => { "learn_preference" => {
let req = parse_tool!(args.clone(), id, LearnPreferenceTool); let req = parse_tool!(args, id, LearnPreferenceTool);
self.state.prefs.modify(|prefs| { self.state.prefs.modify(|prefs| {
prefs.insert( prefs.insert(
req.key.clone(), req.key.clone(),
@@ -1150,7 +1162,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"log_error_fix" => { "log_error_fix" => {
let req = parse_tool!(args.clone(), id, LogErrorFixTool); let req = parse_tool!(args, id, LogErrorFixTool);
self.state.error_fixes.modify(|fixes| { self.state.error_fixes.modify(|fixes| {
fixes.push(crate::models::ErrorFix { fixes.push(crate::models::ErrorFix {
signature: req.signature, signature: req.signature,
@@ -1166,7 +1178,7 @@ impl MemoryHandler {
Ok("Error fix logged".to_string()) Ok("Error fix logged".to_string())
} }
"search_error_fixes" => { "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 q = req.query.to_lowercase();
let mut fixes = self.state.error_fixes.read(); let mut fixes = self.state.error_fixes.read();
fixes.retain(|f| { fixes.retain(|f| {
@@ -1177,7 +1189,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"pin_file" => { "pin_file" => {
let req = parse_tool!(args.clone(), id, PinFileTool); let req = parse_tool!(args, id, PinFileTool);
self.state.pinned_files.modify(|pinned| { self.state.pinned_files.modify(|pinned| {
pinned.retain(|p| { pinned.retain(|p| {
!(p.namespace == req.namespace && p.file_path == req.file_path) !(p.namespace == req.namespace && p.file_path == req.file_path)
@@ -1195,7 +1207,7 @@ impl MemoryHandler {
Ok("File pinned".to_string()) Ok("File pinned".to_string())
} }
"unpin_file" => { "unpin_file" => {
let req = parse_tool!(args.clone(), id, UnpinFileTool); let req = parse_tool!(args, id, UnpinFileTool);
self.state.pinned_files.modify(|pinned| { self.state.pinned_files.modify(|pinned| {
pinned.retain(|p| { pinned.retain(|p| {
!(p.namespace == req.namespace && p.file_path == req.file_path) !(p.namespace == req.namespace && p.file_path == req.file_path)
@@ -1204,7 +1216,7 @@ impl MemoryHandler {
Ok("File unpinned".to_string()) Ok("File unpinned".to_string())
} }
"list_pinned_files" => { "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(); let mut pinned = self.state.pinned_files.read();
if let Some(ns) = req.namespace { if let Some(ns) = req.namespace {
pinned.retain(|p| p.namespace == ns); pinned.retain(|p| p.namespace == ns);
@@ -1219,7 +1231,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"add_session_summary" => { "add_session_summary" => {
let req = parse_tool!(args.clone(), id, AddSessionSummaryTool); let req = parse_tool!(args, id, AddSessionSummaryTool);
self.state.session_summaries.modify(|summaries| { self.state.session_summaries.modify(|summaries| {
summaries.push(crate::models::SessionSummary { summaries.push(crate::models::SessionSummary {
summary: req.summary, summary: req.summary,
@@ -1233,7 +1245,7 @@ impl MemoryHandler {
Ok("Session summary added".to_string()) Ok("Session summary added".to_string())
} }
"get_project_timeline" => { "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(); let mut summaries = self.state.session_summaries.read();
if let Some(ns) = req.namespace { if let Some(ns) = req.namespace {
summaries.retain(|s| s.namespace == ns); summaries.retain(|s| s.namespace == ns);
@@ -1243,7 +1255,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"leave_handoff_memo" => { "leave_handoff_memo" => {
let req = parse_tool!(args.clone(), id, LeaveHandoffMemoTool); let req = parse_tool!(args, id, LeaveHandoffMemoTool);
self.state.handoff_memos.modify(|memos| { self.state.handoff_memos.modify(|memos| {
memos.push(crate::models::HandoffMemo { memos.push(crate::models::HandoffMemo {
id: uuid::Uuid::new_v4().to_string(), id: uuid::Uuid::new_v4().to_string(),
@@ -1258,17 +1270,9 @@ impl MemoryHandler {
}); });
Ok("Handoff memo left".to_string()) Ok("Handoff memo left".to_string())
} }
"read_handoff_memos" => { "read_handoff_memos" => handle_list_with_namespace!(self, handoff_memos, ReadHandoffMemosTool, args, id),
let req = parse_tool!(args.clone(), id, ReadHandoffMemosTool);
let mut memos = self.state.handoff_memos.read();
if let Some(ns) = req.namespace {
memos.retain(|m| m.namespace == ns);
}
let data = serde_json::to_string(&memos).unwrap_or_default();
Ok(data.to_string())
}
"clear_handoff_memos" => { "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(); let ids: HashSet<_> = req.ids.into_iter().collect();
self.state self.state
.handoff_memos .handoff_memos
@@ -1276,7 +1280,7 @@ impl MemoryHandler {
Ok("Handoff memos cleared".to_string()) Ok("Handoff memos cleared".to_string())
} }
"update_env_fingerprint" => { "update_env_fingerprint" => {
let req = parse_tool!(args.clone(), id, UpdateEnvFingerprintTool); let req = parse_tool!(args, id, UpdateEnvFingerprintTool);
self.state.env_fingerprints.modify(|fps| { self.state.env_fingerprints.modify(|fps| {
fps.insert( fps.insert(
req.namespace.clone(), req.namespace.clone(),
@@ -1296,7 +1300,7 @@ impl MemoryHandler {
Ok("Env fingerprint updated".to_string()) Ok("Env fingerprint updated".to_string())
} }
"read_env_fingerprint" => { "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(); let fps = self.state.env_fingerprints.read();
if let Some(fp) = fps.get(&req.namespace) { if let Some(fp) = fps.get(&req.namespace) {
let data = serde_json::to_string(fp).unwrap_or_default(); let data = serde_json::to_string(fp).unwrap_or_default();
@@ -1306,7 +1310,7 @@ impl MemoryHandler {
} }
} }
"log_env_requirement" => { "log_env_requirement" => {
let req = parse_tool!(args.clone(), id, LogEnvRequirementTool); let req = parse_tool!(args, id, LogEnvRequirementTool);
self.state.env_requirements.modify(|reqs| { self.state.env_requirements.modify(|reqs| {
reqs.retain(|r| !(r.namespace == req.namespace && r.key == req.key)); reqs.retain(|r| !(r.namespace == req.namespace && r.key == req.key));
reqs.push(crate::models::EnvRequirement { reqs.push(crate::models::EnvRequirement {
@@ -1319,7 +1323,7 @@ impl MemoryHandler {
Ok("Env requirement logged".to_string()) Ok("Env requirement logged".to_string())
} }
"add_milestone" => { "add_milestone" => {
let req = parse_tool!(args.clone(), id, AddMilestoneTool); let req = parse_tool!(args, id, AddMilestoneTool);
self.state.milestones.modify(|ms| { self.state.milestones.modify(|ms| {
ms.push(crate::models::Milestone { ms.push(crate::models::Milestone {
id: uuid::Uuid::new_v4().to_string(), id: uuid::Uuid::new_v4().to_string(),
@@ -1332,7 +1336,7 @@ impl MemoryHandler {
Ok("Milestone added".to_string()) Ok("Milestone added".to_string())
} }
"update_milestone" => { "update_milestone" => {
let req = parse_tool!(args.clone(), id, UpdateMilestoneTool); let req = parse_tool!(args, id, UpdateMilestoneTool);
let mut found = false; let mut found = false;
self.state.milestones.modify(|ms| { self.state.milestones.modify(|ms| {
for m in ms.iter_mut() { for m in ms.iter_mut() {
@@ -1349,17 +1353,9 @@ impl MemoryHandler {
Ok("Milestone not found".to_string()) Ok("Milestone not found".to_string())
} }
} }
"list_milestones" => { "list_milestones" => handle_list_with_namespace!(self, milestones, ListMilestonesTool, args, id),
let req = parse_tool!(args.clone(), id, ListMilestonesTool);
let mut ms = self.state.milestones.read();
if let Some(ns) = req.namespace {
ms.retain(|m| m.namespace == ns);
}
let data = serde_json::to_string(&ms).unwrap_or_default();
Ok(data.to_string())
}
"generate_standup_report" => { "generate_standup_report" => {
let req = parse_tool!(args.clone(), id, GenerateStandupReportTool); let req = parse_tool!(args, id, GenerateStandupReportTool);
let cutoff = SystemTime::now() let cutoff = SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
.unwrap() .unwrap()
@@ -1390,7 +1386,7 @@ impl MemoryHandler {
Ok(report.to_string()) Ok(report.to_string())
} }
"register_environment" => { "register_environment" => {
let req = parse_tool!(args.clone(), id, RegisterEnvironmentTool); let req = parse_tool!(args, id, RegisterEnvironmentTool);
self.state.environments.modify(|envs| { self.state.environments.modify(|envs| {
envs.retain(|e| !(e.namespace == req.namespace && e.name == req.name)); envs.retain(|e| !(e.namespace == req.namespace && e.name == req.name));
envs.push(crate::models::EnvironmentDetail { envs.push(crate::models::EnvironmentDetail {
@@ -1408,14 +1404,14 @@ impl MemoryHandler {
Ok("Environment registered".to_string()) Ok("Environment registered".to_string())
} }
"get_environment_details" => { "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(); let mut envs = self.state.environments.read();
envs.retain(|e| e.namespace == req.namespace); envs.retain(|e| e.namespace == req.namespace);
let data = serde_json::to_string(&envs).unwrap_or_default(); let data = serde_json::to_string(&envs).unwrap_or_default();
Ok(data.to_string()) Ok(data.to_string())
} }
"add_pr_checklist_item" => { "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| { self.state.pr_checklists.modify(|items| {
items.push(crate::models::PrChecklistItem { items.push(crate::models::PrChecklistItem {
namespace: req.namespace, namespace: req.namespace,
@@ -1426,21 +1422,21 @@ impl MemoryHandler {
Ok("PR checklist item added".to_string()) Ok("PR checklist item added".to_string())
} }
"get_pr_checklist" => { "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(); let mut items = self.state.pr_checklists.read();
items.retain(|i| i.namespace == req.namespace); items.retain(|i| i.namespace == req.namespace);
let data = serde_json::to_string(&items).unwrap_or_default(); let data = serde_json::to_string(&items).unwrap_or_default();
Ok(data.to_string()) Ok(data.to_string())
} }
"clear_pr_checklist" => { "clear_pr_checklist" => {
let req = parse_tool!(args.clone(), id, ClearPrChecklistTool); let req = parse_tool!(args, id, ClearPrChecklistTool);
self.state self.state
.pr_checklists .pr_checklists
.modify(|items| items.retain(|i| i.namespace != req.namespace)); .modify(|items| items.retain(|i| i.namespace != req.namespace));
Ok("PR checklist cleared".to_string()) Ok("PR checklist cleared".to_string())
} }
"log_tech_debt" => { "log_tech_debt" => {
let req = parse_tool!(args.clone(), id, LogTechDebtTool); let req = parse_tool!(args, id, LogTechDebtTool);
self.state.tech_debts.modify(|debts| { self.state.tech_debts.modify(|debts| {
debts.push(crate::models::TechDebt { debts.push(crate::models::TechDebt {
id: uuid::Uuid::new_v4().to_string(), id: uuid::Uuid::new_v4().to_string(),
@@ -1459,7 +1455,7 @@ impl MemoryHandler {
Ok("Tech debt logged".to_string()) Ok("Tech debt logged".to_string())
} }
"resolve_tech_debt" => { "resolve_tech_debt" => {
let req = parse_tool!(args.clone(), id, ResolveTechDebtTool); let req = parse_tool!(args, id, ResolveTechDebtTool);
let mut found = false; let mut found = false;
self.state.tech_debts.modify(|debts| { self.state.tech_debts.modify(|debts| {
for d in debts.iter_mut() { for d in debts.iter_mut() {
@@ -1477,7 +1473,7 @@ impl MemoryHandler {
} }
} }
"list_tech_debt" => { "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(); let mut debts = self.state.tech_debts.read();
debts.retain(|d| { debts.retain(|d| {
d.namespace == req.namespace && (req.include_resolved || !d.is_resolved) d.namespace == req.namespace && (req.include_resolved || !d.is_resolved)
@@ -1486,7 +1482,7 @@ impl MemoryHandler {
Ok(data.to_string()) Ok(data.to_string())
} }
"save_context_workspace" => { "save_context_workspace" => {
let req = parse_tool!(args.clone(), id, SaveContextWorkspaceTool); let req = parse_tool!(args, id, SaveContextWorkspaceTool);
self.state.context_workspaces.modify(|ws| { self.state.context_workspaces.modify(|ws| {
ws.retain(|w| !(w.namespace == req.namespace && w.name == req.name)); ws.retain(|w| !(w.namespace == req.namespace && w.name == req.name));
ws.push(crate::models::ContextWorkspace { ws.push(crate::models::ContextWorkspace {
@@ -1503,21 +1499,21 @@ impl MemoryHandler {
Ok("Context workspace saved".to_string()) Ok("Context workspace saved".to_string())
} }
"load_context_workspace" => { "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(); let mut ws = self.state.context_workspaces.read();
ws.retain(|w| w.namespace == req.namespace && w.name == req.name); ws.retain(|w| w.namespace == req.namespace && w.name == req.name);
let data = serde_json::to_string(&ws.first()).unwrap_or_default(); let data = serde_json::to_string(&ws.first()).unwrap_or_default();
Ok(data.to_string()) Ok(data.to_string())
} }
"list_context_workspaces" => { "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(); let mut ws = self.state.context_workspaces.read();
ws.retain(|w| w.namespace == req.namespace); ws.retain(|w| w.namespace == req.namespace);
let data = serde_json::to_string(&ws).unwrap_or_default(); let data = serde_json::to_string(&ws).unwrap_or_default();
Ok(data.to_string()) Ok(data.to_string())
} }
"omni_search" => { "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() { let matches = if let Ok(idx) = self.state.search_index.read() {
idx.search(&req.query, req.namespace.as_deref()) idx.search(&req.query, req.namespace.as_deref())
.unwrap_or_default() .unwrap_or_default()
@@ -1605,7 +1601,7 @@ impl MemoryHandler {
Ok(report.to_string()) Ok(report.to_string())
} }
"get_project_health" => { "get_project_health" => {
let req = parse_tool!(args.clone(), id, GetProjectHealthTool); let req = parse_tool!(args, id, GetProjectHealthTool);
let active_tasks = self let active_tasks = self
.state .state
.tasks .tasks