From 579c983d3efb8f1414ffb45b9e031f741cce5f76 Mon Sep 17 00:00:00 2001 From: soryu Date: Fri, 23 Jan 2026 23:52:35 +0000 Subject: Add resume to daemon tasks --- makima/src/server/handlers/mesh_supervisor.rs | 39 +++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'makima/src/server/handlers/mesh_supervisor.rs') diff --git a/makima/src/server/handlers/mesh_supervisor.rs b/makima/src/server/handlers/mesh_supervisor.rs index 21c9515..1b5e376 100644 --- a/makima/src/server/handlers/mesh_supervisor.rs +++ b/makima/src/server/handlers/mesh_supervisor.rs @@ -279,8 +279,9 @@ async fn verify_supervisor_auth( /// Try to start a pending task on an available daemon. /// Returns Ok(Some(task)) if a task was started, Ok(None) if no tasks could be started. -/// For retried tasks, excludes daemons that previously failed the task. -async fn try_start_pending_task( +/// For retried tasks, excludes daemons that previously failed the task and includes +/// checkpoint patch data for worktree recovery. +pub async fn try_start_pending_task( state: &SharedState, contract_id: Uuid, owner_id: Uuid, @@ -348,6 +349,34 @@ async fn try_start_pending_task( } }; + // For retried tasks, fetch checkpoint patch for worktree recovery + let (patch_data, patch_base_sha) = if task.retry_count > 0 { + // This is a retry - try to restore from checkpoint + match repository::get_latest_checkpoint_patch(pool, task.id).await { + Ok(Some(patch)) => { + tracing::info!( + task_id = %task.id, + retry_count = task.retry_count, + patch_size = patch.patch_size_bytes, + base_sha = %patch.base_commit_sha, + "Including checkpoint patch for task retry recovery" + ); + let encoded = base64::engine::general_purpose::STANDARD.encode(&patch.patch_data); + (Some(encoded), Some(patch.base_commit_sha)) + } + Ok(None) => { + tracing::debug!(task_id = %task.id, "No checkpoint patch found for retry"); + (None, None) + } + Err(e) => { + tracing::warn!(task_id = %task.id, error = %e, "Failed to fetch checkpoint patch for retry"); + (None, None) + } + } + } else { + (None, None) + }; + // Send spawn command let cmd = DaemonCommand::SpawnTask { task_id: updated_task.id, @@ -366,10 +395,10 @@ async fn try_start_pending_task( contract_id: updated_task.contract_id, is_supervisor: false, autonomous_loop: false, - resume_session: false, + resume_session: task.retry_count > 0, // Use --continue for retried tasks conversation_history: None, - patch_data: None, - patch_base_sha: None, + patch_data, + patch_base_sha, }; if let Err(e) = state.send_daemon_command(daemon.id, cmd).await { -- cgit v1.2.3