Spaces:
Sleeping
Sleeping
from __future__ import annotations | |
import time | |
from ast import List | |
import openai | |
from colorama import Fore, Style | |
from openai.error import APIError, RateLimitError | |
from autogpt.config import Config | |
from autogpt.logs import logger | |
CFG = Config() | |
openai.api_key = CFG.openai_api_key | |
def call_ai_function( | |
function: str, args: list, description: str, model: str | None = None | |
) -> str: | |
"""Call an AI function | |
This is a magic function that can do anything with no-code. See | |
https://github.com/Torantulino/AI-Functions for more info. | |
Args: | |
function (str): The function to call | |
args (list): The arguments to pass to the function | |
description (str): The description of the function | |
model (str, optional): The model to use. Defaults to None. | |
Returns: | |
str: The response from the function | |
""" | |
if model is None: | |
model = CFG.smart_llm_model | |
# For each arg, if any are None, convert to "None": | |
args = [str(arg) if arg is not None else "None" for arg in args] | |
# parse args to comma separated string | |
args = ", ".join(args) | |
messages = [ | |
{ | |
"role": "system", | |
"content": f"You are now the following python function: ```# {description}" | |
f"\n{function}```\n\nOnly respond with your `return` value.", | |
}, | |
{"role": "user", "content": args}, | |
] | |
return create_chat_completion(model=model, messages=messages, temperature=0) | |
# Overly simple abstraction until we create something better | |
# simple retry mechanism when getting a rate error or a bad gateway | |
def create_chat_completion( | |
messages: list, # type: ignore | |
model: str | None = None, | |
temperature: float = CFG.temperature, | |
max_tokens: int | None = None, | |
) -> str: | |
"""Create a chat completion using the OpenAI API | |
Args: | |
messages (list[dict[str, str]]): The messages to send to the chat completion | |
model (str, optional): The model to use. Defaults to None. | |
temperature (float, optional): The temperature to use. Defaults to 0.9. | |
max_tokens (int, optional): The max tokens to use. Defaults to None. | |
Returns: | |
str: The response from the chat completion | |
""" | |
response = None | |
num_retries = 10 | |
warned_user = False | |
if CFG.debug_mode: | |
print( | |
Fore.GREEN | |
+ f"Creating chat completion with model {model}, temperature {temperature}," | |
f" max_tokens {max_tokens}" + Fore.RESET | |
) | |
for attempt in range(num_retries): | |
backoff = 2 ** (attempt + 2) | |
try: | |
if CFG.use_azure: | |
response = openai.ChatCompletion.create( | |
deployment_id=CFG.get_azure_deployment_id_for_model(model), | |
model=model, | |
messages=messages, | |
temperature=temperature, | |
max_tokens=max_tokens, | |
) | |
else: | |
response = openai.ChatCompletion.create( | |
model=model, | |
messages=messages, | |
temperature=temperature, | |
max_tokens=max_tokens, | |
) | |
break | |
except RateLimitError: | |
if CFG.debug_mode: | |
print( | |
Fore.RED + "Error: ", | |
f"Reached rate limit, passing..." + Fore.RESET, | |
) | |
if not warned_user: | |
logger.double_check( | |
f"Please double check that you have setup a {Fore.CYAN + Style.BRIGHT}PAID{Style.RESET_ALL} OpenAI API Account. " | |
+ f"You can read more here: {Fore.CYAN}https://github.com/Significant-Gravitas/Auto-GPT#openai-api-keys-configuration{Fore.RESET}" | |
) | |
warned_user = True | |
except APIError as e: | |
if e.http_status == 502: | |
pass | |
else: | |
raise | |
if attempt == num_retries - 1: | |
raise | |
if CFG.debug_mode: | |
print( | |
Fore.RED + "Error: ", | |
f"API Bad gateway. Waiting {backoff} seconds..." + Fore.RESET, | |
) | |
time.sleep(backoff) | |
if response is None: | |
logger.typewriter_log( | |
"FAILED TO GET RESPONSE FROM OPENAI", | |
Fore.RED, | |
"Auto-GPT has failed to get a response from OpenAI's services. " | |
+ f"Try running Auto-GPT again, and if the problem the persists try running it with `{Fore.CYAN}--debug{Fore.RESET}`.", | |
) | |
logger.double_check() | |
if CFG.debug_mode: | |
raise RuntimeError(f"Failed to get response after {num_retries} retries") | |
else: | |
quit(1) | |
return response.choices[0].message["content"] | |
def create_embedding_with_ada(text) -> list: | |
"""Create an embedding with text-ada-002 using the OpenAI SDK""" | |
num_retries = 10 | |
for attempt in range(num_retries): | |
backoff = 2 ** (attempt + 2) | |
try: | |
if CFG.use_azure: | |
return openai.Embedding.create( | |
input=[text], | |
engine=CFG.get_azure_deployment_id_for_model( | |
"text-embedding-ada-002" | |
), | |
)["data"][0]["embedding"] | |
else: | |
return openai.Embedding.create( | |
input=[text], model="text-embedding-ada-002" | |
)["data"][0]["embedding"] | |
except RateLimitError: | |
pass | |
except APIError as e: | |
if e.http_status == 502: | |
pass | |
else: | |
raise | |
if attempt == num_retries - 1: | |
raise | |
if CFG.debug_mode: | |
print( | |
Fore.RED + "Error: ", | |
f"API Bad gateway. Waiting {backoff} seconds..." + Fore.RESET, | |
) | |
time.sleep(backoff) | |