mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
fix(engine): transition thread to Waiting on NeedApproval
The orchestrator Python returned {"outcome": "need_approval"} without
calling __transition_to__("waiting"), leaving the thread in Running
state. When the user later approved/denied, resume_thread rejected it
with "thread is not resumable from Running".
- Add __transition_to__("waiting", "approval needed") in both code-step
and action-call approval paths in default.py
- Add Rust safety net in loop_engine.rs: if orchestrator returns
NeedApproval but thread isn't Waiting, force the transition
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
@@ -339,6 +339,7 @@ def run_loop(context, goal, actions, state, config):
|
||||
"nudge_count": nudge_count,
|
||||
"consecutive_errors": consecutive_errors,
|
||||
})
|
||||
__transition_to__("waiting", "approval needed")
|
||||
return {
|
||||
"outcome": "need_approval",
|
||||
"action_name": approval.get("action_name", ""),
|
||||
@@ -382,6 +383,7 @@ def run_loop(context, goal, actions, state, config):
|
||||
"nudge_count": nudge_count,
|
||||
"consecutive_errors": consecutive_errors,
|
||||
})
|
||||
__transition_to__("waiting", "approval needed")
|
||||
return {
|
||||
"outcome": "need_approval",
|
||||
"action_name": name,
|
||||
|
||||
@@ -305,6 +305,22 @@ impl ExecutionLoop {
|
||||
.await;
|
||||
}
|
||||
let _ = &orch_result.tokens_used;
|
||||
|
||||
// Safety net: if the orchestrator returned NeedApproval but
|
||||
// didn't transition to Waiting, do it now so resume_thread works.
|
||||
if matches!(orch_result.outcome, ThreadOutcome::NeedApproval { .. })
|
||||
&& self.thread.state != ThreadState::Waiting
|
||||
{
|
||||
debug!(
|
||||
thread_id = %self.thread.id,
|
||||
state = ?self.thread.state,
|
||||
"orchestrator returned NeedApproval without transitioning to Waiting"
|
||||
);
|
||||
let _ = self
|
||||
.thread
|
||||
.transition_to(ThreadState::Waiting, Some("approval needed".into()));
|
||||
}
|
||||
|
||||
self.clear_runtime_checkpoint();
|
||||
self.persist_runtime_state(None, &mut persisted_event_count)
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user