From 6671d7ed57e3c94830b8d34bc55fefa0a9f8c360 Mon Sep 17 00:00:00 2001 From: Jakob Berg Date: Mon, 24 Nov 2025 20:54:05 -0500 Subject: [PATCH] fix: make concurrent tools work --- .../integrations/strands/session_manager.py | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/src/bedrock_agentcore/memory/integrations/strands/session_manager.py b/src/bedrock_agentcore/memory/integrations/strands/session_manager.py index d77db53..8046129 100644 --- a/src/bedrock_agentcore/memory/integrations/strands/session_manager.py +++ b/src/bedrock_agentcore/memory/integrations/strands/session_manager.py @@ -4,7 +4,7 @@ import logging import threading from concurrent.futures import ThreadPoolExecutor, as_completed -from datetime import datetime, timedelta, timezone +from datetime import datetime, timezone from typing import TYPE_CHECKING, Any, Optional import boto3 @@ -48,38 +48,6 @@ class AgentCoreMemorySessionManager(RepositorySessionManager, SessionRepository) - Consistent with existing Strands Session managers (such as: FileSessionManager, S3SessionManager) """ - # Class-level timestamp tracking for monotonic ordering - _timestamp_lock = threading.Lock() - _last_timestamp: Optional[datetime] = None - - @classmethod - def _get_monotonic_timestamp(cls, desired_timestamp: Optional[datetime] = None) -> datetime: - """Get a monotonically increasing timestamp. - - Args: - desired_timestamp (Optional[datetime]): The desired timestamp. If None, uses current time. - - Returns: - datetime: A timestamp guaranteed to be greater than any previously returned timestamp. - """ - if desired_timestamp is None: - desired_timestamp = datetime.now(timezone.utc) - - with cls._timestamp_lock: - if cls._last_timestamp is None: - cls._last_timestamp = desired_timestamp - return desired_timestamp - - # Why the 1 second check? Because Boto3 does NOT support sub 1 second resolution. - if desired_timestamp <= cls._last_timestamp + timedelta(seconds=1): - # Increment by 1 second to ensure ordering - new_timestamp = cls._last_timestamp + timedelta(seconds=1) - else: - new_timestamp = desired_timestamp - - cls._last_timestamp = new_timestamp - return new_timestamp - def __init__( self, agentcore_memory_config: AgentCoreMemoryConfig, @@ -183,7 +151,7 @@ def create_session(self, session: Session, **kwargs: Any) -> Session: payload=[ {"blob": json.dumps(session.to_dict())}, ], - eventTimestamp=self._get_monotonic_timestamp(), + eventTimestamp=datetime.now(timezone.utc), ) logger.info("Created session: %s with event: %s", session.session_id, event.get("event", {}).get("eventId")) return session @@ -254,7 +222,7 @@ def create_agent(self, session_id: str, session_agent: SessionAgent, **kwargs: A payload=[ {"blob": json.dumps(session_agent.to_dict())}, ], - eventTimestamp=self._get_monotonic_timestamp(), + eventTimestamp=datetime.now(timezone.utc), ) logger.info( "Created agent: %s in session: %s with event %s", @@ -355,16 +323,14 @@ def create_message( return # Parse the original timestamp and use it as desired timestamp - original_timestamp = datetime.fromisoformat(session_message.created_at.replace("Z", "+00:00")) - monotonic_timestamp = self._get_monotonic_timestamp(original_timestamp) - + event_time = datetime.fromisoformat(session_message.created_at.replace("Z", "+00:00")) if not AgentCoreMemoryConverter.exceeds_conversational_limit(messages[0]): event = self.memory_client.create_event( memory_id=self.config.memory_id, actor_id=self.config.actor_id, session_id=session_id, messages=messages, - event_timestamp=monotonic_timestamp, + event_timestamp=event_time, ) else: event = self.memory_client.gmdp_client.create_event( @@ -374,7 +340,7 @@ def create_message( payload=[ {"blob": json.dumps(messages[0])}, ], - eventTimestamp=monotonic_timestamp, + eventTimestamp=event_time, ) logger.debug("Created event: %s for message: %s", event.get("eventId"), session_message.message_id) return event