From 58db9e03f0a25613cf90cf8184ebf159123e7477 Mon Sep 17 00:00:00 2001 From: kqlio67 Date: Sun, 29 Sep 2024 23:38:25 +0300 Subject: feat(g4f/Provider/Nexra.py): enhance model handling and add new providers --- g4f/Provider/nexra/NexraBing.py | 82 +++++++++++++++++++++++++++++++++++ g4f/Provider/nexra/NexraChatGPT.py | 66 ++++++++++++++++++++++++++++ g4f/Provider/nexra/NexraChatGPT4o.py | 52 ++++++++++++++++++++++ g4f/Provider/nexra/NexraChatGPTWeb.py | 53 ++++++++++++++++++++++ g4f/Provider/nexra/NexraGeminiPro.py | 52 ++++++++++++++++++++++ g4f/Provider/nexra/NexraImageURL.py | 46 ++++++++++++++++++++ g4f/Provider/nexra/NexraLlama.py | 52 ++++++++++++++++++++++ g4f/Provider/nexra/NexraQwen.py | 52 ++++++++++++++++++++++ g4f/Provider/nexra/__init__.py | 1 + 9 files changed, 456 insertions(+) create mode 100644 g4f/Provider/nexra/NexraBing.py create mode 100644 g4f/Provider/nexra/NexraChatGPT.py create mode 100644 g4f/Provider/nexra/NexraChatGPT4o.py create mode 100644 g4f/Provider/nexra/NexraChatGPTWeb.py create mode 100644 g4f/Provider/nexra/NexraGeminiPro.py create mode 100644 g4f/Provider/nexra/NexraImageURL.py create mode 100644 g4f/Provider/nexra/NexraLlama.py create mode 100644 g4f/Provider/nexra/NexraQwen.py create mode 100644 g4f/Provider/nexra/__init__.py (limited to 'g4f/Provider/nexra') diff --git a/g4f/Provider/nexra/NexraBing.py b/g4f/Provider/nexra/NexraBing.py new file mode 100644 index 00000000..59e06a3d --- /dev/null +++ b/g4f/Provider/nexra/NexraBing.py @@ -0,0 +1,82 @@ +from __future__ import annotations +from aiohttp import ClientSession +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt +import json + +class NexraBing(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra Bing" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" + + bing_models = { + 'Bing (Balanced)': 'Balanced', + 'Bing (Creative)': 'Creative', + 'Bing (Precise)': 'Precise' + } + + models = [*bing_models.keys()] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json", + "Accept": "application/json", + "Origin": cls.url or "https://default-url.com", + "Referer": f"{cls.url}/chat" if cls.url else "https://default-url.com/chat", + } + + async with ClientSession(headers=headers) as session: + prompt = format_prompt(messages) + if prompt is None: + raise ValueError("Prompt cannot be None") + + data = { + "messages": [ + { + "role": "user", + "content": prompt + } + ], + "conversation_style": cls.bing_models.get(model, 'Balanced'), + "markdown": False, + "stream": True, + "model": "Bing" + } + + full_response = "" + last_message = "" + + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + + async for line in response.content: + if line: + raw_data = line.decode('utf-8').strip() + + parts = raw_data.split('') + for part in parts: + if part: + try: + json_data = json.loads(part) + except json.JSONDecodeError: + continue + + if json_data.get("error"): + raise Exception("Error in API response") + + if json_data.get("finish"): + break + + if message := json_data.get("message"): + if message != last_message: + full_response = message + last_message = message + + yield full_response.strip() diff --git a/g4f/Provider/nexra/NexraChatGPT.py b/g4f/Provider/nexra/NexraChatGPT.py new file mode 100644 index 00000000..8ed83f98 --- /dev/null +++ b/g4f/Provider/nexra/NexraChatGPT.py @@ -0,0 +1,66 @@ +from __future__ import annotations +from aiohttp import ClientSession +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt +import json + +class NexraChatGPT(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra ChatGPT" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/gpt" + + models = [ + 'gpt-4', 'gpt-4-0613', 'gpt-4-32k', 'gpt-4-0314', '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.5-turbo-0301', + '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', + ] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Accept": "application/json", + "Content-Type": "application/json", + "Referer": f"{cls.url}/chat", + } + + async with ClientSession(headers=headers) as session: + prompt = format_prompt(messages) + data = { + "prompt": prompt, + "model": model, + "markdown": False, + "messages": messages or [], + } + + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + + content_type = response.headers.get('Content-Type', '') + if 'application/json' in content_type: + result = await response.json() + if result.get("status"): + yield result.get("gpt", "") + else: + raise Exception(f"Error in response: {result.get('message', 'Unknown error')}") + elif 'text/plain' in content_type: + text = await response.text() + try: + result = json.loads(text) + if result.get("status"): + yield result.get("gpt", "") + else: + raise Exception(f"Error in response: {result.get('message', 'Unknown error')}") + except json.JSONDecodeError: + yield text # If not JSON, return text + else: + raise Exception(f"Unexpected response type: {content_type}. Response text: {await response.text()}") + diff --git a/g4f/Provider/nexra/NexraChatGPT4o.py b/g4f/Provider/nexra/NexraChatGPT4o.py new file mode 100644 index 00000000..eb18d439 --- /dev/null +++ b/g4f/Provider/nexra/NexraChatGPT4o.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt + + +class NexraChatGPT4o(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra GPT-4o" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" + models = ['gpt-4o'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json" + } + async with ClientSession(headers=headers) as session: + data = { + "messages": [ + {'role': 'assistant', 'content': ''}, + {'role': 'user', 'content': format_prompt(messages)} + ], + "markdown": False, + "stream": True, + "model": model + } + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + full_response = '' + async for line in response.content: + if line: + messages = line.decode('utf-8').split('\x1e') + for message_str in messages: + try: + message = json.loads(message_str) + if message.get('message'): + full_response = message['message'] + if message.get('finish'): + yield full_response.strip() + return + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraChatGPTWeb.py b/g4f/Provider/nexra/NexraChatGPTWeb.py new file mode 100644 index 00000000..e7738665 --- /dev/null +++ b/g4f/Provider/nexra/NexraChatGPTWeb.py @@ -0,0 +1,53 @@ +from __future__ import annotations +from aiohttp import ClientSession +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt +import json + +class NexraChatGPTWeb(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra ChatGPT Web" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/gptweb" + models = ['gptweb'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json", + } + + async with ClientSession(headers=headers) as session: + prompt = format_prompt(messages) + if prompt is None: + raise ValueError("Prompt cannot be None") + + data = { + "prompt": prompt, + "markdown": False + } + + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + + full_response = "" + async for chunk in response.content: + if chunk: + result = chunk.decode("utf-8").strip() + + try: + json_data = json.loads(result) + + if json_data.get("status"): + full_response = json_data.get("gpt", "") + else: + full_response = f"Error: {json_data.get('message', 'Unknown error')}" + except json.JSONDecodeError: + full_response = "Error: Invalid JSON response." + + yield full_response.strip() diff --git a/g4f/Provider/nexra/NexraGeminiPro.py b/g4f/Provider/nexra/NexraGeminiPro.py new file mode 100644 index 00000000..a57daed4 --- /dev/null +++ b/g4f/Provider/nexra/NexraGeminiPro.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt + + +class NexraGeminiPro(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra Gemini PRO" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" + models = ['gemini-pro'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json" + } + async with ClientSession(headers=headers) as session: + data = { + "messages": [ + {'role': 'assistant', 'content': ''}, + {'role': 'user', 'content': format_prompt(messages)} + ], + "markdown": False, + "stream": True, + "model": model + } + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + full_response = '' + async for line in response.content: + if line: + messages = line.decode('utf-8').split('\x1e') + for message_str in messages: + try: + message = json.loads(message_str) + if message.get('message'): + full_response = message['message'] + if message.get('finish'): + yield full_response.strip() + return + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraImageURL.py b/g4f/Provider/nexra/NexraImageURL.py new file mode 100644 index 00000000..13d70757 --- /dev/null +++ b/g4f/Provider/nexra/NexraImageURL.py @@ -0,0 +1,46 @@ +from __future__ import annotations +from aiohttp import ClientSession +import json +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt +from ...image import ImageResponse + +class NexraImageURL(AsyncGeneratorProvider, ProviderModelMixin): + label = "Image Generation Provider" + api_endpoint = "https://nexra.aryahcr.cc/api/image/complements" + models = ['dalle', 'dalle2', 'dalle-mini', 'emi', 'sdxl-turbo', 'prodia'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json", + } + + async with ClientSession(headers=headers) as session: + prompt = format_prompt(messages) + data = { + "prompt": prompt, + "model": model, + "response": "url" + } + + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + response_text = await response.text() + + cleaned_response = response_text.lstrip('_') + response_json = json.loads(cleaned_response) + + images = response_json.get("images") + if images and len(images) > 0: + image_response = ImageResponse(images[0], alt="Generated Image") + yield image_response + else: + yield "No image URL found." diff --git a/g4f/Provider/nexra/NexraLlama.py b/g4f/Provider/nexra/NexraLlama.py new file mode 100644 index 00000000..9ed892e8 --- /dev/null +++ b/g4f/Provider/nexra/NexraLlama.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt + + +class NexraLlama(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra LLaMA 3.1" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" + models = ['llama-3.1'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json" + } + async with ClientSession(headers=headers) as session: + data = { + "messages": [ + {'role': 'assistant', 'content': ''}, + {'role': 'user', 'content': format_prompt(messages)} + ], + "markdown": False, + "stream": True, + "model": model + } + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + full_response = '' + async for line in response.content: + if line: + messages = line.decode('utf-8').split('\x1e') + for message_str in messages: + try: + message = json.loads(message_str) + if message.get('message'): + full_response = message['message'] + if message.get('finish'): + yield full_response.strip() + return + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/NexraQwen.py b/g4f/Provider/nexra/NexraQwen.py new file mode 100644 index 00000000..ae8e9a0e --- /dev/null +++ b/g4f/Provider/nexra/NexraQwen.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import json +from aiohttp import ClientSession + +from ...typing import AsyncResult, Messages +from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin +from ..helper import format_prompt + + +class NexraQwen(AsyncGeneratorProvider, ProviderModelMixin): + label = "Nexra Qwen" + api_endpoint = "https://nexra.aryahcr.cc/api/chat/complements" + models = ['qwen'] + + @classmethod + async def create_async_generator( + cls, + model: str, + messages: Messages, + proxy: str = None, + **kwargs + ) -> AsyncResult: + headers = { + "Content-Type": "application/json" + } + async with ClientSession(headers=headers) as session: + data = { + "messages": [ + {'role': 'assistant', 'content': ''}, + {'role': 'user', 'content': format_prompt(messages)} + ], + "markdown": False, + "stream": True, + "model": model + } + async with session.post(cls.api_endpoint, json=data, proxy=proxy) as response: + response.raise_for_status() + full_response = '' + async for line in response.content: + if line: + messages = line.decode('utf-8').split('\x1e') + for message_str in messages: + try: + message = json.loads(message_str) + if message.get('message'): + full_response = message['message'] + if message.get('finish'): + yield full_response.strip() + return + except json.JSONDecodeError: + pass diff --git a/g4f/Provider/nexra/__init__.py b/g4f/Provider/nexra/__init__.py new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/g4f/Provider/nexra/__init__.py @@ -0,0 +1 @@ + -- cgit v1.2.3