-
Notifications
You must be signed in to change notification settings - Fork 603
fix(graph): handle cancel_node gracefully without raising exception #1524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Align Graph cancel_node behavior with Swarm by not raising a RuntimeError when a node is cancelled. Instead, handle cancellation gracefully by: - Creating a NodeResult with status=FAILED for the cancelled node - Adding the node to failed_nodes set - Yielding MultiAgentNodeStopEvent for the cancelled node - Returning without exception to allow GraphResult to be yielded Also add a failed_nodes check in _execute_graph to stop execution after a cancellation, preventing downstream nodes from executing. This makes the Graph behavior consistent with Swarm cancel_node handling, where users can cleanly exit without catching RuntimeError.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
/strands Please address lint failures |
NodeResult.result expects AgentResult | MultiAgentResult | Exception, not a string. Wrap the cancel message in an Exception to fix the mypy type error.
|
Fixed the mypy lint error by wrapping Commit: 924a1b3 |
|
/strands Do we need to construct a NodeResult for a cancelled node? Also, do we need to yield MultiAgentNodeStopEvent? |
Simplify the cancel_node handling to match Swarm's approach: - Yield MultiAgentNodeCancelEvent - Set self.state.status = Status.FAILED - Return early (no exception) Remove unnecessary NodeResult construction and MultiAgentNodeStopEvent for cancelled nodes, as Swarm doesn't emit these either. Update the _execute_graph check to use Status.FAILED instead of failed_nodes to stop downstream execution.
|
Simplified the implementation to match Swarm's pattern exactly: Before (over-engineered):
After (matches Swarm): yield MultiAgentNodeCancelEvent(node.node_id, cancel_message)
self.state.status = Status.FAILED
returnThe key insight is that Swarm (lines 750-759) simply:
No Commit: 21d1fa3 |
Motivation
Currently, users can cancel a Graph node execution by setting
event.cancel_node = <STR_MSG|True>within aBeforeNodeCallEventhook. Unlike Swarm, which handles this gracefully by settingstatus = FAILEDand breaking out of the loop, Graph raises aRuntimeErrorthat stops the entire graph execution. This inconsistency forces users to wrap Graph execution in try/catch blocks when intentionally cancelling nodes, which is unnecessary and differs from the Swarm behavior.This change aligns Graph
cancel_nodebehavior with Swarm to provide a clean exit path without exception handling.Resolves #1500
Public API Changes
No public API changes. The behavior change is internal -
cancel_nodestill works the same way, but now exits gracefully:Breaking Changes
This is a breaking change for any code that catches
RuntimeErrorduring graph node cancellation. The existing behavior was inconsistent with Swarm and is considered a bug.Migration