diff options
| author | soryu <soryu@soryu.co> | 2026-01-11 05:52:14 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-15 00:21:16 +0000 |
| commit | 87044a747b47bd83249d61a45842c7f7b2eae56d (patch) | |
| tree | ef2000ce79ffcc2723ef841acef5aa1deb1d5378 /makima/src/llm/mesh_tools.rs | |
| parent | 077820c4167c168072d217a1b01df840463a12a8 (diff) | |
| download | soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.tar.gz soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.zip | |
Contract system
Diffstat (limited to 'makima/src/llm/mesh_tools.rs')
| -rw-r--r-- | makima/src/llm/mesh_tools.rs | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/makima/src/llm/mesh_tools.rs b/makima/src/llm/mesh_tools.rs index 1d12c66..ec9dd01 100644 --- a/makima/src/llm/mesh_tools.rs +++ b/makima/src/llm/mesh_tools.rs @@ -418,6 +418,140 @@ pub static MESH_TOOLS: once_cell::sync::Lazy<Vec<Tool>> = once_cell::sync::Lazy: "required": ["questions"] }), }, + // ============================================================================= + // Supervisor Tools (only available to supervisor tasks) + // ============================================================================= + Tool { + name: "get_all_contract_tasks".to_string(), + description: "Get status of all tasks in the contract tree. Only available to supervisor tasks.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "contract_id": { + "type": "string", + "description": "ID of the contract to query tasks for" + } + }, + "required": ["contract_id"] + }), + }, + Tool { + name: "wait_for_task_completion".to_string(), + description: "Block until a task completes or timeout. Only available to supervisor tasks.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "ID of the task to wait for" + }, + "timeout_seconds": { + "type": "integer", + "description": "Maximum time to wait in seconds (default: 300)", + "default": 300 + } + }, + "required": ["task_id"] + }), + }, + Tool { + name: "read_task_worktree".to_string(), + description: "Read a file from any task's worktree. Only available to supervisor tasks.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "ID of the task whose worktree to read from" + }, + "file_path": { + "type": "string", + "description": "Path to the file within the worktree" + } + }, + "required": ["task_id", "file_path"] + }), + }, + Tool { + name: "spawn_task".to_string(), + description: "Create and start a child task (fire and forget). Only available to supervisor tasks.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name of the task" + }, + "plan": { + "type": "string", + "description": "Detailed instructions/plan for what the task should accomplish" + }, + "parent_task_id": { + "type": "string", + "description": "Optional parent task to branch from" + }, + "checkpoint_sha": { + "type": "string", + "description": "Optional checkpoint SHA to branch from" + }, + "repository_url": { + "type": "string", + "description": "Git repository URL (optional - inherits from contract if not provided)" + }, + "base_branch": { + "type": "string", + "description": "Optional base branch to start from" + } + }, + "required": ["name", "plan"] + }), + }, + Tool { + name: "create_checkpoint".to_string(), + description: "Create a git checkpoint (commit) in the current task's worktree. Only available to supervisor tasks.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "ID of the task to checkpoint" + }, + "message": { + "type": "string", + "description": "Commit message for the checkpoint" + } + }, + "required": ["task_id", "message"] + }), + }, + Tool { + name: "list_task_checkpoints".to_string(), + description: "List all checkpoints for a task.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "ID of the task to list checkpoints for" + } + }, + "required": ["task_id"] + }), + }, + Tool { + name: "get_task_tree".to_string(), + description: "Get the full task tree starting from a specific task.".to_string(), + parameters: json!({ + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "ID of the root task" + } + }, + "required": ["task_id"] + }), + }, ] }); @@ -506,6 +640,37 @@ pub enum MeshToolRequest { task_id: Uuid, mode: String, }, + + // Supervisor tools (only for supervisor tasks) + GetAllContractTasks { + contract_id: Uuid, + }, + WaitForTaskCompletion { + task_id: Uuid, + timeout_seconds: i32, + }, + ReadTaskWorktree { + task_id: Uuid, + file_path: String, + }, + SpawnTask { + name: String, + plan: String, + parent_task_id: Option<Uuid>, + checkpoint_sha: Option<String>, + repository_url: Option<String>, + base_branch: Option<String>, + }, + CreateCheckpoint { + task_id: Uuid, + message: String, + }, + ListTaskCheckpoints { + task_id: Uuid, + }, + GetTaskTree { + task_id: Uuid, + }, } /// Result from executing a mesh tool @@ -560,6 +725,15 @@ pub fn parse_mesh_tool_call( // Interactive tools "ask_user" => parse_ask_user(call), + // Supervisor tools + "get_all_contract_tasks" => parse_get_all_contract_tasks(call), + "wait_for_task_completion" => parse_wait_for_task_completion(call), + "read_task_worktree" => parse_read_task_worktree(call), + "spawn_task" => parse_spawn_task(call), + "create_checkpoint" => parse_create_checkpoint(call), + "list_task_checkpoints" => parse_list_task_checkpoints(call), + "get_task_tree" => parse_get_task_tree(call), + _ => MeshToolExecutionResult { success: false, message: format!("Unknown mesh tool: {}", call.name), @@ -1059,6 +1233,163 @@ fn parse_ask_user(call: &super::tools::ToolCall) -> MeshToolExecutionResult { } // ============================================================================= +// Supervisor Tool Parsing Functions +// ============================================================================= + +fn parse_get_all_contract_tasks(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(contract_id) = parse_uuid_arg(call, "contract_id") else { + return error_result("Missing or invalid contract_id"); + }; + + MeshToolExecutionResult { + success: true, + message: "Querying all contract tasks...".to_string(), + data: None, + request: Some(MeshToolRequest::GetAllContractTasks { contract_id }), + pending_questions: None, + } +} + +fn parse_wait_for_task_completion(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(task_id) = parse_uuid_arg(call, "task_id") else { + return error_result("Missing or invalid task_id"); + }; + + let timeout_seconds = call + .arguments + .get("timeout_seconds") + .and_then(|v| v.as_i64()) + .map(|v| v as i32) + .unwrap_or(300); + + MeshToolExecutionResult { + success: true, + message: format!("Waiting for task completion (timeout: {}s)...", timeout_seconds), + data: None, + request: Some(MeshToolRequest::WaitForTaskCompletion { + task_id, + timeout_seconds, + }), + pending_questions: None, + } +} + +fn parse_read_task_worktree(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(task_id) = parse_uuid_arg(call, "task_id") else { + return error_result("Missing or invalid task_id"); + }; + + let Some(file_path) = call.arguments.get("file_path").and_then(|v| v.as_str()) else { + return error_result("Missing required parameter: file_path"); + }; + + MeshToolExecutionResult { + success: true, + message: format!("Reading file from task worktree: {}", file_path), + data: None, + request: Some(MeshToolRequest::ReadTaskWorktree { + task_id, + file_path: file_path.to_string(), + }), + pending_questions: None, + } +} + +fn parse_spawn_task(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(name) = call.arguments.get("name").and_then(|v| v.as_str()) else { + return error_result("Missing required parameter: name"); + }; + + let Some(plan) = call.arguments.get("plan").and_then(|v| v.as_str()) else { + return error_result("Missing required parameter: plan"); + }; + + let parent_task_id = parse_uuid_arg(call, "parent_task_id"); + + let checkpoint_sha = call + .arguments + .get("checkpoint_sha") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()); + + let repository_url = call + .arguments + .get("repository_url") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()); + + let base_branch = call + .arguments + .get("base_branch") + .and_then(|v| v.as_str()) + .map(|s| s.to_string()); + + MeshToolExecutionResult { + success: true, + message: format!("Spawning task: {}", name), + data: None, + request: Some(MeshToolRequest::SpawnTask { + name: name.to_string(), + plan: plan.to_string(), + parent_task_id, + checkpoint_sha, + repository_url, + base_branch, + }), + pending_questions: None, + } +} + +fn parse_create_checkpoint(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(task_id) = parse_uuid_arg(call, "task_id") else { + return error_result("Missing or invalid task_id"); + }; + + let Some(message) = call.arguments.get("message").and_then(|v| v.as_str()) else { + return error_result("Missing required parameter: message"); + }; + + MeshToolExecutionResult { + success: true, + message: format!("Creating checkpoint: {}", message), + data: None, + request: Some(MeshToolRequest::CreateCheckpoint { + task_id, + message: message.to_string(), + }), + pending_questions: None, + } +} + +fn parse_list_task_checkpoints(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(task_id) = parse_uuid_arg(call, "task_id") else { + return error_result("Missing or invalid task_id"); + }; + + MeshToolExecutionResult { + success: true, + message: "Listing task checkpoints...".to_string(), + data: None, + request: Some(MeshToolRequest::ListTaskCheckpoints { task_id }), + pending_questions: None, + } +} + +fn parse_get_task_tree(call: &super::tools::ToolCall) -> MeshToolExecutionResult { + let Some(task_id) = parse_uuid_arg(call, "task_id") else { + return error_result("Missing or invalid task_id"); + }; + + MeshToolExecutionResult { + success: true, + message: "Getting task tree...".to_string(), + data: None, + request: Some(MeshToolRequest::GetTaskTree { task_id }), + pending_questions: None, + } +} + +// ============================================================================= // Helper Functions // ============================================================================= |
