1212
1313from .._async import run_async
1414from ..agent import AgentResult
15- from ..types . content import ContentBlock
15+ from ..interrupt import Interrupt
1616from ..types .event_loop import Metrics , Usage
17+ from ..types .multiagent import MultiAgentInput
1718
1819logger = logging .getLogger (__name__ )
1920
2021
2122class Status (Enum ):
22- """Execution status for both graphs and nodes."""
23+ """Execution status for both graphs and nodes.
24+
25+ Attributes:
26+ PENDING: Task has not started execution yet.
27+ EXECUTING: Task is currently running.
28+ COMPLETED: Task finished successfully.
29+ FAILED: Task encountered an error and could not complete.
30+ INTERRUPTED: Task was interrupted by user.
31+ """
2332
2433 PENDING = "pending"
2534 EXECUTING = "executing"
2635 COMPLETED = "completed"
2736 FAILED = "failed"
37+ INTERRUPTED = "interrupted"
2838
2939
3040@dataclass
3141class NodeResult :
32- """Unified result from node execution - handles both Agent and nested MultiAgentBase results.
33-
34- The status field represents the semantic outcome of the node's work:
35- - COMPLETED: The node's task was successfully accomplished
36- - FAILED: The node's task failed or produced an error
37- """
42+ """Unified result from node execution - handles both Agent and nested MultiAgentBase results."""
3843
3944 # Core result data - single AgentResult, nested MultiAgentResult, or Exception
4045 result : Union [AgentResult , "MultiAgentResult" , Exception ]
@@ -47,6 +52,7 @@ class NodeResult:
4752 accumulated_usage : Usage = field (default_factory = lambda : Usage (inputTokens = 0 , outputTokens = 0 , totalTokens = 0 ))
4853 accumulated_metrics : Metrics = field (default_factory = lambda : Metrics (latencyMs = 0 ))
4954 execution_count : int = 0
55+ interrupts : list [Interrupt ] = field (default_factory = list )
5056
5157 def get_agent_results (self ) -> list [AgentResult ]:
5258 """Get all AgentResult objects from this node, flattened if nested."""
@@ -78,6 +84,7 @@ def to_dict(self) -> dict[str, Any]:
7884 "accumulated_usage" : self .accumulated_usage ,
7985 "accumulated_metrics" : self .accumulated_metrics ,
8086 "execution_count" : self .execution_count ,
87+ "interrupts" : [interrupt .to_dict () for interrupt in self .interrupts ],
8188 }
8289
8390 @classmethod
@@ -99,6 +106,10 @@ def from_dict(cls, data: dict[str, Any]) -> "NodeResult":
99106
100107 usage = _parse_usage (data .get ("accumulated_usage" , {}))
101108 metrics = _parse_metrics (data .get ("accumulated_metrics" , {}))
109+
110+ interrupts = []
111+ for interrupt_data in data .get ("interrupts" , []):
112+ interrupts .append (Interrupt .from_dict (interrupt_data ))
102113
103114 return cls (
104115 result = result ,
@@ -107,24 +118,21 @@ def from_dict(cls, data: dict[str, Any]) -> "NodeResult":
107118 accumulated_usage = usage ,
108119 accumulated_metrics = metrics ,
109120 execution_count = int (data .get ("execution_count" , 0 )),
121+ interrupts = interrupts ,
110122 )
111123
112124
113125@dataclass
114126class MultiAgentResult :
115- """Result from multi-agent execution with accumulated metrics.
116-
117- The status field represents the outcome of the MultiAgentBase execution:
118- - COMPLETED: The execution was successfully accomplished
119- - FAILED: The execution failed or produced an error
120- """
127+ """Result from multi-agent execution with accumulated metrics."""
121128
122129 status : Status = Status .PENDING
123130 results : dict [str , NodeResult ] = field (default_factory = lambda : {})
124131 accumulated_usage : Usage = field (default_factory = lambda : Usage (inputTokens = 0 , outputTokens = 0 , totalTokens = 0 ))
125132 accumulated_metrics : Metrics = field (default_factory = lambda : Metrics (latencyMs = 0 ))
126133 execution_count : int = 0
127134 execution_time : int = 0
135+ interrupts : list [Interrupt ] = field (default_factory = list )
128136
129137 @classmethod
130138 def from_dict (cls , data : dict [str , Any ]) -> "MultiAgentResult" :
@@ -136,13 +144,18 @@ def from_dict(cls, data: dict[str, Any]) -> "MultiAgentResult":
136144 usage = _parse_usage (data .get ("accumulated_usage" , {}))
137145 metrics = _parse_metrics (data .get ("accumulated_metrics" , {}))
138146
147+ interrupts = []
148+ for interrupt_data in data .get ("interrupts" , []):
149+ interrupts .append (Interrupt .from_dict (interrupt_data ))
150+
139151 multiagent_result = cls (
140152 status = Status (data ["status" ]),
141153 results = results ,
142154 accumulated_usage = usage ,
143155 accumulated_metrics = metrics ,
144156 execution_count = int (data .get ("execution_count" , 0 )),
145157 execution_time = int (data .get ("execution_time" , 0 )),
158+ interrupts = interrupts ,
146159 )
147160 return multiagent_result
148161
@@ -156,6 +169,7 @@ def to_dict(self) -> dict[str, Any]:
156169 "accumulated_metrics" : self .accumulated_metrics ,
157170 "execution_count" : self .execution_count ,
158171 "execution_time" : self .execution_time ,
172+ "interrupts" : [interrupt .to_dict () for interrupt in self .interrupts ],
159173 }
160174
161175
@@ -173,7 +187,7 @@ class MultiAgentBase(ABC):
173187
174188 @abstractmethod
175189 async def invoke_async (
176- self , task : str | list [ ContentBlock ] , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
190+ self , task : MultiAgentInput , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
177191 ) -> MultiAgentResult :
178192 """Invoke asynchronously.
179193
@@ -186,7 +200,7 @@ async def invoke_async(
186200 raise NotImplementedError ("invoke_async not implemented" )
187201
188202 async def stream_async (
189- self , task : str | list [ ContentBlock ] , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
203+ self , task : MultiAgentInput , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
190204 ) -> AsyncIterator [dict [str , Any ]]:
191205 """Stream events during multi-agent execution.
192206
@@ -211,7 +225,7 @@ async def stream_async(
211225 yield {"result" : result }
212226
213227 def __call__ (
214- self , task : str | list [ ContentBlock ] , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
228+ self , task : MultiAgentInput , invocation_state : dict [str , Any ] | None = None , ** kwargs : Any
215229 ) -> MultiAgentResult :
216230 """Invoke synchronously.
217231
0 commit comments