Skip to main content

agentic_memory_mcp/tools/
session_end.rs

1//! Tool: session_end — End a session and optionally create an episode summary.
2
3use 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
24/// Return the tool definition for session_end.
25pub 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
42/// Execute the session_end tool.
43pub 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}