from __future__ import annotations
import asyncio
import json
import requests
from typing import Any, Dict
from ...typing import AsyncResult, Messages
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
from ..helper import format_prompt
class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin):
label = "Nexra ChatGPT"
url = "https://nexra.aryahcr.cc/documentation/chatgpt/en"
api_endpoint_nexra_chatgpt = "https://nexra.aryahcr.cc/api/chat/gpt"
api_endpoint_nexra_chatgpt4o = "https://nexra.aryahcr.cc/api/chat/complements"
api_endpoint_nexra_chatgpt_v2 = "https://nexra.aryahcr.cc/api/chat/complements"
api_endpoint_nexra_gptweb = "https://nexra.aryahcr.cc/api/chat/gptweb"
working = True
supports_system_message = True
supports_message_history = True
supports_stream = True
default_model = 'gpt-3.5-turbo'
nexra_chatgpt = [
'gpt-4', 'gpt-4-0613', 'gpt-4-0314', 'gpt-4-32k-0314',
default_model, 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k-0613', 'gpt-3.5-turbo-0301',
'text-davinci-003', 'text-davinci-002', 'code-davinci-002', 'gpt-3', 'text-curie-001', 'text-babbage-001', 'text-ada-001', 'davinci', 'curie', 'babbage', 'ada', 'babbage-002', 'davinci-002'
]
nexra_chatgpt4o = ['gpt-4o']
nexra_chatgptv2 = ['chatgpt']
nexra_gptweb = ['gptweb']
models = nexra_chatgpt + nexra_chatgpt4o + nexra_chatgptv2 + nexra_gptweb
model_aliases = {
"gpt-4": "gpt-4-0613",
"gpt-4-32k": "gpt-4-32k-0314",
"gpt-3.5-turbo": "gpt-3.5-turbo-16k",
"gpt-3.5-turbo-0613": "gpt-3.5-turbo-16k-0613",
"gpt-3": "text-davinci-003",
"text-davinci-002": "code-davinci-002",
"text-curie-001": "text-babbage-001",
"text-ada-001": "davinci",
"curie": "babbage",
"ada": "babbage-002",
"davinci-002": "davinci-002",
"chatgpt": "chatgpt",
"gptweb": "gptweb"
}
@classmethod
def get_model(cls, model: str) -> str:
if model in cls.models:
return model
elif model in cls.model_aliases:
return cls.model_aliases[model]
else:
return cls.default_model
@classmethod
async def create_async_generator(
cls,
model: str,
messages: Messages,
stream: bool = False,
proxy: str = None,
markdown: bool = False,
**kwargs
) -> AsyncResult:
if model in cls.nexra_chatgpt:
async for chunk in cls._create_async_generator_nexra_chatgpt(model, messages, proxy, **kwargs):
yield chunk
elif model in cls.nexra_chatgpt4o:
async for chunk in cls._create_async_generator_nexra_chatgpt4o(model, messages, stream, proxy, markdown, **kwargs):
yield chunk
elif model in cls.nexra_chatgptv2:
async for chunk in cls._create_async_generator_nexra_chatgpt_v2(model, messages, stream, proxy, markdown, **kwargs):
yield chunk
elif model in cls.nexra_gptweb:
async for chunk in cls._create_async_generator_nexra_gptweb(model, messages, proxy, **kwargs):
yield chunk
@classmethod
async def _create_async_generator_nexra_chatgpt(
cls,
model: str,
messages: Messages,
proxy: str = None,
markdown: bool = False,
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
headers = {
"Content-Type": "application/json"
}
prompt = format_prompt(messages)
data = {
"messages": messages,
"prompt": prompt,
"model": model,
"markdown": markdown
}
loop = asyncio.get_event_loop()
try:
response = await loop.run_in_executor(None, cls._sync_post_request, cls.api_endpoint_nexra_chatgpt, data, headers, proxy)
filtered_response = cls._filter_response(response)
for chunk in filtered_response:
yield chunk
except Exception as e:
print(f"Error during API request (nexra_chatgpt): {e}")
@classmethod
async def _create_async_generator_nexra_chatgpt4o(
cls,
model: str,
messages: Messages,
stream: bool = False,
proxy: str = None,
markdown: bool = False,
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
headers = {
"Content-Type": "application/json"
}
prompt = format_prompt(messages)
data = {
"messages": [
{
"role": "user",
"content": prompt
}
],
"stream": stream,
"markdown": markdown,
"model": model
}
loop = asyncio.get_event_loop()
try:
response = await loop.run_in_executor(None, cls._sync_post_request, cls.api_endpoint_nexra_chatgpt4o, data, headers, proxy, stream)
if stream:
async for chunk in cls._process_streaming_response(response):
yield chunk
else:
for chunk in cls._process_non_streaming_response(response):
yield chunk
except Exception as e:
print(f"Error during API request (nexra_chatgpt4o): {e}")
@classmethod
async def _create_async_generator_nexra_chatgpt_v2(
cls,
model: str,
messages: Messages,
stream: bool = False,
proxy: str = None,
markdown: bool = False,
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
headers = {
"Content-Type": "application/json"
}
prompt = format_prompt(messages)
data = {
"messages": [
{
"role": "user",
"content": prompt
}
],
"stream": stream,
"markdown": markdown,
"model": model
}
loop = asyncio.get_event_loop()
try:
response = await loop.run_in_executor(None, cls._sync_post_request, cls.api_endpoint_nexra_chatgpt_v2, data, headers, proxy, stream)
if stream:
async for chunk in cls._process_streaming_response(response):
yield chunk
else:
for chunk in cls._process_non_streaming_response(response):
yield chunk
except Exception as e:
print(f"Error during API request (nexra_chatgpt_v2): {e}")
@classmethod
async def _create_async_generator_nexra_gptweb(
cls,
model: str,
messages: Messages,
proxy: str = None,
markdown: bool = False,
**kwargs
) -> AsyncResult:
model = cls.get_model(model)
headers = {
"Content-Type": "application/json"
}
prompt = format_prompt(messages)
data = {
"prompt": prompt,
"markdown": markdown,
}
loop = asyncio.get_event_loop()
try:
response = await loop.run_in_executor(None, cls._sync_post_request, cls.api_endpoint_nexra_gptweb, data, headers, proxy)
for chunk in response.iter_content(1024):
if chunk:
decoded_chunk = chunk.decode().lstrip('_')
try:
response_json = json.loads(decoded_chunk)
if response_json.get("status"):
yield response_json.get("gpt", "")
except json.JSONDecodeError:
continue
except Exception as e:
print(f"Error during API request (nexra_gptweb): {e}")
@staticmethod
def _sync_post_request(url: str, data: Dict[str, Any], headers: Dict[str, str], proxy: str = None, stream: bool = False) -> requests.Response:
proxies = {
"http": proxy,
"https": proxy,
} if proxy else None
try:
response = requests.post(url, json=data, headers=headers, proxies=proxies, stream=stream)
response.raise_for_status()
return response
except requests.RequestException as e:
print(f"Request failed: {e}")
raise
@staticmethod
def _process_non_streaming_response(response: requests.Response) -> str:
if response.status_code == 200:
try:
content = response.text.lstrip('')
data = json.loads(content)
return data.get('message', '')
except json.JSONDecodeError:
return "Error: Unable to decode JSON response"
else:
return f"Error: {response.status_code}"
@staticmethod
async def _process_streaming_response(response: requests.Response):
full_message = ""
for line in response.iter_lines(decode_unicode=True):
if line:
try:
line = line.lstrip('')
data = json.loads(line)
if data.get('finish'):
break
message = data.get('message', '')
if message:
yield message[len(full_message):]
full_message = message
except json.JSONDecodeError:
pass
@staticmethod
def _filter_response(response: requests.Response) -> str:
response_json = response.json()
return response_json.get("gpt", "")