Skip to content

Commit 95d9952

Browse files
mjschockclaude
andcommitted
feat: add to_state() method to RunResult for resuming runs
This commit adds a method to convert a RunResult back into a RunState, enabling the resume workflow for interrupted runs. **Changes:** 1. **to_state() Method** (result.py:125-165) - Added method to RunResult class - Creates a new RunState from the result's data - Populates generated_items, model_responses, and guardrail results - Includes comprehensive docstring with usage example **How to Use:** ```python # Run agent until it needs approval result = await Runner.run(agent, "Use the delete_file tool") if result.interruptions: # Convert result to state state = result.to_state() # Approve the tool call state.approve(result.interruptions[0]) # Resume the run result = await Runner.run(agent, state) ``` **Complete HITL Flow:** 1. Run agent with tool that needs_approval=True 2. Run pauses, returns RunResult with interruptions 3. User calls result.to_state() to get RunState 4. User calls state.approve() or state.reject() 5. User passes state back to Runner.run() to resume 6. Run continues from where it left off **Remaining Work:** - Add comprehensive tests - Create example demonstrating HITL - Add documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent d7136af commit 95d9952

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/agents/result.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,48 @@ def _release_last_agent_reference(self) -> None:
175175
# Preserve dataclass field so repr/asdict continue to succeed.
176176
self.__dict__["_last_agent"] = None
177177

178+
def to_state(self) -> Any:
179+
"""Create a RunState from this result to resume execution.
180+
181+
This is useful when the run was interrupted (e.g., for tool approval). You can
182+
approve or reject the tool calls on the returned state, then pass it back to
183+
`Runner.run()` to continue execution.
184+
185+
Returns:
186+
A RunState that can be used to resume the run.
187+
188+
Example:
189+
```python
190+
# Run agent until it needs approval
191+
result = await Runner.run(agent, "Use the delete_file tool")
192+
193+
if result.interruptions:
194+
# Approve the tool call
195+
state = result.to_state()
196+
state.approve(result.interruptions[0])
197+
198+
# Resume the run
199+
result = await Runner.run(agent, state)
200+
```
201+
"""
202+
from .run_state import RunState
203+
204+
# Create a RunState from the current result
205+
state = RunState(
206+
context=self.context_wrapper,
207+
original_input=self.input,
208+
starting_agent=self.last_agent,
209+
max_turns=10, # This will be overridden by the runner
210+
)
211+
212+
# Populate the state with data from the result
213+
state._generated_items = self.new_items
214+
state._model_responses = self.raw_responses
215+
state._input_guardrail_results = self.input_guardrail_results
216+
state._output_guardrail_results = self.output_guardrail_results
217+
218+
return state
219+
178220
def __str__(self) -> str:
179221
return pretty_print_result(self)
180222

0 commit comments

Comments
 (0)