mirror of
https://github.com/Aider-AI/aider.git
synced 2025-05-24 14:25:00 +00:00
Handle retries at a higher level; exceptions come out of the streaming completion object
This commit is contained in:
parent
17c13da008
commit
3f6ae4b2d9
2 changed files with 33 additions and 48 deletions
|
@ -30,7 +30,7 @@ from aider.llm import litellm
|
||||||
from aider.mdstream import MarkdownStream
|
from aider.mdstream import MarkdownStream
|
||||||
from aider.repo import GitRepo
|
from aider.repo import GitRepo
|
||||||
from aider.repomap import RepoMap
|
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 aider.utils import format_content, format_messages, is_image_file
|
||||||
|
|
||||||
from ..dump import dump # noqa: F401
|
from ..dump import dump # noqa: F401
|
||||||
|
@ -891,6 +891,8 @@ class Coder:
|
||||||
else:
|
else:
|
||||||
self.mdstream = None
|
self.mdstream = None
|
||||||
|
|
||||||
|
retry_delay = 0.125
|
||||||
|
|
||||||
self.usage_report = None
|
self.usage_report = None
|
||||||
exhausted = False
|
exhausted = False
|
||||||
interrupted = False
|
interrupted = False
|
||||||
|
@ -899,6 +901,14 @@ class Coder:
|
||||||
try:
|
try:
|
||||||
yield from self.send(messages, functions=self.functions)
|
yield from self.send(messages, functions=self.functions)
|
||||||
break
|
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:
|
except KeyboardInterrupt:
|
||||||
interrupted = True
|
interrupted = True
|
||||||
break
|
break
|
||||||
|
@ -1161,7 +1171,7 @@ class Coder:
|
||||||
|
|
||||||
interrupted = False
|
interrupted = False
|
||||||
try:
|
try:
|
||||||
hash_object, completion = send_with_retries(
|
hash_object, completion = send_completion(
|
||||||
model.name,
|
model.name,
|
||||||
messages,
|
messages,
|
||||||
functions,
|
functions,
|
||||||
|
|
|
@ -14,53 +14,28 @@ CACHE = None
|
||||||
# CACHE = Cache(CACHE_PATH)
|
# 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 lazy_litellm_retry_decorator(func):
|
||||||
def wrapper(*args, **kwargs):
|
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(
|
decorated_func = backoff.on_exception(
|
||||||
backoff.expo,
|
backoff.expo,
|
||||||
(
|
retry_exceptions(),
|
||||||
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,
|
|
||||||
max_time=60,
|
max_time=60,
|
||||||
on_backoff=lambda details: print(
|
on_backoff=lambda details: print(
|
||||||
f"{details.get('exception', 'Exception')}\nRetry in {details['wait']:.1f} seconds."
|
f"{details.get('exception', 'Exception')}\nRetry in {details['wait']:.1f} seconds."
|
||||||
|
@ -71,8 +46,7 @@ def lazy_litellm_retry_decorator(func):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
@lazy_litellm_retry_decorator
|
def send_completion(
|
||||||
def send_with_retries(
|
|
||||||
model_name, messages, functions, stream, temperature=0, extra_headers=None, max_tokens=None
|
model_name, messages, functions, stream, temperature=0, extra_headers=None, max_tokens=None
|
||||||
):
|
):
|
||||||
from aider.llm import litellm
|
from aider.llm import litellm
|
||||||
|
@ -108,9 +82,10 @@ def send_with_retries(
|
||||||
return hash_object, res
|
return hash_object, res
|
||||||
|
|
||||||
|
|
||||||
|
@lazy_litellm_retry_decorator
|
||||||
def simple_send_with_retries(model_name, messages):
|
def simple_send_with_retries(model_name, messages):
|
||||||
try:
|
try:
|
||||||
_hash, response = send_with_retries(
|
_hash, response = send_completion(
|
||||||
model_name=model_name,
|
model_name=model_name,
|
||||||
messages=messages,
|
messages=messages,
|
||||||
functions=None,
|
functions=None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue