Skip to main content

systemprompt_agent/services/mcp/
tool_result_handler.rs

1use anyhow::{Result, anyhow};
2use std::fmt;
3use systemprompt_identifiers::{ContextId, TaskId};
4use systemprompt_models::ai::tools::CallToolResult;
5use systemprompt_traits::validation::Validate;
6
7use super::artifact_transformer::McpToA2aTransformer;
8
9#[derive(Debug)]
10pub struct ProcessToolResultParams<'a> {
11    pub tool_name: &'a str,
12    pub tool_result: &'a CallToolResult,
13    pub output_schema: Option<&'a serde_json::Value>,
14    pub tool_arguments: Option<&'a serde_json::Value>,
15    pub task_id: &'a TaskId,
16    pub context_id: &'a ContextId,
17    pub context: &'a systemprompt_models::RequestContext,
18}
19
20#[derive(Clone, Copy)]
21pub struct ToolResultHandler;
22
23impl fmt::Debug for ToolResultHandler {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        f.debug_struct("ToolResultHandler").finish_non_exhaustive()
26    }
27}
28
29impl Default for ToolResultHandler {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34
35impl ToolResultHandler {
36    pub const fn new() -> Self {
37        Self
38    }
39
40    pub fn process_tool_result(
41        params: &ProcessToolResultParams<'_>,
42    ) -> Result<crate::models::a2a::Artifact> {
43        let ProcessToolResultParams {
44            tool_name,
45            tool_result,
46            output_schema,
47            tool_arguments,
48            task_id,
49            context_id,
50            context,
51        } = params;
52        if !context.is_authenticated() || context.is_system() {
53            return Err(anyhow!(
54                "Invalid user - unauthenticated and system users cannot create artifacts"
55            ));
56        }
57
58        tracing::info!(
59            tool_name = %tool_name,
60            task_id = %task_id,
61            user_id = %context.user_id(),
62            context_id = %context_id,
63            "Transforming tool result to artifact"
64        );
65
66        let artifact =
67            McpToA2aTransformer::transform(&super::artifact_transformer::TransformParams {
68                tool_name,
69                tool_result,
70                output_schema: *output_schema,
71                context_id: context_id.as_str(),
72                task_id: task_id.as_str(),
73                tool_arguments: *tool_arguments,
74            })
75            .map_err(|e| anyhow::anyhow!("Artifact transform failed: {}", e))?;
76
77        artifact
78            .metadata
79            .validate()
80            .map_err(|e| anyhow::anyhow!("Artifact metadata validation failed: {}", e))?;
81
82        tracing::info!(
83            artifact_id = %artifact.id,
84            tool_name = %tool_name,
85            user_id = %context.user_id(),
86            task_id = %task_id,
87            fingerprint = ?artifact.metadata.fingerprint,
88            "Transformed tool result to artifact"
89        );
90
91        Ok(artifact)
92    }
93}