From 857e717e6343fa5c2ae96664bdc64741d5ba6830 Mon Sep 17 00:00:00 2001 From: soryu Date: Sun, 17 May 2026 21:22:34 +0100 Subject: chore: remove LLM module + all dependent surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wholesale removal of the LLM integration layer. ~14,200 LOC deleted across backend and frontend. All chat-driven UIs go with it. ## Backend - Delete `src/llm/` (7,400 LOC): claude/groq clients, contract_tools, contract_evaluator, discuss_tools, mesh_tools, phase_guidance, task_output, templates, markdown round-trip, tools, transcript_analyzer. - Delete handlers wholly dependent on LLM: - `chat.rs` (file-level LLM chat at /files/{id}/chat) - `mesh_chat.rs` (mesh & task LLM chat + history) - `templates.rs` (/contract-types listing) - Strip LLM uses from `mesh_daemon.rs`: - `compute_action_directive` (used phase_guidance::check_deliverables_met to nudge supervisors with "all tasks done" messages). The auto-PR path below still fires when all tasks finish, so no behaviour lost. - `crate::llm::markdown_to_body` → inline 1-line replacement that wraps markdown content in a single BodyElement::Markdown. The editor re-parses on display, so round-trip is preserved. - Drop routes: /files/{id}/chat, /mesh/chat, /mesh/chat/history, /mesh/tasks/{id}/chat, /contract-types. - Drop the matching openapi registrations. ## Frontend - Delete components that were LLM-only: - `mesh/UnifiedMeshChatInput.tsx` - `listen/DiscussContractModal.tsx` - `listen/TranscriptAnalysisPanel.tsx` - `listen/ContractPickerModal.tsx` - `files/CliInput.tsx` - Delete the entire /listen page (its primary value-add was voice → LLM analysis → contract creation; without LLM the page is just a transcript display with no obvious user purpose). - Delete `hooks/useMeshChatHistory.ts` and `lib/listenApi.ts` (transcript-analysis API client to the already-Phase-5-removed listen handlers). - Strip api.ts of LLM exports: LlmModel, ChatMessage/Request/Response, UserQuestion/Answer, chatWithFile, MeshChat* types & functions, getMeshChatHistory, clearMeshChatHistory, chatWithMeshContext, ContractTypeTemplate, listContractTypes, chatWithContract, getContractChatHistory, clearContractChatHistory, discussContract, PhaseDefinition, DeliverableDefinition. - mesh.tsx: drop UnifiedMeshChatInput render + the chatContext memo + handleTaskUpdatedFromCli (only consumer was the input). - files.tsx: drop CliInput render + handleGenerateFromElement + handleBodyUpdate + handleClearFocus + suggestedPrompt state (all CliInput-only). - NavStrip: drop the /listen link. - main.tsx: drop the /listen route. ## Net diff: 37 files changed, 58 insertions, 14,281 deletions. Co-Authored-By: Claude Opus 4.7 (1M context) --- makima/src/llm/discuss_tools.rs | 210 ---------------------------------------- 1 file changed, 210 deletions(-) delete mode 100644 makima/src/llm/discuss_tools.rs (limited to 'makima/src/llm/discuss_tools.rs') 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> = 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, - local_only: bool, - }, -} - -/// Result from executing a discussion tool -#[derive(Debug)] -pub struct DiscussToolExecutionResult { - pub success: bool, - pub message: String, - pub data: Option, - /// Request for async operations (handled by discuss handler) - pub request: Option, - /// Questions to ask the user (pauses conversation) - pub pending_questions: Option>, -} - -/// 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 = 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, - } -} -- cgit v1.2.3