Skip to content

Commit 636ae37

Browse files
authored
fix: ADK 1.20 breaking change. Add retry_on_errors decorator for MCP session retries and fix (#348)
Introduced a new retry_on_errors decorator in utils.py to handle automatic retries on MCP session errors. Updated mcp_tool.py and mcp_toolset.py to use this decorator instead of retry_on_closed_resource, improving error handling and session recovery. fix: ADK 1.20 breaking change on method of sessionmanager
1 parent 768a5e5 commit 636ae37

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

veadk/integrations/ve_identity/mcp_tool.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@
2424
from google.adk.tools.tool_context import ToolContext
2525
from google.adk.tools._gemini_schema_util import _to_gemini_schema
2626
from google.adk.tools.mcp_tool.mcp_session_manager import MCPSessionManager
27-
from google.adk.tools.mcp_tool.mcp_session_manager import retry_on_closed_resource
2827

2928
from veadk.integrations.ve_identity.auth_config import VeIdentityAuthConfig
3029
from veadk.integrations.ve_identity.auth_mixins import (
3130
VeIdentityAuthMixin,
3231
AuthRequiredException,
3332
)
34-
from veadk.integrations.ve_identity.utils import generate_headers
33+
from veadk.integrations.ve_identity.utils import generate_headers, retry_on_errors
3534
from veadk.utils.logger import get_logger
3635

3736
logger = get_logger(__name__)
@@ -157,7 +156,7 @@ async def _execute_with_credential(
157156
args=args, tool_context=tool_context, credential=credential
158157
)
159158

160-
@retry_on_closed_resource
159+
@retry_on_errors
161160
async def _run_async_impl(
162161
self, *, args, tool_context: ToolContext, credential: AuthCredential
163162
):

veadk/integrations/ve_identity/mcp_toolset.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
from mcp.types import ListToolsResult
3030

3131
from google.adk.tools.mcp_tool.mcp_session_manager import (
32-
retry_on_closed_resource,
3332
SseConnectionParams,
3433
StdioConnectionParams,
3534
StreamableHTTPConnectionParams,
@@ -43,7 +42,7 @@
4342
from veadk.integrations.ve_identity.auth_config import VeIdentityAuthConfig
4443
from veadk.integrations.ve_identity.auth_mixins import VeIdentityAuthMixin
4544
from veadk.integrations.ve_identity.mcp_tool import VeIdentityMcpTool
46-
from veadk.integrations.ve_identity.utils import generate_headers
45+
from veadk.integrations.ve_identity.utils import generate_headers, retry_on_errors
4746

4847
logger = logging.getLogger(__name__)
4948

@@ -158,7 +157,7 @@ def __init__(
158157
errlog=errlog,
159158
)
160159

161-
@retry_on_closed_resource
160+
@retry_on_errors
162161
@override
163162
async def get_tools(
164163
self,

veadk/integrations/ve_identity/utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616

1717
from __future__ import annotations
1818
import base64
19+
import functools
1920
from typing import Optional
2021

2122
from google.adk.events import Event
2223
from google.adk.auth import AuthConfig
2324
from google.adk.auth.auth_credential import AuthCredential
2425

26+
from veadk.utils.logger import get_logger
27+
28+
logger = get_logger(__name__)
29+
2530

2631
def is_pending_auth_event(event: Event) -> bool:
2732
"""Check if an ADK event represents a pending authentication request.
@@ -149,3 +154,31 @@ def generate_headers(credential: AuthCredential) -> Optional[dict[str, str]]:
149154
pass
150155

151156
return headers
157+
158+
159+
def retry_on_errors(func):
160+
"""Decorator to automatically retry action when MCP session errors occur.
161+
162+
When MCP session errors occur, the decorator will automatically retry the
163+
action once. The create_session method will handle creating a new session
164+
if the old one was disconnected.
165+
166+
Args:
167+
func: The function to decorate.
168+
169+
Returns:
170+
The decorated function.
171+
"""
172+
173+
@functools.wraps(func) # Preserves original function metadata
174+
async def wrapper(self, *args, **kwargs):
175+
try:
176+
return await func(self, *args, **kwargs)
177+
except Exception as e:
178+
# If an error is thrown, we will retry the function to reconnect to the
179+
# server. create_session will handle detecting and replacing disconnected
180+
# sessions.
181+
logger.info("Retrying %s due to error: %s", func.__name__, e)
182+
return await func(self, *args, **kwargs)
183+
184+
return wrapper

0 commit comments

Comments
 (0)