diff options
-rw-r--r-- | docs/providers-and-models.md | 7 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGPT.py | 270 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGPT4o.py | 86 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGptV2.py | 92 | ||||
-rw-r--r-- | g4f/Provider/nexra/NexraChatGptWeb.py | 64 | ||||
-rw-r--r-- | g4f/Provider/nexra/__init__.py | 3 | ||||
-rw-r--r-- | g4f/models.py | 7 |
7 files changed, 237 insertions, 292 deletions
diff --git a/docs/providers-and-models.md b/docs/providers-and-models.md index 18a36630..b3dbd9f1 100644 --- a/docs/providers-and-models.md +++ b/docs/providers-and-models.md @@ -64,10 +64,7 @@ This document provides an overview of various AI providers and models, including |[app.myshell.ai/chat](https://app.myshell.ai/chat)|`g4f.Provider.MyShell`|✔|❌|?|?|![Disabled](https://img.shields.io/badge/Disabled-red)|❌| |[nexra.aryahcr.cc/bing](https://nexra.aryahcr.cc/documentation/bing/en)|`g4f.Provider.NexraBing`|✔|❌|❌|✔|![Disabled](https://img.shields.io/badge/Disabled-red)|❌| |[nexra.aryahcr.cc/blackbox](https://nexra.aryahcr.cc/documentation/blackbox/en)|`g4f.Provider.NexraBlackbox`|`blackboxai` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| -|[nexra.aryahcr.cc/chatgpt](https://nexra.aryahcr.cc/documentation/chatgpt/en)|`g4f.Provider.NexraChatGPT`|`gpt-4, gpt-3.5-turbo, gpt-3` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| -|[nexra.aryahcr.cc/chatgpt](https://nexra.aryahcr.cc/documentation/chatgpt/en)|`g4f.Provider.NexraChatGPT4o`|`gpt-4o` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| -|[nexra.aryahcr.cc/chatgpt](https://nexra.aryahcr.cc/documentation/chatgpt/en)|`g4f.Provider.NexraChatGptV2`|`gpt-4` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| -|[nexra.aryahcr.cc/chatgpt](https://nexra.aryahcr.cc/documentation/chatgpt/en)|`g4f.Provider.NexraChatGptWeb`|`gpt-4` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| +|[nexra.aryahcr.cc/chatgpt](https://nexra.aryahcr.cc/documentation/chatgpt/en)|`g4f.Provider.NexraChatGPT`|`gpt-4, gpt-3.5-turbo, gpt-3, gpt-4o` |❌|❌|✔|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| |[nexra.aryahcr.cc/dall-e](https://nexra.aryahcr.cc/documentation/dall-e/en)|`g4f.Provider.NexraDallE`|❌|`dalle`|❌|❌|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| |[nexra.aryahcr.cc/dall-e](https://nexra.aryahcr.cc/documentation/dall-e/en)|`g4f.Provider.NexraDallE2`|❌|`dalle-2`|❌|❌|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| |[nexra.aryahcr.cc/emi](https://nexra.aryahcr.cc/documentation/emi/en)|`g4f.Provider.NexraEmi`|❌|`emi`|❌|❌|![Active](https://img.shields.io/badge/Active-brightgreen)|❌| @@ -109,7 +106,7 @@ This document provides an overview of various AI providers and models, including |-------|---------------|-----------|---------| |gpt-3|OpenAI|1+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-base)| |gpt-3.5-turbo|OpenAI|5+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-3-5-turbo)| -|gpt-4|OpenAI|9+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4)| +|gpt-4|OpenAI|7+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4)| |gpt-4-turbo|OpenAI|3+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4)| |gpt-4o|OpenAI|10+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-4o)| |gpt-4o-mini|OpenAI|14+ Providers|[platform.openai.com](https://platform.openai.com/docs/models/gpt-4o-mini)| diff --git a/g4f/Provider/nexra/NexraChatGPT.py b/g4f/Provider/nexra/NexraChatGPT.py index fc5051ee..074a0363 100644 --- a/g4f/Provider/nexra/NexraChatGPT.py +++ b/g4f/Provider/nexra/NexraChatGPT.py @@ -1,45 +1,52 @@ from __future__ import annotations +import asyncio import json import requests +from typing import Any, Dict -from ...typing import CreateResult, Messages -from ..base_provider import ProviderModelMixin, AbstractProvider +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin from ..helper import format_prompt -class NexraChatGPT(AbstractProvider, ProviderModelMixin): + +class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin): label = "Nexra ChatGPT" url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" - api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt" + 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' - models = ['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_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": "gpt-4-32k", - "gpt-4": "gpt-4-0314", - "gpt-4": "gpt-4-32k-0314", - + "gpt-4-32k": "gpt-4-32k-0314", "gpt-3.5-turbo": "gpt-3.5-turbo-16k", - "gpt-3.5-turbo": "gpt-3.5-turbo-0613", - "gpt-3.5-turbo": "gpt-3.5-turbo-16k-0613", - "gpt-3.5-turbo": "gpt-3.5-turbo-0301", - + "gpt-3.5-turbo-0613": "gpt-3.5-turbo-16k-0613", "gpt-3": "text-davinci-003", - "gpt-3": "text-davinci-002", - "gpt-3": "code-davinci-002", - "gpt-3": "text-curie-001", - "gpt-3": "text-babbage-001", - "gpt-3": "text-ada-001", - "gpt-3": "text-ada-001", - "gpt-3": "davinci", - "gpt-3": "curie", - "gpt-3": "babbage", - "gpt-3": "ada", - "gpt-3": "babbage-002", - "gpt-3": "davinci-002", + "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 @@ -50,40 +57,229 @@ class NexraChatGPT(AbstractProvider, ProviderModelMixin): return cls.model_aliases[model] else: return cls.default_model - + @classmethod - def create_completion( + async def create_async_generator( cls, model: str, messages: Messages, + stream: bool = False, proxy: str = None, markdown: bool = False, **kwargs - ) -> CreateResult: - model = cls.get_model(model) + ) -> 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' + "Content-Type": "application/json" } + prompt = format_prompt(messages) data = { - "messages": [], - "prompt": format_prompt(messages), + "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) - response = requests.post(cls.api_endpoint, headers=headers, json=data) + headers = { + "Content-Type": "application/json" + } + + prompt = format_prompt(messages) + data = { + "messages": [ + { + "role": "user", + "content": prompt + } + ], + "stream": stream, + "markdown": markdown, + "model": model + } - return cls.process_response(response) + 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 - def process_response(cls, response): + 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: - data = response.json() - return data.get('gpt', '') + 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", "") diff --git a/g4f/Provider/nexra/NexraChatGPT4o.py b/g4f/Provider/nexra/NexraChatGPT4o.py deleted file mode 100644 index 126d32b8..00000000 --- a/g4f/Provider/nexra/NexraChatGPT4o.py +++ /dev/null @@ -1,86 +0,0 @@ -from __future__ import annotations - -import json -import requests - -from ...typing import CreateResult, Messages -from ..base_provider import ProviderModelMixin, AbstractProvider -from ..helper import format_prompt - -class NexraChatGPT4o(AbstractProvider, ProviderModelMixin): - label = "Nexra ChatGPT4o" - url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" - api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" - working = True - supports_stream = True - - default_model = "gpt-4o" - models = [default_model] - - @classmethod - def get_model(cls, model: str) -> str: - return cls.default_model - - @classmethod - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - markdown: bool = False, - **kwargs - ) -> CreateResult: - model = cls.get_model(model) - - headers = { - 'Content-Type': 'application/json' - } - - data = { - "messages": [ - { - "role": "user", - "content": format_prompt(messages) - } - ], - "stream": stream, - "markdown": markdown, - "model": model - } - - response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) - - if stream: - return cls.process_streaming_response(response) - else: - return cls.process_non_streaming_response(response) - - @classmethod - def process_non_streaming_response(cls, response): - 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}" - - @classmethod - def process_streaming_response(cls, 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 and message != full_message: - yield message[len(full_message):] - full_message = message - except json.JSONDecodeError: - pass diff --git a/g4f/Provider/nexra/NexraChatGptV2.py b/g4f/Provider/nexra/NexraChatGptV2.py deleted file mode 100644 index 1ff42705..00000000 --- a/g4f/Provider/nexra/NexraChatGptV2.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import annotations - -import json -import requests - -from ...typing import CreateResult, Messages -from ..base_provider import ProviderModelMixin, AbstractProvider -from ..helper import format_prompt - -class NexraChatGptV2(AbstractProvider, ProviderModelMixin): - label = "Nexra ChatGPT v2" - url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" - api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" - working = True - supports_stream = True - - default_model = 'chatgpt' - models = [default_model] - model_aliases = {"gpt-4": "chatgpt"} - - @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 - def create_completion( - cls, - model: str, - messages: Messages, - stream: bool, - proxy: str = None, - markdown: bool = False, - **kwargs - ) -> CreateResult: - model = cls.get_model(model) - - headers = { - 'Content-Type': 'application/json' - } - - data = { - "messages": [ - { - "role": "user", - "content": format_prompt(messages) - } - ], - "stream": stream, - "markdown": markdown, - "model": model - } - - response = requests.post(cls.api_endpoint, headers=headers, json=data, stream=stream) - - if stream: - return cls.process_streaming_response(response) - else: - return cls.process_non_streaming_response(response) - - @classmethod - def process_non_streaming_response(cls, response): - 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}" - - @classmethod - def process_streaming_response(cls, 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 diff --git a/g4f/Provider/nexra/NexraChatGptWeb.py b/g4f/Provider/nexra/NexraChatGptWeb.py deleted file mode 100644 index f82694d4..00000000 --- a/g4f/Provider/nexra/NexraChatGptWeb.py +++ /dev/null @@ -1,64 +0,0 @@ -from __future__ import annotations - -import json -import requests - -from ...typing import CreateResult, Messages -from ..base_provider import ProviderModelMixin, AbstractProvider -from ..helper import format_prompt - -class NexraChatGptWeb(AbstractProvider, ProviderModelMixin): - label = "Nexra ChatGPT Web" - url = "https://nexra.aryahcr.cc/documentation/chatgpt/en" - working = True - - default_model = "gptweb" - models = [default_model] - model_aliases = {"gpt-4": "gptweb"} - api_endpoints = {"gptweb": "https://nexra.aryahcr.cc/api/chat/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 - def create_completion( - cls, - model: str, - messages: Messages, - proxy: str = None, - markdown: bool = False, - **kwargs - ) -> CreateResult: - model = cls.get_model(model) - api_endpoint = cls.api_endpoints.get(model, cls.api_endpoints[cls.default_model]) - - headers = { - 'Content-Type': 'application/json' - } - - data = { - "prompt": format_prompt(messages), - "markdown": markdown - } - - response = requests.post(api_endpoint, headers=headers, json=data) - - return cls.process_response(response) - - @classmethod - def process_response(cls, response): - if response.status_code == 200: - try: - content = response.text.lstrip('_') - json_response = json.loads(content) - return json_response.get('gpt', '') - except json.JSONDecodeError: - return "Error: Unable to decode JSON response" - else: - return f"Error: {response.status_code}" diff --git a/g4f/Provider/nexra/__init__.py b/g4f/Provider/nexra/__init__.py index 6121fdc0..bebc1fb6 100644 --- a/g4f/Provider/nexra/__init__.py +++ b/g4f/Provider/nexra/__init__.py @@ -1,9 +1,6 @@ from .NexraBing import NexraBing from .NexraBlackbox import NexraBlackbox from .NexraChatGPT import NexraChatGPT -from .NexraChatGPT4o import NexraChatGPT4o -from .NexraChatGptV2 import NexraChatGptV2 -from .NexraChatGptWeb import NexraChatGptWeb from .NexraDallE import NexraDallE from .NexraDallE2 import NexraDallE2 from .NexraEmi import NexraEmi diff --git a/g4f/models.py b/g4f/models.py index 1bea9eec..32a12d10 100644 --- a/g4f/models.py +++ b/g4f/models.py @@ -42,9 +42,6 @@ from .Provider import ( NexraBing, NexraBlackbox, NexraChatGPT, - NexraChatGPT4o, - NexraChatGptV2, - NexraChatGptWeb, NexraDallE, NexraDallE2, NexraEmi, @@ -140,7 +137,7 @@ gpt_35_turbo = Model( gpt_4o = Model( name = 'gpt-4o', base_provider = 'OpenAI', - best_provider = IterListProvider([NexraChatGPT4o, Blackbox, ChatGptEs, AmigoChat, DarkAI, Editee, GizAI, Airforce, Liaobots, OpenaiChat]) + best_provider = IterListProvider([NexraChatGPT, Blackbox, ChatGptEs, AmigoChat, DarkAI, Editee, GizAI, Airforce, Liaobots, OpenaiChat]) ) gpt_4o_mini = Model( @@ -158,7 +155,7 @@ gpt_4_turbo = Model( gpt_4 = Model( name = 'gpt-4', base_provider = 'OpenAI', - best_provider = IterListProvider([Chatgpt4Online, Ai4Chat, NexraBing, NexraChatGPT, NexraChatGptV2, NexraChatGptWeb, Airforce, Bing, OpenaiChat, gpt_4_turbo.best_provider, gpt_4o.best_provider, gpt_4o_mini.best_provider]) + best_provider = IterListProvider([Chatgpt4Online, Ai4Chat, NexraBing, NexraChatGPT, Airforce, Bing, OpenaiChat, gpt_4_turbo.best_provider, gpt_4o.best_provider, gpt_4o_mini.best_provider]) ) # o1 |