refactor: apply zero-unwrap policy and optimize locks in store.rs and handlers
This commit is contained in:
1 parent
9f24e66d88
commit
8afbf97b11
33 files changed
+3127
-3207
No files matched your search
@@ -0,0 +1,273 @@
|
||||
use crate::models::*;
|
||||
use crate::router::McpTool;
|
||||
use crate::state::MemoryState;
|
||||
use crate::tools::*;
|
||||
use async_trait::async_trait;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub struct AddStickyNoteHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for AddStickyNoteHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"add_sticky_note"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<AddStickyNoteTool>("add_sticky_note", "Execute add_sticky_note")
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: AddStickyNoteTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
state.sticky.modify(|notes| {
|
||||
notes.push(StickyNote {
|
||||
timestamp: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs(),
|
||||
content: req.content,
|
||||
});
|
||||
});
|
||||
Ok("Sticky note added.".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadStickyNotesHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for ReadStickyNotesHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"read_sticky_notes"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<ReadStickyNotesTool>(
|
||||
"read_sticky_notes",
|
||||
"Execute read_sticky_notes",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let data = serde_json::to_string(&state.sticky.read()).unwrap_or_else(|_| "[]".to_string());
|
||||
Ok(data.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DeleteStickyNoteHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for DeleteStickyNoteHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"delete_sticky_note"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<DeleteStickyNoteTool>(
|
||||
"delete_sticky_note",
|
||||
"Execute delete_sticky_note",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: DeleteStickyNoteTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut success = false;
|
||||
state.sticky.modify(|notes| {
|
||||
if req.index > 0 && req.index <= notes.len() {
|
||||
notes.remove(req.index - 1);
|
||||
success = true;
|
||||
}
|
||||
});
|
||||
if success {
|
||||
Ok("Sticky note deleted.".to_string())
|
||||
} else {
|
||||
Err("Invalid sticky note index.".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClearStickyNotesHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for ClearStickyNotesHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"clear_sticky_notes"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<ClearStickyNotesTool>(
|
||||
"clear_sticky_notes",
|
||||
"Execute clear_sticky_notes",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, _args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
state.sticky.modify(|notes| {
|
||||
notes.clear();
|
||||
});
|
||||
Ok("All sticky notes cleared.".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LeaveHandoffMemoHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for LeaveHandoffMemoHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"leave_handoff_memo"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<LeaveHandoffMemoTool>(
|
||||
"leave_handoff_memo",
|
||||
"Execute leave_handoff_memo",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: LeaveHandoffMemoTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
state.handoff_memos.modify(|memos| {
|
||||
memos.push(crate::models::HandoffMemo {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
author: "agy".to_string(),
|
||||
content: req.content,
|
||||
namespace: req.namespace,
|
||||
timestamp: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs(),
|
||||
})
|
||||
});
|
||||
Ok("Handoff memo left".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadHandoffMemosHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for ReadHandoffMemosHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"read_handoff_memos"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<ReadHandoffMemosTool>(
|
||||
"read_handoff_memos",
|
||||
"Execute read_handoff_memos",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: ReadHandoffMemosTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let mut items = state.handoff_memos.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())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClearHandoffMemosHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for ClearHandoffMemosHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"clear_handoff_memos"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<ClearHandoffMemosTool>(
|
||||
"clear_handoff_memos",
|
||||
"Execute clear_handoff_memos",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: ClearHandoffMemosTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let ids: HashSet<_> = req.ids.into_iter().collect();
|
||||
state
|
||||
.handoff_memos
|
||||
.modify(|memos| memos.retain(|m| !ids.contains(&m.id)));
|
||||
Ok("Handoff memos cleared".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AddSessionSummaryHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for AddSessionSummaryHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"add_session_summary"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<AddSessionSummaryTool>(
|
||||
"add_session_summary",
|
||||
"Execute add_session_summary",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: AddSessionSummaryTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
state.session_summaries.modify(|summaries| {
|
||||
summaries.push(crate::models::SessionSummary {
|
||||
summary: req.summary,
|
||||
namespace: req.namespace,
|
||||
timestamp: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs(),
|
||||
})
|
||||
});
|
||||
Ok("Session summary added".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GenerateStandupReportHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl McpTool for GenerateStandupReportHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"generate_standup_report"
|
||||
}
|
||||
|
||||
fn schema(&self) -> Value {
|
||||
crate::mcp::tool_def::<GenerateStandupReportTool>(
|
||||
"generate_standup_report",
|
||||
"Execute generate_standup_report",
|
||||
)
|
||||
}
|
||||
|
||||
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> Result<String, String> {
|
||||
let req: GenerateStandupReportTool =
|
||||
serde_json::from_value(args).map_err(|e| e.to_string())?;
|
||||
let cutoff = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs()
|
||||
.saturating_sub(req.hours_lookback * 3600);
|
||||
let tasks = state
|
||||
.tasks
|
||||
.read()
|
||||
.into_iter()
|
||||
.filter(|t| t.updated_at >= cutoff)
|
||||
.collect::<Vec<_>>();
|
||||
let changes = state
|
||||
.ledger
|
||||
.read()
|
||||
.into_iter()
|
||||
.filter(|c| c.timestamp >= cutoff)
|
||||
.collect::<Vec<_>>();
|
||||
let summaries = state
|
||||
.session_summaries
|
||||
.read()
|
||||
.into_iter()
|
||||
.filter(|s| s.namespace == req.namespace && s.timestamp >= cutoff)
|
||||
.collect::<Vec<_>>();
|
||||
let report = serde_json::json!({ "tasks_updated": tasks, "code_changes": changes, "session_summaries": summaries });
|
||||
Ok(report.to_string())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user