|
2 | 2 | import shutil
|
3 | 3 | import sys
|
4 | 4 | from collections.abc import Generator, Iterator
|
| 5 | +from functools import wraps |
| 6 | +from time import sleep |
5 | 7 |
|
| 8 | +import anthropic |
6 | 9 | from anthropic import Anthropic
|
7 | 10 | from openai import AzureOpenAI, OpenAI
|
8 | 11 | from rich import print
|
@@ -88,6 +91,24 @@ def _chat_complete_openai(messages: list[Message], model: str) -> str:
|
88 | 91 | return content
|
89 | 92 |
|
90 | 93 |
|
| 94 | +def retry_anthropic(func): |
| 95 | + @wraps(func) |
| 96 | + def wrapper(*args, _retries=0, **kwargs): |
| 97 | + try: |
| 98 | + return func(*args, **kwargs) |
| 99 | + except anthropic.RateLimitError: |
| 100 | + if _retries >= 5: |
| 101 | + raise |
| 102 | + # exponential backoff |
| 103 | + backoff = 5 + 2**_retries |
| 104 | + print(f"Rate limit exceeded. Retrying in {backoff} seconds...") |
| 105 | + sleep(backoff) |
| 106 | + return wrapper(*args, **kwargs, _retries=_retries + 1) |
| 107 | + |
| 108 | + return wrapper |
| 109 | + |
| 110 | + |
| 111 | +@retry_anthropic |
91 | 112 | def _chat_complete_anthropic(messages: list[Message], model: str) -> str:
|
92 | 113 | assert anthropic_client, "LLM not initialized"
|
93 | 114 | messages, system_message = _transform_system_messages_anthropic(messages)
|
@@ -179,6 +200,7 @@ def _stream_openai(messages: list[Message], model: str) -> Generator[str, None,
|
179 | 200 | logger.debug(f"Stop reason: {stop_reason}")
|
180 | 201 |
|
181 | 202 |
|
| 203 | +@retry_anthropic |
182 | 204 | def _stream_anthropic(
|
183 | 205 | messages: list[Message], model: str
|
184 | 206 | ) -> Generator[str, None, None]:
|
|
0 commit comments