tool improvment

This commit is contained in:
serversdwn
2025-12-31 22:36:24 -05:00
parent 6716245a99
commit b700ac3808
10 changed files with 598 additions and 80 deletions

View File

@@ -0,0 +1,5 @@
"""Utility modules for tool executors."""
from .resilience import async_retry, async_timeout_wrapper
__all__ = ["async_retry", "async_timeout_wrapper"]

View File

@@ -0,0 +1,70 @@
"""Common resilience utilities for tool executors."""
import asyncio
import functools
import logging
from typing import Optional, Callable, Any, TypeVar
from tenacity import (
retry,
stop_after_attempt,
wait_exponential,
retry_if_exception_type,
before_sleep_log
)
logger = logging.getLogger(__name__)
# Type variable for generic decorators
T = TypeVar('T')
def async_retry(
max_attempts: int = 3,
exceptions: tuple = (Exception,),
**kwargs
):
"""Async retry decorator with exponential backoff.
Args:
max_attempts: Maximum retry attempts
exceptions: Exception types to retry on
**kwargs: Additional tenacity configuration
Example:
@async_retry(max_attempts=3, exceptions=(aiohttp.ClientError,))
async def fetch_data():
...
"""
return retry(
stop=stop_after_attempt(max_attempts),
wait=wait_exponential(multiplier=1, min=1, max=10),
retry=retry_if_exception_type(exceptions),
reraise=True,
before_sleep=before_sleep_log(logger, logging.WARNING),
**kwargs
)
async def async_timeout_wrapper(
coro: Callable[..., T],
timeout: float,
*args,
**kwargs
) -> T:
"""Wrap async function with timeout.
Args:
coro: Async function to wrap
timeout: Timeout in seconds
*args, **kwargs: Arguments for the function
Returns:
Result from the function
Raises:
asyncio.TimeoutError: If timeout exceeded
Example:
result = await async_timeout_wrapper(some_async_func, 5.0, arg1, arg2)
"""
return await asyncio.wait_for(coro(*args, **kwargs), timeout=timeout)