From 91c125bbf250113d46c71167911066fc16b0ae83 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Wed, 19 Nov 2025 09:50:47 -0500 Subject: [PATCH 1/3] interrupt - add responses to context on resume --- src/strands/interrupt.py | 2 ++ src/strands/types/interrupt.py | 17 ++++++++++------- tests/strands/test_interrupt.py | 4 ++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/strands/interrupt.py b/src/strands/interrupt.py index 919927e1a..59473172e 100644 --- a/src/strands/interrupt.py +++ b/src/strands/interrupt.py @@ -104,6 +104,8 @@ def resume(self, prompt: "AgentInput") -> None: self.interrupts[interrupt_id].response = interrupt_response + self.context["responses"] = contents + def to_dict(self) -> dict[str, Any]: """Serialize to dict for session management.""" return asdict(self) diff --git a/src/strands/types/interrupt.py b/src/strands/types/interrupt.py index 001ce6993..59c46e807 100644 --- a/src/strands/types/interrupt.py +++ b/src/strands/types/interrupt.py @@ -71,19 +71,14 @@ def approve(self, event: BeforeToolCallEvent) -> None: - Interrupts are session managed in-between return and user response. """ -from typing import TYPE_CHECKING, Any, Protocol, TypedDict +from typing import Any, Protocol, TypedDict from ..interrupt import Interrupt, InterruptException -if TYPE_CHECKING: - from ..agent import Agent - class _Interruptible(Protocol): """Interface that adds interrupt support to hook events and tools.""" - agent: "Agent" - def interrupt(self, name: str, reason: Any = None, response: Any = None) -> Any: """Trigger the interrupt with a reason. @@ -97,9 +92,17 @@ def interrupt(self, name: str, reason: Any = None, response: Any = None) -> Any: Raises: InterruptException: If human input is required. + RuntimeError: If agent instance attribute not set. """ + for attr_name in ["agent", "source"]: + if hasattr(self, attr_name): + agent = getattr(self, attr_name) + break + else: + raise RuntimeError("agent instance attribute not set") + id = self._interrupt_id(name) - state = self.agent._interrupt_state + state = agent._interrupt_state interrupt_ = state.interrupts.setdefault(id, Interrupt(id, name, reason, response)) if interrupt_.response: diff --git a/tests/strands/test_interrupt.py b/tests/strands/test_interrupt.py index a45d524e4..04ce89d98 100644 --- a/tests/strands/test_interrupt.py +++ b/tests/strands/test_interrupt.py @@ -100,6 +100,10 @@ def test_interrupt_state_resume(): exp_response = "test response" assert tru_response == exp_response + tru_context = interrupt_state.context + exp_context = {"responses": prompt} + assert tru_context == exp_context + def test_interrupt_state_resumse_deactivated(): interrupt_state = _InterruptState(activated=False) From 7d621bf0479d106c91321e3e5cd22476aef5af13 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Wed, 19 Nov 2025 10:05:34 -0500 Subject: [PATCH 2/3] test runtime error --- tests/strands/types/test_interrupt.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/strands/types/test_interrupt.py b/tests/strands/types/test_interrupt.py index ad31384b6..1f8318104 100644 --- a/tests/strands/types/test_interrupt.py +++ b/tests/strands/types/test_interrupt.py @@ -77,3 +77,12 @@ def test_interrupt_hook_event_interrupt_response_empty(interrupt, agent, interru with pytest.raises(InterruptException): interrupt_hook_event.interrupt("test_name") + + +def test_interrupt_hook_event_interrupt_missing_agent(): + class Event(_Interruptible): + pass + + event = Event() + with pytest.raises(RuntimeError, match=f"agent instance attribute not set"): + event.interrupt("test_name") From db5bdb63cc1767771776ef019559000a93d97774 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Wed, 19 Nov 2025 10:48:04 -0500 Subject: [PATCH 3/3] lint --- tests/strands/types/test_interrupt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/strands/types/test_interrupt.py b/tests/strands/types/test_interrupt.py index 1f8318104..9e79a4626 100644 --- a/tests/strands/types/test_interrupt.py +++ b/tests/strands/types/test_interrupt.py @@ -84,5 +84,5 @@ class Event(_Interruptible): pass event = Event() - with pytest.raises(RuntimeError, match=f"agent instance attribute not set"): + with pytest.raises(RuntimeError, match="agent instance attribute not set"): event.interrupt("test_name")