diff --git a/src/agent.rs b/src/agent.rs index 9098d3e..b6bf3d7 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -426,15 +426,21 @@ async fn agent_loop( .and_then(|json| serde_json::from_str::(&json).ok()) .unwrap_or_else(AgentState::new); - // For failed/done workflows: reset failed steps and continue directly - // For running workflows: process feedback via LLM - let is_resuming = wf.status == "failed" || wf.status == "done"; + // Resume directly if: workflow is failed/done/waiting_approval, + // OR if state snapshot has a WaitingApproval step (e.g. after pod restart) + let has_waiting_step = state.steps.iter().any(|s| matches!(s.status, StepStatus::WaitingApproval)); + let is_resuming = wf.status == "failed" || wf.status == "done" + || wf.status == "waiting_approval" || has_waiting_step; if is_resuming { - // Reset Failed steps to Pending so they get re-executed + // Reset Failed/WaitingApproval steps so they get re-executed for step in &mut state.steps { if matches!(step.status, StepStatus::Failed) { step.status = StepStatus::Pending; } + if matches!(step.status, StepStatus::WaitingApproval) { + // Mark as Running so it continues (not re-plans) + step.status = StepStatus::Running; + } } // Attach comment as feedback to the first actionable step if let Some(order) = state.first_actionable_step() { @@ -442,8 +448,8 @@ async fn agent_loop( step.user_feedbacks.push(content.clone()); } } - tracing::info!("[workflow {}] Resuming from state, first actionable: {:?}", - workflow_id, state.first_actionable_step()); + tracing::info!("[workflow {}] Resuming from state (status={}), first actionable: {:?}", + workflow_id, wf.status, state.first_actionable_step()); } else { // Active workflow: LLM decides whether to revise plan state = process_feedback(