agentic_memory_mcp/tools/
session_end.rs1use std::sync::Arc;
4use tokio::sync::Mutex;
5
6use serde::Deserialize;
7use serde_json::{json, Value};
8
9use crate::session::SessionManager;
10use crate::types::{McpError, McpResult, ToolCallResult, ToolDefinition};
11
12#[derive(Debug, Deserialize)]
13struct EndParams {
14 session_id: Option<u32>,
15 #[serde(default = "default_create_episode")]
16 create_episode: bool,
17 summary: Option<String>,
18}
19
20fn default_create_episode() -> bool {
21 true
22}
23
24pub fn definition() -> ToolDefinition {
26 ToolDefinition {
27 name: "session_end".to_string(),
28 description: Some(
29 "End a session and optionally create an episode summary node".to_string(),
30 ),
31 input_schema: json!({
32 "type": "object",
33 "properties": {
34 "session_id": { "type": "integer" },
35 "create_episode": { "type": "boolean", "default": true },
36 "summary": { "type": "string", "description": "Episode summary content" }
37 }
38 }),
39 }
40}
41
42pub async fn execute(
44 args: Value,
45 session: &Arc<Mutex<SessionManager>>,
46) -> McpResult<ToolCallResult> {
47 let params: EndParams =
48 serde_json::from_value(args).map_err(|e| McpError::InvalidParams(e.to_string()))?;
49
50 let mut session = session.lock().await;
51 let session_id = params
52 .session_id
53 .unwrap_or_else(|| session.current_session_id());
54
55 if params.create_episode {
56 let summary = params
57 .summary
58 .unwrap_or_else(|| format!("Session {session_id} completed"));
59
60 let episode_id = session.end_session_with_episode(session_id, &summary)?;
61
62 Ok(ToolCallResult::json(&json!({
63 "session_id": session_id,
64 "episode_node_id": episode_id,
65 "summary": summary,
66 })))
67 } else {
68 session.save()?;
69 Ok(ToolCallResult::json(&json!({
70 "session_id": session_id,
71 "episode_node_id": null,
72 "message": "Session ended without episode",
73 })))
74 }
75}