Symptom
Two related workflow-engine problems observed together:
- Run sticks in
running forever: run_agent_step waits for terminal status completed, but some providers legitimately settle at idle after answering (observed with a codex worker). The step's wait never resolves; the run record stays running indefinitely.
workflow cancel doesn't actually cancel: the cancel call returns success, but the run record remains running — cancellation is cooperative and never interrupts the in-flight status wait from (1), so a stuck run cannot be killed through the API.
Repro
Local run id u4-eval-yaml-1783615980 (2026-07-09): a one-step workflow whose agent finished its answer and settled idle; run stayed running; cancel reported success; record still running afterward.
Root cause pointer
run_agent_step completion condition: waits on completed only, while provider status machines can finish a turn at idle.
- Cancel path: sets a cooperative flag but the blocked
wait_until_status in the step task is never interrupted, so the terminal state transition to cancelled is unreachable for exactly the runs that need it.
Suggested direction
Accept idle (post-input) as a step-completion signal alongside completed, and make cancel interrupt the in-flight wait (cancel the asyncio task or add a cancellation event to the wait loop) so the run record converges.
Symptom
Two related workflow-engine problems observed together:
runningforever:run_agent_stepwaits for terminal statuscompleted, but some providers legitimately settle atidleafter answering (observed with a codex worker). The step's wait never resolves; the run record staysrunningindefinitely.workflow canceldoesn't actually cancel: the cancel call returns success, but the run record remainsrunning— cancellation is cooperative and never interrupts the in-flight status wait from (1), so a stuck run cannot be killed through the API.Repro
Local run id
u4-eval-yaml-1783615980(2026-07-09): a one-step workflow whose agent finished its answer and settledidle; run stayedrunning; cancel reported success; record stillrunningafterward.Root cause pointer
run_agent_stepcompletion condition: waits oncompletedonly, while provider status machines can finish a turn atidle.wait_until_statusin the step task is never interrupted, so the terminal state transition tocancelledis unreachable for exactly the runs that need it.Suggested direction
Accept
idle(post-input) as a step-completion signal alongsidecompleted, and make cancel interrupt the in-flight wait (cancel the asyncio task or add a cancellation event to the wait loop) so the run record converges.