Skip to main content

agentic_evolve_mcp/tools/
evolve_coverage.rs

1//! Tool: evolve_coverage — Get pattern coverage for a set of signatures.
2
3use std::sync::Arc;
4use tokio::sync::Mutex;
5
6use serde::Deserialize;
7use serde_json::{json, Value};
8
9use agentic_evolve_core::types::pattern::{
10    FunctionSignature, Language, ParamSignature, Visibility,
11};
12
13use crate::session::SessionManager;
14use crate::types::{McpError, McpResult, ToolCallResult, ToolDefinition};
15
16#[derive(Debug, Deserialize)]
17struct CoverageParams {
18    signatures: Vec<SignatureInput>,
19    #[serde(default = "default_threshold")]
20    threshold: f64,
21}
22
23#[derive(Debug, Deserialize)]
24struct SignatureInput {
25    name: String,
26    language: String,
27    #[serde(default)]
28    params: Vec<ParamInput>,
29    #[serde(default)]
30    return_type: Option<String>,
31    #[serde(default)]
32    is_async: bool,
33}
34
35#[derive(Debug, Deserialize)]
36struct ParamInput {
37    name: String,
38    #[serde(rename = "type", default = "default_type")]
39    param_type: String,
40    #[serde(default)]
41    is_optional: bool,
42}
43
44fn default_threshold() -> f64 {
45    0.5
46}
47
48fn default_type() -> String {
49    "Any".to_string()
50}
51
52/// Return the tool definition for evolve_coverage.
53pub fn definition() -> ToolDefinition {
54    ToolDefinition {
55        name: "evolve_coverage".to_string(),
56        description: Some("Get pattern coverage for a set of function signatures".to_string()),
57        input_schema: json!({
58            "type": "object",
59            "properties": {
60                "signatures": {
61                    "type": "array",
62                    "items": {
63                        "type": "object",
64                        "properties": {
65                            "name": { "type": "string" },
66                            "language": { "type": "string" },
67                            "params": {
68                                "type": "array",
69                                "items": {
70                                    "type": "object",
71                                    "properties": {
72                                        "name": { "type": "string" },
73                                        "type": { "type": "string" },
74                                        "is_optional": { "type": "boolean" }
75                                    },
76                                    "required": ["name"]
77                                }
78                            },
79                            "return_type": { "type": "string" },
80                            "is_async": { "type": "boolean" }
81                        },
82                        "required": ["name", "language"]
83                    },
84                    "description": "Function signatures to check coverage for"
85                },
86                "threshold": {
87                    "type": "number",
88                    "default": 0.5,
89                    "description": "Minimum match score to consider covered (0.0 to 1.0)"
90                },
91                "include_content": {
92                    "type": "boolean",
93                    "default": false,
94                    "description": "Include full template content in response"
95                },
96                "intent": {
97                    "type": "string",
98                    "enum": ["exists", "ids", "summary", "full"],
99                    "description": "Response detail level"
100                },
101                "since": {
102                    "type": "integer",
103                    "description": "Only return data changed after this Unix timestamp"
104                },
105                "token_budget": {
106                    "type": "integer",
107                    "description": "Maximum token budget for the response"
108                },
109                "max_results": {
110                    "type": "integer",
111                    "default": 10,
112                    "description": "Maximum number of results to return"
113                },
114                "cursor": {
115                    "type": "string",
116                    "description": "Pagination cursor from a previous response"
117                }
118            },
119            "required": ["signatures"]
120        }),
121    }
122}
123
124/// Execute the evolve_coverage tool.
125pub async fn execute(
126    args: Value,
127    session: &Arc<Mutex<SessionManager>>,
128) -> McpResult<ToolCallResult> {
129    let params: CoverageParams =
130        serde_json::from_value(args).map_err(|e| McpError::InvalidParams(e.to_string()))?;
131
132    let signatures: Vec<FunctionSignature> = params
133        .signatures
134        .into_iter()
135        .map(|s| {
136            let language = Language::from_name(&s.language);
137            let sig_params: Vec<ParamSignature> = s
138                .params
139                .into_iter()
140                .map(|p| ParamSignature {
141                    name: p.name,
142                    param_type: p.param_type,
143                    is_optional: p.is_optional,
144                })
145                .collect();
146            FunctionSignature {
147                name: s.name,
148                params: sig_params,
149                return_type: s.return_type,
150                language,
151                is_async: s.is_async,
152                visibility: Visibility::Public,
153            }
154        })
155        .collect();
156
157    let session = session.lock().await;
158    let report = session.coverage(&signatures, params.threshold);
159
160    Ok(ToolCallResult::json(&report))
161}