736 lines
26 KiB
Rust
736 lines
26 KiB
Rust
//! MCP (Model Context Protocol) tool registry and execution
|
|
//!
|
|
//! Provides tool definition, registration, and execution for RAG, Guidance,
|
|
//! Settings, and IaC tools.
|
|
|
|
use provisioning_mcp_server::tools::settings::{DeploymentMode, SettingsTools};
|
|
use serde::{Deserialize, Serialize};
|
|
use serde_json::{json, Value};
|
|
use tokio::sync::Mutex;
|
|
|
|
/// Tool execution result
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ToolExecution {
|
|
pub tool_name: String,
|
|
pub result: Value,
|
|
pub duration_ms: u64,
|
|
}
|
|
|
|
/// MCP tool registry for provisioning system
|
|
pub struct ToolRegistry {
|
|
tools: std::collections::HashMap<String, ToolDefinition>,
|
|
settings_tools: Mutex<SettingsTools>,
|
|
}
|
|
|
|
/// Tool definition for MCP
|
|
#[derive(Debug, Clone)]
|
|
pub struct ToolDefinition {
|
|
pub name: String,
|
|
pub description: String,
|
|
pub category: ToolCategory,
|
|
pub input_schema: Value,
|
|
}
|
|
|
|
/// Tool categories
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum ToolCategory {
|
|
Rag,
|
|
Guidance,
|
|
Settings,
|
|
Iac,
|
|
}
|
|
|
|
impl ToolRegistry {
|
|
/// Create a new tool registry
|
|
pub fn new() -> Self {
|
|
let mut registry = Self {
|
|
tools: std::collections::HashMap::new(),
|
|
settings_tools: Mutex::new(SettingsTools::new()),
|
|
};
|
|
registry.register_all_tools();
|
|
registry
|
|
}
|
|
|
|
/// Register all tool categories (RAG, Guidance, Settings, IaC)
|
|
fn register_all_tools(&mut self) {
|
|
self.register_rag_tools();
|
|
self.register_guidance_tools();
|
|
self.register_settings_tools();
|
|
self.register_iac_tools();
|
|
}
|
|
|
|
/// Register RAG tools
|
|
fn register_rag_tools(&mut self) {
|
|
self.tools.insert(
|
|
"rag_ask_question".to_string(),
|
|
ToolDefinition {
|
|
name: "rag_ask_question".to_string(),
|
|
description: "Ask a question using RAG (Retrieval-Augmented Generation) with knowledge base search".to_string(),
|
|
category: ToolCategory::Rag,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"question": {"type": "string", "description": "The question to ask"},
|
|
"context": {"type": "string", "description": "Optional context for the question"},
|
|
"top_k": {"type": "integer", "description": "Number of top results to return", "default": 3}
|
|
},
|
|
"required": ["question"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"rag_semantic_search".to_string(),
|
|
ToolDefinition {
|
|
name: "rag_semantic_search".to_string(),
|
|
description: "Perform semantic search on the knowledge base".to_string(),
|
|
category: ToolCategory::Rag,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "Search query"},
|
|
"category": {"type": "string", "description": "Optional category filter"},
|
|
"top_k": {"type": "integer", "description": "Number of results", "default": 5}
|
|
},
|
|
"required": ["query"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"rag_get_status".to_string(),
|
|
ToolDefinition {
|
|
name: "rag_get_status".to_string(),
|
|
description: "Get the current status of the RAG knowledge base".to_string(),
|
|
category: ToolCategory::Rag,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {}
|
|
}),
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Register Guidance tools
|
|
fn register_guidance_tools(&mut self) {
|
|
self.tools.insert(
|
|
"guidance_check_system_status".to_string(),
|
|
ToolDefinition {
|
|
name: "guidance_check_system_status".to_string(),
|
|
description: "Check the current system status and configuration".to_string(),
|
|
category: ToolCategory::Guidance,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"guidance_suggest_next_action".to_string(),
|
|
ToolDefinition {
|
|
name: "guidance_suggest_next_action".to_string(),
|
|
description: "Get suggestions for the next action based on current system state".to_string(),
|
|
category: ToolCategory::Guidance,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"context": {"type": "string", "description": "Optional context for suggestion"}
|
|
}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"guidance_find_docs".to_string(),
|
|
ToolDefinition {
|
|
name: "guidance_find_docs".to_string(),
|
|
description: "Find relevant documentation and guides".to_string(),
|
|
category: ToolCategory::Guidance,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "What to search for"},
|
|
"context": {"type": "string", "description": "Optional context"}
|
|
},
|
|
"required": ["query"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"guidance_troubleshoot".to_string(),
|
|
ToolDefinition {
|
|
name: "guidance_troubleshoot".to_string(),
|
|
description: "Troubleshoot an issue or error".to_string(),
|
|
category: ToolCategory::Guidance,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"error": {"type": "string", "description": "Error message or description"},
|
|
"context": {"type": "string", "description": "Context about the issue"}
|
|
},
|
|
"required": ["error"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"guidance_validate_config".to_string(),
|
|
ToolDefinition {
|
|
name: "guidance_validate_config".to_string(),
|
|
description: "Validate a configuration file or settings".to_string(),
|
|
category: ToolCategory::Guidance,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"config_path": {"type": "string", "description": "Path to configuration file"}
|
|
},
|
|
"required": ["config_path"]
|
|
}),
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Register Settings tools
|
|
fn register_settings_tools(&mut self) {
|
|
self.tools.insert(
|
|
"installer_get_settings".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_get_settings".to_string(),
|
|
description: "Get installer settings and configuration".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "Optional settings query"}
|
|
}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_complete_config".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_complete_config".to_string(),
|
|
description: "Complete partial configuration with defaults".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"config": {"type": "object", "description": "Partial configuration"}
|
|
}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_validate_config".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_validate_config".to_string(),
|
|
description: "Validate configuration against schema".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"config": {"type": "object", "description": "Configuration to validate"}
|
|
},
|
|
"required": ["config"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_get_defaults".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_get_defaults".to_string(),
|
|
description: "Get default settings for a deployment mode".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"mode": {"type": "string", "description": "Deployment mode"}
|
|
},
|
|
"required": ["mode"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_platform_recommendations".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_platform_recommendations".to_string(),
|
|
description: "Get platform-specific recommendations".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_service_recommendations".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_service_recommendations".to_string(),
|
|
description: "Get service recommendations for a deployment mode".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"mode": {"type": "string", "description": "Deployment mode"}
|
|
},
|
|
"required": ["mode"]
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"installer_resource_recommendations".to_string(),
|
|
ToolDefinition {
|
|
name: "installer_resource_recommendations".to_string(),
|
|
description: "Get resource recommendations for a deployment mode".to_string(),
|
|
category: ToolCategory::Settings,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"mode": {"type": "string", "description": "Deployment mode"}
|
|
},
|
|
"required": ["mode"]
|
|
}),
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Register IaC tools
|
|
fn register_iac_tools(&mut self) {
|
|
self.tools.insert(
|
|
"iac_detect_technologies".to_string(),
|
|
ToolDefinition {
|
|
name: "iac_detect_technologies".to_string(),
|
|
description: "Detect technologies used in infrastructure".to_string(),
|
|
category: ToolCategory::Iac,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {"type": "string", "description": "Path to analyze"}
|
|
}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"iac_analyze_completeness".to_string(),
|
|
ToolDefinition {
|
|
name: "iac_analyze_completeness".to_string(),
|
|
description: "Analyze completeness of infrastructure configuration".to_string(),
|
|
category: ToolCategory::Iac,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"config": {"type": "object", "description": "Configuration to analyze"}
|
|
}
|
|
}),
|
|
},
|
|
);
|
|
|
|
self.tools.insert(
|
|
"iac_infer_requirements".to_string(),
|
|
ToolDefinition {
|
|
name: "iac_infer_requirements".to_string(),
|
|
description: "Infer infrastructure requirements from description".to_string(),
|
|
category: ToolCategory::Iac,
|
|
input_schema: json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"description": {"type": "string", "description": "Infrastructure description"}
|
|
},
|
|
"required": ["description"]
|
|
}),
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Get all tool definitions
|
|
pub fn list_tools(&self) -> Vec<ToolDefinition> {
|
|
self.tools.values().cloned().collect()
|
|
}
|
|
|
|
/// Get tools by category
|
|
pub fn tools_by_category(&self, category: ToolCategory) -> Vec<ToolDefinition> {
|
|
self.tools
|
|
.values()
|
|
.filter(|t| t.category == category)
|
|
.cloned()
|
|
.collect()
|
|
}
|
|
|
|
/// Check if tool exists
|
|
pub fn has_tool(&self, name: &str) -> bool {
|
|
self.tools.contains_key(name)
|
|
}
|
|
|
|
/// Execute a tool (async)
|
|
pub async fn execute(&self, tool_name: &str, args: &Value) -> Result<Value, String> {
|
|
match tool_name {
|
|
// RAG tools
|
|
"rag_ask_question" => self.rag_ask_question(args).await,
|
|
"rag_semantic_search" => self.rag_semantic_search(args).await,
|
|
"rag_get_status" => self.rag_get_status(args).await,
|
|
// Guidance tools
|
|
"guidance_check_system_status" => self.guidance_check_system_status(args).await,
|
|
"guidance_suggest_next_action" => self.guidance_suggest_next_action(args).await,
|
|
"guidance_find_docs" => self.guidance_find_docs(args).await,
|
|
"guidance_troubleshoot" => self.guidance_troubleshoot(args).await,
|
|
"guidance_validate_config" => self.guidance_validate_config(args).await,
|
|
// Settings tools
|
|
"installer_get_settings" => self.installer_get_settings(args).await,
|
|
"installer_complete_config" => self.installer_complete_config(args).await,
|
|
"installer_validate_config" => self.installer_validate_config(args).await,
|
|
"installer_get_defaults" => self.installer_get_defaults(args).await,
|
|
"installer_platform_recommendations" => {
|
|
self.installer_platform_recommendations(args).await
|
|
}
|
|
"installer_service_recommendations" => {
|
|
self.installer_service_recommendations(args).await
|
|
}
|
|
"installer_resource_recommendations" => {
|
|
self.installer_resource_recommendations(args).await
|
|
}
|
|
// IaC tools
|
|
"iac_detect_technologies" => self.iac_detect_technologies(args).await,
|
|
"iac_analyze_completeness" => self.iac_analyze_completeness(args).await,
|
|
"iac_infer_requirements" => self.iac_infer_requirements(args).await,
|
|
_ => Err(format!("Unknown tool: {}", tool_name)),
|
|
}
|
|
}
|
|
|
|
// ========== RAG TOOL IMPLEMENTATIONS ==========
|
|
|
|
async fn rag_ask_question(&self, args: &Value) -> Result<Value, String> {
|
|
let question = args
|
|
.get("question")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("question parameter required")?;
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "rag_ask_question",
|
|
"message": format!("RAG query would be processed for: {}", question)
|
|
}))
|
|
}
|
|
|
|
async fn rag_semantic_search(&self, args: &Value) -> Result<Value, String> {
|
|
let query = args
|
|
.get("query")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("query parameter required")?;
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "rag_semantic_search",
|
|
"message": format!("Semantic search would be performed for: {}", query),
|
|
"results": []
|
|
}))
|
|
}
|
|
|
|
async fn rag_get_status(&self, _args: &Value) -> Result<Value, String> {
|
|
Ok(json!({
|
|
"status": "active",
|
|
"tool": "rag_get_status",
|
|
"knowledge_base": {
|
|
"documents_loaded": true,
|
|
"total_documents": 76,
|
|
"categories": ["architecture", "deployment", "security", "reliability"]
|
|
}
|
|
}))
|
|
}
|
|
|
|
// ========== GUIDANCE TOOL IMPLEMENTATIONS ==========
|
|
|
|
/// Execute a Nushell command and parse JSON output
|
|
async fn execute_nu_command(cmd: &str) -> Result<Value, String> {
|
|
use tokio::process::Command;
|
|
|
|
let output = Command::new("nu")
|
|
.arg("-c")
|
|
.arg(cmd)
|
|
.output()
|
|
.await
|
|
.map_err(|e| format!("Failed to execute Nushell: {}", e))?;
|
|
|
|
if !output.status.success() {
|
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
return Err(format!("Nushell command failed: {}", stderr));
|
|
}
|
|
|
|
serde_json::from_slice(&output.stdout)
|
|
.map_err(|e| format!("Failed to parse JSON output: {}", e))
|
|
}
|
|
|
|
async fn guidance_check_system_status(&self, _args: &Value) -> Result<Value, String> {
|
|
Self::execute_nu_command("provisioning status-json").await
|
|
}
|
|
|
|
async fn guidance_suggest_next_action(&self, _args: &Value) -> Result<Value, String> {
|
|
Self::execute_nu_command("provisioning next").await
|
|
}
|
|
|
|
async fn guidance_find_docs(&self, args: &Value) -> Result<Value, String> {
|
|
let query = args
|
|
.get("query")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("query parameter required")?;
|
|
|
|
let cmd = format!("provisioning guide {}", query);
|
|
Self::execute_nu_command(&cmd).await
|
|
}
|
|
|
|
async fn guidance_troubleshoot(&self, _args: &Value) -> Result<Value, String> {
|
|
Self::execute_nu_command("provisioning health-json").await
|
|
}
|
|
|
|
async fn guidance_validate_config(&self, args: &Value) -> Result<Value, String> {
|
|
let config_path = args
|
|
.get("config_path")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("config_path parameter required")?;
|
|
|
|
let cmd = format!("validate-system-config {}", config_path);
|
|
Self::execute_nu_command(&cmd).await
|
|
}
|
|
|
|
// ========== SETTINGS TOOL IMPLEMENTATIONS ==========
|
|
|
|
async fn installer_get_settings(&self, args: &Value) -> Result<Value, String> {
|
|
let query = args.get("query").and_then(|v| v.as_str());
|
|
|
|
let mut settings_tools = self.settings_tools.lock().await;
|
|
|
|
let settings = settings_tools
|
|
.get_settings(query)
|
|
.await
|
|
.map_err(|e| format!("Failed to get settings: {}", e))?;
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "installer_get_settings",
|
|
"platforms": settings.get("platforms"),
|
|
"modes": settings.get("modes"),
|
|
"default_domain": settings.get("default_domain"),
|
|
"auto_generate_secrets": settings.get("auto_generate_secrets"),
|
|
"available_services": settings.get("available_services")
|
|
}))
|
|
}
|
|
|
|
async fn installer_complete_config(&self, args: &Value) -> Result<Value, String> {
|
|
let config = args
|
|
.get("config")
|
|
.cloned()
|
|
.ok_or("config parameter required")?;
|
|
|
|
let mut settings_tools = self.settings_tools.lock().await;
|
|
|
|
settings_tools
|
|
.complete_config(config)
|
|
.await
|
|
.map_err(|e| format!("Failed to complete config: {}", e))
|
|
}
|
|
|
|
async fn installer_validate_config(&self, args: &Value) -> Result<Value, String> {
|
|
let config = args
|
|
.get("config")
|
|
.cloned()
|
|
.ok_or("config parameter required")?;
|
|
|
|
let settings_tools = self.settings_tools.lock().await;
|
|
|
|
settings_tools
|
|
.validate_config(config)
|
|
.map_err(|e| format!("Failed to validate config: {}", e))
|
|
}
|
|
|
|
async fn installer_get_defaults(&self, args: &Value) -> Result<Value, String> {
|
|
let mode = args
|
|
.get("mode")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("mode parameter required")?;
|
|
|
|
let settings_tools = self.settings_tools.lock().await;
|
|
|
|
let defaults = settings_tools
|
|
.get_mode_defaults(mode)
|
|
.map_err(|e| format!("Failed to get defaults: {}", e))?;
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "installer_get_defaults",
|
|
"mode": defaults.get("mode"),
|
|
"description": defaults.get("description"),
|
|
"service_count": defaults.get("service_count"),
|
|
"min_cpu_cores": defaults.get("min_cpu_cores"),
|
|
"min_memory_gb": defaults.get("min_memory_gb"),
|
|
"recommended_services": defaults.get("recommended_services"),
|
|
"auto_generate_secrets": defaults.get("auto_generate_secrets"),
|
|
"domain": defaults.get("domain")
|
|
}))
|
|
}
|
|
|
|
async fn installer_platform_recommendations(&self, _args: &Value) -> Result<Value, String> {
|
|
let mut settings_tools = self.settings_tools.lock().await;
|
|
|
|
let recommendations = settings_tools
|
|
.get_platform_recommendations()
|
|
.await
|
|
.map_err(|e| format!("Failed to get platform recommendations: {}", e))?;
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "installer_platform_recommendations",
|
|
"recommendations": recommendations
|
|
}))
|
|
}
|
|
|
|
async fn installer_service_recommendations(&self, args: &Value) -> Result<Value, String> {
|
|
let mode_str = args
|
|
.get("mode")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("mode parameter required")?;
|
|
|
|
let mode = DeploymentMode::from_str(mode_str)
|
|
.ok_or(format!("Invalid deployment mode: {}", mode_str))?;
|
|
|
|
let settings_tools = self.settings_tools.lock().await;
|
|
|
|
let recommendations = settings_tools.get_service_recommendations(&mode);
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "installer_service_recommendations",
|
|
"mode": mode_str,
|
|
"recommendations": recommendations
|
|
}))
|
|
}
|
|
|
|
async fn installer_resource_recommendations(&self, args: &Value) -> Result<Value, String> {
|
|
let mode_str = args
|
|
.get("mode")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("mode parameter required")?;
|
|
|
|
let mode = DeploymentMode::from_str(mode_str)
|
|
.ok_or(format!("Invalid deployment mode: {}", mode_str))?;
|
|
|
|
let settings_tools = self.settings_tools.lock().await;
|
|
|
|
let recommendations = settings_tools.get_resource_recommendations(&mode);
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "installer_resource_recommendations",
|
|
"mode": mode_str,
|
|
"recommendations": recommendations
|
|
}))
|
|
}
|
|
|
|
// ========== IAC TOOL IMPLEMENTATIONS ==========
|
|
|
|
async fn iac_detect_technologies(&self, args: &Value) -> Result<Value, String> {
|
|
let path = args
|
|
.get("path")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("path parameter required")?;
|
|
|
|
let path_obj = std::path::Path::new(path);
|
|
let mut technologies = Vec::new();
|
|
|
|
// Check for Kubernetes
|
|
if path_obj.join("kustomization.yaml").exists() || path_obj.join("deployment.yaml").exists()
|
|
{
|
|
technologies.push("kubernetes");
|
|
}
|
|
|
|
// Check for Docker
|
|
if path_obj.join("Dockerfile").exists() || path_obj.join("docker-compose.yml").exists() {
|
|
technologies.push("docker");
|
|
}
|
|
|
|
// Check for Terraform
|
|
if path_obj.join("main.tf").exists() {
|
|
technologies.push("terraform");
|
|
}
|
|
|
|
// Check for KCL (legacy)
|
|
if path_obj.join("kcl.mod").exists() {
|
|
technologies.push("kcl");
|
|
}
|
|
|
|
// Check for Nickel (current IaC)
|
|
if path_obj.join("main.ncl").exists() {
|
|
technologies.push("nickel");
|
|
}
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "iac_detect_technologies",
|
|
"path": path,
|
|
"technologies": technologies
|
|
}))
|
|
}
|
|
|
|
async fn iac_analyze_completeness(&self, args: &Value) -> Result<Value, String> {
|
|
let path = args
|
|
.get("path")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("path parameter required")?;
|
|
|
|
let path_obj = std::path::Path::new(path);
|
|
let mut missing = Vec::new();
|
|
|
|
// Check for essential infrastructure files
|
|
if !path_obj.join("infrastructure.ncl").exists() {
|
|
missing.push("infrastructure.ncl");
|
|
}
|
|
if !path_obj.join("config.toml").exists() {
|
|
missing.push("config.toml");
|
|
}
|
|
if !path_obj.join("README.md").exists() {
|
|
missing.push("README.md");
|
|
}
|
|
|
|
let complete = missing.is_empty();
|
|
let completeness_score = if missing.is_empty() { 1.0 } else { 0.7 };
|
|
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "iac_analyze_completeness",
|
|
"complete": complete,
|
|
"completeness_score": completeness_score,
|
|
"missing_files": missing
|
|
}))
|
|
}
|
|
|
|
async fn iac_infer_requirements(&self, args: &Value) -> Result<Value, String> {
|
|
let _description = args
|
|
.get("description")
|
|
.and_then(|v| v.as_str())
|
|
.ok_or("description parameter required")?;
|
|
|
|
// Basic requirements inference (can be enhanced with ML later)
|
|
Ok(json!({
|
|
"status": "success",
|
|
"tool": "iac_infer_requirements",
|
|
"requirements": {
|
|
"compute": "2 CPU, 4GB RAM (minimum)",
|
|
"storage": "20GB",
|
|
"network": "Private network recommended",
|
|
"high_availability": false
|
|
}
|
|
}))
|
|
}
|
|
}
|
|
|
|
impl Default for ToolRegistry {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|