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,
|
"nudge_count": nudge_count,
|
||||||
"consecutive_errors": consecutive_errors,
|
"consecutive_errors": consecutive_errors,
|
||||||
})
|
})
|
||||||
|
__transition_to__("waiting", "approval needed")
|
||||||
return {
|
return {
|
||||||
"outcome": "need_approval",
|
"outcome": "need_approval",
|
||||||
"action_name": approval.get("action_name", ""),
|
"action_name": approval.get("action_name", ""),
|
||||||
@@ -382,6 +383,7 @@ def run_loop(context, goal, actions, state, config):
|
|||||||
"nudge_count": nudge_count,
|
"nudge_count": nudge_count,
|
||||||
"consecutive_errors": consecutive_errors,
|
"consecutive_errors": consecutive_errors,
|
||||||
})
|
})
|
||||||
|
__transition_to__("waiting", "approval needed")
|
||||||
return {
|
return {
|
||||||
"outcome": "need_approval",
|
"outcome": "need_approval",
|
||||||
"action_name": name,
|
"action_name": name,
|
||||||
|
|||||||
@@ -305,6 +305,22 @@ impl ExecutionLoop {
|
|||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
let _ = &orch_result.tokens_used;
|
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.clear_runtime_checkpoint();
|
||||||
self.persist_runtime_state(None, &mut persisted_event_count)
|
self.persist_runtime_state(None, &mut persisted_event_count)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user