From c62a0a6da4317497b991f83d4d8561bdbe7292aa Mon Sep 17 00:00:00 2001 From: Jacky W Date: Thu, 29 May 2025 07:44:57 +0400 Subject: [PATCH 1/3] fix: introduce PreciseTimestamp to fix mysql datetime precision issue. --- src/google/adk/sessions/database_session_service.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/google/adk/sessions/database_session_service.py b/src/google/adk/sessions/database_session_service.py index 7c64548b73..f2f4342eb8 100644 --- a/src/google/adk/sessions/database_session_service.py +++ b/src/google/adk/sessions/database_session_service.py @@ -92,6 +92,17 @@ def process_result_value(self, value, dialect: Dialect): return value +class PreciseTimestamp(TypeDecorator): + """Represents a timestamp precise to the microsecond.""" + + impl = DateTime + + def load_dialect_impl(self, dialect): + if dialect.name == 'mysql': + return dialect.type_descriptor(mysql.DATETIME(fsp=6)) + return self.impl + + class Base(DeclarativeBase): """Base class for database tables.""" @@ -156,7 +167,7 @@ class StorageEvent(Base): branch: Mapped[str] = mapped_column( String(DEFAULT_MAX_VARCHAR_LENGTH), nullable=True ) - timestamp: Mapped[DateTime] = mapped_column(DateTime(), default=func.now()) + timestamp: Mapped[PreciseTimestamp] = mapped_column(PreciseTimestamp, default=func.now()) content: Mapped[dict[str, Any]] = mapped_column(DynamicJSON, nullable=True) actions: Mapped[MutableDict[str, Any]] = mapped_column(PickleType) From 59c0606ac08ddb45ce469a4d1e1c6e515ef94df4 Mon Sep 17 00:00:00 2001 From: Jacky W Date: Thu, 29 May 2025 08:24:16 +0400 Subject: [PATCH 2/3] fix: add cache_ok option to remove sa warning. --- src/google/adk/sessions/database_session_service.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/google/adk/sessions/database_session_service.py b/src/google/adk/sessions/database_session_service.py index f2f4342eb8..fbd25275bd 100644 --- a/src/google/adk/sessions/database_session_service.py +++ b/src/google/adk/sessions/database_session_service.py @@ -96,6 +96,7 @@ class PreciseTimestamp(TypeDecorator): """Represents a timestamp precise to the microsecond.""" impl = DateTime + cache_ok = True def load_dialect_impl(self, dialect): if dialect.name == 'mysql': From 1922599075af935a63544762765d6f0e6224907a Mon Sep 17 00:00:00 2001 From: Jacky W Date: Thu, 29 May 2025 22:17:27 +0400 Subject: [PATCH 3/3] chore: format code. --- src/google/adk/sessions/database_session_service.py | 10 ++++++---- src/google/adk/sessions/vertex_ai_session_service.py | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/google/adk/sessions/database_session_service.py b/src/google/adk/sessions/database_session_service.py index fbd25275bd..4d965deb19 100644 --- a/src/google/adk/sessions/database_session_service.py +++ b/src/google/adk/sessions/database_session_service.py @@ -99,9 +99,9 @@ class PreciseTimestamp(TypeDecorator): cache_ok = True def load_dialect_impl(self, dialect): - if dialect.name == 'mysql': - return dialect.type_descriptor(mysql.DATETIME(fsp=6)) - return self.impl + if dialect.name == "mysql": + return dialect.type_descriptor(mysql.DATETIME(fsp=6)) + return self.impl class Base(DeclarativeBase): @@ -168,7 +168,9 @@ class StorageEvent(Base): branch: Mapped[str] = mapped_column( String(DEFAULT_MAX_VARCHAR_LENGTH), nullable=True ) - timestamp: Mapped[PreciseTimestamp] = mapped_column(PreciseTimestamp, default=func.now()) + timestamp: Mapped[PreciseTimestamp] = mapped_column( + PreciseTimestamp, default=func.now() + ) content: Mapped[dict[str, Any]] = mapped_column(DynamicJSON, nullable=True) actions: Mapped[MutableDict[str, Any]] = mapped_column(PickleType) diff --git a/src/google/adk/sessions/vertex_ai_session_service.py b/src/google/adk/sessions/vertex_ai_session_service.py index 475377fa05..7174967f80 100644 --- a/src/google/adk/sessions/vertex_ai_session_service.py +++ b/src/google/adk/sessions/vertex_ai_session_service.py @@ -188,10 +188,10 @@ async def list_sessions( ) -> ListSessionsResponse: reasoning_engine_id = _parse_reasoning_engine_id(app_name) - path = f"reasoningEngines/{reasoning_engine_id}/sessions" + path = f'reasoningEngines/{reasoning_engine_id}/sessions' if user_id: - parsed_user_id = urllib.parse.quote(f'''"{user_id}"''', safe="") - path = path + f"?filter=user_id={parsed_user_id}" + parsed_user_id = urllib.parse.quote(f'''"{user_id}"''', safe='') + path = path + f'?filter=user_id={parsed_user_id}' api_client = _get_api_client(self.project, self.location) api_response = await api_client.async_request(