import hashlib import json import time from aider.dump import dump # noqa: F401 from aider.exceptions import LiteLLMExceptions from aider.llm import litellm # from diskcache import Cache CACHE_PATH = "~/.aider.send.cache.v1" CACHE = None # CACHE = Cache(CACHE_PATH) RETRY_TIMEOUT = 60 def send_completion( model_name, messages, functions, stream, temperature=0, extra_params=None, ): kwargs = dict( model=model_name, messages=messages, stream=stream, ) if temperature is not None: kwargs["temperature"] = temperature if functions is not None: function = functions[0] kwargs["tools"] = [dict(type="function", function=function)] kwargs["tool_choice"] = {"type": "function", "function": {"name": function["name"]}} if extra_params is not None: kwargs.update(extra_params) key = json.dumps(kwargs, sort_keys=True).encode() # Generate SHA1 hash of kwargs and append it to chat_completion_call_hashes hash_object = hashlib.sha1(key) if not stream and CACHE is not None and key in CACHE: return hash_object, CACHE[key] res = litellm.completion(**kwargs) if not stream and CACHE is not None: CACHE[key] = res return hash_object, res def simple_send_with_retries(model_name, messages, extra_params=None): litellm_ex = LiteLLMExceptions() retry_delay = 0.125 while True: try: kwargs = { "model_name": model_name, "messages": messages, "functions": None, "stream": False, "extra_params": extra_params, } _hash, response = send_completion(**kwargs) if not response or not hasattr(response, "choices") or not response.choices: return None return response.choices[0].message.content except litellm_ex.exceptions_tuple() as err: ex_info = litellm_ex.get_ex_info(err) print(str(err)) if ex_info.description: print(ex_info.description) should_retry = ex_info.retry if should_retry: retry_delay *= 2 if retry_delay > RETRY_TIMEOUT: should_retry = False if not should_retry: return None print(f"Retrying in {retry_delay:.1f} seconds...") time.sleep(retry_delay) continue except AttributeError: return None