do_memory_mcp/server/tools/
episode_steps.rs1use crate::server::MemoryMCPServer;
7use anyhow::{Result, anyhow};
8use do_memory_core::ExecutionStep;
9use serde_json::{Value, json};
10use tracing::debug;
11use tracing::info;
12use uuid::Uuid;
13
14impl MemoryMCPServer {
15 pub async fn add_episode_step_tool(&self, args: Value) -> Result<Value> {
30 debug!("Adding episode step with args: {}", args);
31
32 let episode_id_str = args
34 .get("episode_id")
35 .and_then(|v| v.as_str())
36 .ok_or_else(|| anyhow!("Missing required field: episode_id"))?;
37
38 let episode_id = Uuid::parse_str(episode_id_str)
39 .map_err(|e| anyhow!("Invalid episode_id format: {}", e))?;
40
41 let step_number = args
42 .get("step_number")
43 .and_then(|v| v.as_u64())
44 .ok_or_else(|| anyhow!("Missing required field: step_number"))?
45 as usize;
46
47 let tool = args
48 .get("tool")
49 .and_then(|v| v.as_str())
50 .ok_or_else(|| anyhow!("Missing required field: tool"))?
51 .to_string();
52
53 let action = args
54 .get("action")
55 .and_then(|v| v.as_str())
56 .ok_or_else(|| anyhow!("Missing required field: action"))?
57 .to_string();
58
59 let mut step = ExecutionStep::new(step_number, tool.clone(), action.clone());
61
62 if let Some(params) = args.get("parameters") {
64 step.parameters = params.clone();
65 }
66
67 if let Some(result) = args.get("result") {
69 let result_type = result
70 .get("type")
71 .and_then(|v| v.as_str())
72 .unwrap_or("success");
73
74 step.result = Some(match result_type {
75 "success" => do_memory_core::ExecutionResult::Success {
76 output: result
77 .get("output")
78 .and_then(|v| v.as_str())
79 .unwrap_or("")
80 .to_string(),
81 },
82 "error" => do_memory_core::ExecutionResult::Error {
83 message: result
84 .get("message")
85 .and_then(|v| v.as_str())
86 .unwrap_or("Unknown error")
87 .to_string(),
88 },
89 "timeout" => do_memory_core::ExecutionResult::Timeout,
90 _ => {
91 return Err(anyhow!(
92 "Invalid result type: {}. Must be one of: success, error, timeout",
93 result_type
94 ));
95 }
96 });
97 }
98
99 if let Some(latency) = args.get("latency_ms").and_then(|v| v.as_u64()) {
101 step.latency_ms = latency;
102 }
103
104 self.memory.log_step(episode_id, step).await;
106
107 info!(
108 episode_id = %episode_id,
109 step_number = step_number,
110 tool = %tool,
111 "Added step to episode via MCP"
112 );
113
114 Ok(json!({
115 "success": true,
116 "episode_id": episode_id.to_string(),
117 "step_number": step_number,
118 "message": "Step added successfully"
119 }))
120 }
121}