mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-30 17:24:59 +00:00
Merge branch 'main' into async
This commit is contained in:
commit
4abb2e78b6
3 changed files with 41 additions and 55 deletions
|
@ -30,7 +30,7 @@ from aider.llm import litellm
|
|||
from aider.mdstream import MarkdownStream
|
||||
from aider.repo import GitRepo
|
||||
from aider.repomap import RepoMap
|
||||
from aider.sendchat import send_with_retries
|
||||
from aider.sendchat import retry_exceptions, send_completion
|
||||
from aider.utils import format_content, format_messages, is_image_file
|
||||
|
||||
from ..dump import dump # noqa: F401
|
||||
|
@ -70,6 +70,7 @@ class Coder:
|
|||
lint_outcome = None
|
||||
test_outcome = None
|
||||
multi_response_content = ""
|
||||
partial_response_content = ""
|
||||
|
||||
partial_response_content = None
|
||||
|
||||
|
@ -895,6 +896,8 @@ class Coder:
|
|||
else:
|
||||
self.mdstream = None
|
||||
|
||||
retry_delay = 0.125
|
||||
|
||||
self.usage_report = None
|
||||
exhausted = False
|
||||
interrupted = False
|
||||
|
@ -903,6 +906,14 @@ class Coder:
|
|||
try:
|
||||
yield from self.send(messages, functions=self.functions)
|
||||
break
|
||||
except retry_exceptions() as err:
|
||||
self.io.tool_error(str(err))
|
||||
retry_delay *= 2
|
||||
if retry_delay > 60:
|
||||
break
|
||||
self.io.tool_output(f"Retrying in {retry_delay:.1f} seconds...")
|
||||
time.sleep(retry_delay)
|
||||
continue
|
||||
except KeyboardInterrupt:
|
||||
interrupted = True
|
||||
break
|
||||
|
@ -1165,7 +1176,7 @@ class Coder:
|
|||
|
||||
interrupted = False
|
||||
try:
|
||||
hash_object, completion = send_with_retries(
|
||||
hash_object, completion = send_completion(
|
||||
model.name,
|
||||
messages,
|
||||
functions,
|
||||
|
|
|
@ -14,53 +14,28 @@ CACHE = None
|
|||
# CACHE = Cache(CACHE_PATH)
|
||||
|
||||
|
||||
def retry_exceptions():
|
||||
import httpx
|
||||
|
||||
return (
|
||||
httpx.ConnectError,
|
||||
httpx.RemoteProtocolError,
|
||||
httpx.ReadTimeout,
|
||||
litellm.exceptions.APIConnectionError,
|
||||
litellm.exceptions.APIError,
|
||||
litellm.exceptions.RateLimitError,
|
||||
litellm.exceptions.ServiceUnavailableError,
|
||||
litellm.exceptions.Timeout,
|
||||
litellm.exceptions.InternalServerError,
|
||||
litellm.llms.anthropic.AnthropicError,
|
||||
)
|
||||
|
||||
|
||||
def lazy_litellm_retry_decorator(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
import httpx
|
||||
|
||||
def should_giveup(e):
|
||||
if not hasattr(e, "status_code"):
|
||||
return False
|
||||
|
||||
if type(e) in (
|
||||
httpx.ConnectError,
|
||||
httpx.RemoteProtocolError,
|
||||
httpx.ReadTimeout,
|
||||
litellm.exceptions.APIConnectionError,
|
||||
litellm.exceptions.APIError,
|
||||
litellm.exceptions.RateLimitError,
|
||||
litellm.exceptions.ServiceUnavailableError,
|
||||
litellm.exceptions.Timeout,
|
||||
litellm.exceptions.InternalServerError,
|
||||
litellm.llms.anthropic.AnthropicError,
|
||||
):
|
||||
return False
|
||||
|
||||
# These seem to return .status_code = ""
|
||||
# litellm._should_retry() expects an int and throws a TypeError
|
||||
#
|
||||
# litellm.llms.anthropic.AnthropicError
|
||||
# litellm.exceptions.APIError
|
||||
if not e.status_code:
|
||||
return False
|
||||
|
||||
return not litellm._should_retry(e.status_code)
|
||||
|
||||
decorated_func = backoff.on_exception(
|
||||
backoff.expo,
|
||||
(
|
||||
httpx.ConnectError,
|
||||
httpx.RemoteProtocolError,
|
||||
httpx.ReadTimeout,
|
||||
litellm.exceptions.APIConnectionError,
|
||||
litellm.exceptions.APIError,
|
||||
litellm.exceptions.RateLimitError,
|
||||
litellm.exceptions.ServiceUnavailableError,
|
||||
litellm.exceptions.Timeout,
|
||||
litellm.exceptions.InternalServerError,
|
||||
litellm.llms.anthropic.AnthropicError,
|
||||
),
|
||||
giveup=should_giveup,
|
||||
retry_exceptions(),
|
||||
max_time=60,
|
||||
on_backoff=lambda details: print(
|
||||
f"{details.get('exception', 'Exception')}\nRetry in {details['wait']:.1f} seconds."
|
||||
|
@ -71,8 +46,7 @@ def lazy_litellm_retry_decorator(func):
|
|||
return wrapper
|
||||
|
||||
|
||||
@lazy_litellm_retry_decorator
|
||||
def send_with_retries(
|
||||
def send_completion(
|
||||
model_name, messages, functions, stream, temperature=0, extra_headers=None, max_tokens=None
|
||||
):
|
||||
from aider.llm import litellm
|
||||
|
@ -108,9 +82,10 @@ def send_with_retries(
|
|||
return hash_object, res
|
||||
|
||||
|
||||
@lazy_litellm_retry_decorator
|
||||
def simple_send_with_retries(model_name, messages):
|
||||
try:
|
||||
_hash, response = send_with_retries(
|
||||
_hash, response = send_completion(
|
||||
model_name=model_name,
|
||||
messages=messages,
|
||||
functions=None,
|
||||
|
|
|
@ -4,7 +4,7 @@ from unittest.mock import MagicMock, patch
|
|||
import httpx
|
||||
|
||||
from aider.llm import litellm
|
||||
from aider.sendchat import send_with_retries
|
||||
from aider.sendchat import simple_send_with_retries
|
||||
|
||||
|
||||
class PrintCalled(Exception):
|
||||
|
@ -14,7 +14,7 @@ class PrintCalled(Exception):
|
|||
class TestSendChat(unittest.TestCase):
|
||||
@patch("litellm.completion")
|
||||
@patch("builtins.print")
|
||||
def test_send_with_retries_rate_limit_error(self, mock_print, mock_completion):
|
||||
def test_simple_send_with_retries_rate_limit_error(self, mock_print, mock_completion):
|
||||
mock = MagicMock()
|
||||
mock.status_code = 500
|
||||
|
||||
|
@ -29,19 +29,19 @@ class TestSendChat(unittest.TestCase):
|
|||
None,
|
||||
]
|
||||
|
||||
# Call the send_with_retries method
|
||||
send_with_retries("model", ["message"], None, False)
|
||||
# Call the simple_send_with_retries method
|
||||
simple_send_with_retries("model", ["message"])
|
||||
mock_print.assert_called_once()
|
||||
|
||||
@patch("litellm.completion")
|
||||
@patch("builtins.print")
|
||||
def test_send_with_retries_connection_error(self, mock_print, mock_completion):
|
||||
def test_simple_send_with_retries_connection_error(self, mock_print, mock_completion):
|
||||
# Set up the mock to raise
|
||||
mock_completion.side_effect = [
|
||||
httpx.ConnectError("Connection error"),
|
||||
None,
|
||||
]
|
||||
|
||||
# Call the send_with_retries method
|
||||
send_with_retries("model", ["message"], None, False)
|
||||
# Call the simple_send_with_retries method
|
||||
simple_send_with_retries("model", ["message"])
|
||||
mock_print.assert_called_once()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue