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/server/handlers/mesh_chat.rs | |
| parent | 077820c4167c168072d217a1b01df840463a12a8 (diff) | |
| download | soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.tar.gz soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.zip | |
Contract system
Diffstat (limited to 'makima/src/server/handlers/mesh_chat.rs')
| -rw-r--r-- | makima/src/server/handlers/mesh_chat.rs | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/makima/src/server/handlers/mesh_chat.rs b/makima/src/server/handlers/mesh_chat.rs index 5d6d2ee..3f650bc 100644 --- a/makima/src/server/handlers/mesh_chat.rs +++ b/makima/src/server/handlers/mesh_chat.rs @@ -930,6 +930,46 @@ async fn handle_mesh_request( merge_mode, priority, } => { + // Subtasks inherit contract_id from parent task + let contract_id = if let Some(parent_id) = parent_task_id { + match repository::get_task(pool, parent_id).await { + Ok(Some(parent_task)) => { + match parent_task.contract_id { + Some(cid) => cid, + None => { + return MeshRequestResult { + success: false, + message: "Parent task has no contract_id".to_string(), + data: None, + }; + } + } + } + Ok(None) => { + return MeshRequestResult { + success: false, + message: format!("Parent task {} not found", parent_id), + data: None, + }; + } + Err(e) => { + return MeshRequestResult { + success: false, + message: format!("Failed to look up parent task: {}", e), + data: None, + }; + } + } + } else { + // Root tasks created via LLM chat require a contract_id + // TODO: Add contract_id to create_task tool definition + return MeshRequestResult { + success: false, + message: "Cannot create root task without contract_id. Use parent_task_id to create subtasks.".to_string(), + data: None, + }; + }; + // Check if repository_url matches a daemon's working directory (for this owner) let is_daemon_working_dir = repository_url.as_ref().map(|url| { state.daemon_connections.iter().any(|entry| { @@ -962,6 +1002,7 @@ async fn handle_mesh_request( }; let create_req = CreateTaskRequest { + contract_id, name: name.clone(), description: None, plan, @@ -975,6 +1016,8 @@ async fn handle_mesh_request( completion_action, continue_from_task_id: None, copy_files: None, + is_supervisor: false, + checkpoint_sha: None, }; match repository::create_task_for_owner(pool, owner_id, create_req).await { @@ -1074,6 +1117,8 @@ async fn handle_mesh_request( completion_action: task.completion_action.clone(), continue_from_task_id: task.continue_from_task_id, copy_files: task.copy_files.as_ref().and_then(|v| serde_json::from_value(v.clone()).ok()), + contract_id: task.contract_id, + is_supervisor: task.is_supervisor, }; match state.send_daemon_command(target_daemon_id, command).await { @@ -1610,6 +1655,9 @@ async fn handle_mesh_request( crate::db::models::BodyElement::Image { src, alt, caption } => { json!({ "type": "image", "src": src, "alt": alt, "caption": caption }) } + crate::db::models::BodyElement::Markdown { content } => { + json!({ "type": "markdown", "content": content }) + } } }) .collect(); @@ -1640,6 +1688,9 @@ async fn handle_mesh_request( }).collect(); Some(list_text.join("\n")) } + crate::db::models::BodyElement::Markdown { content } => { + Some(content.clone()) + } _ => None, } }) @@ -1976,6 +2027,79 @@ async fn handle_mesh_request( }, } } + + // Supervisor-only tools - these should be handled via the supervisor.sh script, + // not through the mesh chat. Return an informative error. + MeshToolRequest::GetAllContractTasks { contract_id } => { + MeshRequestResult { + success: false, + message: format!( + "get_all_contract_tasks is a supervisor-only tool. Use supervisor.sh to access this functionality. Contract: {}", + contract_id + ), + data: None, + } + } + MeshToolRequest::WaitForTaskCompletion { task_id, timeout_seconds } => { + MeshRequestResult { + success: false, + message: format!( + "wait_for_task_completion is a supervisor-only tool. Use supervisor.sh to access this functionality. Task: {}, Timeout: {}s", + task_id, timeout_seconds + ), + data: None, + } + } + MeshToolRequest::ReadTaskWorktree { task_id, file_path } => { + MeshRequestResult { + success: false, + message: format!( + "read_task_worktree is a supervisor-only tool. Use supervisor.sh to access this functionality. Task: {}, Path: {}", + task_id, file_path + ), + data: None, + } + } + MeshToolRequest::SpawnTask { name, plan, parent_task_id, checkpoint_sha, .. } => { + MeshRequestResult { + success: false, + message: format!( + "spawn_task is a supervisor-only tool. Only the contract supervisor can spawn new tasks. Task name: {}", + name + ), + data: None, + } + } + MeshToolRequest::CreateCheckpoint { task_id, message } => { + MeshRequestResult { + success: false, + message: format!( + "create_checkpoint is a supervisor-only tool. Use supervisor.sh to access this functionality. Task: {}, Message: {}", + task_id, message + ), + data: None, + } + } + MeshToolRequest::ListTaskCheckpoints { task_id } => { + MeshRequestResult { + success: false, + message: format!( + "list_task_checkpoints is a supervisor-only tool. Use supervisor.sh to access this functionality. Task: {}", + task_id + ), + data: None, + } + } + MeshToolRequest::GetTaskTree { task_id } => { + MeshRequestResult { + success: false, + message: format!( + "get_task_tree is a supervisor-only tool. Use supervisor.sh to access this functionality. Task: {}", + task_id + ), + data: None, + } + } } } |
