-
Notifications
You must be signed in to change notification settings - Fork 147
fix(memory): use current Strands bidi session hooks #664
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,11 +11,7 @@ | |
|
|
||
| import boto3 | ||
| from botocore.config import Config as BotocoreConfig | ||
| from strands.experimental.hooks.events import ( | ||
| BidiAfterInvocationEvent, | ||
| BidiAgentInitializedEvent, | ||
| BidiMessageAddedEvent, | ||
| ) | ||
| from strands.experimental.bidi.hooks import BidiAgentStopEvent | ||
| from strands.experimental.hooks.multiagent.events import ( | ||
| AfterMultiAgentInvocationEvent, | ||
| AfterNodeCallEvent, | ||
|
|
@@ -45,7 +41,7 @@ | |
| from .converters import MemoryConverter | ||
|
|
||
| if TYPE_CHECKING: | ||
| from strands.agent.agent import Agent | ||
| from strands.types.agent import LocalAgent | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
@@ -829,7 +825,7 @@ def _filter_restored_tool_context(self, messages: list[SessionMessage]) -> list[ | |
|
|
||
| # region RepositorySessionManager overrides | ||
| @override | ||
| def append_message(self, message: Message, agent: "Agent", **kwargs: Any) -> None: | ||
| def append_message(self, message: Message, agent: "LocalAgent", **kwargs: Any) -> None: | ||
| """Append a message to the agent's session using AgentCore's eventId as message_id. | ||
|
|
||
| Args: | ||
|
|
@@ -951,9 +947,8 @@ def register_hooks(self, registry: HookRegistry, **kwargs) -> None: | |
| return | ||
|
|
||
| # Async mode: register async callbacks that offload the existing sync | ||
| # methods to a worker thread via asyncio.to_thread. AgentInitializedEvent | ||
| # and BidiAgentInitializedEvent must stay sync (Strands disallows async | ||
| # callbacks for AgentInitializedEvent — see strands/hooks/registry.py:227). | ||
| # methods to a worker thread via asyncio.to_thread. Initialization | ||
| # callbacks must stay synchronous. | ||
| logger.warning( | ||
| "AgentCoreMemorySessionManager async_mode=True: the agent must be invoked " | ||
| "via the async path (e.g. agent.stream_async(...) or agent.invoke_async(...)). " | ||
|
|
@@ -990,21 +985,10 @@ async def _on_message_added_persist(event: MessageAddedEvent) -> None: | |
| registry.add_callback(AfterNodeCallEvent, _offload(self.sync_multi_agent, lambda e: e.source)) | ||
| registry.add_callback(AfterMultiAgentInvocationEvent, _offload(self.sync_multi_agent, lambda e: e.source)) | ||
|
|
||
| # Register BidiAgent callbacks so async-mode parity matches sync-mode. | ||
| # BidiAgentInitializedEvent dispatches through invoke_callbacks (sync), | ||
| # so its callback must stay sync; the other two dispatch through | ||
| # invoke_callbacks_async, so async wrappers are safe. | ||
| registry.add_callback(BidiAgentInitializedEvent, lambda event: self.initialize_bidi_agent(event.agent)) | ||
|
|
||
| async def _on_bidi_message_added(event: BidiMessageAddedEvent) -> None: | ||
| await asyncio.to_thread(self.append_bidi_message, event.message, event.agent) | ||
| await asyncio.to_thread(self.sync_bidi_agent, event.agent) | ||
|
|
||
| registry.add_callback(BidiMessageAddedEvent, _on_bidi_message_added) | ||
| registry.add_callback(BidiAfterInvocationEvent, _offload(self.sync_bidi_agent, lambda e: e.agent)) | ||
| registry.add_callback(BidiAgentStopEvent, _offload(self.sync_agent, lambda e: e.agent)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be missing something here, but with batching enabled, doesn’t since Bidi doesn’t fire |
||
|
|
||
| @override | ||
| def initialize(self, agent: "Agent", **kwargs: Any) -> None: | ||
| def initialize(self, agent: "LocalAgent", **kwargs: Any) -> None: | ||
| if self.has_existing_agent: | ||
| logger.warning( | ||
| "An Agent already exists in session %s. We currently support one agent per session.", self.session_id | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that bidi uses
MessageAddedEvent, willretrieve_customer_contextrun for bidi too? It looks like it updatesagent.messages, while the model still receives the original input event. could we skip retrieval for bidi or inject it into the outgoing event?