diff options
Diffstat (limited to 'makima/src/llm/discuss_tools.rs')
| -rw-r--r-- | makima/src/llm/discuss_tools.rs | 210 |
1 files changed, 0 insertions, 210 deletions
diff --git a/makima/src/llm/discuss_tools.rs b/makima/src/llm/discuss_tools.rs deleted file mode 100644 index 7330db3..0000000 --- a/makima/src/llm/discuss_tools.rs +++ /dev/null @@ -1,210 +0,0 @@ -//! Tool definitions for contract discussion via LLM. -//! -//! These tools allow Makima to help users define and create contracts -//! through natural conversation. - -use serde_json::json; - -use super::tools::Tool; - -/// Available tools for contract discussion -pub static DISCUSS_TOOLS: once_cell::sync::Lazy<Vec<Tool>> = once_cell::sync::Lazy::new(|| { - vec![ - Tool { - name: "create_contract".to_string(), - description: "Create a new contract based on the discussion. Only call this when the user has confirmed they're ready to create the contract.".to_string(), - parameters: json!({ - "type": "object", - "properties": { - "name": { - "type": "string", - "description": "Name for the contract" - }, - "description": { - "type": "string", - "description": "Detailed description of what the contract is for" - }, - "contract_type": { - "type": "string", - "enum": ["simple", "specification", "execute"], - "description": "Type of contract workflow" - }, - "repository_url": { - "type": "string", - "description": "Optional repository URL if discussed" - }, - "local_only": { - "type": "boolean", - "description": "If true, tasks won't auto-push or create PRs" - } - }, - "required": ["name", "description", "contract_type"] - }), - }, - Tool { - name: "ask_clarification".to_string(), - description: "Ask the user a clarifying question with multiple choice options.".to_string(), - parameters: json!({ - "type": "object", - "properties": { - "question": { - "type": "string", - "description": "The question to ask" - }, - "options": { - "type": "array", - "items": { "type": "string" }, - "description": "Multiple choice options" - }, - "allow_custom": { - "type": "boolean", - "description": "Allow user to provide a custom answer" - } - }, - "required": ["question", "options"] - }), - }, - ] -}); - -/// Request for discussion tool operations that require async database access -#[derive(Debug, Clone)] -pub enum DiscussToolRequest { - /// Create a new contract - CreateContract { - name: String, - description: String, - contract_type: String, - repository_url: Option<String>, - local_only: bool, - }, -} - -/// Result from executing a discussion tool -#[derive(Debug)] -pub struct DiscussToolExecutionResult { - pub success: bool, - pub message: String, - pub data: Option<serde_json::Value>, - /// Request for async operations (handled by discuss handler) - pub request: Option<DiscussToolRequest>, - /// Questions to ask the user (pauses conversation) - pub pending_questions: Option<Vec<super::tools::UserQuestion>>, -} - -/// Parse and validate a discussion tool call, returning a DiscussToolRequest for async handling -pub fn parse_discuss_tool_call(call: &super::tools::ToolCall) -> DiscussToolExecutionResult { - match call.name.as_str() { - "create_contract" => parse_create_contract(call), - "ask_clarification" => parse_ask_clarification(call), - _ => DiscussToolExecutionResult { - success: false, - message: format!("Unknown discussion tool: {}", call.name), - data: None, - request: None, - pending_questions: None, - }, - } -} - -fn parse_create_contract(call: &super::tools::ToolCall) -> DiscussToolExecutionResult { - let name = call.arguments.get("name").and_then(|v| v.as_str()); - let description = call.arguments.get("description").and_then(|v| v.as_str()); - let contract_type = call.arguments.get("contract_type").and_then(|v| v.as_str()); - - let Some(name) = name else { - return error_result("Missing required parameter: name"); - }; - let Some(description) = description else { - return error_result("Missing required parameter: description"); - }; - let Some(contract_type) = contract_type else { - return error_result("Missing required parameter: contract_type"); - }; - - let valid_types = ["simple", "specification", "execute"]; - if !valid_types.contains(&contract_type) { - return error_result("Invalid contract_type. Must be one of: simple, specification, execute"); - } - - let repository_url = call - .arguments - .get("repository_url") - .and_then(|v| v.as_str()) - .map(|s| s.to_string()); - - let local_only = call - .arguments - .get("local_only") - .and_then(|v| v.as_bool()) - .unwrap_or(false); - - DiscussToolExecutionResult { - success: true, - message: format!("Creating contract '{}'...", name), - data: None, - request: Some(DiscussToolRequest::CreateContract { - name: name.to_string(), - description: description.to_string(), - contract_type: contract_type.to_string(), - repository_url, - local_only, - }), - pending_questions: None, - } -} - -fn parse_ask_clarification(call: &super::tools::ToolCall) -> DiscussToolExecutionResult { - let question = call.arguments.get("question").and_then(|v| v.as_str()); - let options = call.arguments.get("options").and_then(|v| v.as_array()); - - let Some(question) = question else { - return error_result("Missing required parameter: question"); - }; - let Some(options) = options else { - return error_result("Missing required parameter: options"); - }; - - let options: Vec<String> = options - .iter() - .filter_map(|o| o.as_str()) - .map(|s| s.to_string()) - .collect(); - - if options.is_empty() { - return error_result("Options array cannot be empty"); - } - - let allow_custom = call - .arguments - .get("allow_custom") - .and_then(|v| v.as_bool()) - .unwrap_or(true); - - // Create a UserQuestion for the ask_clarification tool - let user_question = super::tools::UserQuestion { - id: "clarification".to_string(), - question: question.to_string(), - options, - allow_multiple: false, - allow_custom, - }; - - DiscussToolExecutionResult { - success: true, - message: format!("Asking clarification: {}", question), - data: None, - request: None, - pending_questions: Some(vec![user_question]), - } -} - -fn error_result(message: &str) -> DiscussToolExecutionResult { - DiscussToolExecutionResult { - success: false, - message: message.to_string(), - data: None, - request: None, - pending_questions: None, - } -} |
